예제 #1
0
        public virtual IList <GrammarAST> GetNodesWithType(IntervalSet types)
        {
            IList <GrammarAST>      nodes = new List <GrammarAST>();
            LinkedList <GrammarAST> work  = new LinkedList <GrammarAST>();

            work.AddLast(this);
            GrammarAST t;

            while (work.Count > 0)
            {
                t = work.First.Value;
                work.RemoveFirst();
                if (types == null || types.Contains(t.Type))
                {
                    nodes.Add(t);
                }
                if (t.Children != null)
                {
                    foreach (var child in t.GetChildrenAsArray())
                    {
                        work.AddLast(child);
                    }
                }
            }
            return(nodes);
        }
예제 #2
0
 protected virtual void CheckSetCollision(GrammarAST ast, IntervalSet set, int el)
 {
     if (set.Contains(el))
     {
         g.tool.errMgr.GrammarError(ErrorType.CHARACTERS_COLLISION_IN_SET, g.fileName, ast.Token,
                                    (char)el, ast.Text);
     }
 }
예제 #3
0
        public virtual ATN CreateATN()
        {
            _CreateATN(g.rules.Values);

            Debug.Assert(atn.maxTokenType == g.GetMaxTokenType());
            AddRuleFollowLinks();
            AddEOFTransitionToStartRules();
            ATNOptimizer.Optimize(g, atn);

            foreach (System.Tuple <Rule, ATNState, ATNState> pair in preventEpsilonClosureBlocks)
            {
                LL1Analyzer analyzer  = new LL1Analyzer(atn);
                ATNState    blkStart  = pair.Item2;
                ATNState    blkStop   = pair.Item3;
                IntervalSet lookahead = analyzer.Look(blkStart, blkStop, PredictionContext.EmptyLocal);
                if (lookahead.Contains(Antlr4.Runtime.TokenConstants.Epsilon))
                {
                    ErrorType errorType = pair.Item1 is LeftRecursiveRule ? ErrorType.EPSILON_LR_FOLLOW : ErrorType.EPSILON_CLOSURE;
                    g.tool.errMgr.GrammarError(errorType, g.fileName, ((GrammarAST)pair.Item1.ast.GetChild(0)).Token, pair.Item1.name);
                }
            }

            foreach (System.Tuple <Rule, ATNState, ATNState> pair in preventEpsilonOptionalBlocks)
            {
                int bypassCount = 0;
                for (int i = 0; i < pair.Item2.NumberOfTransitions; i++)
                {
                    ATNState startState = pair.Item2.Transition(i).target;
                    if (startState == pair.Item3)
                    {
                        bypassCount++;
                        continue;
                    }

                    LL1Analyzer analyzer = new LL1Analyzer(atn);
                    if (analyzer.Look(startState, pair.Item3, PredictionContext.EmptyLocal).Contains(Antlr4.Runtime.TokenConstants.Epsilon))
                    {
                        g.tool.errMgr.GrammarError(ErrorType.EPSILON_OPTIONAL, g.fileName, ((GrammarAST)pair.Item1.ast.GetChild(0)).Token, pair.Item1.name);
                        goto continueOptionalCheck;
                    }
                }

                if (bypassCount != 1)
                {
                    throw new InvalidOperationException("Expected optional block with exactly 1 bypass alternative.");
                }

continueOptionalCheck:
                ;
            }

            return(atn);
        }
예제 #4
0
 public virtual void GetNodesWithTypePreorderDFS_(IList <GrammarAST> nodes, IntervalSet types)
 {
     if (types.Contains(this.Type))
     {
         nodes.Add(this);
     }
     // walk all children of root.
     for (int i = 0; i < ChildCount; i++)
     {
         GrammarAST child = (GrammarAST)GetChild(i);
         child.GetNodesWithTypePreorderDFS_(nodes, types);
     }
 }
예제 #5
0
        protected virtual void ProcessLexer()
        {
            // make sure all non-fragment lexer rules must match at least one symbol
            foreach (Rule rule in g.rules.Values)
            {
                if (rule.IsFragment())
                {
                    continue;
                }

                LL1Analyzer analyzer = new LL1Analyzer(g.atn);
                IntervalSet look     = analyzer.Look(g.atn.ruleToStartState[rule.index], PredictionContext.EmptyLocal);
                if (look.Contains(TokenConstants.Epsilon))
                {
                    g.tool.errMgr.GrammarError(ErrorType.EPSILON_TOKEN, g.fileName, ((GrammarAST)rule.ast.GetChild(0)).Token, rule.name);
                }
            }
        }
