public LeftRecursiveRuleFunction(OutputModelFactory factory, LeftRecursiveRule r)
            : base(factory, r)
        {
            // Since we delete x=lr, we have to manually add decls for all labels
            // on left-recur refs to proper structs
            foreach (System.Tuple <GrammarAST, string> pair in r.leftRecursiveRuleRefLabels)
            {
                GrammarAST idAST    = pair.Item1;
                string     altLabel = pair.Item2;
                string     label    = idAST.Text;
                GrammarAST rrefAST  = (GrammarAST)idAST.Parent.GetChild(1);
                if (rrefAST.Type == ANTLRParser.RULE_REF)
                {
                    Rule            targetRule = factory.GetGrammar().GetRule(rrefAST.Text);
                    string          ctxName    = factory.GetTarget().GetRuleFunctionContextStructName(targetRule);
                    RuleContextDecl d;
                    if (idAST.Parent.Type == ANTLRParser.ASSIGN)
                    {
                        d = new RuleContextDecl(factory, label, ctxName);
                    }
                    else
                    {
                        d = new RuleContextListDecl(factory, label, ctxName);
                    }

                    StructDecl @struct = ruleCtx;
                    if (altLabelCtxs != null)
                    {
                        AltLabelStructDecl s;
                        if (altLabel != null && altLabelCtxs.TryGetValue(altLabel, out s) && s != null)
                        {
                            @struct = s; // if alt label, use subctx
                        }
                    }

                    @struct.AddDecl(d); // stick in overall rule's ctx
                }
            }
        }
Exemple #2
0
        public virtual void AddContextGetters(OutputModelFactory factory, ICollection <RuleAST> contextASTs)
        {
            IList <AltAST> unlabeledAlternatives = new List <AltAST>();
            IDictionary <string, IList <AltAST> > labeledAlternatives = new Dictionary <string, IList <AltAST> >();

            foreach (RuleAST ast in contextASTs)
            {
                try
                {
                    foreach (var altAst in rule.g.GetUnlabeledAlternatives(ast))
                    {
                        unlabeledAlternatives.Add(altAst);
                    }

                    foreach (KeyValuePair <string, IList <System.Tuple <int, AltAST> > > entry in rule.g.GetLabeledAlternatives(ast))
                    {
                        IList <AltAST> list;
                        if (!labeledAlternatives.TryGetValue(entry.Key, out list))
                        {
                            list = new List <AltAST>();
                            labeledAlternatives[entry.Key] = list;
                        }

                        foreach (System.Tuple <int, AltAST> tuple in entry.Value)
                        {
                            list.Add(tuple.Item2);
                        }
                    }
                }
                catch (RecognitionException)
                {
                }
            }

            // Add ctx labels for elements in alts with no '#' label
            if (unlabeledAlternatives.Count > 0)
            {
                ISet <Decl.Decl> decls = GetDeclsForAllElements(unlabeledAlternatives);

                // put directly in base context
                foreach (Decl.Decl decl in decls)
                {
                    ruleCtx.AddDecl(decl);
                }
            }

            // make structs for '#' labeled alts, define ctx labels for elements
            altLabelCtxs = new Dictionary <string, AltLabelStructDecl>();
            if (labeledAlternatives.Count > 0)
            {
                foreach (KeyValuePair <string, IList <AltAST> > entry in labeledAlternatives)
                {
                    AltLabelStructDecl labelDecl = new AltLabelStructDecl(factory, rule, entry.Key);
                    altLabelCtxs[entry.Key] = labelDecl;
                    ISet <Decl.Decl> decls = GetDeclsForAllElements(entry.Value);
                    foreach (Decl.Decl decl in decls)
                    {
                        labelDecl.AddDecl(decl);
                    }
                }
            }
        }