Search in sources :

Example 46 with IntervalSet

use of org.antlr.v4.runtime.misc.IntervalSet in project antlr4 by antlr.

the class ATNOptimizer method optimizeSets.

private static void optimizeSets(Grammar g, ATN atn) {
    if (g.isParser()) {
        // parser codegen doesn't currently support SetTransition
        return;
    }
    int removedStates = 0;
    List<DecisionState> decisions = atn.decisionToState;
    for (DecisionState decision : decisions) {
        if (decision.ruleIndex >= 0) {
            Rule rule = g.getRule(decision.ruleIndex);
            if (Character.isLowerCase(rule.name.charAt(0))) {
                // parser codegen doesn't currently support SetTransition
                continue;
            }
        }
        IntervalSet setTransitions = new IntervalSet();
        for (int i = 0; i < decision.getNumberOfTransitions(); i++) {
            Transition epsTransition = decision.transition(i);
            if (!(epsTransition instanceof EpsilonTransition)) {
                continue;
            }
            if (epsTransition.target.getNumberOfTransitions() != 1) {
                continue;
            }
            Transition transition = epsTransition.target.transition(0);
            if (!(transition.target instanceof BlockEndState)) {
                continue;
            }
            if (transition instanceof NotSetTransition) {
                // TODO: not yet implemented
                continue;
            }
            if (transition instanceof AtomTransition || transition instanceof RangeTransition || transition instanceof SetTransition) {
                setTransitions.add(i);
            }
        }
        // due to min alt resolution policies, can only collapse sequential alts
        for (int i = setTransitions.getIntervals().size() - 1; i >= 0; i--) {
            Interval interval = setTransitions.getIntervals().get(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 instanceof NotSetTransition) {
                    throw new UnsupportedOperationException("Not yet implemented.");
                }
                IntervalSet set = matchTransition.label();
                List<Interval> intervals = set.getIntervals();
                int n = intervals.size();
                for (int k = 0; k < n; k++) {
                    Interval setInterval = intervals.get(k);
                    int a = setInterval.a;
                    int b = setInterval.b;
                    if (a != -1 && b != -1) {
                        for (int v = a; v <= b; v++) {
                            if (matchSet.contains(v)) {
                                // 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, CharSupport.getANTLRCharLiteralForChar(v), CharSupport.getIntervalSetEscapedString(matchSet));
                                break;
                            }
                        }
                    }
                }
                matchSet.addAll(set);
            }
            Transition newTransition;
            if (matchSet.getIntervals().size() == 1) {
                if (matchSet.size() == 1) {
                    newTransition = CodePointTransitions.createWithCodePoint(blockEndState, matchSet.getMinElement());
                } else {
                    Interval matchInterval = matchSet.getIntervals().get(0);
                    newTransition = CodePointTransitions.createWithCodePointRange(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.removeTransition(interval.a + 1);
                atn.removeState(removed.target);
                removedStates++;
            }
        }
    }
//		System.out.println("ATN optimizer removed " + removedStates + " states by collapsing sets.");
}
Also used : AtomTransition(org.antlr.v4.runtime.atn.AtomTransition) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) SetTransition(org.antlr.v4.runtime.atn.SetTransition) DecisionState(org.antlr.v4.runtime.atn.DecisionState) BlockEndState(org.antlr.v4.runtime.atn.BlockEndState) RangeTransition(org.antlr.v4.runtime.atn.RangeTransition) ATNState(org.antlr.v4.runtime.atn.ATNState) IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) NotSetTransition(org.antlr.v4.runtime.atn.NotSetTransition) AtomTransition(org.antlr.v4.runtime.atn.AtomTransition) EpsilonTransition(org.antlr.v4.runtime.atn.EpsilonTransition) SetTransition(org.antlr.v4.runtime.atn.SetTransition) RangeTransition(org.antlr.v4.runtime.atn.RangeTransition) Transition(org.antlr.v4.runtime.atn.Transition) Rule(org.antlr.v4.tool.Rule) EpsilonTransition(org.antlr.v4.runtime.atn.EpsilonTransition) Interval(org.antlr.v4.runtime.misc.Interval)

Example 47 with IntervalSet

use of org.antlr.v4.runtime.misc.IntervalSet in project antlr4 by antlr.

the class TestTokenPositionOptions method testLeftRecursionWithSet.

