public void testActions(String templates, String actionName, String action, String expected) throws org.antlr.runtime.RecognitionException { int lp = templates.indexOf('('); String name = templates.substring(0, lp); STGroup group = new STGroupString(templates); ST st = group.getInstanceOf(name); st.add(actionName, action); String grammar = st.render(); ErrorQueue equeue = new ErrorQueue(); Grammar g = new Grammar(grammar, equeue); if (g.ast != null && !g.ast.hasErrors) { SemanticPipeline sem = new SemanticPipeline(g); sem.process(); ATNFactory factory = new ParserATNFactory(g); if (g.isLexer()) factory = new LexerATNFactory((LexerGrammar) g); g.atn = factory.createATN(); CodeGenerator gen = new CodeGenerator(g); ST outputFileST = gen.generateParser(); String output = outputFileST.render(); // System.out.println(output); String b = "#" + actionName + "#"; int start = output.indexOf(b); String e = "#end-" + actionName + "#"; int end = output.indexOf(e); String snippet = output.substring(start + b.length(), end); assertEquals(expected, snippet); } if (equeue.size() > 0) { System.err.println(equeue.toString()); } }
/** * From (blk)* build ( blk+ )? with *two* decisions, one for entry and one for choosing alts of * blk. * * <p>|-------------| v | o--[o-blk-o]->o o | ^ -----------------| * * <p>Note that the optional bypass must jump outside the loop as (A|B)* is not the same thing as * (A|B|)+. */ @NotNull public Handle star(@NotNull GrammarAST starAST, @NotNull Handle elem) { StarBlockStartState blkStart = (StarBlockStartState) elem.left; BlockEndState blkEnd = (BlockEndState) elem.right; StarLoopEntryState entry = newState(StarLoopEntryState.class, starAST); atn.defineDecisionState(entry); LoopEndState end = newState(LoopEndState.class, starAST); StarLoopbackState loop = newState(StarLoopbackState.class, starAST); entry.loopBackState = loop; end.loopBackStateNumber = loop.stateNumber; BlockAST blkAST = (BlockAST) starAST.getChild(0); entry.isGreedy = isGreedy(blkAST); if (!g.isLexer() || entry.isGreedy) { epsilon(entry, blkStart); // loop enter edge (alt 1) epsilon(entry, end); // bypass loop edge (alt 2) } else { // only lexers flip entry/exit branches for nongreedy // if not greedy, priority to exit branch; make it first epsilon(entry, end); // bypass loop edge (alt 1) epsilon(entry, blkStart); // loop enter edge (alt 2) } epsilon(blkEnd, loop); // block end hits loop back epsilon(loop, entry); // loop back to entry/exit decision starAST.atnState = entry; // decision is to enter/exit; blk is its own decision return new Handle(entry, end); }
/** * From (blk)+ build * * <p>|---------| v | [o-blk-o]->o->o * * <p>We add a decision for loop back node to the existing one at blk start. */ @NotNull public Handle plus(@NotNull GrammarAST plusAST, @NotNull Handle blk) { PlusBlockStartState blkStart = (PlusBlockStartState) blk.left; BlockEndState blkEnd = (BlockEndState) blk.right; PlusLoopbackState loop = newState(PlusLoopbackState.class, plusAST); atn.defineDecisionState(loop); LoopEndState end = newState(LoopEndState.class, plusAST); blkStart.loopBackState = loop; end.loopBackStateNumber = loop.stateNumber; plusAST.atnState = blkStart; epsilon(blkEnd, loop); // blk can see loop back BlockAST blkAST = (BlockAST) plusAST.getChild(0); loop.isGreedy = isGreedy(blkAST); if (!g.isLexer() || loop.isGreedy) { epsilon(loop, blkStart); // loop back to start epsilon(loop, end); // or exit } else { // only lexers flip entry/exit branches for nongreedy // if not greedy, priority to exit branch; make it first epsilon(loop, end); // exit epsilon(loop, blkStart); // loop back to start } return new Handle(blkStart, end); }
protected int getTokenType(@NotNull GrammarAST atom) { int ttype; if (g.isLexer()) { ttype = CharSupport.getCharValueFromGrammarCharLiteral(atom.getText()); } else { ttype = g.getTokenType(atom.getText()); } return ttype; }
ATN createATN(Grammar g) { if (g.atn != null) return g.atn; semanticProcess(g); ParserATNFactory f = new ParserATNFactory(g); if (g.isLexer()) f = new LexerATNFactory((LexerGrammar) g); g.atn = f.createATN(); return g.atn; }
public List<String> getEvalInfoForString(String grammarString, String pattern) throws RecognitionException { ErrorQueue equeue = new ErrorQueue(); Grammar g = new Grammar(grammarString); List<String> evals = new ArrayList<String>(); if (g.ast != null && !g.ast.hasErrors) { SemanticPipeline sem = new SemanticPipeline(g); sem.process(); ATNFactory factory = new ParserATNFactory(g); if (g.isLexer()) factory = new LexerATNFactory((LexerGrammar) g); g.atn = factory.createATN(); CodeGenerator gen = new CodeGenerator(g); ST outputFileST = gen.generateParser(); // STViz viz = outputFileST.inspect(); // try { // viz.waitForClose(); // } // catch (Exception e) { // e.printStackTrace(); // } boolean debug = false; DebugInterpreter interp = new DebugInterpreter( outputFileST.groupThatCreatedThisInstance, outputFileST.impl.nativeGroup.errMgr, debug); InstanceScope scope = new InstanceScope(null, outputFileST); StringWriter sw = new StringWriter(); AutoIndentWriter out = new AutoIndentWriter(sw); interp.exec(out, scope); for (String e : interp.evals) { if (e.contains(pattern)) { evals.add(e); } } } if (equeue.size() > 0) { System.err.println(equeue.toString()); } return evals; }
public static Map<String, GrammarAST> getUnusedParserRules(Grammar g) { if (g.ast == null || g.isLexer()) return null; List<GrammarAST> ruleNodes = g.ast.getNodesWithTypePreorderDFS(IntervalSet.of(ANTLRParser.RULE_REF)); // in case of errors, we walk AST ourselves // ANTLR's Grammar object might have bailed on rule defs etc... Set<String> ruleRefs = new HashSet<String>(); Map<String, GrammarAST> ruleDefs = new HashMap<String, GrammarAST>(); for (GrammarAST x : ruleNodes) { if (x.getParent().getType() == ANTLRParser.RULE) { // System.out.println("def "+x); ruleDefs.put(x.getText(), x); } else if (x instanceof RuleRefAST) { RuleRefAST r = (RuleRefAST) x; // System.out.println("ref "+r); ruleRefs.add(r.getText()); } } ruleDefs.keySet().removeAll(ruleRefs); return ruleDefs; }
protected ATN createATN(Grammar g, boolean useSerializer) { if (g.atn == null) { semanticProcess(g); assertEquals(0, g.tool.getNumErrors()); ParserATNFactory f; if (g.isLexer()) { f = new LexerATNFactory((LexerGrammar) g); } else { f = new ParserATNFactory(g); } g.atn = f.createATN(); assertEquals(0, g.tool.getNumErrors()); } ATN atn = g.atn; if (useSerializer) { char[] serialized = ATNSerializer.getSerializedAsChars(atn); return new ATNDeserializer().deserialize(serialized); } return atn; }