예제 #6
0
        protected virtual void CheckSetCollision(GrammarAST ast, IntervalSet set, int a, int b)
        {
            for (int i = a; i <= b; i++)
            {
                if (set.Contains(i))
                {
                    string setText;
                    if (ast.Children == null)
                    {
                        setText = ast.Text;
                    }
                    else
                    {
                        StringBuilder sb = new StringBuilder();
                        foreach (object child in ast.Children)
                        {
                            if (child is RangeAST)
                            {
                                sb.Append(((RangeAST)child).GetChild(0).Text);
                                sb.Append("..");
                                sb.Append(((RangeAST)child).GetChild(1).Text);
                            }
                            else
                            {
                                sb.Append(((GrammarAST)child).Text);
                            }
                            sb.Append(" | ");
                        }
                        sb.Remove(sb.Length - 3, 3);
                        setText = sb.ToString();
                    }

                    g.tool.errMgr.GrammarError(ErrorType.CHARACTERS_COLLISION_IN_SET, g.fileName, ast.Token,
                                               (char)a + "-" + (char)b, setText);
                    break;
                }
            }
        }
예제 #7
0
        protected virtual void CheckSetCollision(GrammarAST ast, IntervalSet set, int a, int b)
        {
            for (int i = a; i <= b; i++)
            {
                if (set.Contains(i))
                {
                    string setText;
                    if (ast.Children == null)
                    {
                        setText = ast.Text;
                    }
                    else
                    {
                        StringBuilder sb = new StringBuilder();
                        foreach (object child in ast.Children)
                        {
                            if (child is RangeAST)
                            {
                                sb.Append(((RangeAST)child).GetChild(0).Text);
                                sb.Append("..");
                                sb.Append(((RangeAST)child).GetChild(1).Text);
                            }
                            else
                            {
                                sb.Append(((GrammarAST)child).Text);
                            }
                            sb.Append(" | ");
                        }
                        sb.Remove(sb.Length - 3, 3);
                        setText = sb.ToString();
                    }

                    g.tool.errMgr.GrammarError(ErrorType.CHARACTERS_COLLISION_IN_SET, g.fileName, ast.Token,
                                        (char)a + "-" + (char)b, setText);
                    break;
                }
            }
        }
예제 #8
0
 protected virtual void CheckSetCollision(GrammarAST ast, IntervalSet set, int el)
 {
     if (set.Contains(el))
     {
         g.tool.errMgr.GrammarError(ErrorType.CHARACTERS_COLLISION_IN_SET, g.fileName, ast.Token,
                 (char)el, ast.Text);
     }
 }
예제 #9
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);
        }
예제 #10
0
        public virtual string Text(GrammarAST t)
        {
            if (t == null)
            {
                return("");
            }

            int tokenStartIndex = t.TokenStartIndex;
            int tokenStopIndex  = t.TokenStopIndex;

            // ignore tokens from existing option subtrees like:
            //    (ELEMENT_OPTIONS (= assoc right))
            //
            // element options are added back according to the values in the map
            // returned by getOptions().
            IntervalSet        ignore          = new IntervalSet();
            IList <GrammarAST> optionsSubTrees = t.GetNodesWithType(ELEMENT_OPTIONS);

            foreach (GrammarAST sub in optionsSubTrees)
            {
                ignore.Add(sub.TokenStartIndex, sub.TokenStopIndex);
            }

            // Individual labels appear as RULE_REF or TOKEN_REF tokens in the tree,
            // but do not support the ELEMENT_OPTIONS syntax. Make sure to not try
            // and add the tokenIndex option when writing these tokens.
            IntervalSet        noOptions       = new IntervalSet();
            IList <GrammarAST> labeledSubTrees = t.GetNodesWithType(new IntervalSet(ASSIGN, PLUS_ASSIGN));

            foreach (GrammarAST sub in labeledSubTrees)
            {
                noOptions.Add(sub.GetChild(0).TokenStartIndex);
            }

            StringBuilder buf = new StringBuilder();
            int           i   = tokenStartIndex;

            while (i <= tokenStopIndex)
            {
                if (ignore.Contains(i))
                {
                    i++;
                    continue;
                }

                IToken tok = tokenStream.Get(i);

                // Compute/hold any element options
                StringBuilder elementOptions = new StringBuilder();
                if (!noOptions.Contains(i))
                {
                    GrammarAST node = t.GetNodeWithTokenIndex(tok.TokenIndex);
                    if (node != null &&
                        (tok.Type == TOKEN_REF ||
                         tok.Type == STRING_LITERAL ||
                         tok.Type == RULE_REF))
                    {
                        elementOptions.Append("tokenIndex=").Append(tok.TokenIndex);
                    }

                    if (node is GrammarASTWithOptions)
                    {
                        GrammarASTWithOptions o = (GrammarASTWithOptions)node;
                        foreach (KeyValuePair <string, GrammarAST> entry in o.GetOptions())
                        {
                            if (elementOptions.Length > 0)
                            {
                                elementOptions.Append(',');
                            }

                            elementOptions.Append(entry.Key);
                            elementOptions.Append('=');
                            elementOptions.Append(entry.Value.Text);
                        }
                    }
                }

                buf.Append(tok.Text); // add actual text of the current token to the rewritten alternative
                i++;                  // move to the next token

                // Are there args on a rule?
                if (tok.Type == RULE_REF && i <= tokenStopIndex && tokenStream.Get(i).Type == ARG_ACTION)
                {
                    buf.Append('[' + tokenStream.Get(i).Text + ']');
                    i++;
                }

                // now that we have the actual element, we can add the options.
                if (elementOptions.Length > 0)
                {
                    buf.Append('<').Append(elementOptions).Append('>');
                }
            }
            return(buf.ToString());
        }
        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;
        }