@Test
public void testLeftRecursionWithSet() throws Exception {
    Grammar g = new Grammar("grammar T;\n" + "s : e ';' ;\n" + "e : e op=('*'|'/') e\n" + "  | e '+' e\n" + "  | e '.' ID\n" + "  | '-' e\n" + "  | ID\n" + "  ;\n" + "ID : [a-z]+ ;\n");
    String expectedTree = "(COMBINED_GRAMMAR T (RULES (RULE s (BLOCK (ALT e ';'))) (RULE e (BLOCK (ALT (BLOCK (ALT {} ('-' (ELEMENT_OPTIONS (= tokenIndex 49))) (e (ELEMENT_OPTIONS (= tokenIndex 51) (= p 2)))) (ALT (ID (ELEMENT_OPTIONS (= tokenIndex 55))))) (* (BLOCK (ALT ({precpred(_ctx, 5)}? (ELEMENT_OPTIONS (= p 5))) (= op (SET ('*' (ELEMENT_OPTIONS (= tokenIndex 24))) ('/' (ELEMENT_OPTIONS (= tokenIndex 26))))) (e (ELEMENT_OPTIONS (= tokenIndex 29) (= p 6)))) (ALT ({precpred(_ctx, 4)}? (ELEMENT_OPTIONS (= p 4))) ('+' (ELEMENT_OPTIONS (= tokenIndex 35))) (e (ELEMENT_OPTIONS (= tokenIndex 37) (= p 5)))) (ALT ({precpred(_ctx, 3)}? (ELEMENT_OPTIONS (= p 3))) ('.' (ELEMENT_OPTIONS (= tokenIndex 43))) (ID (ELEMENT_OPTIONS (= tokenIndex 45)))))))))))";
    assertEquals(expectedTree, g.ast.toStringTree());
    String expectedElementTokens = "[@5,11:11='s',<57>,2:0]\n" + "[@9,15:15='e',<57>,2:4]\n" + "[@11,17:19='';'',<62>,2:6]\n" + "[@15,23:23='e',<57>,3:0]\n" + "[@49,73:75=''-'',<62>,6:4]\n" + "[@51,77:77='e',<57>,6:8]\n" + "[@55,83:84='ID',<66>,7:4]\n" + "[@24,33:35=''*'',<62>,3:10]\n" + "[@26,37:39=''/'',<62>,3:14]\n" + "[@29,42:42='e',<57>,3:19]\n" + "[@35,50:52=''+'',<62>,4:6]\n" + "[@37,54:54='e',<57>,4:10]\n" + "[@43,62:64=''.'',<62>,5:6]\n" + "[@45,66:67='ID',<66>,5:10]";
    IntervalSet types = new IntervalSet(ANTLRParser.TOKEN_REF, ANTLRParser.STRING_LITERAL, ANTLRParser.RULE_REF);
    List<GrammarAST> nodes = g.ast.getNodesWithTypePreorderDFS(types);
    List<Token> tokens = new ArrayList<Token>();
    for (GrammarAST node : nodes) {
        tokens.add(node.getToken());
    }
    assertEquals(expectedElementTokens, Utils.join(tokens.toArray(), "\n"));
}
Also used : IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) GrammarAST(org.antlr.v4.tool.ast.GrammarAST) ArrayList(java.util.ArrayList) Token(org.antlr.runtime.Token) Grammar(org.antlr.v4.tool.Grammar) Test(org.junit.Test)

Example 48 with IntervalSet

use of org.antlr.v4.runtime.misc.IntervalSet in project antlr4 by antlr.

the class TestIntervalSet method testNotSetFragmentedVocabulary.

@Test
public void testNotSetFragmentedVocabulary() throws Exception {
    IntervalSet vocabulary = IntervalSet.of(1, 255);
    vocabulary.add(1000, 2000);
    vocabulary.add(9999);
    IntervalSet s = IntervalSet.of(50, 60);
    s.add(3);
    s.add(250, 300);
    // this is outside range of vocab and should be ignored
    s.add(10000);
    String expecting = "{1..2, 4..49, 61..249, 1000..2000, 9999}";
    String result = (s.complement(vocabulary)).toString();
    assertEquals(expecting, result);
}
Also used : IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) Test(org.junit.Test)

Example 49 with IntervalSet

use of org.antlr.v4.runtime.misc.IntervalSet in project antlr4 by antlr.

the class TestIntervalSet method testMergeWhereAdditionMergesThreeExistingIntervals.

/**
	 * This case is responsible for antlr/antlr4#153.
	 * https://github.com/antlr/antlr4/issues/153
	 */
@Test
public void testMergeWhereAdditionMergesThreeExistingIntervals() throws Exception {
    IntervalSet s = new IntervalSet();
    s.add(0);
    s.add(3);
    s.add(5);
    s.add(0, 7);
    String expecting = "{0..7}";
    String result = s.toString();
    assertEquals(expecting, result);
}
Also used : IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) Test(org.junit.Test)

Example 50 with IntervalSet

use of org.antlr.v4.runtime.misc.IntervalSet in project antlr4 by antlr.

the class TestIntervalSet method testMembership.

@Test
public void testMembership() throws Exception {
    IntervalSet s = IntervalSet.of(15, 15);
    s.add(50, 60);
    assertTrue(!s.contains(0));
    assertTrue(!s.contains(20));
    assertTrue(!s.contains(100));
    assertTrue(s.contains(15));
    assertTrue(s.contains(55));
    assertTrue(s.contains(50));
    assertTrue(s.contains(60));
}
Also used : IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) Test(org.junit.Test)

Aggregations

IntervalSet (org.antlr.v4.runtime.misc.IntervalSet)84 Test (org.junit.Test)48 ATNState (org.antlr.v4.runtime.atn.ATNState)11 GrammarAST (org.antlr.v4.tool.ast.GrammarAST)10 ATN (org.antlr.v4.runtime.atn.ATN)8 ArrayList (java.util.ArrayList)7 Grammar (org.antlr.v4.tool.Grammar)7 Interval (org.antlr.v4.runtime.misc.Interval)6 SetTransition (org.antlr.v4.runtime.atn.SetTransition)5 UnicodeSet (com.ibm.icu.text.UnicodeSet)4 HashMap (java.util.HashMap)4 Token (org.antlr.runtime.Token)4 NotSetTransition (org.antlr.v4.runtime.atn.NotSetTransition)4 BaseJavaTest (org.antlr.v4.test.runtime.java.BaseJavaTest)4 LinkedHashMap (java.util.LinkedHashMap)3 ParserRuleContext (org.antlr.v4.runtime.ParserRuleContext)3 AtomTransition (org.antlr.v4.runtime.atn.AtomTransition)3 DecisionState (org.antlr.v4.runtime.atn.DecisionState)3 RuleTransition (org.antlr.v4.runtime.atn.RuleTransition)3 Transition (org.antlr.v4.runtime.atn.Transition)3