public override ParseGraphNode BuildParseGraph(RuntimeState state) { List <ParseGraphNode> nodes = new List <ParseGraphNode>(); foreach (PatternExpression node in new PatternExpression[] { a, b }) { ParseGraphNode nodeGraph = node.BuildParseGraph(state); if (nodeGraph is AltNode) { nodes.AddRange(((AltNode)nodeGraph).Alts); } else { nodes.Add(nodeGraph); } } return(new AltNode(Source, nodes, false)); }
public PrecedenceAltGroup(Source source, Precedence precedence, List<IParseable> nodes) { this.nodes = nodes; this.precedence = precedence; if (nodes.Count == 1) parseGraph = nodes[0]; else parseGraph = new LongestAlt(source, nodes); leftRecursiveNodes = new List<ParseGraphNode>(); foreach (IParseable node in (IEnumerable<IParseable>) nodes) { PatternNode patternNode = node as PatternNode; if (patternNode != null) { ConcretePattern pattern = patternNode.Pattern as ConcretePattern; if (pattern != null) { if (pattern.RecursionBehaviour == RecursionBehaviour.LeftRecursive) leftRecursiveNodes.Add(new PatternNode(source, pattern, true)); } } } if (leftRecursiveNodes.Count == 0) leftRecursiveParseGraph = null; else if (leftRecursiveNodes.Count == 1) leftRecursiveParseGraph = leftRecursiveNodes[0]; else leftRecursiveParseGraph = new AltNode(source, leftRecursiveNodes, true); }
public override ParseGraphNode BuildParseGraph(RuntimeState state) { ParseGraphNode parseGraph = body.BuildParseGraph(state); if (options.Count == 0) { return(parseGraph); } OptionsNode optionsNode = new OptionsNode(Source, parseGraph); foreach (Option option in options) { string optionKey = option.optionKey.name; object optionValue; if (option.optionValue == null) { optionValue = true; } else { optionValue = option.optionValue.Get(state); } switch (optionKey) { case "buildTextNodes": optionsNode.BuildTextNodes.Value = ConvertNode.ToBool(optionValue); break; case "dropPrecedence": optionsNode.DropPrecedence.Value = ConvertNode.ToBool(optionValue); break; case "recursive": { if (ConvertNode.ToBool(optionValue)) { optionsNode.RecursionBehaviour.Value = RecursionBehaviour.Recursive; } else { optionsNode.RecursionBehaviour.Value = RecursionBehaviour.None; } } break; case "leftRecursive": optionsNode.RecursionBehaviour.Value = RecursionBehaviour.LeftRecursive; break; case "rightRecursive": optionsNode.RecursionBehaviour.Value = RecursionBehaviour.RightRecursive; break; case "whitespace": optionsNode.Whitespace.Value = Pattern.PatternForType((Type)optionValue); break; case "exclude": optionsNode.Exclude.Value = Pattern.PatternForType((Type)optionValue); break; } } return(optionsNode); }
private void AddNode(TreeIter parent, ParseGraphNode node) { if (node is AnyNode) { AddNode(parent, (AnyNode)node); } else if (node is TextNode) { AddNode(parent, (TextNode)node); } else if (node is CharNode) { AddNode(parent, (CharNode)node); } else if (node is PatternNode) { AddNode(parent, (PatternNode)node); } else if (node is AltNode) { AddNode(parent, (AltNode)node); } else if (node is RepNode) { AddNode(parent, (RepNode)node); } else if (node is SeqNode) { AddNode(parent, (SeqNode)node); } else if (node is TokenNode) { AddNode(parent, (TokenNode)node); } else if (node is LabelNode) { AddNode(parent, (LabelNode)node); } else if (node is OptionsNode) { AddNode(parent, (OptionsNode)node); } else if (node is FailNode) { AddNode(parent, (FailNode)node); } else if (node is AndNode) { AddNode(parent, (AndNode)node); } else if (node is NotNode) { AddNode(parent, (NotNode)node); } else if (node is UserDefinedNode) { AddNode(parent, (UserDefinedNode)node); } else { throw new Exception("Unsupported grammar node type " + node.GetType() + " in viewer"); } }
public override Block CompileNewState(Runtime runtime, StateForCompiler state) { ParserBlock block = new ParserBlock(); block.Comment("begin precedence alt -----------"); // todo enter block.BeginScope(); BlockLabel returnLabel = new BlockLabel("return"); BlockLocal oldLeftRecursiveAlts = new BlockLocal(typeof(IParseable)); block.DeclareLocal(oldLeftRecursiveAlts); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts")); block.StoreLocal(oldLeftRecursiveAlts); ParseGraphNode oldLeftRecursiveAltsForCompiler = state.LeftRecursiveAlts; foreach (PrecedenceAltGroup group in groups) { block.BeginScope(); BlockLocal groupLocal = new BlockLocal(typeof(PrecedenceAltGroup)); block.DeclareLocal(groupLocal); block.Load(group); block.StoreLocal(groupLocal); BlockLabel apply = new BlockLabel("apply"); BlockLabel continueLabel = new BlockLabel("continue"); BlockLocal currentPrecedence = new BlockLocal(typeof(Precedence)); block.DeclareLocal(currentPrecedence); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("CurrentPrecedence")); block.Dup(); block.StoreLocal(currentPrecedence); block.BranchIfNull(apply); BlockLocal groupPrecedence = new BlockLocal(typeof(Precedence)); block.DeclareLocal(groupPrecedence); block.LoadLocal(groupLocal); block.GetProperty(groupLocal.Type.GetProperty("Precedence")); block.Dup(); block.StoreLocal(groupPrecedence); block.BranchIfNull(apply); block.LoadLocal(currentPrecedence); block.GetProperty(currentPrecedence.Type.GetProperty("Group")); block.LoadLocal(groupPrecedence); block.GetProperty(groupPrecedence.Type.GetProperty("Group")); block.BranchIfNotEqual(apply); block.LoadLocal(groupPrecedence); block.LoadLocal(currentPrecedence); block.LoadState(); block.GetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent")); block.LogicalNot(); block.Call(groupPrecedence.Type.GetMethod("IsLowerThan")); block.BranchIfTrue(continueLabel); block.MarkLabel(apply); block.LoadState(); block.LoadLocal(groupLocal); block.GetProperty(groupLocal.Type.GetProperty("LeftRecursiveParseGraph")); block.SetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts")); state.LeftRecursiveAlts = group.LeftRecursiveParseGraph; block.Emit(group.ParseGraph.Compile(runtime, state)); block.Dup(); BlockLabel no = new BlockLabel("no"); block.BranchIfNo(no); block.LoadState(); block.LoadLocal(oldLeftRecursiveAlts); block.SetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts")); // todo yes block.Branch(returnLabel); block.MarkLabel(no); block.Pop(); block.MarkLabel(continueLabel); block.EndScope(); } block.LoadState(); block.LoadLocal(oldLeftRecursiveAlts); block.SetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts")); state.LeftRecursiveAlts = oldLeftRecursiveAltsForCompiler; block.EndScope(); // todo no block.LoadNo(); block.MarkLabel(returnLabel); block.Comment("end precedence alt -----------"); return(block); }