예제 #12
0
        private static void OptimizeSets(Grammar g, ATN atn)
        {
            if (g.IsParser())
            {
                // parser codegen doesn't currently support SetTransition
                return;
            }

            int removedStates = 0;
            IList <DecisionState> decisions = atn.decisionToState;

            foreach (DecisionState decision in decisions)
            {
                if (decision.ruleIndex >= 0)
                {
                    Rule rule = g.GetRule(decision.ruleIndex);
                    if (char.IsLower(rule.name[0]))
                    {
                        // parser codegen doesn't currently support SetTransition
                        continue;
                    }
                }

                IntervalSet setTransitions = new IntervalSet();
                for (int i = 0; i < decision.NumberOfTransitions; i++)
                {
                    Transition epsTransition = decision.Transition(i);
                    if (!(epsTransition is EpsilonTransition))
                    {
                        continue;
                    }

                    if (epsTransition.target.NumberOfTransitions != 1)
                    {
                        continue;
                    }

                    Transition transition = epsTransition.target.Transition(0);
                    if (!(transition.target is BlockEndState))
                    {
                        continue;
                    }

                    if (transition is NotSetTransition)
                    {
                        // TODO: not yet implemented
                        continue;
                    }

                    if (transition is AtomTransition ||
                        transition is RangeTransition ||
                        transition is SetTransition)
                    {
                        setTransitions.Add(i);
                    }
                }

                // due to min alt resolution policies, can only collapse sequential alts
                for (int i = setTransitions.GetIntervals().Count - 1; i >= 0; i--)
                {
                    Interval interval = setTransitions.GetIntervals()[i];
                    if (interval.Length <= 1)
                    {
                        continue;
                    }

                    ATNState    blockEndState = decision.Transition(interval.a).target.Transition(0).target;
                    IntervalSet matchSet      = new IntervalSet();
                    for (int j = interval.a; j <= interval.b; j++)
                    {
                        Transition matchTransition = decision.Transition(j).target.Transition(0);
                        if (matchTransition is NotSetTransition)
                        {
                            throw new NotImplementedException();
                        }

                        IntervalSet set     = matchTransition.Label;
                        int         minElem = set.MinElement;
                        int         maxElem = set.MaxElement;
                        for (int k = minElem; k <= maxElem; k++)
                        {
                            if (matchSet.Contains(k))
                            {
                                char setMin = (char)set.MinElement;
                                char setMax = (char)set.MaxElement;
                                // TODO: Token is missing (i.e. position in source will not be displayed).
                                g.tool.errMgr.GrammarError(ErrorType.CHARACTERS_COLLISION_IN_SET, g.fileName,
                                                           null, (char)minElem + "-" + (char)maxElem, "[" + setMin + "-" + setMax + "]");
                                break;
                            }
                        }

                        matchSet.AddAll(set);
                    }

                    Transition newTransition;
                    if (matchSet.GetIntervals().Count == 1)
                    {
                        if (matchSet.Count == 1)
                        {
                            newTransition = new AtomTransition(blockEndState, matchSet.MinElement);
                        }
                        else
                        {
                            Interval matchInterval = matchSet.GetIntervals()[0];
                            newTransition = new RangeTransition(blockEndState, matchInterval.a, matchInterval.b);
                        }
                    }
                    else
                    {
                        newTransition = new SetTransition(blockEndState, matchSet);
                    }

                    decision.Transition(interval.a).target.SetTransition(0, newTransition);
                    for (int j = interval.a + 1; j <= interval.b; j++)
                    {
                        Transition removed = decision.Transition(interval.a + 1);
                        decision.RemoveTransition(interval.a + 1);
                        atn.RemoveState(removed.target);
                        removedStates++;
                    }
                }
            }

            //System.Console.WriteLine("ATN optimizer removed " + removedStates + " states by collapsing sets.");
        }
