public SyntaxParseResult <IN> ParseNonTerminal(IList <Token <IN> > tokens, NonTerminalClause <IN> nonTermClause, int currentPosition) { var startPosition = currentPosition; var endingPosition = 0; var nt = Configuration.NonTerminals[nonTermClause.NonTerminalName]; var errors = new List <UnexpectedTokenSyntaxError <IN> >(); var i = 0; var allAcceptableTokens = new List <IN>(); nt.Rules.ForEach(r => { if (r != null && r.PossibleLeadingTokens != null) { allAcceptableTokens.AddRange(r.PossibleLeadingTokens); } }); allAcceptableTokens = allAcceptableTokens.Distinct().ToList(); var rules = nt.Rules .Where(r => startPosition < tokens.Count && r.PossibleLeadingTokens.Contains(tokens[startPosition].TokenID) || r.MayBeEmpty) .ToList(); if (rules.Count == 0) { return(NoMatchingRuleError(tokens, currentPosition, allAcceptableTokens)); } var innerRuleErrors = new List <UnexpectedTokenSyntaxError <IN> >(); var greaterIndex = 0; var rulesResults = new List <SyntaxParseResult <IN> >(); while (i < rules.Count) { var innerrule = rules[i]; var innerRuleRes = Parse(tokens, innerrule, startPosition, nonTermClause.NonTerminalName); rulesResults.Add(innerRuleRes); var other = greaterIndex == 0 && innerRuleRes.EndingPosition == 0; if (innerRuleRes.EndingPosition > greaterIndex && innerRuleRes.Errors != null && !innerRuleRes.Errors.Any() || other) { greaterIndex = innerRuleRes.EndingPosition; //innerRuleErrors.Clear(); innerRuleErrors.AddRange(innerRuleRes.Errors); } innerRuleErrors.AddRange(innerRuleRes.Errors); i++; } errors.AddRange(innerRuleErrors); SyntaxParseResult <IN> max = null; if (rulesResults.Any()) { if (rulesResults.Any(x => x.IsOk)) { max = rulesResults.Where(x => x.IsOk).OrderBy(x => x.EndingPosition).Last(); } else { max = rulesResults.Where(x => !x.IsOk).OrderBy(x => x.EndingPosition).Last(); } } else { max = new SyntaxParseResult <IN>(); max.IsError = true; max.Root = null; max.IsEnded = false; max.EndingPosition = currentPosition; } var result = new SyntaxParseResult <IN>(); result.Errors = errors; result.Root = max.Root; result.EndingPosition = max.EndingPosition; result.IsError = max.IsError; result.IsEnded = max.IsEnded; if (rulesResults.Any()) { var terr = rulesResults.SelectMany(x => x.Errors).ToList(); var unexpected = terr.Cast <UnexpectedTokenSyntaxError <IN> >().ToList(); var expecting = unexpected.SelectMany(x => x.ExpectedTokens).ToList(); result.AddExpectings(expecting); } return(result); }
public SyntaxParseResult <IN> ParseNonTerminal(IList <Token <IN> > tokens, NonTerminalClause <IN> nonTermClause, int currentPosition) { var startPosition = currentPosition; var endingPosition = 0; var nt = Configuration.NonTerminals[nonTermClause.NonTerminalName]; var errors = new List <UnexpectedTokenSyntaxError <IN> >(); var i = 0; var allAcceptableTokens = new List <IN>(); nt.Rules.ForEach(r => { if (r != null && r.PossibleLeadingTokens != null) { allAcceptableTokens.AddRange(r.PossibleLeadingTokens); } }); allAcceptableTokens = allAcceptableTokens.Distinct().ToList(); var rules = nt.Rules .Where(r => r.PossibleLeadingTokens.Contains(tokens[startPosition].TokenID) || r.MayBeEmpty) .ToList(); if (rules.Count == 0) { errors.Add(new UnexpectedTokenSyntaxError <IN>(tokens[startPosition], allAcceptableTokens.ToArray <IN>())); } var innerRuleErrors = new List <UnexpectedTokenSyntaxError <IN> >(); SyntaxParseResult <IN> okResult = null; var greaterIndex = 0; var allRulesInError = true; var test = new List <SyntaxParseResult <IN> >(); while (i < rules.Count) { var innerrule = rules[i]; var innerRuleRes = Parse(tokens, innerrule, startPosition, nonTermClause.NonTerminalName); if (!innerRuleRes.IsError && okResult == null || okResult != null && innerRuleRes.EndingPosition > okResult.EndingPosition) { okResult = innerRuleRes; okResult.Errors = innerRuleRes.Errors; endingPosition = innerRuleRes.EndingPosition; } else { test.Add(innerRuleRes); } var other = greaterIndex == 0 && innerRuleRes.EndingPosition == 0; if (innerRuleRes.EndingPosition > greaterIndex && innerRuleRes.Errors != null && !innerRuleRes.Errors.Any() || other) { greaterIndex = innerRuleRes.EndingPosition; innerRuleErrors.Clear(); innerRuleErrors.AddRange(innerRuleRes.Errors); } innerRuleErrors.AddRange(innerRuleRes.Errors); allRulesInError = allRulesInError && innerRuleRes.IsError; i++; } errors.AddRange(innerRuleErrors); var result = new SyntaxParseResult <IN>(); result.Errors = errors; if (okResult != null) { result.Root = okResult.Root; result.IsError = false; result.EndingPosition = okResult.EndingPosition; result.IsEnded = okResult.IsEnded; result.Errors = errors; } else { result.IsError = true; result.Errors = errors; greaterIndex = errors.Count > 0 ? errors.Select(e => e.UnexpectedToken.PositionInTokenFlow).Max() : 0; result.EndingPosition = greaterIndex; result.AddExpectings(errors.SelectMany(e => e.ExpectedTokens)); } if (test.Any()) { var terr = test.SelectMany(x => x.Errors).ToList(); var unexpected = terr.OfType <UnexpectedTokenSyntaxError <IN> >().ToList(); var expecting = unexpected.SelectMany(x => x.ExpectedTokens).ToList(); result.AddExpectings(expecting); ; } return(result); }