Beispiel #1
0
    public static SqlTextLength Create(SyntaxParseResult syntaxParseResult)
    {
        var textType   = DetermineTextType(syntaxParseResult);
        var textLength = CalculateTextLength(syntaxParseResult, textType);

        return(new SqlTextLength(textLength));
    }
        private static SyntaxParseResult <IN> NoMatchingRuleError(IList <Token <IN> > tokens, int currentPosition, List <IN> allAcceptableTokens)
        {
            var noRuleErrors = new List <UnexpectedTokenSyntaxError <IN> >();

            if (currentPosition < tokens.Count)
            {
                noRuleErrors.Add(new UnexpectedTokenSyntaxError <IN>(tokens[currentPosition],
                                                                     allAcceptableTokens.ToArray <IN>()));
            }
            else
            {
                noRuleErrors.Add(new UnexpectedTokenSyntaxError <IN>(new Token <IN>()
                {
                    IsEOS = true
                },
                                                                     allAcceptableTokens.ToArray <IN>()));
            }

            var error = new SyntaxParseResult <IN>();

            error.IsError        = true;
            error.Root           = null;
            error.IsEnded        = false;
            error.Errors         = noRuleErrors;
            error.EndingPosition = currentPosition;

            return(error);
        }
        public SyntaxParseResult <IN> Parse(IList <Token <IN> > tokens, string startingNonTerminal = null)
        {
            string start = startingNonTerminal ?? StartingNonTerminal;
            Dictionary <string, NonTerminal <IN> >  NonTerminals = Configuration.NonTerminals;
            List <UnexpectedTokenSyntaxError <IN> > errors       = new List <UnexpectedTokenSyntaxError <IN> >();
            NonTerminal <IN> nt = NonTerminals[start];

            List <Rule <IN> > rules = nt.Rules.Where <Rule <IN> >(r => r.PossibleLeadingTokens.Contains(tokens[0].TokenID)).ToList <Rule <IN> >();

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

            foreach (Rule <IN> rule in rules)
            {
                SyntaxParseResult <IN> r = Parse(tokens, rule, 0, start);
                rs.Add(r);
            }
            SyntaxParseResult <IN> result = null;


            if (rs.Count > 0)
            {
                result = rs.Find(r => r.IsEnded && !r.IsError);

                if (result == null)
                {
                    List <int> endingPositions = rs.Select(r => r.EndingPosition).ToList <int>();
                    int        lastposition    = endingPositions.Max();
                    List <SyntaxParseResult <IN> > furtherResults = rs.Where <SyntaxParseResult <IN> >(r => r.EndingPosition == lastposition).ToList <SyntaxParseResult <IN> >();

                    errors.Add(new UnexpectedTokenSyntaxError <IN>(tokens[lastposition], null));
                    furtherResults.ForEach(r =>
                    {
                        if (r.Errors != null)
                        {
                            errors.AddRange(r.Errors);
                        }
                    });
                }
            }
            if (result == null)
            {
                result = new SyntaxParseResult <IN>();
                errors.Sort();

                if (errors.Count > 0)
                {
                    int lastErrorPosition = errors.Select(e => e.UnexpectedToken.PositionInTokenFlow).ToList().Max();
                    var lastErrors        = errors.Where(e => e.UnexpectedToken.PositionInTokenFlow == lastErrorPosition).ToList();
                    result.Errors = lastErrors;
                }
                else
                {
                    result.Errors = errors;
                }
                result.IsError = true;
            }
            return(result);
        }
        public SyntaxParseResult <IN> ParseOneOrMore(IList <Token <IN> > tokens, OneOrMoreClause <IN> clause, int position)
        {
            var  result          = new SyntaxParseResult <IN>();
            var  manyNode        = new ManySyntaxNode <IN>("");
            var  currentPosition = position;
            var  innerClause     = clause.Clause;
            bool isError;

            SyntaxParseResult <IN> lastInnerResult = null;

            SyntaxParseResult <IN> firstInnerResult = null;

            if (innerClause is TerminalClause <IN> )
            {
                manyNode.IsManyTokens = true;
                firstInnerResult      = ParseTerminal(tokens, innerClause as TerminalClause <IN>, currentPosition);
            }
            else if (innerClause is NonTerminalClause <IN> )
            {
                manyNode.IsManyValues = true;
                firstInnerResult      = ParseNonTerminal(tokens, innerClause as NonTerminalClause <IN>, currentPosition);
            }
            else
            {
                throw new InvalidOperationException("unable to apply repeater to " + innerClause.GetType().Name);
            }

            if (firstInnerResult != null && !firstInnerResult.IsError)
            {
                manyNode.Add(firstInnerResult.Root);
                lastInnerResult = firstInnerResult;
                currentPosition = firstInnerResult.EndingPosition;
                var more       = new ZeroOrMoreClause <IN>(innerClause);
                var nextResult = ParseZeroOrMore(tokens, more, currentPosition);
                if (nextResult != null && !nextResult.IsError)
                {
                    currentPosition = nextResult.EndingPosition;
                    var moreChildren = (ManySyntaxNode <IN>)nextResult.Root;
                    manyNode.Children.AddRange(moreChildren.Children);
                }

                isError = false;
            }

            else
            {
                isError = true;
            }

            result.EndingPosition = currentPosition;
            result.IsError        = isError;
            result.Root           = manyNode;
            result.IsEnded        = lastInnerResult != null && lastInnerResult.IsEnded;
            return(result);
        }
        public SyntaxParseResult <IN> ParseTerminal(IList <Token <IN> > tokens, TerminalClause <IN> term, int position)
        {
            SyntaxParseResult <IN> result = new SyntaxParseResult <IN>();

            result.IsError        = !term.Check(tokens[position].TokenID);
            result.EndingPosition = !result.IsError ? position + 1 : position;
            Token <IN> token = tokens[position];

            token.Discarded = term.Discarded;
            result.Root     = new SyntaxLeaf <IN>(token);
            return(result);
        }
