diff --git a/src/sly/parser/parser/ISyntaxParser.cs b/src/sly/parser/parser/ISyntaxParser.cs index 22e10eec..a1ed7383 100644 --- a/src/sly/parser/parser/ISyntaxParser.cs +++ b/src/sly/parser/parser/ISyntaxParser.cs @@ -10,7 +10,7 @@ public interface ISyntaxParser where IN : struct Dictionary> LexemeLabels { get; set; } - SyntaxParseResult Parse(IList> tokens, string startingNonTerminal = null); + SyntaxParseResult Parse(Token[] tokens, string startingNonTerminal = null); void Init(ParserConfiguration configuration, string root); diff --git a/src/sly/parser/parser/Parser.cs b/src/sly/parser/parser/Parser.cs index 30c710bd..b69261eb 100644 --- a/src/sly/parser/parser/Parser.cs +++ b/src/sly/parser/parser/Parser.cs @@ -108,7 +108,7 @@ public ParseResult ParseWithContext(IList> tokens, object par var result = new ParseResult(); var cleaner = new SyntaxTreeCleaner(); - var syntaxResult = SyntaxParser.Parse(tokens, startingNonTerminal); + var syntaxResult = SyntaxParser.Parse(tokens.ToArray(), startingNonTerminal); syntaxResult.UsesOperations = Configuration.UsesOperations; syntaxResult = cleaner.CleanSyntaxTree(syntaxResult); if (!syntaxResult.IsError && syntaxResult.Root != null) diff --git a/src/sly/parser/parser/SyntaxParseResult.cs b/src/sly/parser/parser/SyntaxParseResult.cs index 51a5a081..9b8cbd31 100644 --- a/src/sly/parser/parser/SyntaxParseResult.cs +++ b/src/sly/parser/parser/SyntaxParseResult.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using sly.parser.syntax.grammar; using sly.parser.syntax.tree; @@ -14,7 +15,7 @@ public class SyntaxParseResult where IN : struct - private List> Errors { get; set; } + private HashSet> Errors { get; set; } public int EndingPosition { get; set; } @@ -22,8 +23,9 @@ public class SyntaxParseResult where IN : struct private void InitErrors() { - if (Errors == null) { - Errors = new List>(); + if (Errors == null) + { + Errors = new HashSet>(); } } @@ -39,14 +41,10 @@ public void AddErrors(IList> errors) public void AddError(UnexpectedTokenSyntaxError error) { InitErrors(); - if (!Errors.Contains(error)) - { - // #493 : dedup errors - Errors.Add(error); - } + Errors.Add(error); } - public IList> GetErrors() => Errors; + public IList> GetErrors() => Errors?.ToList(); public List> Expecting {get; set;} diff --git a/src/sly/parser/parser/llparser/bnf/RecursiveDescentSyntaxParser.NonTerminal.cs b/src/sly/parser/parser/llparser/bnf/RecursiveDescentSyntaxParser.NonTerminal.cs index ebb76e01..55dcd796 100644 --- a/src/sly/parser/parser/llparser/bnf/RecursiveDescentSyntaxParser.NonTerminal.cs +++ b/src/sly/parser/parser/llparser/bnf/RecursiveDescentSyntaxParser.NonTerminal.cs @@ -9,14 +9,14 @@ public partial class RecursiveDescentSyntaxParser where IN : struct { #region parsing - public SyntaxParseResult ParseNonTerminal(IList> tokens, NonTerminalClause nonTermClause, + public SyntaxParseResult ParseNonTerminal(Token[] tokens, NonTerminalClause nonTermClause, int currentPosition, SyntaxParsingContext parsingContext) { var result = ParseNonTerminal(tokens, nonTermClause.NonTerminalName, currentPosition, parsingContext); return result; } - public SyntaxParseResult ParseNonTerminal(IList> tokens, string nonTerminalName, + public SyntaxParseResult ParseNonTerminal(Token[] tokens, string nonTerminalName, int currentPosition, SyntaxParsingContext parsingContext) { if (parsingContext.TryGetParseResult(new NonTerminalClause(nonTerminalName), currentPosition, @@ -38,7 +38,7 @@ public SyntaxParseResult ParseNonTerminal(IList> tokens, stri while (i < rules.Count) { var innerrule = rules[i]; - if (startPosition < tokens.Count + if (startPosition < tokens.Length && (!tokens[startPosition].IsEOS || (tokens[startPosition].IsEOS && innerrule.MayBeEmpty)) && innerrule.Match(tokens, startPosition, Configuration)) { @@ -46,16 +46,17 @@ public SyntaxParseResult ParseNonTerminal(IList> tokens, stri rulesResults.Add(innerRuleRes); var other = greaterIndex == 0 && innerRuleRes.EndingPosition == 0; - if (innerRuleRes.EndingPosition > greaterIndex && innerRuleRes.GetErrors() != null && - innerRuleRes.GetErrors().Count == 0 || other) + var innerRuleResErrors = innerRuleRes.GetErrors(); + if (innerRuleRes.EndingPosition > greaterIndex && innerRuleResErrors != null && + innerRuleResErrors.Count == 0 || other) { greaterIndex = innerRuleRes.EndingPosition; - if (innerRuleRes.GetErrors() != null) - innerRuleErrors.AddRange(innerRuleRes.GetErrors()); + if (innerRuleResErrors != null) + innerRuleErrors.AddRange(innerRuleResErrors); } - if (innerRuleRes.GetErrors() != null) - innerRuleErrors.AddRange(innerRuleRes.GetErrors()); + if (innerRuleResErrors != null) + innerRuleErrors.AddRange(innerRuleResErrors); } i++; @@ -123,9 +124,10 @@ public SyntaxParseResult ParseNonTerminal(IList> tokens, stri List> terr = new List>(); foreach (var ruleResult in rulesResults) { - if (ruleResult.GetErrors() != null) + var ruleErrors = ruleResult.GetErrors(); + if (ruleErrors != null) { - terr.AddRange(ruleResult.GetErrors()); + terr.AddRange(ruleErrors); } } diff --git a/src/sly/parser/parser/llparser/bnf/RecursiveDescentSyntaxParser.Terminal.cs b/src/sly/parser/parser/llparser/bnf/RecursiveDescentSyntaxParser.Terminal.cs index 7449b037..4cade1f1 100644 --- a/src/sly/parser/parser/llparser/bnf/RecursiveDescentSyntaxParser.Terminal.cs +++ b/src/sly/parser/parser/llparser/bnf/RecursiveDescentSyntaxParser.Terminal.cs @@ -9,7 +9,7 @@ public partial class RecursiveDescentSyntaxParser where IN : struct { #region parsing - public SyntaxParseResult ParseTerminal(IList> tokens, TerminalClause terminal, int position, + public SyntaxParseResult ParseTerminal(Token[] tokens, TerminalClause terminal, int position, SyntaxParsingContext parsingContext) { if (parsingContext.TryGetParseResult(terminal, position, out var parseResult)) diff --git a/src/sly/parser/parser/llparser/bnf/RecursiveDescentSyntaxParser.cs b/src/sly/parser/parser/llparser/bnf/RecursiveDescentSyntaxParser.cs index 54ab25d4..0b703c82 100644 --- a/src/sly/parser/parser/llparser/bnf/RecursiveDescentSyntaxParser.cs +++ b/src/sly/parser/parser/llparser/bnf/RecursiveDescentSyntaxParser.cs @@ -24,12 +24,12 @@ public RecursiveDescentSyntaxParser(ParserConfiguration configuration, #region parsing - public SyntaxParseResult Parse(IList> tokens, string startingNonTerminal = null) + public SyntaxParseResult Parse(Token[] tokens, string startingNonTerminal = null) { return SafeParse(tokens, new SyntaxParsingContext(Configuration.UseMemoization), startingNonTerminal); } - public SyntaxParseResult SafeParse(IList> tokens, SyntaxParsingContext parsingContext, string startingNonTerminal = null) + public SyntaxParseResult SafeParse(Token[] tokens, SyntaxParsingContext parsingContext, string startingNonTerminal = null) { var start = startingNonTerminal ?? StartingNonTerminal; var NonTerminals = Configuration.NonTerminals; @@ -93,7 +93,7 @@ public SyntaxParseResult SafeParse(IList> tokens, SyntaxParsi } else { - if (result.EndingPosition < tokens.Count-1) + if (result.EndingPosition < tokens.Length-1) { SyntaxParseResult r = new SyntaxParseResult() { @@ -133,7 +133,7 @@ public SyntaxParseResult SafeParse(IList> tokens, SyntaxParsi } - public virtual SyntaxParseResult Parse(IList> tokens, Rule rule, int position, + public virtual SyntaxParseResult Parse(Token[] tokens, Rule rule, int position, string nonTerminalName, SyntaxParsingContext parsingContext) { var currentPosition = position; @@ -169,16 +169,17 @@ public virtual SyntaxParseResult Parse(IList> tokens, Rule 0) - errors.AddRange(nonTerminalResult.GetErrors()); + if (ntErrors != null && ntErrors.Count > 0) + errors.AddRange(ntErrors); } else { - errors.AddRange(nonTerminalResult.GetErrors()); + errors.AddRange(ntErrors); } isError = nonTerminalResult.IsError; @@ -214,12 +215,12 @@ public virtual SyntaxParseResult Parse(IList> tokens, Rule NoMatchingRuleError(IList> tokens, int currentPosition, + private SyntaxParseResult NoMatchingRuleError(Token[] tokens, int currentPosition, List> allAcceptableTokens) { var noRuleErrors = new List>(); - if (currentPosition < tokens.Count) + if (currentPosition < tokens.Length) { noRuleErrors.Add(new UnexpectedTokenSyntaxError(tokens[currentPosition], I18n, allAcceptableTokens)); diff --git a/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.EBNFRecursiveDescentSyntaxParser.Choice.cs b/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.EBNFRecursiveDescentSyntaxParser.Choice.cs index 719b0469..1ce25458 100644 --- a/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.EBNFRecursiveDescentSyntaxParser.Choice.cs +++ b/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.EBNFRecursiveDescentSyntaxParser.Choice.cs @@ -12,7 +12,7 @@ public partial class EBNFRecursiveDescentSyntaxParser where IN : struct { #region parsing - public SyntaxParseResult ParseChoice(IList> tokens, ChoiceClause clause, + public SyntaxParseResult ParseChoice(Token[] tokens, ChoiceClause clause, int position, SyntaxParsingContext parsingContext) { if (parsingContext.TryGetParseResult(clause, position, out var parseResult)) diff --git a/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.Expressions.cs b/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.Expressions.cs index 251d9f2d..7eed7962 100644 --- a/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.Expressions.cs +++ b/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.Expressions.cs @@ -11,7 +11,7 @@ public partial class EBNFRecursiveDescentSyntaxParser { #region parsing - public virtual SyntaxParseResult ParseInfixExpressionRule(IList> tokens, Rule rule, + public virtual SyntaxParseResult ParseInfixExpressionRule(Token[] tokens, Rule rule, int position, string nonTerminalName, SyntaxParsingContext parsingContext) { @@ -97,9 +97,9 @@ public virtual SyntaxParseResult ParseInfixExpressionRule(IList(); finalResult.Root = finalNode; - finalResult.IsEnded = currentPosition >= tokens.Count - 1 - || currentPosition == tokens.Count - 2 && - tokens[tokens.Count - 1].IsEOS; + finalResult.IsEnded = currentPosition >= tokens.Length - 1 + || currentPosition == tokens.Length - 2 && + tokens[tokens.Length - 1].IsEOS; finalResult.EndingPosition = currentPosition; return finalResult; } @@ -120,9 +120,9 @@ public virtual SyntaxParseResult ParseInfixExpressionRule(IList= tokens.Count - 1 - || result.EndingPosition == tokens.Count - 2 && - tokens[tokens.Count - 1].IsEOS; + result.IsEnded = result.EndingPosition >= tokens.Length - 1 + || result.EndingPosition == tokens.Length - 2 && + tokens[tokens.Length - 1].IsEOS; return result; } diff --git a/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.Many.cs b/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.Many.cs index bc373d51..9214756e 100644 --- a/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.Many.cs +++ b/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.Many.cs @@ -11,7 +11,7 @@ public partial class EBNFRecursiveDescentSyntaxParser where IN : struct { #region parsing - public SyntaxParseResult ParseZeroOrMore(IList> tokens, ZeroOrMoreClause clause, int position, + public SyntaxParseResult ParseZeroOrMore(Token[] tokens, ZeroOrMoreClause clause, int position, SyntaxParsingContext parsingContext) { if (parsingContext.TryGetParseResult(clause, position, out var parseResult)) @@ -67,9 +67,10 @@ public SyntaxParseResult ParseZeroOrMore(IList> tokens, ZeroO currentPosition = innerResult.EndingPosition; lastInnerResult = innerResult; hasByPasNodes = hasByPasNodes || innerResult.HasByPassNodes; - if (lastInnerResult.GetErrors() != null) + var lastInnerErrors = lastInnerResult.GetErrors(); + if (lastInnerErrors != null) { - innerErrors.AddRange(lastInnerResult.GetErrors()); + innerErrors.AddRange(lastInnerErrors); } } else @@ -80,7 +81,7 @@ public SyntaxParseResult ParseZeroOrMore(IList> tokens, ZeroO } } - stillOk = innerResult != null && !innerResult.IsError && currentPosition < tokens.Count; + stillOk = innerResult != null && !innerResult.IsError && currentPosition < tokens.Length; } @@ -94,7 +95,7 @@ public SyntaxParseResult ParseZeroOrMore(IList> tokens, ZeroO return result; } - public SyntaxParseResult ParseRepeat(IList> tokens, RepeatClause clause, int position, + public SyntaxParseResult ParseRepeat(Token[] tokens, RepeatClause clause, int position, SyntaxParsingContext parsingContext) { if (parsingContext.TryGetParseResult(clause, position, out var parseResult)) @@ -155,7 +156,7 @@ public SyntaxParseResult ParseRepeat(IList> tokens, RepeatCla return result; } - private SyntaxParseResult ParseInnerRepeat(IList> tokens, SyntaxParsingContext parsingContext, IClause innerClause, + private SyntaxParseResult ParseInnerRepeat(Token[] tokens, SyntaxParsingContext parsingContext, IClause innerClause, ManySyntaxNode manyNode, int currentPosition, out bool hasByPasNodes) { SyntaxParseResult innerResult; @@ -189,7 +190,7 @@ private SyntaxParseResult ParseInnerRepeat(IList> tokens, Syn return innerResult; } - public SyntaxParseResult ParseOneOrMore(IList> tokens, OneOrMoreClause clause, int position, + public SyntaxParseResult ParseOneOrMore(Token[] tokens, OneOrMoreClause clause, int position, SyntaxParsingContext parsingContext) { if (parsingContext.TryGetParseResult(clause, position, out var parseResult)) diff --git a/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.Option.cs b/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.Option.cs index e43edd59..e101fb73 100644 --- a/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.Option.cs +++ b/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.Option.cs @@ -10,7 +10,7 @@ public partial class EBNFRecursiveDescentSyntaxParser where IN : struct { #region parsing - public SyntaxParseResult ParseOption(IList> tokens, OptionClause clause, Rule rule, + public SyntaxParseResult ParseOption(Token[] tokens, OptionClause clause, Rule rule, int position, SyntaxParsingContext parsingContext) { if (parsingContext.TryGetParseResult(clause, position, out var parseResult)) diff --git a/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.cs b/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.cs index 0b24b710..7210a541 100644 --- a/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.cs +++ b/src/sly/parser/parser/llparser/ebnf/EBNFRecursiveDescentSyntaxParser.cs @@ -19,7 +19,7 @@ public EBNFRecursiveDescentSyntaxParser(ParserConfiguration configurati #region parsing - public override SyntaxParseResult Parse(IList> tokens, Rule rule, int position, + public override SyntaxParseResult Parse(Token[] tokens, Rule rule, int position, string nonTerminalName, SyntaxParsingContext parsingContext) { if (rule.IsInfixExpressionRule && rule.IsExpressionRule) @@ -147,9 +147,9 @@ public override SyntaxParseResult Parse(IList> tokens, Rule(nonTerminalName, children); node = ManageExpressionRules(rule, node); result.Root = node; - result.IsEnded = currentPosition >= tokens.Count - 1 - || currentPosition == tokens.Count - 2 && - tokens[tokens.Count - 1].IsEOS; + result.IsEnded = currentPosition >= tokens.Length - 1 + || currentPosition == tokens.Length - 2 && + tokens[tokens.Length - 1].IsEOS; } else {