Added check for labels with different token types.

Spaces -> Tabs.
This commit is contained in:
Ivan Kochurkin 2016-12-07 22:39:27 +03:00
parent 50646a6da8
commit d5dda9f998
1 changed files with 67 additions and 57 deletions

View File

@ -43,6 +43,7 @@ import org.antlr.v4.tool.LabelElementPair;
import org.antlr.v4.tool.LexerGrammar; import org.antlr.v4.tool.LexerGrammar;
import org.antlr.v4.tool.Rule; import org.antlr.v4.tool.Rule;
import org.antlr.v4.tool.ast.GrammarAST; import org.antlr.v4.tool.ast.GrammarAST;
import org.antlr.v4.tool.LabelType;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
@ -94,10 +95,10 @@ public class SymbolChecks {
} }
public void process() { public void process() {
// methods affect fields, but no side-effects outside this object // methods affect fields, but no side-effects outside this object
// So, call order sensitive // So, call order sensitive
// First collect all rules for later use in checkForLabelConflict() // First collect all rules for later use in checkForLabelConflict()
if ( g.rules!=null ) { if (g.rules != null) {
for (Rule r : g.rules.values()) nameToRuleMap.put(r.name, r); for (Rule r : g.rules.values()) nameToRuleMap.put(r.name, r);
} }
checkReservedNames(g.rules.values()); checkReservedNames(g.rules.values());
@ -107,41 +108,39 @@ public class SymbolChecks {
} }
public void checkActionRedefinitions(List<GrammarAST> actions) { public void checkActionRedefinitions(List<GrammarAST> actions) {
if ( actions==null ) return; if (actions == null) return;
String scope = g.getDefaultActionScope(); String scope = g.getDefaultActionScope();
String name; String name;
GrammarAST nameNode; GrammarAST nameNode;
for (GrammarAST ampersandAST : actions) { for (GrammarAST ampersandAST : actions) {
nameNode = (GrammarAST)ampersandAST.getChild(0); nameNode = (GrammarAST) ampersandAST.getChild(0);
if ( ampersandAST.getChildCount()==2 ) { if (ampersandAST.getChildCount() == 2) {
name = nameNode.getText(); name = nameNode.getText();
} } else {
else {
scope = nameNode.getText(); scope = nameNode.getText();
name = ampersandAST.getChild(1).getText(); name = ampersandAST.getChild(1).getText();
} }
Set<String> scopeActions = actionScopeToActionNames.get(scope); Set<String> scopeActions = actionScopeToActionNames.get(scope);
if ( scopeActions==null ) { // init scope if (scopeActions == null) { // init scope
scopeActions = new HashSet<String>(); scopeActions = new HashSet<String>();
actionScopeToActionNames.put(scope, scopeActions); actionScopeToActionNames.put(scope, scopeActions);
} }
if ( !scopeActions.contains(name) ) { if (!scopeActions.contains(name)) {
scopeActions.add(name); scopeActions.add(name);
} } else {
else { errMgr.grammarError(ErrorType.ACTION_REDEFINITION,
errMgr.grammarError(ErrorType.ACTION_REDEFINITION, g.fileName, nameNode.token, name);
g.fileName, nameNode.token, name); }
} }
} }
}
public void checkForTokenConflicts(List<GrammarAST> tokenIDRefs) { public void checkForTokenConflicts(List<GrammarAST> tokenIDRefs) {
// for (GrammarAST a : tokenIDRefs) { // for (GrammarAST a : tokenIDRefs) {
// Token t = a.token; // Token t = a.token;
// String ID = t.getText(); // String ID = t.getText();
// tokenIDs.add(ID); // tokenIDs.add(ID);
// } // }
} }
/** Make sure a label doesn't conflict with another symbol. /** Make sure a label doesn't conflict with another symbol.
* Labels must not conflict with: rules, tokens, scope names, * Labels must not conflict with: rules, tokens, scope names,
@ -150,43 +149,54 @@ public class SymbolChecks {
* for repeated defs. * for repeated defs.
*/ */
public void checkForLabelConflicts(Collection<Rule> rules) { public void checkForLabelConflicts(Collection<Rule> rules) {
for (Rule r : rules) { for (Rule r : rules) {
checkForAttributeConflicts(r); checkForAttributeConflicts(r);
Map<String, LabelElementPair> labelNameSpace = Map<String, LabelElementPair> labelNameSpace =
new HashMap<String, LabelElementPair>(); new HashMap<String, LabelElementPair>();
for (int i=1; i<=r.numberOfAlts; i++) { for (int i = 1; i <= r.numberOfAlts; i++) {
if (r.hasAltSpecificContexts()) { if (r.hasAltSpecificContexts()) {
labelNameSpace.clear(); labelNameSpace.clear();
} }
Alternative a = r.alt[i]; Alternative a = r.alt[i];
for (List<LabelElementPair> pairs : a.labelDefs.values() ) { for (List<LabelElementPair> pairs : a.labelDefs.values()) {
for (LabelElementPair p : pairs) { for (LabelElementPair p : pairs) {
checkForLabelConflict(r, p.label); checkForLabelConflict(r, p.label);
String name = p.label.getText(); String name = p.label.getText();
LabelElementPair prev = labelNameSpace.get(name); LabelElementPair prev = labelNameSpace.get(name);
if ( prev==null ) labelNameSpace.put(name, p); if (prev == null) labelNameSpace.put(name, p);
else checkForTypeMismatch(prev, p); else checkForTypeMismatch(prev, p);
} }
} }
} }
} }
} }
void checkForTypeMismatch(LabelElementPair prevLabelPair, void checkForTypeMismatch(LabelElementPair prevLabelPair, LabelElementPair labelPair) {
LabelElementPair labelPair) // label already defined; if same type, no problem
{ if (prevLabelPair.type != labelPair.type) {
// label already defined; if same type, no problem String typeMismatchExpr = labelPair.type + "!=" + prevLabelPair.type;
if ( prevLabelPair.type != labelPair.type ) { errMgr.grammarError(
String typeMismatchExpr = labelPair.type+"!="+prevLabelPair.type; ErrorType.LABEL_TYPE_CONFLICT,
errMgr.grammarError( g.fileName,
ErrorType.LABEL_TYPE_CONFLICT, labelPair.label.token,
g.fileName, labelPair.label.getText(),
labelPair.label.token, typeMismatchExpr);
labelPair.label.getText(), }
typeMismatchExpr); if (!prevLabelPair.element.getText().equals(labelPair.element.getText()) &&
} (prevLabelPair.type.equals(LabelType.RULE_LABEL) || prevLabelPair.type.equals(LabelType.RULE_LIST_LABEL)) &&
} (labelPair.type.equals(LabelType.RULE_LABEL) || labelPair.type.equals(LabelType.RULE_LIST_LABEL))) {
String prevLabelOp = prevLabelPair.type.equals(LabelType.RULE_LIST_LABEL) ? "+=" : "=";
String labelOp = labelPair.type.equals(LabelType.RULE_LIST_LABEL) ? "+=" : "=";
errMgr.grammarError(
ErrorType.LABEL_TYPE_CONFLICT,
g.fileName,
labelPair.label.token,
labelPair.label.getText() + labelOp + labelPair.element.getText(),
prevLabelPair.label.getText() + prevLabelOp + prevLabelPair.element.getText());
}
}
public void checkForLabelConflict(Rule r, GrammarAST labelID) { public void checkForLabelConflict(Rule r, GrammarAST labelID) {
String name = labelID.getText(); String name = labelID.getText();