Beispiel #6
0
    private static SqlTextLengthSpecification DetermineTextLengthSpecification(SyntaxParseResult syntaxParseResult)
    {
        if (syntaxParseResult.Precision1.HasValue)
        {
            return(SqlTextLengthSpecification.Numeric);
        }

        if ("max".InsensitiveEquals(syntaxParseResult.Text))
        {
            return(SqlTextLengthSpecification.Max);
        }

        return(SqlTextLengthSpecification.NotSpecified);
    }
Beispiel #7
0
        public SyntaxParseResult <IN> CleanSyntaxTree(SyntaxParseResult <IN> result)
        {
            ISyntaxNode <IN> tree = result.Root;

            if (tree != null)
            {
                tree = RemoveByPassNodes(tree);
                if (NeedAssociativityProcessing(tree))
                {
                    tree = SetAssociativity(tree);
                }
                result.Root = tree;
            }
            return(result);
        }
Beispiel #8
0
    private static TextType DetermineTextType(SyntaxParseResult syntaxParseResult)
    {
        if (syntaxParseResult.SqlTypeName.Equals("char") || syntaxParseResult.SqlTypeName.Equals("varchar"))
        {
            return(TextType.NonUnicode);
        }

        if (syntaxParseResult.SqlTypeName.Equals("nchar") || syntaxParseResult.SqlTypeName.Equals("nvarchar"))
        {
            return(TextType.Unicode);
        }

        throw new ArgumentException($"Type, {syntaxParseResult.SqlTypeName}, was non of the expected values " +
                                    $"of char, varchar, nchar, or nvarchar");
    }
        public SyntaxParseResult <IN> ParseChoice(IList <Token <IN> > tokens, ChoiceClause <IN> choice,
                                                  int position)
        {
            var currentPosition = position;

            SyntaxParseResult <IN> result = new SyntaxParseResult <IN>()
            {
                IsError        = true,
                IsEnded        = false,
                EndingPosition = currentPosition
            };


            foreach (var alternate in choice.Choices)
            {
                if (alternate is TerminalClause <IN> terminalAlternate)
                {
                    result = ParseTerminal(tokens, terminalAlternate, currentPosition);
                }
                else if (alternate is NonTerminalClause <IN> nonTerminalAlternate)
                {
                    result = ParseNonTerminal(tokens, nonTerminalAlternate, currentPosition);
                }
                else
                {
                    throw new InvalidOperationException("unable to apply repeater inside  " + choice.GetType().Name);
                }
                if (result.IsOk)
                {
                    if (choice.IsTerminalChoice && choice.IsDiscarded && result.Root is SyntaxLeaf <IN> leaf)
                    {
                        var discardedToken = new SyntaxLeaf <IN>(leaf.Token, true);
                        result.Root = discardedToken;
                    }

                    return(result);
                }
            }

            if (result.IsError && choice.IsTerminalChoice)
            {
                var terminalAlternates = choice.Choices.Cast <TerminalClause <IN> >();
                var expected           = terminalAlternates.Select(x => x.ExpectedToken).ToList();
                result.Errors.Add(new UnexpectedTokenSyntaxError <IN>(tokens[currentPosition], expected.ToArray()));
            }

            return(result);
        }
