コード例 #1
0
        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]);
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
 internal RecursiveParserNode(Rule rule, RuleExpression.RuleUsage targetCallExpr)
     : base(rule, null)
 {
     this.Target         = null;
     this.TargetCallExpr = targetCallExpr;
 }
コード例 #4
0
        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();
            }
        }