Search in sources :

Example 96 with Rule

use of org.antlr.v4.tool.Rule in project antlr4 by antlr.

the class LeftRecursiveRuleTransformer method parseArtificialRule.

public RuleAST parseArtificialRule(final Grammar g, String ruleText) {
    ANTLRLexer lexer = new ANTLRLexer(new ANTLRStringStream(ruleText));
    GrammarASTAdaptor adaptor = new GrammarASTAdaptor(lexer.getCharStream());
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    lexer.tokens = tokens;
    ToolANTLRParser p = new ToolANTLRParser(tokens, tool);
    p.setTreeAdaptor(adaptor);
    Token ruleStart = null;
    try {
        ParserRuleReturnScope r = p.rule();
        RuleAST tree = (RuleAST) r.getTree();
        ruleStart = (Token) r.getStart();
        GrammarTransformPipeline.setGrammarPtr(g, tree);
        GrammarTransformPipeline.augmentTokensWithOriginalPosition(g, tree);
        return tree;
    } catch (Exception e) {
        tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, e, ruleStart, "error parsing rule created during left-recursion detection: " + ruleText);
    }
    return null;
}
Also used : ANTLRStringStream(org.antlr.runtime.ANTLRStringStream) RuleAST(org.antlr.v4.tool.ast.RuleAST) CommonTokenStream(org.antlr.runtime.CommonTokenStream) ANTLRLexer(org.antlr.v4.parse.ANTLRLexer) GrammarASTAdaptor(org.antlr.v4.parse.GrammarASTAdaptor) Token(org.antlr.runtime.Token) ParserRuleReturnScope(org.antlr.runtime.ParserRuleReturnScope) ToolANTLRParser(org.antlr.v4.parse.ToolANTLRParser) RecognitionException(org.antlr.runtime.RecognitionException)

Example 97 with Rule

use of org.antlr.v4.tool.Rule 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 98 with Rule

use of org.antlr.v4.tool.Rule in project antlr4 by antlr.

the class TestTokenTypeAssignment method testPredDoesNotHideNameToLiteralMapInLexer.

@Test
public void testPredDoesNotHideNameToLiteralMapInLexer() throws Exception {
    // 'x' is token and char in lexer rule
    Grammar g = new Grammar("grammar t;\n" + "a : 'x' X ; \n" + // must match as alias even with pred
    "X: 'x' {true}?;\n");
    assertEquals("{'x'=1}", g.stringLiteralToTypeMap.toString());
    assertEquals("{EOF=-1, X=1}", g.tokenNameToTypeMap.toString());
    // pushed in lexer from parser
    assertEquals("{'x'=1}", g.implicitLexer.stringLiteralToTypeMap.toString());
    assertEquals("{EOF=-1, X=1}", g.implicitLexer.tokenNameToTypeMap.toString());
}
Also used : Grammar(org.antlr.v4.tool.Grammar) LexerGrammar(org.antlr.v4.tool.LexerGrammar) Test(org.junit.Test)

Example 99 with Rule

use of org.antlr.v4.tool.Rule 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 100 with Rule

use of org.antlr.v4.tool.Rule in project antlr4 by antlr.

the class OutputModelController method buildParserOutputModel.

/**
 * Build a file with a parser containing rule functions. Use the
 *  controller as factory in SourceGenTriggers so it triggers codegen
 *  extensions too, not just the factory functions in this factory.
 */
public OutputModelObject buildParserOutputModel(boolean header) {
    CodeGenerator gen = delegate.getGenerator();
    ParserFile file = parserFile(gen.getRecognizerFileName(header));
    setRoot(file);
    file.parser = parser(file);
    Grammar g = delegate.getGrammar();
    for (Rule r : g.rules.values()) {
        buildRuleFunction(file.parser, r);
    }
    return file;
}
Also used : Grammar(org.antlr.v4.tool.Grammar) Rule(org.antlr.v4.tool.Rule) LeftRecursiveRule(org.antlr.v4.tool.LeftRecursiveRule) ParserFile(org.antlr.v4.codegen.model.ParserFile)

Aggregations

LexerGrammar (org.antlr.v4.tool.LexerGrammar)100 Rule (org.antlr.v4.tool.Rule)95 Test (org.junit.Test)94 ATN (org.antlr.v4.runtime.atn.ATN)87 GrammarAST (org.antlr.v4.tool.ast.GrammarAST)69 ArrayList (java.util.ArrayList)59 Grammar (org.antlr.v4.tool.Grammar)58 LeftRecursiveRule (org.antlr.v4.tool.LeftRecursiveRule)51 ATNState (org.antlr.v4.runtime.atn.ATNState)42 IntervalSet (org.antlr.v4.runtime.misc.IntervalSet)37 ParserRuleContext (org.antlr.v4.runtime.ParserRuleContext)36 Token (org.antlr.v4.runtime.Token)21 ActionAST (org.antlr.v4.tool.ast.ActionAST)21 CommonTokenStream (org.antlr.v4.runtime.CommonTokenStream)20 ParseTree (org.antlr.v4.runtime.tree.ParseTree)19 RuleAST (org.antlr.v4.tool.ast.RuleAST)19 HashMap (java.util.HashMap)18 RuleStartState (org.antlr.v4.runtime.atn.RuleStartState)16 AltAST (org.antlr.v4.tool.ast.AltAST)16 GrammarASTAdaptor (org.antlr.v4.parse.GrammarASTAdaptor)14