use of org.antlr.v4.runtime.misc.Tuple2 in project antlr4 by tunnelvisionlabs.
the class LeftRecursiveRuleTransformer method translateLeftRecursiveRule.
/**
* Return true if successful
*/
public boolean translateLeftRecursiveRule(GrammarRootAST ast, LeftRecursiveRule r, String language) {
// tool.log("grammar", ruleAST.toStringTree());
GrammarAST prevRuleAST = r.ast;
String ruleName = prevRuleAST.getChild(0).getText();
LeftRecursiveRuleAnalyzer leftRecursiveRuleWalker = new LeftRecursiveRuleAnalyzer(prevRuleAST, tool, ruleName, language);
boolean isLeftRec;
try {
// System.out.println("TESTING ---------------\n"+
// leftRecursiveRuleWalker.text(ruleAST));
isLeftRec = leftRecursiveRuleWalker.rec_rule();
} catch (RecognitionException re) {
// didn't match; oh well
isLeftRec = false;
}
if (!isLeftRec)
return false;
// replace old rule's AST; first create text of altered rule
GrammarAST RULES = (GrammarAST) ast.getFirstChildWithType(ANTLRParser.RULES);
String newRuleText = leftRecursiveRuleWalker.getArtificialOpPrecRule();
// System.out.println("created: "+newRuleText);
// now parse within the context of the grammar that originally created
// the AST we are transforming. This could be an imported grammar so
// we cannot just reference this.g because the role might come from
// the imported grammar and not the root grammar (this.g)
RuleAST t = parseArtificialRule(prevRuleAST.g, newRuleText);
// reuse the name token from the original AST since it refers to the proper source location in the original grammar
((GrammarAST) t.getChild(0)).token = ((GrammarAST) prevRuleAST.getChild(0)).getToken();
// update grammar AST and set rule's AST.
RULES.setChild(prevRuleAST.getChildIndex(), t);
r.ast = t;
// Reduce sets in newly created rule tree
GrammarTransformPipeline transform = new GrammarTransformPipeline(g, g.tool);
transform.reduceBlocksToSets(r.ast);
transform.expandParameterizedLoops(r.ast);
// Rerun semantic checks on the new rule
RuleCollector ruleCollector = new RuleCollector(g);
ruleCollector.visit(t, "rule");
BasicSemanticChecks basics = new BasicSemanticChecks(g, ruleCollector);
// disable the assoc element option checks because they are already
// handled for the pre-transformed rule.
basics.checkAssocElementOption = false;
basics.visit(t, "rule");
// track recursive alt info for codegen
r.recPrimaryAlts = new ArrayList<LeftRecursiveRuleAltInfo>();
r.recPrimaryAlts.addAll(leftRecursiveRuleWalker.prefixAndOtherAlts);
if (r.recPrimaryAlts.isEmpty()) {
tool.errMgr.grammarError(ErrorType.NO_NON_LR_ALTS, g.fileName, ((GrammarAST) r.ast.getChild(0)).getToken(), r.name);
}
r.recOpAlts = new OrderedHashMap<Integer, LeftRecursiveRuleAltInfo>();
r.recOpAlts.putAll(leftRecursiveRuleWalker.binaryAlts);
r.recOpAlts.putAll(leftRecursiveRuleWalker.ternaryAlts);
r.recOpAlts.putAll(leftRecursiveRuleWalker.suffixAlts);
// walk alt info records and set their altAST to point to appropriate ALT subtree
// from freshly created AST
setAltASTPointers(r, t);
// update Rule to just one alt and add prec alt
ActionAST arg = (ActionAST) r.ast.getFirstChildWithType(ANTLRParser.ARG_ACTION);
if (arg != null) {
r.args = ScopeParser.parseTypedArgList(arg, arg.getText(), g);
r.args.type = AttributeDict.DictType.ARG;
r.args.ast = arg;
// todo: isn't this Rule or something?
arg.resolver = r.alt[1];
}
// these are so $label in action translation works
for (Tuple2<GrammarAST, String> pair : leftRecursiveRuleWalker.leftRecursiveRuleRefLabels) {
GrammarAST labelNode = pair.getItem1();
GrammarAST labelOpNode = (GrammarAST) labelNode.getParent();
GrammarAST elementNode = (GrammarAST) labelOpNode.getChild(1);
LabelElementPair lp = new LabelElementPair(g, labelNode, elementNode, labelOpNode.getType());
r.alt[1].labelDefs.map(labelNode.getText(), lp);
}
// copy to rule from walker
r.leftRecursiveRuleRefLabels = leftRecursiveRuleWalker.leftRecursiveRuleRefLabels;
tool.log("grammar", "added: " + t.toStringTree());
return true;
}
use of org.antlr.v4.runtime.misc.Tuple2 in project antlr4 by tunnelvisionlabs.
the class RuleDependencyChecker method getElementDependencies.
private static void getElementDependencies(AnnotatedElement annotatedElement, List<Tuple2<RuleDependency, AnnotatedElement>> result) {
RuleDependency dependency = annotatedElement.getAnnotation(RuleDependency.class);
if (dependency != null) {
result.add(Tuple.create(dependency, annotatedElement));
}
RuleDependencies dependencies = annotatedElement.getAnnotation(RuleDependencies.class);
if (dependencies != null) {
for (RuleDependency d : dependencies.value()) {
if (d != null) {
result.add(Tuple.create(d, annotatedElement));
}
}
}
}
use of org.antlr.v4.runtime.misc.Tuple2 in project antlr4 by tunnelvisionlabs.
the class BaseTest method getParserAndLexer.
public Tuple2<Parser, Lexer> getParserAndLexer(String input, String parserName, String lexerName) throws Exception {
final Class<? extends Lexer> lexerClass = loadLexerClassFromTempDir(lexerName);
final Class<? extends Parser> parserClass = loadParserClassFromTempDir(parserName);
Class<? extends Lexer> c = lexerClass.asSubclass(Lexer.class);
Constructor<? extends Lexer> ctor = c.getConstructor(CharStream.class);
Lexer lexer = ctor.newInstance(CharStreams.fromString(input));
Class<? extends Parser> pc = parserClass.asSubclass(Parser.class);
Constructor<? extends Parser> pctor = pc.getConstructor(TokenStream.class);
CommonTokenStream tokens = new CommonTokenStream(lexer);
Parser parser = pctor.newInstance(tokens);
return Tuple.create(parser, lexer);
}
use of org.antlr.v4.runtime.misc.Tuple2 in project antlr4 by tunnelvisionlabs.
the class Grammar method defAlias.
protected static boolean defAlias(GrammarAST r, String pattern, org.antlr.runtime.tree.TreeWizard wiz, List<Tuple2<GrammarAST, GrammarAST>> lexerRuleToStringLiteral) {
HashMap<String, Object> nodes = new HashMap<String, Object>();
if (wiz.parse(r, pattern, nodes)) {
GrammarAST litNode = (GrammarAST) nodes.get("lit");
GrammarAST nameNode = (GrammarAST) nodes.get("name");
Tuple2<GrammarAST, GrammarAST> pair = Tuple.create(nameNode, litNode);
lexerRuleToStringLiteral.add(pair);
return true;
}
return false;
}
use of org.antlr.v4.runtime.misc.Tuple2 in project antlr4 by tunnelvisionlabs.
the class RuleFunction method addContextGetters.
public void addContextGetters(OutputModelFactory factory, Collection<RuleAST> contextASTs) {
List<AltAST> unlabeledAlternatives = new ArrayList<AltAST>();
Map<String, List<AltAST>> labeledAlternatives = new LinkedHashMap<String, List<AltAST>>();
for (RuleAST ast : contextASTs) {
try {
unlabeledAlternatives.addAll(rule.g.getUnlabeledAlternatives(ast));
for (Map.Entry<String, List<Tuple2<Integer, AltAST>>> entry : rule.g.getLabeledAlternatives(ast).entrySet()) {
List<AltAST> list = labeledAlternatives.get(entry.getKey());
if (list == null) {
list = new ArrayList<AltAST>();
labeledAlternatives.put(entry.getKey(), list);
}
for (Tuple2<Integer, AltAST> tuple : entry.getValue()) {
list.add(tuple.getItem2());
}
}
} catch (RecognitionException ex) {
}
}
// Add ctx labels for elements in alts with no '#' label
if (!unlabeledAlternatives.isEmpty()) {
Set<Decl> decls = getDeclsForAllElements(unlabeledAlternatives);
// put directly in base context
for (Decl decl : decls) {
ruleCtx.addDecl(decl);
}
}
// make structs for '#' labeled alts, define ctx labels for elements
altLabelCtxs = new LinkedHashMap<String, AltLabelStructDecl>();
if (!labeledAlternatives.isEmpty()) {
for (Map.Entry<String, List<AltAST>> entry : labeledAlternatives.entrySet()) {
AltLabelStructDecl labelDecl = new AltLabelStructDecl(factory, rule, entry.getKey());
altLabelCtxs.put(entry.getKey(), labelDecl);
Set<Decl> decls = getDeclsForAllElements(entry.getValue());
for (Decl decl : decls) {
labelDecl.addDecl(decl);
}
}
}
}
Aggregations