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 InitStartingTokensWithOneOrMore(Rule <IN> rule, OneOrMoreClause <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 InitStartingTokensWithOneOrMore(Rule <IN> rule, OneOrMoreClause <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);
     }
 }