Beispiel #10
0
    private static int CalculateTextLength(SyntaxParseResult syntaxParseResult, TextType nonUnicode)
    {
        var textLengthSpecification = DetermineTextLengthSpecification(syntaxParseResult);

        switch (textLengthSpecification)
        {
        case SqlTextLengthSpecification.NotSpecified:
            return(1);

        case SqlTextLengthSpecification.Numeric:
            ValidateTextLength(nonUnicode, syntaxParseResult.Precision1.Value);
            return(syntaxParseResult.Precision1.Value);

        case SqlTextLengthSpecification.Max:
            ValidateSqlTypeIsVarcharOrNvarchar(syntaxParseResult);
            return(Int32.MaxValue);

        default:
            throw new ArgumentOutOfRangeException();
        }
    }
Beispiel #11
0
        public static void Main()
        {
            while (true)
            {
                Console.Write("> ");

                string input = Console.ReadLine();

                if (input == "")
                {
                    continue;
                }

                if (input == "exit")
                {
                    return;
                }

                SyntaxLexer  lexer       = new SyntaxLexer();
                SyntaxParser parser      = new SyntaxParser();
                Interpreter  interpreter = new Interpreter();

                List <SyntaxToken> tokens = lexer.Lex(input);

                SyntaxParseResult result = parser.Parse(tokens);

                foreach (Diagnostic diagnostic in result.Diagnostics)
                {
                    Console.WriteLine($"{diagnostic.Severity}: {diagnostic.Message} at {diagnostic.Range.Start}");
                }

                DustObject value = interpreter.Interpret(result.Node);

                Console.WriteLine($"{value.ToString().Value} ({value.TypeName})");
            }
        }
Beispiel #12
0
 public ExceptToFunctions(SyntaxParseResult result)
 {
     this.result = 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 => 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> ParseOption(IList <Token <IN> > tokens, OptionClause <IN> clause, Rule <IN> rule,
                                                  int position)
        {
            var result          = new SyntaxParseResult <IN>();
            var currentPosition = position;
            var innerClause     = clause.Clause;

            SyntaxParseResult <IN> innerResult = null;


            if (innerClause is TerminalClause <IN> )
            {
                innerResult = ParseTerminal(tokens, innerClause as TerminalClause <IN>, currentPosition);
            }
            else if (innerClause is NonTerminalClause <IN> )
            {
                innerResult = ParseNonTerminal(tokens, innerClause as NonTerminalClause <IN>, currentPosition);
            }
            else
            {
                throw new InvalidOperationException("unable to apply repeater to " + innerClause.GetType().Name);
            }


            if (innerResult.IsError)
            {
                if (innerClause is TerminalClause <IN> )
                {
                    result                = new SyntaxParseResult <IN>();
                    result.IsError        = true;
                    result.Root           = new SyntaxLeaf <IN>(Token <IN> .Empty());
                    result.EndingPosition = position;
                }
                else
                {
                    result         = new SyntaxParseResult <IN>();
                    result.IsError = true;
                    var children = new List <ISyntaxNode <IN> > {
                        innerResult.Root
                    };
                    if (innerResult.IsError)
                    {
                        children.Clear();
                    }
                    result.Root = new OptionSyntaxNode <IN>(rule.NonTerminalName + "__" + rule.Key, children,
                                                            rule.GetVisitor());
                    result.EndingPosition = position;
                }
            }
            else
            {
                var node = innerResult.Root;

                var children = new List <ISyntaxNode <IN> > {
                    innerResult.Root
                };
                result.Root =
                    new OptionSyntaxNode <IN>(rule.NonTerminalName + "__" + rule.Key, children, rule.GetVisitor());
                result.EndingPosition = innerResult.EndingPosition;
            }

            return(result);
        }
Beispiel #15
0
        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);
        }
