/// <summary>
            /// Parse using a state machine, does not use the call stack.
            /// </summary>
            public SearchResult Search(Parser <TInput> parser, int start, bool initialPrevWasMissing)
            {
                this.prevWasMissing = initialPrevWasMissing;

                Push(parser, start, initialPrevWasMissing);

                Parser <TInput> nextParser = null;

                while (true)
                {
                    if (this.state.Parser.IsHidden)
                    {
                        this.state.InputLength = SafeScanner.ScanSafe(this.state.Parser, source, 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;
                        }
                    }
                }
            }
예제 #2
0
 private static int Scan(Parser <TInput> parser, Source <TInput> source, int start)
 {
     return(SafeScanner.ScanSafe(parser, source, start));
 }