void IParserNodeVisitor.VisitRuleCall(ParserNode.RuleCall ruleCall) { if (_currState.PrevNode == ruleCall.Parent || (_currState.PrevNode is ParserNode.RecursiveParserNode && (_currState.PrevNode as ParserNode.RecursiveParserNode).Target == ruleCall)) { _currState = _currState.EnterNode(ruleCall.Child); } else if (_currState.PrevNode == ruleCall.Child) { _currState = _currState.ExitNode(); } else { throw new InvalidOperationException(); } }
private void WrapChilds(RuleAlternativeInfo info) { var lst = new List <ParsingTreeNode.ParsedNode>(); for (var n = _currChild; n != null; n = n.Next) { lst.Add(n); } var callExpressions = info.AlternativesInfo.Alternatives.Select(a => new { alternative = a, expr = new RuleExpression.RuleUsage(a.Rule.Name) }).ToArray(); var parentAlternatives = new ParserNode.Alternatives( info.RootRule, new RuleExpression.Or(callExpressions.Select(a => a.expr).ToArray()), callExpressions.Select(a => new ParserNode.RuleCall(a.alternative.Rule, a.expr, new ParserNode.FsmParserNode(null, null, null))).ToArray() ); var parentCall = new ParserNode.RuleCall(_currChild.Rule, new RuleExpression.RuleUsage(info.RootRule.Name), parentAlternatives); ParsingTreeNode.ParsedNode next = null; for (int i = lst.Count - 1; i >= 0; i--) { var curr = lst[i]; if (i % 2 != 0) { next = new ParsingTreeNode.Group(curr.GrammarNode.Parent, curr.Location, next, curr.UpdateNext(null) ); } else { next = new ParsingTreeNode.Group(parentCall, curr.Location, next, new ParsingTreeNode.Group(parentAlternatives, curr.Location, null, new ParsingTreeNode.Group(new ParserNode.RuleCall(parentAlternatives.Rule, new RuleExpression.RuleUsage(curr.Rule.Name), new ParserNode.FsmParserNode(null, null, null)), curr.Location, null, curr.UpdateNext(null) ) ) ); } } _currChild = next; }
public void VisitRuleCall(ParserNode.RuleCall ruleCall) { this.LogLine("{0}", ruleCall); _v.VisitRuleCall(ruleCall); }
void IRuleExpressionVisitor.VisitRuleUsage(RuleExpression.RuleUsage ruleUsage) { if (_currContext.invocationCount == 0) { // _log.WriteLine("entering from [{0}] to [{1}]", _currContext.rule == null ? "<NULL>" : _currContext.rule.Name, ruleUsage.RuleName).Push(); RuleExpression expr; if (_nav.TryEnterParameterContext(ruleUsage.RuleName, out expr)) { _currContext = _currContext.ForChildExpression(expr, _nav.CurrRuleInfo.Rule); } else { GrammarNavigator.RuleInfo ruleInfo; //if (!_nav.TryResolveRule(ruleUsage.RuleName, out ruleInfo)) if (!_nav.TryEnterRule(ruleUsage.RuleName, out ruleInfo)) { throw new InvalidOperationException(string.Format("Referenced rule [{0}] not found!", ruleUsage.RuleName)); } var rule = ruleInfo.IsExplicitRule ? ruleInfo.Rule : this.ExpandExtensibleRule(ruleInfo); RuleExpression expression; if (this.TryRewriteRecursionCalls(rule, out expression)) { ParserNode recursiveTargetNode; if (_cachedMaterializedRewritedRuleEnterByPath.TryGetValue(ruleInfo.NamePath, out recursiveTargetNode)) { _nav.Exit(); var node = new ParserNode.RecursiveParserNode(rule, ruleUsage); node.SetTarget(recursiveTargetNode); _currContext = _currContext.ForParentExpression(node); return; } } this.SetRuleParamsInfo(rule, ruleUsage); var entryContext = this.FindRuleRecursiveInvocationNode(rule, ruleUsage); if (entryContext != null) { //_log.WriteLine("recursively exiting from [{0}] to [{1}]", ruleUsage.RuleName, _currContext.rule.Name).Pop(); _nav.Exit(); var node = new ParserNode.RecursiveParserNode(rule, ruleUsage); _recursiveNodes.Add(node); _currContext = _currContext.ForParentExpression(node); } else { _currContext = _currContext.ForChildExpression(expression, rule); } // _nav.Enter(ruleUsage.RuleName); } } else if (_currContext.invocationCount == 1) { if (_currContext.childEntries.node == null || _currContext.childEntries.prev != null) { throw new InvalidOperationException(); } var ruleNamePath = _nav.CurrRuleInfo.NamePath; //_log.WriteLine("exiting from [{0}] to [{1}]", ruleUsage.RuleName, _currContext.rule.Name).Pop(); _nav.Exit(); var node = new ParserNode.RuleCall( _currContext.rule, _currContext.expression, _currContext.childEntries.node ); if (!_cachedMaterializedRewritedRuleEnterByPath.ContainsKey(ruleNamePath)) { _cachedMaterializedRewritedRuleEnterByPath.Add(ruleNamePath, node); } _currContext = _currContext.ForParentExpression(node); } else { throw new InvalidOperationException(); } }
void IParserNodeVisitor.VisitRuleCall(ParserNode.RuleCall ruleCall) { this.PrintNode(ruleCall); }