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); }
void DecorateCore() { ReadSettings(); var productions = _config.Productions; var initial = productions.Count; PopulateUsings(); for (var i = 0; i < initial; i++) { DecorateProduction(productions[i]); } if (productions.Count == 0) { _reporter.AddError(1, 1, 1, 1, "No productions defined."); return; } PopulateTopLevelSegments(); DetectUnreachableNonTerminals(); if (!VerifyProductionReferences()) { return; } _config.UseErrorRecovery = _terminals.ContainsKey(Segment.Error.Name); _config.Graph = ParseGraph.ConstructGraph(_config); ValidateGraph(); }
public virtual bool Update(Pattern updated) { bool updates = ParseGraph.Update(updated); if (updates) { Updated(); } return(updates); }
static object GenerateParseGraph(string text) { var errorReporter = new Mock <IErrorReporter>(MockBehavior.Strict); var parser = new ConfigParser(errorReporter.Object); var config = parser.Parse(new ConfigScanner(text)); SyntaxTreeDecorator.Decorate(config, errorReporter.Object); var parse = ParseGraph.ConstructGraph(config); return(parse.Graph); }
public string StartPointsRenderer(ParseGraph parseGraph) { var bulider = new StringBuilder(); foreach (var pair in parseGraph) { pair.Key.AppendTo(bulider); bulider.Append(": "); bulider.Append(GetID(pair.Value).ToString(CultureInfo.InvariantCulture)); bulider.AppendLine(); } return(bulider.ToString()); }
public void ConstructDFA1() { var parseGraph = ParseGraph.ConstructGraph(ConstructSample1()); const string expected = "0 (S) -- <A> --> 1 \r\n" + "[<A'> -> • <A>, EOF] [<A'> -> <A> •, EOF] \r\n" + "[<A> -> • a, EOF] \r\n" + "[<A> -> • ( <A> ), EOF] \r\n" + "0 (S) -- a --> 2 \r\n" + "[<A'> -> • <A>, EOF] [<A> -> a •, )/EOF] \r\n" + "[<A> -> • a, EOF] \r\n" + "[<A> -> • ( <A> ), EOF] \r\n" + "0 (S) -- ( --> 3 \r\n" + "[<A'> -> • <A>, EOF] [<A> -> • a, )] \r\n" + "[<A> -> • a, EOF] [<A> -> • ( <A> ), )] \r\n" + "[<A> -> • ( <A> ), EOF] [<A> -> ( • <A> ), )/EOF]\r\n" + "3 -- a --> 2 \r\n" + "[<A> -> • a, )] [<A> -> a •, )/EOF] \r\n" + "[<A> -> • ( <A> ), )] \r\n" + "[<A> -> ( • <A> ), )/EOF] \r\n" + "3 -- ( --> 3 \r\n" + "[<A> -> • a, )] [<A> -> • a, )] \r\n" + "[<A> -> • ( <A> ), )] [<A> -> • ( <A> ), )] \r\n" + "[<A> -> ( • <A> ), )/EOF] [<A> -> ( • <A> ), )/EOF]\r\n" + "3 -- <A> --> 4 \r\n" + "[<A> -> • a, )] [<A> -> ( <A> • ), EOF] \r\n" + "[<A> -> • ( <A> ), )] \r\n" + "[<A> -> ( • <A> ), )/EOF] \r\n" + "4 -- ) --> 5 \r\n" + "[<A> -> ( <A> • ), EOF] [<A> -> ( <A> ) •, )/EOF]\r\n" + ""; const string expectedStartPoints = "<A>: 0\r\n" + ""; var renderer = new ParseRenderer(); Assert.That(renderer.Render(parseGraph.Graph, 25), Is.EqualTo(expected)); Assert.That(renderer.StartPointsRenderer(parseGraph), Is.EqualTo(expectedStartPoints)); }
public override Block CompileNew(Runtime runtime, StateForCompiler state) { ParserBlock block = new ParserBlock(runtime); block.Comment("start of abstract pattern -------------"); BlockLabel returnLabel = new BlockLabel("return"); block.Enter(this, Type.Name); block.BeginScope(); BlockLocal start = block.SavePosition(); BlockLabel notExcluded = new BlockLabel("notExcluded"); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Excluded")); block.Load(this); block.Call(typeof(Multiset <Pattern>).GetMethod("Contains")); block.BranchIfFalse(notExcluded); block.No(this); block.LoadNo(); block.Branch(returnLabel); block.MarkLabel(notExcluded); BlockLocal oldCurrentPrecedence = new BlockLocal(typeof(Precedence)); block.DeclareLocal(oldCurrentPrecedence); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("CurrentPrecedence")); block.StoreLocal(oldCurrentPrecedence); BlockLabel doesntOverwrite = new BlockLabel("doesntOverwrite"); block.Load(Precedence); block.LoadLocal(oldCurrentPrecedence); block.Call(typeof(Precedence).GetMethod("Overwrites")); block.BranchIfFalse(doesntOverwrite); block.LoadState(); block.Load(Precedence); block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence")); block.MarkLabel(doesntOverwrite); block.Emit(ParseGraph.Compile(runtime, state)); block.LoadState(); block.LoadLocal(oldCurrentPrecedence); block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence")); block.Dup(); BlockLabel yes = new BlockLabel("yes"); block.BranchIfNotNo(yes); block.No(this, start); block.Branch(returnLabel); block.MarkLabel(yes); block.Yes(this, start); block.EndScope(); block.MarkLabel(returnLabel); block.Comment("end of abstract pattern -------------"); return(block); }
public void ConstructDFA2() { var parseGraph = ParseGraph.ConstructGraph(ConstructSample2()); const string expected = "0 (S) -- <E> --> 1 \r\n" + "[<E'> -> • <E>, EOF] [<E'> -> <E> •, EOF] \r\n" + "[<E> -> • n, EOF] \r\n" + "[<E> -> • <V>, EOF] \r\n" + "[<V> -> • id, EOF] \r\n" + "0 (S) -- n --> 2 \r\n" + "[<E'> -> • <E>, EOF] [<E> -> n •, EOF] \r\n" + "[<E> -> • n, EOF] \r\n" + "[<E> -> • <V>, EOF] \r\n" + "[<V> -> • id, EOF] \r\n" + "0 (S) -- <V> --> 3 \r\n" + "[<E'> -> • <E>, EOF] [<E> -> <V> •, EOF] \r\n" + "[<E> -> • n, EOF] \r\n" + "[<E> -> • <V>, EOF] \r\n" + "[<V> -> • id, EOF] \r\n" + "0 (S) -- id --> 4 \r\n" + "[<E'> -> • <E>, EOF] [<V> -> id •, EOF] \r\n" + "[<E> -> • n, EOF] \r\n" + "[<E> -> • <V>, EOF] \r\n" + "[<V> -> • id, EOF] \r\n" + "5 (S) -- <S> --> 6 \r\n" + "[<S'> -> • <S>, EOF] [<S'> -> <S> •, EOF] \r\n" + "[<S> -> • id, EOF] \r\n" + "[<S> -> • <V> := <E>, EOF] \r\n" + "[<V> -> • id, :=] \r\n" + "5 (S) -- id --> 7 \r\n" + "[<S'> -> • <S>, EOF] [<S> -> id •, EOF] \r\n" + "[<S> -> • id, EOF] [<V> -> id •, :=] \r\n" + "[<S> -> • <V> := <E>, EOF] \r\n" + "[<V> -> • id, :=] \r\n" + "5 (S) -- <V> --> 8 \r\n" + "[<S'> -> • <S>, EOF] [<S> -> <V> • := <E>, EOF]\r\n" + "[<S> -> • id, EOF] \r\n" + "[<S> -> • <V> := <E>, EOF] \r\n" + "[<V> -> • id, :=] \r\n" + "8 -- := --> 9 \r\n" + "[<S> -> <V> • := <E>, EOF] [<E> -> • n, EOF] \r\n" + " [<E> -> • <V>, EOF] \r\n" + " [<V> -> • id, EOF] \r\n" + " [<S> -> <V> := • <E>, EOF]\r\n" + "9 -- n --> 2 \r\n" + "[<E> -> • n, EOF] [<E> -> n •, EOF] \r\n" + "[<E> -> • <V>, EOF] \r\n" + "[<V> -> • id, EOF] \r\n" + "[<S> -> <V> := • <E>, EOF] \r\n" + "9 -- <V> --> 3 \r\n" + "[<E> -> • n, EOF] [<E> -> <V> •, EOF] \r\n" + "[<E> -> • <V>, EOF] \r\n" + "[<V> -> • id, EOF] \r\n" + "[<S> -> <V> := • <E>, EOF] \r\n" + "9 -- id --> 4 \r\n" + "[<E> -> • n, EOF] [<V> -> id •, EOF] \r\n" + "[<E> -> • <V>, EOF] \r\n" + "[<V> -> • id, EOF] \r\n" + "[<S> -> <V> := • <E>, EOF] \r\n" + "9 -- <E> --> 10 \r\n" + "[<E> -> • n, EOF] [<S> -> <V> := <E> •, EOF]\r\n" + "[<E> -> • <V>, EOF] \r\n" + "[<V> -> • id, EOF] \r\n" + "[<S> -> <V> := • <E>, EOF] \r\n" + ""; const string expectedStartPoints = "<E>: 0\r\n" + "<S>: 5\r\n" + ""; var renderer = new ParseRenderer(); Assert.That(renderer.Render(parseGraph.Graph, 26), Is.EqualTo(expected)); Assert.That(renderer.StartPointsRenderer(parseGraph), Is.EqualTo(expectedStartPoints)); }
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 Block CompileNew(Runtime runtime, StateForCompiler state) { ParserBlock block = new ParserBlock(runtime); block.Comment("start of concrete pattern -------------"); BlockLabel returnLabel = new BlockLabel("return"); block.BeginScope(); block.Enter(this, Type.Name); BlockLocal start = block.SavePosition(); BlockLabel notExcluded = new BlockLabel("notExcluded"); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Excluded")); block.Load(this); block.Call(typeof(Multiset <Pattern>).GetMethod("Contains")); block.BranchIfFalse(notExcluded); block.No(this, "Excluded"); block.LoadNo(); block.Branch(returnLabel); block.MarkLabel(notExcluded); BlockLocal key = new BlockLocal(typeof(ParserMemoryKey)); block.DeclareLocal(key); block.Load(this); block.LoadLocal(start); block.New(typeof(ParserMemoryKey).GetConstructor(new Type[] { typeof(ConcretePattern), typeof(int) })); block.StoreLocal(key); BlockLocal oldSkipMemoryForLeftRecursion = new BlockLocal(typeof(bool)); block.DeclareLocal(oldSkipMemoryForLeftRecursion); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("SkipMemoryForLeftRecursion")); block.Dup(); block.StoreLocal(oldSkipMemoryForLeftRecursion); BlockLabel checkMemory = new BlockLabel("checkMemory"); block.BranchIfFalse(checkMemory); block.LoadState(); block.Load(false); block.SetProperty(typeof(ParserState).GetProperty("SkipMemoryForLeftRecursion")); BlockLabel setRecursion = new BlockLabel("setRecursion"); block.Branch(setRecursion); block.MarkLabel(checkMemory); block.BeginScope(); BlockLocal entry = new BlockLocal(typeof(ParserMemoryEntry)); block.DeclareLocal(entry); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Memory")); block.LoadLocal(key); block.LoadLocalAddress(entry); block.Call(typeof(Dictionary <ParserMemoryKey, ParserMemoryEntry>).GetMethod("TryGetValue")); block.BranchIfFalse(setRecursion); // todo link next BlockLabel memoryYes = new BlockLabel("memoryYes"); block.LoadLocal(entry); block.GetProperty(typeof(ParserMemoryEntry).GetProperty("Tree")); BlockLabel returnTree = new BlockLabel("returnTree"); block.BranchIfNotNo(memoryYes); block.No(this, start, "from memory"); block.Branch(returnTree); block.MarkLabel(memoryYes); block.Yes(this, start, "from memory"); block.LoadLexer(); block.LoadLocal(entry); block.GetProperty(typeof(ParserMemoryEntry).GetProperty("End")); block.SetProperty(typeof(Lexer).GetProperty("Position")); block.MarkLabel(returnTree); block.LoadLocal(entry); block.GetProperty(typeof(ParserMemoryEntry).GetProperty("Tree")); block.Branch(returnLabel); block.MarkLabel(setRecursion); BlockLocal oldRecursionExclude = new BlockLocal(typeof(ConcretePattern)); block.DeclareLocal(oldRecursionExclude); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("RecursionExclude")); block.StoreLocal(oldRecursionExclude); if (RecursionBehaviour != RecursionBehaviour.Recursive) { BlockLabel recursionExcludeSaveNull = new BlockLabel("recursionExcludeSaveNull"); block.LoadLocal(oldRecursionExclude); block.BranchIfNull(recursionExcludeSaveNull); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Excluded")); block.LoadLocal(oldRecursionExclude); block.Call(typeof(Multiset <Pattern>).GetMethod("Remove", new Type[] { typeof(Pattern) })); block.MarkLabel(recursionExcludeSaveNull); block.LoadState(); block.Load(this); block.SetProperty(typeof(ParserState).GetProperty("RecursionExclude")); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Excluded")); block.Load(this); block.Call(typeof(Multiset <Pattern>).GetMethod("Add", new Type[] { typeof(Pattern) })); } BlockLocal oldRecursionBehaviour = new BlockLocal(typeof(RecursionBehaviour)); block.DeclareLocal(oldRecursionBehaviour); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("RecursionBehaviour")); block.StoreLocal(oldRecursionBehaviour); block.LoadState(); block.Load(Convert.ToInt32(RecursionBehaviour)); block.SetProperty(typeof(ParserState).GetProperty("RecursionBehaviour")); RecursionBehaviour oldRecursionBehaviourState = state.RecursionBehaviour; state.RecursionBehaviour = RecursionBehaviour; BlockLocal oldCurrentPrecedence = new BlockLocal(typeof(Precedence)); block.DeclareLocal(oldCurrentPrecedence); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("CurrentPrecedence")); block.StoreLocal(oldCurrentPrecedence); BlockLabel doesntOverwrite = new BlockLabel("doesntOverwrite"); block.Load(Precedence); block.LoadLocal(oldCurrentPrecedence); block.Call(typeof(Precedence).GetMethod("Overwrites")); block.BranchIfFalse(doesntOverwrite); block.LoadState(); block.Load(Precedence); block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence")); block.MarkLabel(doesntOverwrite); BlockLocal oldPrecedenceCanEqualCurrent = new BlockLocal(typeof(bool)); block.DeclareLocal(oldPrecedenceCanEqualCurrent); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent")); block.StoreLocal(oldPrecedenceCanEqualCurrent); block.LoadState(); block.Load(RecursionBehaviour == RecursionBehaviour.Recursive); block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent")); BlockLocal tree = new BlockLocal(typeof(ParseTree)); block.DeclareLocal(tree); block.Emit(ParseGraph.Compile(runtime, state)); block.StoreLocal(tree); block.LoadState(); block.LoadLocal(oldCurrentPrecedence); block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence")); block.LoadState(); block.LoadLocal(oldPrecedenceCanEqualCurrent); block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent")); block.LoadState(); block.LoadLocal(oldRecursionBehaviour); block.SetProperty(typeof(ParserState).GetProperty("RecursionBehaviour")); state.RecursionBehaviour = oldRecursionBehaviourState; block.LoadState(); block.LoadLocal(oldRecursionExclude); block.SetProperty(typeof(ParserState).GetProperty("RecursionExclude")); block.LoadState(); block.LoadLocal(oldSkipMemoryForLeftRecursion); block.SetProperty(typeof(ParserState).GetProperty("SkipMemoryForLeftRecursion")); if (RecursionBehaviour != RecursionBehaviour.Recursive) { BlockLabel recursionExcludeRestoreNull = new BlockLabel("recursionExcludeRestoreNull"); block.LoadLocal(oldRecursionExclude); block.BranchIfNull(recursionExcludeRestoreNull); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Excluded")); block.LoadLocal(oldRecursionExclude); block.Call(typeof(Multiset <Pattern>).GetMethod("Add", new Type[] { typeof(Pattern) })); block.MarkLabel(recursionExcludeRestoreNull); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Excluded")); block.Load(this); block.Call(typeof(Multiset <Pattern>).GetMethod("Remove", new Type[] { typeof(Pattern) })); } BlockLabel no = new BlockLabel("yes1"); block.LoadLocal(tree); block.BranchIfNo(no); block.Whitespace(runtime, state); CompileInstantiate(block, start, tree); block.MarkLabel(no); BlockLocal nextTag = new BlockLocal(typeof(object)); block.DeclareLocal(nextTag); block.New(typeof(object)); block.StoreLocal(nextTag); // todo tag next BlockLabel yes = new BlockLabel("yes"); block.LoadLocal(tree); block.BranchIfNotNo(yes); block.No(this, start, "a"); BlockLabel finish = new BlockLabel("finish"); block.Branch(finish); block.MarkLabel(yes); block.Yes(this, start); if (RecursionBehaviour == RecursionBehaviour.LeftRecursive) { CompileLeftRecurse(runtime, state, block, start, tree); } block.MarkLabel(finish); if (ShouldRemember) { // TODO - can remove some other code if not remembering block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("Memory")); block.LoadLocal(key); block.LoadLocal(tree); block.LoadLexer(); block.GetProperty(typeof(Lexer).GetProperty("Position")); block.LoadLocal(nextTag); block.New(typeof(ParserMemoryEntry).GetConstructor(new Type[] { typeof(ParseTree), typeof(int), typeof(object) })); block.SetProperty(typeof(Dictionary <ParserMemoryKey, ParserMemoryEntry>).GetProperty("Item")); } block.LoadLocal(tree); block.EndScope(); block.MarkLabel(returnLabel); block.Comment("end of concrete pattern -------------"); return(block); }