Пример #1
0
        public override void FinishPrequels(GrammarAST firstPrequel)
        {
            if (firstPrequel == null)
            {
                return;
            }
            GrammarAST         parent  = (GrammarAST)firstPrequel.Parent;
            IList <GrammarAST> options = parent.GetAllChildrenWithType(OPTIONS);
            IList <GrammarAST> imports = parent.GetAllChildrenWithType(IMPORT);
            IList <GrammarAST> tokens  = parent.GetAllChildrenWithType(TOKENS_SPEC);

            CheckNumPrequels(options, imports, tokens);
        }
Пример #2
0
        protected virtual bool ExpandOptionalQuantifiersForBlock(GrammarAST block, bool variant)
        {
            IList <GrammarAST> children = new List <GrammarAST>();

            for (int i = 0; i < block.ChildCount; i++)
            {
                GrammarAST child = (GrammarAST)block.GetChild(i);
                if (child.Type != ANTLRParser.ALT)
                {
                    children.Add(child);
                    continue;
                }

                GrammarAST expandedAlt = ExpandOptionalQuantifiersForAlt(child);
                if (expandedAlt == null)
                {
                    return(false);
                }

                children.Add(expandedAlt);
            }

            GrammarAST newChildren = (GrammarAST)adaptor.Nil();

            newChildren.AddChildren(children);
            block.ReplaceChildren(0, block.ChildCount - 1, newChildren);
            block.FreshenParentAndChildIndexesDeeply();

            if (!variant && block.Parent is RuleAST)
            {
                RuleAST            ruleAST   = (RuleAST)block.Parent;
                string             ruleName  = ruleAST.GetChild(0).Text;
                Rule               r         = _rules[ruleName];
                IList <GrammarAST> blockAlts = block.GetAllChildrenWithType(ANTLRParser.ALT);
                r.numberOfAlts = blockAlts.Count;
                r.alt          = new Alternative[blockAlts.Count + 1];
                for (int i = 0; i < blockAlts.Count; i++)
                {
                    r.alt[i + 1]     = new Alternative(r, i + 1);
                    r.alt[i + 1].ast = (AltAST)blockAlts[i];
                }
            }

            return(true);
        }
Пример #3
0
        /**
         * Important enough to avoid multiple definitions that we do very early,
         * right after AST construction. Also check for undefined rules in
         * parser/lexer to avoid exceptions later. Return true if we find multiple
         * definitions of the same rule or a reference to an undefined rule or
         * parser rule ref in lexer rule.
         */
        public virtual bool CheckForRuleIssues(Grammar g)
        {
            // check for redefined rules
            GrammarAST         RULES = (GrammarAST)g.ast.GetFirstChildWithType(ANTLRParser.RULES);
            IList <GrammarAST> rules = new List <GrammarAST>(RULES.GetAllChildrenWithType(ANTLRParser.RULE));

            foreach (GrammarAST mode in g.ast.GetAllChildrenWithType(ANTLRParser.MODE))
            {
                foreach (GrammarAST child in mode.GetAllChildrenWithType(ANTLRParser.RULE))
                {
                    rules.Add(child);
                }
            }

            bool redefinition = false;
            IDictionary <string, RuleAST> ruleToAST = new Dictionary <string, RuleAST>();

            foreach (GrammarAST r in rules)
            {
                RuleAST    ruleAST  = (RuleAST)r;
                GrammarAST ID       = (GrammarAST)ruleAST.GetChild(0);
                string     ruleName = ID.Text;
                RuleAST    prev;
                if (ruleToAST.TryGetValue(ruleName, out prev) && prev != null)
                {
                    GrammarAST prevChild = (GrammarAST)prev.GetChild(0);
                    g.tool.errMgr.GrammarError(ErrorType.RULE_REDEFINITION,
                                               g.fileName,
                                               ID.Token,
                                               ruleName,
                                               prevChild.Token.Line);
                    redefinition = true;
                    continue;
                }
                ruleToAST[ruleName] = ruleAST;
            }

            // check for undefined rules
            UndefChecker chk = new UndefChecker(this, g, ruleToAST);

            chk.VisitGrammar(g.ast);

            return(redefinition || chk.badref);
        }
