wasn't checking soon enough for rule redef; now it sets a dead flag in
AST so no more walking dup. error(51): T.g:7:0: rule s redefinition (ignoring); previous at line 3
This commit is contained in:
parent
6a345316df
commit
afe2224881
|
@ -7,6 +7,9 @@ November 17, 2012
|
|||
* properly check for grammar/filename difference
|
||||
* if labels, don't allow set collapse for
|
||||
a : A # X | B ;
|
||||
* wasn't checking soon enough for rule redef; now it sets a dead flag in
|
||||
AST so no more walking dup.
|
||||
error(51): T.g:7:0: rule s redefinition (ignoring); previous at line 3
|
||||
|
||||
November 11, 2012
|
||||
|
||||
|
|
|
@ -3,6 +3,5 @@ grammar T;
|
|||
s : A # X
|
||||
| B
|
||||
;
|
||||
b : A # Y
|
||||
| B{}
|
||||
;
|
||||
|
||||
s : A ;
|
||||
|
|
|
@ -62,6 +62,7 @@ import org.antlr.v4.tool.Rule;
|
|||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.GrammarASTErrorNode;
|
||||
import org.antlr.v4.tool.ast.GrammarRootAST;
|
||||
import org.antlr.v4.tool.ast.RuleAST;
|
||||
import org.stringtemplate.v4.STGroup;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
|
@ -387,6 +388,8 @@ public class Tool {
|
|||
|
||||
if ( g.ast.hasErrors ) return;
|
||||
|
||||
checkForRedefinedRules(g);
|
||||
|
||||
int prevErrors = errMgr.getNumErrors();
|
||||
// MAKE SURE GRAMMAR IS SEMANTICALLY CORRECT (FILL IN GRAMMAR OBJECT)
|
||||
SemanticPipeline sem = new SemanticPipeline(g);
|
||||
|
@ -417,6 +420,32 @@ public class Tool {
|
|||
}
|
||||
}
|
||||
|
||||
/** Important enough to avoid multiple defs that we do very early,
|
||||
* right after AST construction. Turn redef'd rule's AST RULE node dead
|
||||
* field to true.
|
||||
*/
|
||||
public void checkForRedefinedRules(Grammar g) {
|
||||
GrammarAST RULES = (GrammarAST)g.ast.getFirstChildWithType(ANTLRParser.RULES);
|
||||
List<RuleAST> rules = (List<RuleAST>)RULES.getChildren();
|
||||
Map<String, RuleAST> ruleToAST = new HashMap<String, RuleAST>();
|
||||
for (RuleAST r : rules) {
|
||||
GrammarAST ID = (GrammarAST)r.getChild(0);
|
||||
String ruleName = ID.getText();
|
||||
RuleAST prev = ruleToAST.get(ruleName);
|
||||
if ( prev !=null ) {
|
||||
GrammarAST prevChild = (GrammarAST)prev.getChild(0);
|
||||
g.tool.errMgr.grammarError(ErrorType.RULE_REDEFINITION,
|
||||
g.fileName,
|
||||
ID.getToken(),
|
||||
ruleName,
|
||||
prevChild.getToken().getLine());
|
||||
r.dead = true;
|
||||
continue;
|
||||
}
|
||||
ruleToAST.put(ruleName, r);
|
||||
}
|
||||
}
|
||||
|
||||
public List<GrammarRootAST> sortGrammarByTokenVocab(List<String> fileNames) {
|
||||
// System.out.println(fileNames);
|
||||
Graph<String> g = new Graph<String>();
|
||||
|
|
|
@ -498,7 +498,8 @@ rule
|
|||
@after {
|
||||
exitRule($start);
|
||||
}
|
||||
: ^( RULE RULE_REF {currentRuleName=$RULE_REF.text; currentRuleAST=$RULE;}
|
||||
: {!((RuleAST)$start).dead}?
|
||||
^( RULE RULE_REF {currentRuleName=$RULE_REF.text; currentRuleAST=$RULE;}
|
||||
DOC_COMMENT? (^(RULEMODIFIERS (m=ruleModifier{mods.add($m.start);})+))?
|
||||
ARG_ACTION?
|
||||
ret=ruleReturns?
|
||||
|
@ -515,6 +516,20 @@ rule
|
|||
ruleBlock exceptionGroup
|
||||
{finishRule((RuleAST)$RULE, $RULE_REF, $ruleBlock.start); currentRuleName=null; currentRuleAST=null;}
|
||||
)
|
||||
| // ugly repeated alt w/o actions but needed to force ANTLR to use
|
||||
// sem pred to avoid actions when rule dead
|
||||
{((RuleAST)$start).dead}?
|
||||
^( RULE RULE_REF
|
||||
DOC_COMMENT? (^(RULEMODIFIERS (m=ruleModifier)+))?
|
||||
ARG_ACTION?
|
||||
ret=ruleReturns?
|
||||
thr=throwsSpec?
|
||||
loc=locals?
|
||||
( opts=optionsSpec
|
||||
| a=ruleAction
|
||||
)*
|
||||
ruleBlock exceptionGroup
|
||||
)
|
||||
;
|
||||
|
||||
exceptionGroup
|
||||
|
@ -643,7 +658,7 @@ lexerOuterAlternative
|
|||
finishOuterAlt((AltAST)$start);
|
||||
exitLexerOuterAlternative((AltAST)$start);
|
||||
}
|
||||
: lexerAlternative
|
||||
: lexerAlternative
|
||||
;
|
||||
|
||||
|
||||
|
@ -656,7 +671,7 @@ outerAlternative
|
|||
finishOuterAlt((AltAST)$start);
|
||||
exitOuterAlternative((AltAST)$start);
|
||||
}
|
||||
: alternative
|
||||
: alternative
|
||||
;
|
||||
|
||||
lexerAlternative
|
||||
|
@ -705,7 +720,7 @@ labeledLexerElement
|
|||
}
|
||||
: ^((ASSIGN|PLUS_ASSIGN) ID (lexerAtom|block))
|
||||
;
|
||||
|
||||
|
||||
lexerBlock
|
||||
@init {
|
||||
enterLexerBlock($start);
|
||||
|
@ -744,7 +759,7 @@ actionElement
|
|||
| SEMPRED
|
||||
| ^(SEMPRED elementOptions)
|
||||
;
|
||||
|
||||
|
||||
alternative
|
||||
@init {
|
||||
enterAlternative((AltAST)$start);
|
||||
|
@ -778,10 +793,10 @@ lexerCommandExpr
|
|||
@after {
|
||||
exitLexerCommandExpr($start);
|
||||
}
|
||||
: ID
|
||||
: ID
|
||||
| INT
|
||||
;
|
||||
|
||||
|
||||
element
|
||||
@init {
|
||||
enterElement($start);
|
||||
|
@ -796,7 +811,7 @@ element
|
|||
| SEMPRED {sempredInAlt((PredAST)$SEMPRED);}
|
||||
| ^(ACTION elementOptions) {actionInAlt((ActionAST)$ACTION);}
|
||||
| ^(SEMPRED elementOptions) {sempredInAlt((PredAST)$SEMPRED);}
|
||||
|
||||
|
||||
| ^(NOT blockSet)
|
||||
| ^(NOT block)
|
||||
;
|
||||
|
|
|
@ -85,43 +85,28 @@ public class SymbolChecks {
|
|||
|
||||
public void process() {
|
||||
// methods affect fields, but no side-effects outside this object
|
||||
// So, call order sensitive
|
||||
//checkForImportedRuleIssues(collector.qualifiedRulerefs);
|
||||
// done in sem pipe for now
|
||||
checkForRuleConflicts(g.rules.values()); // sets nameToRuleMap
|
||||
// So, call order sensitive
|
||||
// First collect all rules for later use in checkForLabelConflict()
|
||||
if ( g.rules!=null ) {
|
||||
for (Rule r : g.rules.values()) nameToRuleMap.put(r.name, r);
|
||||
}
|
||||
checkActionRedefinitions(collector.namedActions);
|
||||
//checkRuleArgs(collector.rulerefs);
|
||||
checkForTokenConflicts(collector.tokenIDRefs); // sets tokenIDs
|
||||
checkForLabelConflicts(g.rules.values());
|
||||
}
|
||||
checkForTokenConflicts(collector.tokenIDRefs); // sets tokenIDs
|
||||
checkForLabelConflicts(g.rules.values());
|
||||
}
|
||||
|
||||
public void checkForRuleConflicts(Collection<Rule> rules) {
|
||||
if ( rules==null ) return;
|
||||
for (Rule r : rules) {
|
||||
Rule prevRule = nameToRuleMap.get(r.name);
|
||||
if ( prevRule==null ) {
|
||||
nameToRuleMap.put(r.name, r);
|
||||
}
|
||||
else {
|
||||
GrammarAST idNode = (GrammarAST)r.ast.getChild(0);
|
||||
errMgr.grammarError(ErrorType.RULE_REDEFINITION,
|
||||
r.g.fileName, idNode.token, r.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkActionRedefinitions(List<GrammarAST> actions) {
|
||||
if ( actions==null ) return;
|
||||
String scope = g.getDefaultActionScope();
|
||||
String name;
|
||||
GrammarAST nameNode;
|
||||
for (GrammarAST ampersandAST : actions) {
|
||||
nameNode = (GrammarAST)ampersandAST.getChild(0);
|
||||
if ( ampersandAST.getChildCount()==2 ) {
|
||||
name = nameNode.getText();
|
||||
}
|
||||
else {
|
||||
scope = nameNode.getText();
|
||||
public void checkActionRedefinitions(List<GrammarAST> actions) {
|
||||
if ( actions==null ) return;
|
||||
String scope = g.getDefaultActionScope();
|
||||
String name;
|
||||
GrammarAST nameNode;
|
||||
for (GrammarAST ampersandAST : actions) {
|
||||
nameNode = (GrammarAST)ampersandAST.getChild(0);
|
||||
if ( ampersandAST.getChildCount()==2 ) {
|
||||
name = nameNode.getText();
|
||||
}
|
||||
else {
|
||||
scope = nameNode.getText();
|
||||
name = ampersandAST.getChild(1).getText();
|
||||
}
|
||||
Set<String> scopeActions = actionScopeToActionNames.get(scope);
|
||||
|
|
|
@ -71,7 +71,7 @@ public enum ErrorType {
|
|||
|
||||
// Grammar errors
|
||||
SYNTAX_ERROR(50, "<arg>", ErrorSeverity.ERROR),
|
||||
RULE_REDEFINITION(51, "rule <arg> redefinition", ErrorSeverity.ERROR),
|
||||
RULE_REDEFINITION(51, "rule <arg> redefinition (ignoring); previous at line <arg2>", ErrorSeverity.ERROR),
|
||||
LEXER_RULES_NOT_ALLOWED(52, "lexer rule <arg> not allowed in parser", ErrorSeverity.ERROR),
|
||||
PARSER_RULES_NOT_ALLOWED(53, "parser rule <arg> not allowed in lexer", ErrorSeverity.ERROR),
|
||||
REPEATED_PREQUEL(54, "repeated grammar prequel spec (option, token, or import); please merge", ErrorSeverity.ERROR),
|
||||
|
|
|
@ -34,6 +34,9 @@ import org.antlr.runtime.tree.Tree;
|
|||
import org.antlr.v4.parse.ANTLRParser;
|
||||
|
||||
public class RuleAST extends GrammarASTWithOptions {
|
||||
/** Kill redef of rules */
|
||||
public boolean dead;
|
||||
|
||||
public RuleAST(GrammarAST node) {
|
||||
super(node);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue