Esempio n. 1
0
        public override ParseTree Parse(Lexer lexer, ParserState state)
        {
            state.RuntimeState.Runtime.ParseTrace.Enter(this, lexer.CurrentSource(), "Pattern " + Type.Name);

            int start = lexer.Position;

            if (state.Excluded.Contains(this))
            {
                state.RuntimeState.Runtime.ParseTrace.No(this, lexer.CurrentSource(), "Excluded");
                return(ParseTree.No);
            }

            Precedence oldCurrentPrecedence = state.CurrentPrecedence;

            if (Precedence.Overwrites(state.CurrentPrecedence))
            {
                state.CurrentPrecedence = Precedence;
            }

            ParseTree tree = ParseGraph.Parse(lexer, state);

            state.CurrentPrecedence = oldCurrentPrecedence;

            if (tree == ParseTree.No)
            {
                state.RuntimeState.Runtime.ParseTrace.No(this, lexer.SourceFrom(start));
                return(ParseTree.No);
            }

            state.RuntimeState.Runtime.ParseTrace.Yes(this, lexer.SourceFrom(start));

            return(tree);
        }
Esempio n. 2
0
        public override ParseTree Parse(Lexer lexer, ParserState state)
        {
            int start = lexer.Position;

            state.RuntimeState.Runtime.ParseTrace.Enter(this, lexer.CurrentSource(), "Pattern " + Type.Name);

            /*state.RuntimeState.Runtime.ParseTrace.Enter(this, lexer.CurrentSource(), "Excluded:");
             *
             * foreach (Pattern excluded in state.Excluded)
             *  state.RuntimeState.Runtime.ParseTrace.Single(excluded.Type.Name);
             *
             * state.RuntimeState.Runtime.ParseTrace.Leave(this);*/

            if (state.Excluded.Contains(this))
            {
                state.RuntimeState.Runtime.ParseTrace.No(this, lexer.CurrentSource(), "Excluded");
                return(ParseTree.No);
            }

            ParserMemoryKey key = new ParserMemoryKey(this, start);

            bool oldSkipMemoryForLeftRecursion = state.SkipMemoryForLeftRecursion;

            if (state.SkipMemoryForLeftRecursion)
            {
                state.SkipMemoryForLeftRecursion = false;
            }
            else
            {
                ParserMemoryEntry entry;

                if (state.Memory.TryGetValue(key, out entry))
                {
                    state.RuntimeState.Runtime.ParseTrace.LinkNext(entry.Tag);

                    if (entry.Tree == ParseTree.No)
                    {
                        state.RuntimeState.Runtime.ParseTrace.No(this, lexer.SourceFrom(start), "From memory");
                    }
                    else
                    {
                        state.RuntimeState.Runtime.ParseTrace.Yes(this, lexer.SourceFrom(start), "From memory");
                        lexer.Position = entry.End;
                    }

                    return(entry.Tree);
                }
            }

            ConcretePattern oldRecursionExclude = state.RecursionExclude;

            if (RecursionBehaviour != RecursionBehaviour.Recursive)
            {
                if (state.RecursionExclude != null)
                {
                    state.Excluded.Remove(state.RecursionExclude);
                }

                state.RecursionExclude = this;

                state.Excluded.Add(this);
            }

            RecursionBehaviour oldRecursionBehaviour = state.RecursionBehaviour;

            state.RecursionBehaviour = RecursionBehaviour;

            Precedence oldCurrentPrecedence = state.CurrentPrecedence;

            if (Precedence.Overwrites(state.CurrentPrecedence))
            {
                state.CurrentPrecedence = Precedence;
            }

            bool oldPrecedenceCanEqualCurrent = state.PrecedenceCanEqualCurrent;

            state.PrecedenceCanEqualCurrent = RecursionBehaviour == RecursionBehaviour.Recursive;

            ParseTree tree = ParseGraph.Parse(lexer, state);

            state.CurrentPrecedence          = oldCurrentPrecedence;
            state.PrecedenceCanEqualCurrent  = oldPrecedenceCanEqualCurrent;
            state.RecursionBehaviour         = oldRecursionBehaviour;
            state.RecursionExclude           = oldRecursionExclude;
            state.SkipMemoryForLeftRecursion = oldSkipMemoryForLeftRecursion;

            if (RecursionBehaviour != RecursionBehaviour.Recursive)
            {
                if (oldRecursionExclude != null)
                {
                    state.Excluded.Add(oldRecursionExclude);
                }

                state.Excluded.Remove(this);
            }

            if (tree != ParseTree.No)
            {
                lexer.Whitespace(state.RuntimeState);
                tree = Instantiate(lexer, state, start, tree);
            }

            object nextTag = new object();

            state.RuntimeState.Runtime.ParseTrace.TagNext(nextTag);

            if (tree == ParseTree.No)
            {
                state.RuntimeState.Runtime.ParseTrace.No(this, lexer.SourceFrom(start));
            }
            else
            {
                state.RuntimeState.Runtime.ParseTrace.Yes(this, lexer.SourceFrom(start));

                if (RecursionBehaviour == RecursionBehaviour.LeftRecursive)
                {
                    tree = LeftRecurse(lexer, state, start, tree);
                }
            }

            // TODO - can remove some other code if not remembering

            if (ShouldRemember)
            {
                state.Memory[key] = new ParserMemoryEntry(tree, lexer.Position, nextTag);
            }

            return(tree);
        }