use of org.antlr.v4.analysis.LeftRecursiveRuleAltInfo in project antlr4 by antlr.
the class LeftRecursiveRule method getPrimaryAlts.
/** Return an array that maps predicted alt from primary decision
* to original alt of rule. For following rule, return [0, 2, 4]
*
e : e '*' e
| INT
| e '+' e
| ID
;
* That maps predicted alt 1 to original alt 2 and predicted 2 to alt 4.
*
* @since 4.5.1
*/
public int[] getPrimaryAlts() {
if (recPrimaryAlts.size() == 0)
return null;
int[] alts = new int[recPrimaryAlts.size() + 1];
for (int i = 0; i < recPrimaryAlts.size(); i++) {
// recPrimaryAlts is a List not Map like recOpAlts
LeftRecursiveRuleAltInfo altInfo = recPrimaryAlts.get(i);
alts[i + 1] = altInfo.altNum;
}
return alts;
}
use of org.antlr.v4.analysis.LeftRecursiveRuleAltInfo in project antlr4 by antlr.
the class LeftRecursiveRule method getAltLabels.
/** Get -> labels from those alts we deleted for left-recursive rules. */
@Override
public Map<String, List<Pair<Integer, AltAST>>> getAltLabels() {
Map<String, List<Pair<Integer, AltAST>>> labels = new HashMap<String, List<Pair<Integer, AltAST>>>();
Map<String, List<Pair<Integer, AltAST>>> normalAltLabels = super.getAltLabels();
if (normalAltLabels != null)
labels.putAll(normalAltLabels);
if (recPrimaryAlts != null) {
for (LeftRecursiveRuleAltInfo altInfo : recPrimaryAlts) {
if (altInfo.altLabel != null) {
List<Pair<Integer, AltAST>> pairs = labels.get(altInfo.altLabel);
if (pairs == null) {
pairs = new ArrayList<Pair<Integer, AltAST>>();
labels.put(altInfo.altLabel, pairs);
}
pairs.add(new Pair<Integer, AltAST>(altInfo.altNum, altInfo.originalAltAST));
}
}
}
if (recOpAlts != null) {
for (int i = 0; i < recOpAlts.size(); i++) {
LeftRecursiveRuleAltInfo altInfo = recOpAlts.getElement(i);
if (altInfo.altLabel != null) {
List<Pair<Integer, AltAST>> pairs = labels.get(altInfo.altLabel);
if (pairs == null) {
pairs = new ArrayList<Pair<Integer, AltAST>>();
labels.put(altInfo.altLabel, pairs);
}
pairs.add(new Pair<Integer, AltAST>(altInfo.altNum, altInfo.originalAltAST));
}
}
}
if (labels.isEmpty())
return null;
return labels;
}
use of org.antlr.v4.analysis.LeftRecursiveRuleAltInfo in project antlr4 by antlr.
the class LeftRecursiveRuleAnalyzer method otherAlt.
@Override
public void otherAlt(AltAST originalAltTree, int alt) {
AltAST altTree = (AltAST) originalAltTree.dupTree();
stripAltLabel(altTree);
String altText = text(altTree);
String altLabel = altTree.altLabel != null ? altTree.altLabel.getText() : null;
LeftRecursiveRuleAltInfo a = new LeftRecursiveRuleAltInfo(alt, altText, null, altLabel, false, originalAltTree);
// We keep other alts with prefix alts since they are all added to the start of the generated rule, and
// we want to retain any prior ordering between them
prefixAndOtherAlts.add(a);
// System.out.println("otherAlt " + alt + ": " + altText);
}
use of org.antlr.v4.analysis.LeftRecursiveRuleAltInfo in project antlr4 by antlr.
the class LeftRecursiveRuleAnalyzer method suffixAlt.
@Override
public void suffixAlt(AltAST originalAltTree, int alt) {
AltAST altTree = (AltAST) originalAltTree.dupTree();
String altLabel = altTree.altLabel != null ? altTree.altLabel.getText() : null;
String label = null;
boolean isListLabel = false;
GrammarAST lrlabel = stripLeftRecursion(altTree);
if (lrlabel != null) {
label = lrlabel.getText();
isListLabel = lrlabel.getParent().getType() == PLUS_ASSIGN;
leftRecursiveRuleRefLabels.add(new Pair<GrammarAST, String>(lrlabel, altLabel));
}
stripAltLabel(altTree);
String altText = text(altTree);
altText = altText.trim();
LeftRecursiveRuleAltInfo a = new LeftRecursiveRuleAltInfo(alt, altText, label, altLabel, isListLabel, originalAltTree);
suffixAlts.put(alt, a);
// System.out.println("suffixAlt " + alt + ": " + altText + ", rewrite=" + rewriteText);
}
use of org.antlr.v4.analysis.LeftRecursiveRuleAltInfo in project antlr4 by antlr.
the class LeftRecursiveRuleAnalyzer method getArtificialOpPrecRule.
// --------- get transformed rules ----------------
public String getArtificialOpPrecRule() {
ST ruleST = recRuleTemplates.getInstanceOf("recRule");
ruleST.add("ruleName", ruleName);
ST ruleArgST = codegenTemplates.getInstanceOf("recRuleArg");
ruleST.add("argName", ruleArgST);
ST setResultST = codegenTemplates.getInstanceOf("recRuleSetResultAction");
ruleST.add("setResultAction", setResultST);
ruleST.add("userRetvals", retvals);
LinkedHashMap<Integer, LeftRecursiveRuleAltInfo> opPrecRuleAlts = new LinkedHashMap<Integer, LeftRecursiveRuleAltInfo>();
opPrecRuleAlts.putAll(binaryAlts);
opPrecRuleAlts.putAll(ternaryAlts);
opPrecRuleAlts.putAll(suffixAlts);
for (int alt : opPrecRuleAlts.keySet()) {
LeftRecursiveRuleAltInfo altInfo = opPrecRuleAlts.get(alt);
ST altST = recRuleTemplates.getInstanceOf("recRuleAlt");
ST predST = codegenTemplates.getInstanceOf("recRuleAltPredicate");
predST.add("opPrec", precedence(alt));
predST.add("ruleName", ruleName);
altST.add("pred", predST);
altST.add("alt", altInfo);
altST.add("precOption", LeftRecursiveRuleTransformer.PRECEDENCE_OPTION_NAME);
altST.add("opPrec", precedence(alt));
ruleST.add("opAlts", altST);
}
ruleST.add("primaryAlts", prefixAndOtherAlts);
tool.log("left-recursion", ruleST.render());
return ruleST.render();
}
Aggregations