예제 #13
0
        public virtual string Text(GrammarAST t)
        {
            if (t == null)
                return "";

            int tokenStartIndex = t.TokenStartIndex;
            int tokenStopIndex = t.TokenStopIndex;

            // ignore tokens from existing option subtrees like:
            //    (ELEMENT_OPTIONS (= assoc right))
            //
            // element options are added back according to the values in the map
            // returned by getOptions().
            IntervalSet ignore = new IntervalSet();
            IList<GrammarAST> optionsSubTrees = t.GetNodesWithType(ELEMENT_OPTIONS);
            foreach (GrammarAST sub in optionsSubTrees)
            {
                ignore.Add(sub.TokenStartIndex, sub.TokenStopIndex);
            }

            // Individual labels appear as RULE_REF or TOKEN_REF tokens in the tree,
            // but do not support the ELEMENT_OPTIONS syntax. Make sure to not try
            // and add the tokenIndex option when writing these tokens.
            IntervalSet noOptions = new IntervalSet();
            IList<GrammarAST> labeledSubTrees = t.GetNodesWithType(new IntervalSet(ASSIGN, PLUS_ASSIGN));
            foreach (GrammarAST sub in labeledSubTrees)
            {
                noOptions.Add(sub.GetChild(0).TokenStartIndex);
            }

            StringBuilder buf = new StringBuilder();
            int i = tokenStartIndex;
            while (i <= tokenStopIndex)
            {
                if (ignore.Contains(i))
                {
                    i++;
                    continue;
                }

                IToken tok = tokenStream.Get(i);

                // Compute/hold any element options
                StringBuilder elementOptions = new StringBuilder();
                if (!noOptions.Contains(i))
                {
                    GrammarAST node = t.GetNodeWithTokenIndex(tok.TokenIndex);
                    if (node != null &&
                         (tok.Type == TOKEN_REF ||
                          tok.Type == STRING_LITERAL ||
                          tok.Type == RULE_REF))
                    {
                        elementOptions.Append("tokenIndex=").Append(tok.TokenIndex);
                    }

                    if (node is GrammarASTWithOptions)
                    {
                        GrammarASTWithOptions o = (GrammarASTWithOptions)node;
                        foreach (KeyValuePair<string, GrammarAST> entry in o.GetOptions())
                        {
                            if (elementOptions.Length > 0)
                            {
                                elementOptions.Append(',');
                            }

                            elementOptions.Append(entry.Key);
                            elementOptions.Append('=');
                            elementOptions.Append(entry.Value.Text);
                        }
                    }
                }

                buf.Append(tok.Text); // add actual text of the current token to the rewritten alternative
                i++;                       // move to the next token

                // Are there args on a rule?
                if (tok.Type == RULE_REF && i <= tokenStopIndex && tokenStream.Get(i).Type == ARG_ACTION)
                {
                    buf.Append('[' + tokenStream.Get(i).Text + ']');
                    i++;
                }

                // now that we have the actual element, we can add the options.
                if (elementOptions.Length > 0)
                {
                    buf.Append('<').Append(elementOptions).Append('>');
                }
            }
            return buf.ToString();
        }
예제 #14
0
 public virtual IList<GrammarAST> GetNodesWithType(IntervalSet types)
 {
     IList<GrammarAST> nodes = new List<GrammarAST>();
     LinkedList<GrammarAST> work = new LinkedList<GrammarAST>();
     work.AddLast(this);
     GrammarAST t;
     while (work.Count > 0)
     {
         t = work.First.Value;
         work.RemoveFirst();
         if (types == null || types.Contains(t.Type))
             nodes.Add(t);
         if (t.Children != null)
         {
             foreach (var child in t.GetChildrenAsArray())
                 work.AddLast(child);
         }
     }
     return nodes;
 }
