package org.antlr.v4.tool;
import org.antlr.v4.tool.ast.ActionAST;
import org.antlr.v4.tool.ast.AltAST;
import org.antlr.v4.tool.ast.GrammarAST;
import org.antlr.v4.tool.ast.TerminalAST;
import org.stringtemplate.v4.misc.MultiMap;
import java.util.ArrayList;
import java.util.List;
public class Alternative implements AttributeResolver {
public Rule rule;
public AltAST ast;
public int altNum;
public MultiMap<String, TerminalAST> tokenRefs = new MultiMap<String, TerminalAST>();
public MultiMap<String, GrammarAST> tokenRefsInActions = new MultiMap<String, GrammarAST>();
public MultiMap<String, GrammarAST> ruleRefs = new MultiMap<String, GrammarAST>();
public MultiMap<String, GrammarAST> ruleRefsInActions = new MultiMap<String, GrammarAST>();
public MultiMap<String, LabelElementPair> labelDefs = new MultiMap<String, LabelElementPair>();
public List<ActionAST> actions = new ArrayList<ActionAST>();
public Alternative(Rule r, int altNum) { this.rule = r; this.altNum = altNum; }
@Override
public boolean resolvesToToken(String x, ActionAST node) {
if ( tokenRefs.get(x)!=null ) return true;
LabelElementPair anyLabelDef = getAnyLabelDef(x);
if ( anyLabelDef!=null && anyLabelDef.type==LabelType.TOKEN_LABEL ) return true;
return false;
}
@Override
public boolean resolvesToAttributeDict(String x, ActionAST node) {
if ( resolvesToToken(x, node) ) return true;
if ( ruleRefs.get(x)!=null ) return true;
LabelElementPair anyLabelDef = getAnyLabelDef(x);
if ( anyLabelDef!=null && anyLabelDef.type==LabelType.RULE_LABEL ) return true;
return false;
}
@Override
public Attribute resolveToAttribute(String x, ActionAST node) {
return rule.resolveToAttribute(x, node);
}
@Override
public Attribute resolveToAttribute(String x, String y, ActionAST node) {
if ( tokenRefs.get(x)!=null ) {
return rule.getPredefinedScope(LabelType.TOKEN_LABEL).get(y);
}
if ( ruleRefs.get(x)!=null ) {
return rule.g.getRule(x).resolveRetvalOrProperty(y);
}
LabelElementPair anyLabelDef = getAnyLabelDef(x);
if ( anyLabelDef!=null && anyLabelDef.type==LabelType.RULE_LABEL ) {
return rule.g.getRule(anyLabelDef.element.getText()).resolveRetvalOrProperty(y);
}
else if ( anyLabelDef!=null ) {
AttributeDict scope = rule.getPredefinedScope(anyLabelDef.type);
if (scope == null) {
return null;
}
return scope.get(y);
}
return null;
}
@Override
public boolean resolvesToLabel(String x, ActionAST node) {
LabelElementPair anyLabelDef = getAnyLabelDef(x);
return anyLabelDef!=null &&
(anyLabelDef.type==LabelType.TOKEN_LABEL ||
anyLabelDef.type==LabelType.RULE_LABEL);
}
@Override
public boolean resolvesToListLabel(String x, ActionAST node) {
LabelElementPair anyLabelDef = getAnyLabelDef(x);
return anyLabelDef!=null &&
(anyLabelDef.type==LabelType.RULE_LIST_LABEL ||
anyLabelDef.type==LabelType.TOKEN_LIST_LABEL);
}
public LabelElementPair getAnyLabelDef(String x) {
List<LabelElementPair> labels = labelDefs.get(x);
if ( labels!=null ) return labels.get(0);
return null;
}
public Rule resolveToRule(String x) {
if ( ruleRefs.get(x)!=null ) return rule.g.getRule(x);
LabelElementPair anyLabelDef = getAnyLabelDef(x);
if ( anyLabelDef!=null && anyLabelDef.type==LabelType.RULE_LABEL ) {
return rule.g.getRule(anyLabelDef.element.getText());
}
return null;
}
}