Пример #4
0
        protected virtual bool TranslateLeftFactoredDecision(GrammarAST block, string factoredRule, bool variant, DecisionFactorMode mode, bool includeFactoredElement)
        {
            if (mode == DecisionFactorMode.PARTIAL_UNFACTORED && includeFactoredElement)
            {
                throw new ArgumentException("Cannot include the factored element in unfactored alternatives.");
            }
            else if (mode == DecisionFactorMode.COMBINED_FACTOR && !includeFactoredElement)
            {
                throw new ArgumentException("Cannot return a combined answer without the factored element.");
            }

            if (!ExpandOptionalQuantifiersForBlock(block, variant))
            {
                return(false);
            }

            IList <GrammarAST> alternatives = block.GetAllChildrenWithType(ANTLRParser.ALT);

            GrammarAST[] factoredAlternatives   = new GrammarAST[alternatives.Count];
            GrammarAST[] unfactoredAlternatives = new GrammarAST[alternatives.Count];
            IntervalSet  factoredIntervals      = new IntervalSet();
            IntervalSet  unfactoredIntervals    = new IntervalSet();

            for (int i = 0; i < alternatives.Count; i++)
            {
                GrammarAST alternative = alternatives[i];
                if (mode.IncludeUnfactoredAlts())
                {
                    GrammarAST unfactoredAlt = TranslateLeftFactoredAlternative(alternative.DupTree(), factoredRule, variant, DecisionFactorMode.PARTIAL_UNFACTORED, false);
                    unfactoredAlternatives[i] = unfactoredAlt;
                    if (unfactoredAlt != null)
                    {
                        unfactoredIntervals.Add(i);
                    }
                }

                if (mode.IncludeFactoredAlts())
                {
                    GrammarAST factoredAlt = TranslateLeftFactoredAlternative(alternative, factoredRule, variant, mode == DecisionFactorMode.COMBINED_FACTOR ? DecisionFactorMode.PARTIAL_FACTORED : DecisionFactorMode.FULL_FACTOR, includeFactoredElement);
                    factoredAlternatives[i] = factoredAlt;
                    if (factoredAlt != null)
                    {
                        factoredIntervals.Add(alternative.ChildIndex);
                    }
                }
            }

            if (factoredIntervals.IsNil && !mode.IncludeUnfactoredAlts())
            {
                return(false);
            }
            else if (unfactoredIntervals.IsNil && !mode.IncludeFactoredAlts())
            {
                return(false);
            }

            if (unfactoredIntervals.IsNil && factoredIntervals.Count == alternatives.Count && mode.IncludeFactoredAlts() && !includeFactoredElement)
            {
                for (int i = 0; i < factoredAlternatives.Length; i++)
                {
                    GrammarAST translatedAlt = factoredAlternatives[i];
                    if (translatedAlt.ChildCount == 0)
                    {
                        adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON"));
                    }

                    adaptor.SetChild(block, i, translatedAlt);
                }

                return(true);
            }
            else if (factoredIntervals.IsNil && unfactoredIntervals.Count == alternatives.Count && mode.IncludeUnfactoredAlts())
            {
                for (int i = 0; i < unfactoredAlternatives.Length; i++)
                {
                    GrammarAST translatedAlt = unfactoredAlternatives[i];
                    if (translatedAlt.ChildCount == 0)
                    {
                        adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON"));
                    }

                    adaptor.SetChild(block, i, translatedAlt);
                }

                return(true);
            }

            if (mode == DecisionFactorMode.FULL_FACTOR)
            {
                return(false);
            }

            /* for a, b, c being arbitrary `element` trees, this block performs
             * this transformation:
             *
             * factoredElement a
             * | factoredElement b
             * | factoredElement c
             * | ...
             *
             * ==>
             *
             * factoredElement (a | b | c | ...)
             */
            GrammarAST newChildren = (GrammarAST)adaptor.Nil();

            for (int i = 0; i < alternatives.Count; i++)
            {
                if (mode.IncludeFactoredAlts() && factoredIntervals.Contains(i))
                {
                    bool combineWithPrevious = i > 0 && factoredIntervals.Contains(i - 1) && (!mode.IncludeUnfactoredAlts() || !unfactoredIntervals.Contains(i - 1));
                    if (combineWithPrevious)
                    {
                        GrammarAST translatedAlt = factoredAlternatives[i];
                        if (translatedAlt.ChildCount == 0)
                        {
                            adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON"));
                        }

                        GrammarAST previous = (GrammarAST)newChildren.GetChild(newChildren.ChildCount - 1);

#if false
                        if (LOGGER.isLoggable(Level.FINE))
                        {
                            LOGGER.log(Level.FINE, previous.ToStringTree());
                            LOGGER.log(Level.FINE, translatedAlt.ToStringTree());
                        }
#endif

                        if (previous.ChildCount == 1 || previous.GetChild(1).Type != ANTLRParser.BLOCK)
                        {
                            GrammarAST newBlock = new BlockAST(adaptor.CreateToken(ANTLRParser.BLOCK, "BLOCK"));
                            GrammarAST newAlt   = new AltAST(adaptor.CreateToken(ANTLRParser.ALT, "ALT"));
                            adaptor.AddChild(newBlock, newAlt);
                            while (previous.ChildCount > 1)
                            {
                                adaptor.AddChild(newAlt, previous.DeleteChild(1));
                            }

                            if (newAlt.ChildCount == 0)
                            {
                                adaptor.AddChild(newAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON"));
                            }

                            adaptor.AddChild(previous, newBlock);
                        }

                        if (translatedAlt.ChildCount == 1 || translatedAlt.GetChild(1).Type != ANTLRParser.BLOCK)
                        {
                            GrammarAST newBlock = new BlockAST(adaptor.CreateToken(ANTLRParser.BLOCK, "BLOCK"));
                            GrammarAST newAlt   = new AltAST(adaptor.CreateToken(ANTLRParser.ALT, "ALT"));
                            adaptor.AddChild(newBlock, newAlt);
                            while (translatedAlt.ChildCount > 1)
                            {
                                adaptor.AddChild(newAlt, translatedAlt.DeleteChild(1));
                            }

                            if (newAlt.ChildCount == 0)
                            {
                                adaptor.AddChild(newAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON"));
                            }

                            adaptor.AddChild(translatedAlt, newBlock);
                        }

                        GrammarAST combinedBlock = (GrammarAST)previous.GetChild(1);
                        adaptor.AddChild(combinedBlock, translatedAlt.GetChild(1).GetChild(0));

#if false
                        if (LOGGER.isLoggable(Level.FINE))
                        {
                            LOGGER.log(Level.FINE, previous.ToStringTree());
                        }
#endif
                    }
                    else
                    {
                        GrammarAST translatedAlt = factoredAlternatives[i];
                        if (translatedAlt.ChildCount == 0)
                        {
                            adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON"));
                        }

                        adaptor.AddChild(newChildren, translatedAlt);
                    }
                }

                if (mode.IncludeUnfactoredAlts() && unfactoredIntervals.Contains(i))
                {
                    GrammarAST translatedAlt = unfactoredAlternatives[i];
                    if (translatedAlt.ChildCount == 0)
                    {
                        adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON"));
                    }

                    adaptor.AddChild(newChildren, translatedAlt);
                }
            }

            adaptor.ReplaceChildren(block, 0, block.ChildCount - 1, newChildren);

            if (!variant && block.Parent is RuleAST)
            {
                RuleAST            ruleAST   = (RuleAST)block.Parent;
                string             ruleName  = ruleAST.GetChild(0).Text;
                Rule               r         = _rules[ruleName];
                IList <GrammarAST> blockAlts = block.GetAllChildrenWithType(ANTLRParser.ALT);
                r.numberOfAlts = blockAlts.Count;
                r.alt          = new Alternative[blockAlts.Count + 1];
                for (int i = 0; i < blockAlts.Count; i++)
                {
                    r.alt[i + 1]     = new Alternative(r, i + 1);
                    r.alt[i + 1].ast = (AltAST)blockAlts[i];
                }
            }

            return(true);
        }