Example #1
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;
        }
Example #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);
        }