예제 #1
0
        public override Handle Set(GrammarAST associatedAST, IList<GrammarAST> alts, bool invert)
        {
            ATNState left = NewState(associatedAST);
            ATNState right = NewState(associatedAST);
            IntervalSet set = new IntervalSet();
            foreach (GrammarAST t in alts)
            {
                if (t.Type == ANTLRParser.RANGE)
                {
                    int a = CharSupport.GetCharValueFromGrammarCharLiteral(t.GetChild(0).Text);
                    int b = CharSupport.GetCharValueFromGrammarCharLiteral(t.GetChild(1).Text);
                    if (CheckRange((GrammarAST)t.GetChild(0), (GrammarAST)t.GetChild(1), a, b))
                    {
                        CheckSetCollision(associatedAST, set, a, b);
                        set.Add(a, b);
                    }
                }
                else if (t.Type == ANTLRParser.LEXER_CHAR_SET)
                {
                    set.AddAll(GetSetFromCharSetLiteral(t));
                }
                else if (t.Type == ANTLRParser.STRING_LITERAL)
                {
                    int c = CharSupport.GetCharValueFromGrammarCharLiteral(t.Text);
                    if (c != -1)
                    {
                        CheckSetCollision(associatedAST, set, c);
                        set.Add(c);
                    }
                    else
                    {
                        g.tool.errMgr.GrammarError(ErrorType.INVALID_LITERAL_IN_LEXER_SET,
                                                   g.fileName, t.Token, t.Text);
                    }
                }
                else if (t.Type == ANTLRParser.TOKEN_REF)
                {
                    g.tool.errMgr.GrammarError(ErrorType.UNSUPPORTED_REFERENCE_IN_LEXER_SET,
                                               g.fileName, t.Token, t.Text);
                }
            }
            if (invert)
            {
                left.AddTransition(new NotSetTransition(right, set));
            }
            else
            {
                Transition transition;
                if (set.GetIntervals().Count == 1)
                {
                    Interval interval = set.GetIntervals()[0];
                    transition = new RangeTransition(right, interval.a, interval.b);
                }
                else
                {
                    transition = new SetTransition(right, set);
                }

                left.AddTransition(transition);
            }
            associatedAST.atnState = left;
            return new Handle(left, right);
        }
예제 #2
0
        public override Handle Set(GrammarAST associatedAST, IList <GrammarAST> alts, bool invert)
        {
            ATNState    left  = NewState(associatedAST);
            ATNState    right = NewState(associatedAST);
            IntervalSet set   = new IntervalSet();

            foreach (GrammarAST t in alts)
            {
                if (t.Type == ANTLRParser.RANGE)
                {
                    int a = CharSupport.GetCharValueFromGrammarCharLiteral(t.GetChild(0).Text);
                    int b = CharSupport.GetCharValueFromGrammarCharLiteral(t.GetChild(1).Text);
                    if (CheckRange((GrammarAST)t.GetChild(0), (GrammarAST)t.GetChild(1), a, b))
                    {
                        CheckSetCollision(associatedAST, set, a, b);
                        set.Add(a, b);
                    }
                }
                else if (t.Type == ANTLRParser.LEXER_CHAR_SET)
                {
                    set.AddAll(GetSetFromCharSetLiteral(t));
                }
                else if (t.Type == ANTLRParser.STRING_LITERAL)
                {
                    int c = CharSupport.GetCharValueFromGrammarCharLiteral(t.Text);
                    if (c != -1)
                    {
                        CheckSetCollision(associatedAST, set, c);
                        set.Add(c);
                    }
                    else
                    {
                        g.tool.errMgr.GrammarError(ErrorType.INVALID_LITERAL_IN_LEXER_SET,
                                                   g.fileName, t.Token, t.Text);
                    }
                }
                else if (t.Type == ANTLRParser.TOKEN_REF)
                {
                    g.tool.errMgr.GrammarError(ErrorType.UNSUPPORTED_REFERENCE_IN_LEXER_SET,
                                               g.fileName, t.Token, t.Text);
                }
            }
            if (invert)
            {
                left.AddTransition(new NotSetTransition(right, set));
            }
            else
            {
                Transition transition;
                if (set.GetIntervals().Count == 1)
                {
                    Interval interval = set.GetIntervals()[0];
                    transition = new RangeTransition(right, interval.a, interval.b);
                }
                else
                {
                    transition = new SetTransition(right, set);
                }

                left.AddTransition(transition);
            }
            associatedAST.atnState = left;
            return(new Handle(left, right));
        }
예제 #3
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.");
        }
예제 #4
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.");
        }