report errors with too few alt labels or redef of alt label

This commit is contained in:
Terence Parr 2012-02-16 17:14:41 -08:00
parent 646b22b9ec
commit 100b530201
6 changed files with 64 additions and 14 deletions

View File

@ -8,5 +8,11 @@ e : e '*' e -> Mult
| '(' e ')' -> Parens
;
x : A -> Foo
| B
;
y : Y -> Mult ;
INT : [0-9]+ ;
WS : [ \t\n]+ -> skip ;

View File

@ -1,10 +1,10 @@
import org.antlr.v4.runtime.tree.*;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
public class ABaseVisitor<T> extends ParseTreeVisitor<T> implements AVisitor<T> {
public T visit(AParser.MultContext ctx) { visitChildren(ctx); return null; }
public T visit(AParser.ParensContext ctx) { visitChildren(ctx); return null; }
public T visit(AParser.sContext ctx) { visitChildren(ctx); return null; }
public T visit(AParser.FooContext ctx) { visitChildren(ctx); return null; }
public T visit(AParser.AddContext ctx) { visitChildren(ctx); return null; }
public T visit(AParser.IntContext ctx) { visitChildren(ctx); return null; }
}
}

View File

@ -1,10 +1,8 @@
import org.antlr.v4.runtime.tree.*;
import org.antlr.v4.runtime.Token;
public interface AVisitor<T> {
T visit(AParser.MultContext ctx);
T visit(AParser.ParensContext ctx);
T visit(AParser.sContext ctx);
T visit(AParser.FooContext ctx);
T visit(AParser.AddContext ctx);
T visit(AParser.IntContext ctx);
}
}

View File

@ -40,10 +40,7 @@ import org.antlr.v4.tool.ast.*;
import org.stringtemplate.v4.misc.MultiMap;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
/** No side-effects except for setting options into the appropriate node.
* TODO: make the side effects into a separate pass this
@ -242,6 +239,44 @@ public class BasicSemanticChecks extends GrammarTreeVisitor {
// }
}
Map<String,String> altLabelToRuleName = new HashMap<String, String>();
@Override
public void finishRule(RuleAST rule, GrammarAST ID, GrammarAST block) {
MultiMap<String,GrammarAST> ruleToAltLabels = new MultiMap<String, GrammarAST>();
if ( rule.isLexerRule() ) return;
BlockAST blk = (BlockAST)rule.getFirstChildWithType(BLOCK);
int nalts = blk.getChildCount();
for (int i=0; i< nalts; i++) {
AltAST altAST = (AltAST)blk.getChild(i);
if ( altAST.altLabel!=null ) {
System.out.println("alt label "+altAST.altLabel);
ruleToAltLabels.map(rule.getRuleName(), altAST.altLabel);
String altLabel = altAST.altLabel.getText();
String prevRuleForLabel = altLabelToRuleName.get(altLabel);
if ( prevRuleForLabel!=null ) {
g.tool.errMgr.grammarError(ErrorType.ALT_LABEL_REDEF,
g.fileName, rule.getToken(),
altLabel,
rule.getRuleName(),
prevRuleForLabel);
}
else {
altLabelToRuleName.put(altLabel, rule.getRuleName());
}
}
}
System.out.println(rule.getRuleName()+" has "+ nalts +" alts");
List<GrammarAST> altLabels = ruleToAltLabels.get(rule.getRuleName());
int numAltLabels = 0;
if ( altLabels!=null ) numAltLabels = altLabels.size();
System.out.println("labels="+altLabels);
if ( numAltLabels>0 && nalts != numAltLabels ) {
g.tool.errMgr.grammarError(ErrorType.RULE_WITH_TOO_FEW_ALT_LABELS,
g.fileName, rule.getToken(), rule.getRuleName());
}
}
// Routines to do the actual work of checking issues with a grammar.
// They are triggered by the visitor methods above.

View File

@ -139,7 +139,9 @@ public enum ErrorType {
ALL_OPS_NEED_SAME_ASSOC(118, "all operators of alt <arg> of left-recursive rule must have same associativity", ErrorSeverity.WARNING),
LEFT_RECURSION_CYCLES(119, "The following sets of rules are mutually left-recursive <arg:{c| [<c:{r|<r.name>}; separator=\", \">]}; separator=\" and \">", ErrorSeverity.ERROR),
MODE_NOT_IN_LEXER(120, "lexical modes are only allowed in lexer grammars", ErrorSeverity.ERROR),
CANNOT_FIND_ATTRIBUTE_NAME_IN_DECL(121, "cannot find an attribute name in attribute declaration", ErrorSeverity.ERROR),
CANNOT_FIND_ATTRIBUTE_NAME_IN_DECL(121, "cannot find an attribute name in attribute declaration", ErrorSeverity.ERROR),
RULE_WITH_TOO_FEW_ALT_LABELS(122, "rule <arg>: must label all alternatives or none", ErrorSeverity.ERROR),
ALT_LABEL_REDEF(123, "rule alt label <arg> redefined in rule <arg2>, originally in <arg3>", ErrorSeverity.ERROR),
/** Documentation comment is unterminated */
//UNTERMINATED_DOC_COMMENT(, "", ErrorSeverity.ERROR),

View File

@ -34,8 +34,6 @@ import org.antlr.runtime.tree.Tree;
import org.antlr.v4.parse.ANTLRParser;
public class RuleAST extends GrammarASTWithOptions {
public RuleAST(GrammarAST node) {
super(node);
}
@ -43,6 +41,17 @@ public class RuleAST extends GrammarASTWithOptions {
public RuleAST(Token t) { super(t); }
public RuleAST(int type) { super(type); }
public boolean isLexerRule() {
String name = getRuleName();
return name!=null && Character.isUpperCase(name.charAt(0));
}
public String getRuleName() {
GrammarAST nameNode = (GrammarAST)getChild(0);
if ( nameNode!=null ) return nameNode.getText();
return null;
}
@Override
public Tree dupNode() { return new RuleAST(this); }