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; }
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); }