private void SetRuleParamsInfo(Rule rule, RuleExpression.RuleUsage ruleUsage) { var ruleArgsInfo = rule.GetEntities().OfType <RuleParameter>().ToArray(); if (ruleArgsInfo.Length != ruleUsage.Arguments.Count) { throw new InvalidOperationException(string.Format("Trying to call rule [{0}] with [{1}] parameters!", rule.ToString(), ruleUsage.Arguments.Count)); } for (int i = 0; i < ruleArgsInfo.Length; i++) { _nav.SetParamExpression(ruleArgsInfo[i], ruleUsage.Arguments[i]); } }
private GraphContext FindRuleRecursiveInvocationNode(Rule rule, RuleExpression.RuleUsage ruleUsage) { GraphContext entryContext = null; for (var c = _currContext.parentContext; c != null; c = c.parentContext) { //var a = ruleUsage.Arguments; //var g = c.expression.ToString(); //var b = c.rule.GetEntities().OfType<RuleExpression.RuleUsage>().ToArray(); if (c.rule == rule && c.parentContext.rule != rule && ruleUsage.ToString() == c.parentContext.expression.ToString()) { entryContext = c; break; } } return(entryContext); }
internal RecursiveParserNode(Rule rule, RuleExpression.RuleUsage targetCallExpr) : base(rule, null) { this.Target = null; this.TargetCallExpr = targetCallExpr; }
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(); } }