Esempio n. 1
0
 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();
     }
 }
Esempio n. 2
0
        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;
        }
Esempio n. 3
0
 public void VisitRuleCall(ParserNode.RuleCall ruleCall)
 {
     this.LogLine("{0}", ruleCall); _v.VisitRuleCall(ruleCall);
 }
Esempio n. 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();
            }
        }
Esempio n. 5
0
 void IParserNodeVisitor.VisitRuleCall(ParserNode.RuleCall ruleCall)
 {
     this.PrintNode(ruleCall);
 }