protected override void InitStartingTokensForRule(Dictionary <string, NonTerminal <IN> > nonTerminals, Rule <IN> rule)
        {
            if (rule.PossibleLeadingTokens == null || rule.PossibleLeadingTokens.Count == 0)
            {
                rule.PossibleLeadingTokens = new List <IN>();
                if (rule.Clauses.Count > 0)
                {
                    IClause <IN> first = rule.Clauses[0];
                    if (first is TerminalClause <IN> )
                    {
                        TerminalClause <IN> term = first as TerminalClause <IN>;

                        InitStartingTokensWithTerminal(rule, term);
                    }
                    else if (first is NonTerminalClause <IN> )
                    {
                        NonTerminalClause <IN> nonterm = first as NonTerminalClause <IN>;
                        InitStartingTokensWithNonTerminal(rule, nonterm, nonTerminals);
                    }
                    else if (first is ZeroOrMoreClause <IN> )
                    {
                        ZeroOrMoreClause <IN> many = first as ZeroOrMoreClause <IN>;
                        InitStartingTokensWithZeroOrMore(rule, many, nonTerminals);
                    }
                    else if (first is OneOrMoreClause <IN> )
                    {
                        OneOrMoreClause <IN> many = first as OneOrMoreClause <IN>;
                        InitStartingTokensWithOneOrMore(rule, many, nonTerminals);
                    }
                }
            }
        }
        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);
        }
        private void InitStartingTokensWithZeroOrMore(Rule <IN> rule, ZeroOrMoreClause <IN> manyClause,
                                                      Dictionary <string, NonTerminal <IN> > nonTerminals)
        {
            if (manyClause.Clause is TerminalClause <IN> )
            {
                var term = manyClause.Clause as TerminalClause <IN>;

                InitStartingTokensWithTerminal(rule, term);
            }
            else if (manyClause.Clause is NonTerminalClause <IN> )
            {
                var nonterm = manyClause.Clause as NonTerminalClause <IN>;
                InitStartingTokensWithNonTerminal(rule, nonterm, nonTerminals);
            }
        }
 private void InitStartingTokensWithZeroOrMore(Rule <IN> rule, ZeroOrMoreClause <IN> manyClause,
                                               Dictionary <string, NonTerminal <IN> > nonTerminals)
 {
     if (manyClause.Clause is TerminalClause <IN> term)
     {
         InitStartingTokensWithTerminal(rule, term);
     }
     else if (manyClause.Clause is NonTerminalClause <IN> nonTerm)
     {
         InitStartingTokensWithNonTerminal(rule, nonTerm, nonTerminals);
     }
     else if (manyClause.Clause is ChoiceClause <IN> choice)
     {
         InitStartingTokensWithChoice(rule, choice, nonTerminals);
     }
 }
        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);
        }