示例#1
0
        public override Parser <TInput> VisitBest(BestParser <TInput> parser)
        {
            if (state.State == 0)
            {
                int minLength  = -1;
                int maxLength  = -1;
                int bestParser = -1;

                // figure out which parser will consume most input
                for (int i = 0; i < parser.Parsers.Count; i++)
                {
                    var p      = parser.Parsers[i];
                    var length = scanner.Scan(p, state.InputStart);

                    if (length > maxLength)
                    {
                        maxLength  = length;
                        bestParser = i;
                    }
                    else if (length < minLength)
                    {
                        minLength = length;
                    }
                }

                if (maxLength >= 0)
                {
                    state.State           = 1;
                    state.NextOutputStart = state.OutputStart;
                    return(parser.Parsers[bestParser]);
                }
                else
                {
                    state.InputLength = -1;
                    return(null);
                }
            }
            else
            {
                state.InputLength = state.LastResult;
                return(null);
            }
        }
        /// <summary>
        /// Parse using a state machine, does not use the call stack.
        /// </summary>
        public SearchResult Search(Parser <TInput> parser, int start, bool initialPrevWasMissing)
        {
            this.state          = default(SearchState);
            this.stackPosition  = -1;
            this.prevWasMissing = initialPrevWasMissing;

            Push(parser, start, initialPrevWasMissing);

            Parser <TInput> nextParser = null;

            while (true)
            {
                if (this.state.Parser.IsHidden)
                {
                    this.state.InputLength = scanner.Scan(this.state.Parser, this.state.InputStart);
                    nextParser             = null;
                }
                else
                {
                    if (this.state.State == 0)
                    {
                        beforeAction(this.state.Parser, source, this.state.InputStart, this.prevWasMissing);
                    }

                    nextParser = this.state.Parser.Accept(this);
                }

                if (nextParser != null)
                {
                    Push(nextParser, inputStart: this.state.InputStart + this.state.InputLength, prevWasMissing: this.prevWasMissing);
                }
                else
                {
                    var length = this.state.InputLength;
                    this.afterAction?.Invoke(this.state.Parser);

                    if (this.stackPosition == 0)
                    {
                        return(new SearchResult(length, this.prevWasMissing));
                    }
                    else
                    {
                        Pop();
                        this.state.LastResult = length;
                    }
                }
            }
        }