예제 #15
0
 public virtual void GetNodesWithTypePreorderDFS_(IList<GrammarAST> nodes, IntervalSet types)
 {
     if (types.Contains(this.Type))
         nodes.Add(this);
     // walk all children of root.
     for (int i = 0; i < ChildCount; i++)
     {
         GrammarAST child = (GrammarAST)GetChild(i);
         child.GetNodesWithTypePreorderDFS_(nodes, types);
     }
 }
예제 #16
0
        private static void OptimizeSets(Grammar g, ATN atn)
        {
            if (g.IsParser())
            {
                // parser codegen doesn't currently support SetTransition
                return;
            }

            int removedStates = 0;
            IList<DecisionState> decisions = atn.decisionToState;
            foreach (DecisionState decision in decisions)
            {
                if (decision.ruleIndex >= 0)
                {
                    Rule rule = g.GetRule(decision.ruleIndex);
                    if (char.IsLower(rule.name[0]))
                    {
                        // parser codegen doesn't currently support SetTransition
                        continue;
                    }
                }

                IntervalSet setTransitions = new IntervalSet();
                for (int i = 0; i < decision.NumberOfTransitions; i++)
                {
                    Transition epsTransition = decision.Transition(i);
                    if (!(epsTransition is EpsilonTransition))
                    {
                        continue;
                    }

                    if (epsTransition.target.NumberOfTransitions != 1)
                    {
                        continue;
                    }

                    Transition transition = epsTransition.target.Transition(0);
                    if (!(transition.target is BlockEndState))
                    {
                        continue;
                    }

                    if (transition is NotSetTransition)
                    {
                        // TODO: not yet implemented
                        continue;
                    }

                    if (transition is AtomTransition
                        || transition is RangeTransition
                        || transition is SetTransition)
                    {
                        setTransitions.Add(i);
                    }
                }

                // due to min alt resolution policies, can only collapse sequential alts
                for (int i = setTransitions.GetIntervals().Count - 1; i >= 0; i--)
                {
                    Interval interval = setTransitions.GetIntervals()[i];
                    if (interval.Length <= 1)
                    {
                        continue;
                    }

                    ATNState blockEndState = decision.Transition(interval.a).target.Transition(0).target;
                    IntervalSet matchSet = new IntervalSet();
                    for (int j = interval.a; j <= interval.b; j++)
                    {
                        Transition matchTransition = decision.Transition(j).target.Transition(0);
                        if (matchTransition is NotSetTransition)
                        {
                            throw new NotImplementedException();
                        }

                        IntervalSet set = matchTransition.Label;
                        int minElem = set.MinElement;
                        int maxElem = set.MaxElement;
                        for (int k = minElem; k <= maxElem; k++)
                        {
                            if (matchSet.Contains(k))
                            {
                                char setMin = (char)set.MinElement;
                                char setMax = (char)set.MaxElement;
                                // TODO: Token is missing (i.e. position in source will not be displayed).
                                g.tool.errMgr.GrammarError(ErrorType.CHARACTERS_COLLISION_IN_SET, g.fileName,
                                                           null, (char)minElem + "-" + (char)maxElem, "[" + setMin + "-" + setMax + "]");
                                break;
                            }
                        }

                        matchSet.AddAll(set);
                    }

                    Transition newTransition;
                    if (matchSet.GetIntervals().Count == 1)
                    {
                        if (matchSet.Count == 1)
                        {
                            newTransition = new AtomTransition(blockEndState, matchSet.MinElement);
                        }
                        else
                        {
                            Interval matchInterval = matchSet.GetIntervals()[0];
                            newTransition = new RangeTransition(blockEndState, matchInterval.a, matchInterval.b);
                        }
                    }
                    else
                    {
                        newTransition = new SetTransition(blockEndState, matchSet);
                    }

                    decision.Transition(interval.a).target.SetTransition(0, newTransition);
                    for (int j = interval.a + 1; j <= interval.b; j++)
                    {
                        Transition removed = decision.Transition(interval.a + 1);
                        decision.RemoveTransition(interval.a + 1);
                        atn.RemoveState(removed.target);
                        removedStates++;
                    }
                }
            }

            //System.Console.WriteLine("ATN optimizer removed " + removedStates + " states by collapsing sets.");
        }