private ParseExplanation BuildParseRuleExplanation(PathBack pathBack, GrammarRule rule) { return(new ParseExplanation { RuleApplied = rule, ResultToken = rule.ResultToken, ChildrenExplained = pathBack.pathNodes.Select(pn => pn.incomingEdge.Meta).ToList() }); }
private List <PathBack> FindAllPathsBack(Node head, int length) { List <PathBack> paths = new List <PathBack>(); Stack <StackFrame> stack = new Stack <StackFrame>(); stack.Push(new StackFrame { currentDepth = 1, currentNode = head, nextParentId = 0 }); while (stack.Count > 0) { var frame = stack.Peek(); if (frame.currentDepth == length) { var pathBack = new PathBack { previousNode = frame.currentNode, pathNodes = stack.Skip(1).Select(fr => new NodeWithIncomingEdge { targetNode = fr.currentNode, incomingEdge = fr.currentNode.PrevNodes[fr.nextParentId] }).ToList() }; paths.Add(pathBack); stack.Pop(); if (stack.Count > 0) { stack.Peek().nextParentId++; } continue; } else { if (frame.nextParentId >= frame.currentNode.PrevNodes.Count) { stack.Pop(); if (stack.Count > 0) { stack.Peek().nextParentId++; } continue; } else { stack.Push(new StackFrame { currentDepth = frame.currentDepth + 1, currentNode = frame.currentNode.PrevNodes[frame.nextParentId].PrevNode, nextParentId = 0 }); continue; } } } return(paths); }
private Node CreateReduceNode(PathBack pathBack, GrammarRule rule) { if (!Table[pathBack.previousNode.State].ShiftActionsMap.TryGetValue(rule.ResultToken, out int newState)) { // after we reduced, there is no non-terminal-shift available. let's return null as a new node to signify no parse available return(null); } var result = new Node(rule.ResultToken, newState); result.PrevNodes.Add(new Edge { PrevNode = pathBack.previousNode, Meta = BuildParseRuleExplanation(pathBack, rule) }); return(result); }