Skip to content

Commit

Permalink
Merge pull request #517 from b3b00/bugfix/#516-not-closed-xml-parsing…
Browse files Browse the repository at this point in the history
…-error

Bugfix/#516 not closed xml parsing error
  • Loading branch information
b3b00 authored Dec 17, 2024
2 parents ec213eb + c33eb85 commit d220846
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 10 deletions.
37 changes: 36 additions & 1 deletion src/samples/ParserExample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,41 @@ public static object Rec(List<object> args)
return "_";
}

private static void testIssue516()
{
ParserBuilder<MinimalXmlLexer, string> builder = new ParserBuilder<MinimalXmlLexer, string>();
var xmlparser = new MinimalXmlParser();
var r = builder.BuildParser(xmlparser, ParserType.EBNF_LL_RECURSIVE_DESCENT, "document");
Check.That(r.IsError).IsFalse();
var parser = r.Result;
var parsed = parser.Parse(@"
<?xml version=""1.0""?>
<!-- starting doc -->
<root name=""root"">
<autoInner name=""autoinner1""/>
<inner name=""inner"">
<?PI name=""pi""?>
<innerinner name=""innerinner"">
inner inner content
");
if (parsed.IsError)
{
parsed.Errors.ForEach(Console.WriteLine);
}

return;
var jBuilder = new ParserBuilder<JsonTokenGeneric, JSon>();
var jsonParser = new EbnfJsonGenericParser();
var jr = jBuilder.BuildParser(jsonParser, ParserType.EBNF_LL_RECURSIVE_DESCENT, "root");
Check.That(jr).IsOk();
var jparsed = jr.Result.Parse("{ \"toto\":1");
if (jparsed.IsError)
{
jparsed.Errors.ForEach(Console.WriteLine);
}

}

private static void TestIssue507()
{
var tests = new EBNFTests();
Expand Down Expand Up @@ -1360,7 +1394,8 @@ print a
}
private static void Main(string[] args)
{
TestIssue507();
testIssue516();
//TestIssue507();
//TestFStrings();
//TestIssue495();
//testGenericLexerJson();
Expand Down
2 changes: 1 addition & 1 deletion src/sly/parser/parser/UnexpectedTokenSyntaxError.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class UnexpectedTokenSyntaxError<T> : ParseError, IComparable where T : s
{
private readonly string _i18N;

private readonly Dictionary<T, Dictionary<string, string>> _labels;
private readonly Dictionary<T, Dictionary<string, string>> _labels = new Dictionary<T, Dictionary<string, string>>();
public UnexpectedTokenSyntaxError(Token<T> unexpectedToken, Dictionary<T, Dictionary<string, string>> labels, string i18n=null, params LeadingToken<T>[] expectedTokens )
{
_labels = labels;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public SyntaxParseResult<IN> SafeParse(IList<Token<IN>> tokens, SyntaxParsingCon
var errors = new List<UnexpectedTokenSyntaxError<IN>>();
var nt = NonTerminals[start];


var rs = new List<SyntaxParseResult<IN>>();

var matchingRuleCount = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,25 @@ public SyntaxParseResult<IN> ParseChoice(IList<Token<IN>> tokens, ChoiceClause<I
EndingPosition = currentPosition
};

List<SyntaxParseResult<IN>> alternateResults = new List<SyntaxParseResult<IN>>();

foreach (var alternate in clause.Choices)
{
switch (alternate)
{
case TerminalClause<IN> terminalAlternate:
result = ParseTerminal(tokens, terminalAlternate, currentPosition, parsingContext);
var rterm = ParseTerminal(tokens, terminalAlternate, currentPosition, parsingContext);
alternateResults.Add(rterm);
break;
case NonTerminalClause<IN> nonTerminalAlternate:
result = ParseNonTerminal(tokens, nonTerminalAlternate, currentPosition, parsingContext);
var rnonterm = ParseNonTerminal(tokens, nonTerminalAlternate, currentPosition, parsingContext);
alternateResults.Add(rnonterm);
break;
default:
throw new InvalidOperationException("unable to apply repeater inside " + clause.GetType().Name);
}

result = alternateResults.Last();
if (result.IsOk)
{
if (clause.IsTerminalChoice && clause.IsDiscarded && result.Root is SyntaxLeaf<IN> leaf)
Expand All @@ -57,13 +61,21 @@ public SyntaxParseResult<IN> ParseChoice(IList<Token<IN>> tokens, ChoiceClause<I
}
}

if (result.IsError && clause.IsTerminalChoice)
// here all alternateResult ar KO
if (clause.IsTerminalChoice)
{
var terminalAlternates = clause.Choices.Cast<TerminalClause<IN>>();
var expected = terminalAlternates.Select(x => x.ExpectedToken).ToList();
result.AddError(new UnexpectedTokenSyntaxError<IN>(tokens[currentPosition], LexemeLabels, I18n,
expected.ToArray()));
}
else
{
var greaterPosition = alternateResults.Select(x => x.EndingPosition).Max();
var errors= alternateResults.Where(x => x.EndingPosition == greaterPosition).SelectMany(x => x.GetErrors()).ToList();
result.AddErrors(errors);
result.IsError = true;
}

parsingContext.Memoize(clause, position, result);
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ public override SyntaxParseResult<IN> Parse(IList<Token<IN>> tokens, Rule<IN> ru
isError = isError || termRes.IsError;
break;
}
case NonTerminalClause<IN> terminalClause:
case NonTerminalClause<IN> nonTerminalClause:
{
var nonTerminalResult =
ParseNonTerminal(tokens, terminalClause, currentPosition, parsingContext);
ParseNonTerminal(tokens, nonTerminalClause, currentPosition, parsingContext);
if (!nonTerminalResult.IsError)
{
errors.AddRange(nonTerminalResult.GetErrors());
Expand Down Expand Up @@ -154,7 +154,7 @@ public override SyntaxParseResult<IN> Parse(IList<Token<IN>> tokens, Rule<IN> ru
node.ExpressionAffix = rule.ExpressionAffix;
node = ManageExpressionRules(rule, node);
result.Root = node;
result.IsEnded = tokens[result.EndingPosition].IsEOS
result.IsEnded = tokens[result.EndingPosition].IsEOS
|| node.IsEpsilon && tokens[result.EndingPosition+1].IsEOS;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/sly/sly.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2"/>
<PackageReference Include="System.Collections.Immutable" Version="9.0.0"/>
<PackageReference Include="System.Collections.Immutable" Version="8.0.0"/>
<PackageReference Include="System.Memory" Version="4.5.5"/>
<PackageReference Include="System.ValueTuple" Version="4.5.0"/>
</ItemGroup>
Expand Down
34 changes: 34 additions & 0 deletions tests/ParserTests/samples/XmlTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using NFluent;
using sly.parser;
using sly.parser.generator;
using XML;
using Xunit;

namespace ParserTests.samples;

public class XmlTests
{

[Fact]
public void TestXmlParserWithLexerModes()
{
ParserBuilder<MinimalXmlLexer, string> builder = new ParserBuilder<MinimalXmlLexer, string>();
var xmlparser = new MinimalXmlParser();
var r = builder.BuildParser(xmlparser, ParserType.EBNF_LL_RECURSIVE_DESCENT, "document");
Check.That(r.IsError).IsFalse();
var parser = r.Result;
var parsed = parser.Parse(@"
<?xml version=""1.0""?>
<!-- starting doc -->
<root name=""root"">
<autoInner name=""autoinner1""/>
<inner name=""inner"">
<?PI name=""pi""?>
<innerinner name=""innerinner"">
inner inner content
");
Check.That(parsed).Not.IsOkParsing();
var error = parsed.Errors[0];
Check.That(error.ErrorType).IsEqualTo(ErrorType.UnexpectedEOS);
}
}

0 comments on commit d220846

Please sign in to comment.