Beispiel #16
0
 private static void ValidateSqlTypeIsVarcharOrNvarchar(SyntaxParseResult syntaxParseResult)
 {
     syntaxParseResult.SqlTypeName.Should().BeOneOf("varchar", "nvarchar");
 }
        public virtual SyntaxParseResult <IN> Parse(IList <Token <IN> > tokens, Rule <IN> rule, int position, string nonTerminalName)
        {
            int currentPosition = position;
            List <UnexpectedTokenSyntaxError <IN> > errors = new List <UnexpectedTokenSyntaxError <IN> >();
            bool isError = false;
            List <ISyntaxNode <IN> > children = new List <ISyntaxNode <IN> >();

            if (rule.PossibleLeadingTokens.Contains(tokens[position].TokenID))
            {
                if (rule.Clauses != null && rule.Clauses.Count > 0)
                {
                    children = new List <ISyntaxNode <IN> >();
                    foreach (IClause <IN> clause in rule.Clauses)
                    {
                        if (clause is TerminalClause <IN> )
                        {
                            SyntaxParseResult <IN> termRes = ParseTerminal(tokens, clause as TerminalClause <IN>, currentPosition);
                            if (!termRes.IsError)
                            {
                                children.Add(termRes.Root);
                                currentPosition = termRes.EndingPosition;
                            }
                            else
                            {
                                Token <IN> tok = tokens[currentPosition];
                                errors.Add(new UnexpectedTokenSyntaxError <IN>(tok, ((TerminalClause <IN>)clause).ExpectedToken));
                            }
                            isError = isError || termRes.IsError;
                        }
                        else if (clause is NonTerminalClause <IN> )
                        {
                            SyntaxParseResult <IN> nonTerminalResult =
                                ParseNonTerminal(tokens, clause as NonTerminalClause <IN>, currentPosition);
                            if (!nonTerminalResult.IsError)
                            {
                                children.Add(nonTerminalResult.Root);
                                currentPosition = nonTerminalResult.EndingPosition;
                                if (nonTerminalResult.Errors != null && nonTerminalResult.Errors.Any())
                                {
                                    errors.AddRange(nonTerminalResult.Errors);
                                }
                            }
                            else
                            {
                                errors.AddRange(nonTerminalResult.Errors);
                            }
                            isError = isError || nonTerminalResult.IsError;
                        }
                        if (isError)
                        {
                            break;
                        }
                    }
                }
            }

            if (nonTerminalName == "rootGroup")
            {
                ;
            }

            SyntaxParseResult <IN> result = new SyntaxParseResult <IN>();

            result.IsError        = isError;
            result.Errors         = errors;
            result.EndingPosition = currentPosition;
            if (!isError)
            {
                SyntaxNode <IN> node = null;
                if (rule.IsSubRule)
                {
                    node = new GroupSyntaxNode <IN>($"{nonTerminalName}__{rule.Key}", children);
                }
                else
                {
                    node = new SyntaxNode <IN>($"{nonTerminalName}__{rule.Key}", children);
                }
                node = ManageExpressionRules(rule, node);
                if (node.IsByPassNode) // inutile de créer un niveau supplémentaire
                {
                    result.Root = children[0];
                }
                result.Root    = node;
                result.IsEnded = result.EndingPosition >= tokens.Count - 1 ||
                                 result.EndingPosition == tokens.Count - 2 && tokens[tokens.Count - 1].TokenID.Equals(default(IN));
                if (result.IsEnded)
                {
                    ;
                }
                if (rule.IsExpressionRule)
                {
                }
            }


            return(result);
        }
        public override SyntaxParseResult <IN> Parse(IList <Token <IN> > tokens, Rule <IN> rule, int position,
                                                     string nonTerminalName)
        {
            var currentPosition = position;
            var errors          = new List <UnexpectedTokenSyntaxError <IN> >();
            var isError         = false;
            var children        = new List <ISyntaxNode <IN> >();

            if (rule.PossibleLeadingTokens.Contains(tokens[position].TokenID) || rule.MayBeEmpty)
            {
                if (rule.Clauses != null && rule.Clauses.Count > 0)
                {
                    children = new List <ISyntaxNode <IN> >();
                    foreach (var clause in rule.Clauses)
                    {
                        if (clause is TerminalClause <IN> termClause)
                        {
                            var termRes =
                                ParseTerminal(tokens, termClause, currentPosition);
                            if (!termRes.IsError)
                            {
                                children.Add(termRes.Root);
                                currentPosition = termRes.EndingPosition;
                            }
                            else
                            {
                                var tok = tokens[currentPosition];
                                errors.Add(new UnexpectedTokenSyntaxError <IN>(tok,
                                                                               ((TerminalClause <IN>)clause).ExpectedToken));
                            }

                            isError = isError || termRes.IsError;
                        }
                        else if (clause is NonTerminalClause <IN> )
                        {
                            var nonTerminalResult =
                                ParseNonTerminal(tokens, clause as NonTerminalClause <IN>, currentPosition);
                            if (!nonTerminalResult.IsError)
                            {
                                errors.AddRange(nonTerminalResult.Errors);
                                children.Add(nonTerminalResult.Root);
                                currentPosition = nonTerminalResult.EndingPosition;
                            }
                            else
                            {
                                errors.AddRange(nonTerminalResult.Errors);
                            }

                            isError = isError || nonTerminalResult.IsError;
                        }
                        else if (clause is OneOrMoreClause <IN> || clause is ZeroOrMoreClause <IN> )
                        {
                            SyntaxParseResult <IN> manyResult = null;
                            if (clause is OneOrMoreClause <IN> oneOrMore)
                            {
                                manyResult = ParseOneOrMore(tokens, oneOrMore, currentPosition);
                            }
                            else if (clause is ZeroOrMoreClause <IN> zeroOrMore)
                            {
                                manyResult = ParseZeroOrMore(tokens, zeroOrMore, currentPosition);
                            }
                            if (!manyResult.IsError)
                            {
                                errors.AddRange(manyResult.Errors);
                                children.Add(manyResult.Root);
                                currentPosition = manyResult.EndingPosition;
                            }
                            else
                            {
                                if (manyResult.Errors != null && manyResult.Errors.Count > 0)
                                {
                                    errors.AddRange(manyResult.Errors);
                                }
                            }

                            isError = isError || manyResult.IsError;
                        }
                        else if (clause is OptionClause <IN> option)
                        {
                            var optionResult = ParseOption(tokens, option, rule, currentPosition);
                            currentPosition = optionResult.EndingPosition;
                            children.Add(optionResult.Root);
                        }

                        if (isError)
                        {
                            break;
                        }
                    }
                }
            }

            var result = new SyntaxParseResult <IN>();

            result.IsError        = isError;
            result.Errors         = errors;
            result.EndingPosition = currentPosition;
            if (!isError)
            {
                SyntaxNode <IN> node = null;
                if (rule.IsSubRule)
                {
                    node           = new GroupSyntaxNode <IN>(nonTerminalName + "__" + rule.Key, children);
                    node           = ManageExpressionRules(rule, node);
                    result.Root    = node;
                    result.IsEnded = currentPosition >= tokens.Count - 1 ||
                                     currentPosition == tokens.Count - 2 &&
                                     tokens[tokens.Count - 1].TokenID.Equals(default(IN));
                }
                else
                {
                    node = new SyntaxNode <IN>(nonTerminalName + "__" + rule.Key, children);
                    node.ExpressionAffix = rule.ExpressionAffix;
                    node           = ManageExpressionRules(rule, node);
                    result.Root    = node;
                    result.IsEnded = currentPosition >= tokens.Count - 1 ||
                                     currentPosition == tokens.Count - 2 &&
                                     tokens[tokens.Count - 1].TokenID.Equals(default(IN));
                }
            }

            return(result);
        }
        public SyntaxParseResult <IN> ParseNonTerminal(IList <Token <IN> > tokens, NonTerminalClause <IN> nonTermClause, int currentPosition)
        {
            int startPosition   = currentPosition;
            int endingPosition  = 0;
            NonTerminal <IN> nt = Configuration.NonTerminals[nonTermClause.NonTerminalName];
            List <UnexpectedTokenSyntaxError <IN> > errors = new List <UnexpectedTokenSyntaxError <IN> >();

            int i = 0;

            List <IN> allAcceptableTokens = new List <IN>();

            nt.Rules.ForEach(r =>
            {
                if (r != null && r.PossibleLeadingTokens != null)
                {
                    allAcceptableTokens.AddRange(r.PossibleLeadingTokens);
                }
            });
            allAcceptableTokens = allAcceptableTokens.Distinct <IN>().ToList <IN>();

            List <Rule <IN> > rules = nt.Rules
                                      .Where <Rule <IN> >(r => r.PossibleLeadingTokens.Contains(tokens[startPosition].TokenID) || r.MayBeEmpty)
                                      .ToList <Rule <IN> >();

            if (rules.Count == 0)
            {
                errors.Add(new UnexpectedTokenSyntaxError <IN>(tokens[startPosition],
                                                               allAcceptableTokens.ToArray <IN>()));
            }

            List <UnexpectedTokenSyntaxError <IN> > innerRuleErrors = new List <UnexpectedTokenSyntaxError <IN> >();
            SyntaxParseResult <IN> okResult = null;
            int  greaterIndex    = 0;
            bool allRulesInError = true;

            while (i < rules.Count)
            {
                Rule <IN> innerrule = rules[i];
                SyntaxParseResult <IN> 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;
                }
                bool 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);

            SyntaxParseResult <IN> 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.Select(e => e.UnexpectedToken.PositionInTokenFlow).Max();
                result.EndingPosition = greaterIndex;
            }
            return(result);
        }
        public SyntaxParseResult <IN> ParseZeroOrMore(IList <Token <IN> > tokens, ZeroOrMoreClause <IN> clause, int position)
        {
            var result          = new SyntaxParseResult <IN>();
            var manyNode        = new ManySyntaxNode <IN>("");
            var currentPosition = position;
            var innerClause     = clause.Clause;
            var stillOk         = true;

            SyntaxParseResult <IN> lastInnerResult = null;

            var innerErrors = new List <UnexpectedTokenSyntaxError <IN> >();

            while (stillOk)
            {
                SyntaxParseResult <IN> innerResult = null;
                if (innerClause is TerminalClause <IN> )
                {
                    manyNode.IsManyTokens = true;
                    innerResult           = ParseTerminal(tokens, innerClause as TerminalClause <IN>, currentPosition);
                }
                else if (innerClause is NonTerminalClause <IN> nonTerm)
                {
                    innerResult = ParseNonTerminal(tokens, nonTerm, currentPosition);
                    if (nonTerm.IsGroup)
                    {
                        manyNode.IsManyGroups = true;
                    }
                    else
                    {
                        manyNode.IsManyValues = true;
                    }
                }
                else if (innerClause is GroupClause <IN> )
                {
                    manyNode.IsManyGroups = true;
                    innerResult           = ParseNonTerminal(tokens, innerClause as NonTerminalClause <IN>, currentPosition);
                }
                else
                {
                    throw new InvalidOperationException("unable to apply repeater to " + innerClause.GetType().Name);
                }

                if (innerResult != null && !innerResult.IsError)
                {
                    manyNode.Add(innerResult.Root);
                    currentPosition = innerResult.EndingPosition;
                    lastInnerResult = innerResult;
                }
                else
                {
                    if (innerResult != null)
                    {
                        innerErrors.AddRange(innerResult.Errors);
                    }
                }

                stillOk = stillOk && innerResult != null && !innerResult.IsError && currentPosition < tokens.Count;
            }


            result.EndingPosition = currentPosition;
            result.IsError        = false;
            result.Errors         = innerErrors;
            result.Root           = manyNode;
            result.IsEnded        = lastInnerResult != null && lastInnerResult.IsEnded;
            return(result);
        }