Add compiler warning 158: FRAGMENT_ACTION_IGNORED (fixes #472)
This commit is contained in:
parent
b2af59e73e
commit
0ed651cbc6
|
@ -116,6 +116,13 @@ public class BasicSemanticChecks extends GrammarTreeVisitor {
|
||||||
*/
|
*/
|
||||||
protected int nonFragmentRuleCount;
|
protected int nonFragmentRuleCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is {@code true} from the time {@link #discoverLexerRule} is called
|
||||||
|
* for a lexer rule with the {@code fragment} modifier until
|
||||||
|
* {@link #exitLexerRule} is called.
|
||||||
|
*/
|
||||||
|
private boolean inFragmentRule;
|
||||||
|
|
||||||
public BasicSemanticChecks(Grammar g, RuleCollector ruleCollector) {
|
public BasicSemanticChecks(Grammar g, RuleCollector ruleCollector) {
|
||||||
this.g = g;
|
this.g = g;
|
||||||
this.ruleCollector = ruleCollector;
|
this.ruleCollector = ruleCollector;
|
||||||
|
@ -200,20 +207,24 @@ public class BasicSemanticChecks extends GrammarTreeVisitor {
|
||||||
{
|
{
|
||||||
checkInvalidRuleDef(ID.token);
|
checkInvalidRuleDef(ID.token);
|
||||||
|
|
||||||
boolean fragmentRule = false;
|
|
||||||
if (modifiers != null) {
|
if (modifiers != null) {
|
||||||
for (GrammarAST tree : modifiers) {
|
for (GrammarAST tree : modifiers) {
|
||||||
if (tree.getType() == ANTLRParser.FRAGMENT) {
|
if (tree.getType() == ANTLRParser.FRAGMENT) {
|
||||||
fragmentRule = true;
|
inFragmentRule = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fragmentRule) {
|
if (!inFragmentRule) {
|
||||||
nonFragmentRuleCount++;
|
nonFragmentRuleCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void exitLexerRule(GrammarAST tree) {
|
||||||
|
inFragmentRule = false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void ruleRef(GrammarAST ref, ActionAST arg) {
|
public void ruleRef(GrammarAST ref, ActionAST arg) {
|
||||||
checkInvalidRuleRef(ref.token);
|
checkInvalidRuleRef(ref.token);
|
||||||
|
@ -381,6 +392,21 @@ public class BasicSemanticChecks extends GrammarTreeVisitor {
|
||||||
@Override
|
@Override
|
||||||
protected void enterLexerCommand(GrammarAST tree) {
|
protected void enterLexerCommand(GrammarAST tree) {
|
||||||
checkElementIsOuterMostInSingleAlt(tree);
|
checkElementIsOuterMostInSingleAlt(tree);
|
||||||
|
|
||||||
|
if (inFragmentRule) {
|
||||||
|
String fileName = tree.token.getInputStream().getSourceName();
|
||||||
|
String ruleName = currentRuleName;
|
||||||
|
g.tool.errMgr.grammarError(ErrorType.FRAGMENT_ACTION_IGNORED, fileName, tree.token, ruleName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionInAlt(ActionAST action) {
|
||||||
|
if (inFragmentRule) {
|
||||||
|
String fileName = action.token.getInputStream().getSourceName();
|
||||||
|
String ruleName = currentRuleName;
|
||||||
|
g.tool.errMgr.grammarError(ErrorType.FRAGMENT_ACTION_IGNORED, fileName, action.token, ruleName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -852,6 +852,37 @@ public enum ErrorType {
|
||||||
* @since 4.2.1
|
* @since 4.2.1
|
||||||
*/
|
*/
|
||||||
UNRECOGNIZED_ASSOC_OPTION(157, "rule '<arg>' contains an 'assoc' terminal option in an unrecognized location", ErrorSeverity.WARNING),
|
UNRECOGNIZED_ASSOC_OPTION(157, "rule '<arg>' contains an 'assoc' terminal option in an unrecognized location", ErrorSeverity.WARNING),
|
||||||
|
/**
|
||||||
|
* Compiler Warning 158.
|
||||||
|
*
|
||||||
|
* <p>fragment rule '<em>rule</em>' contains an action or command which can
|
||||||
|
* never be executed</p>
|
||||||
|
*
|
||||||
|
* <p>A lexer rule which is marked with the {@code fragment} modifier
|
||||||
|
* contains an embedded action or lexer command. ANTLR lexers only execute
|
||||||
|
* commands and embedded actions located in the top-level matched rule.
|
||||||
|
* Since fragment rules can never be the top-level rule matched by a lexer,
|
||||||
|
* actions or commands placed in these rules can never be executed during
|
||||||
|
* the lexing process.</p>
|
||||||
|
*
|
||||||
|
* <p>The following rule produces this warning.</p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* X1 : 'x' -> more // ok
|
||||||
|
* ;
|
||||||
|
* Y1 : 'x' {more();} // ok
|
||||||
|
* ;
|
||||||
|
* fragment
|
||||||
|
* X2 : 'x' -> more // warning 158
|
||||||
|
* ;
|
||||||
|
* fragment
|
||||||
|
* Y2 : 'x' {more();} // warning 158
|
||||||
|
* ;
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @since 4.2.1
|
||||||
|
*/
|
||||||
|
FRAGMENT_ACTION_IGNORED(158, "fragment rule '<arg>' contains an action or command which can never be executed", ErrorSeverity.WARNING),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Backward incompatibility errors
|
* Backward incompatibility errors
|
||||||
|
|
|
@ -473,4 +473,33 @@ public class TestToolSyntaxErrors extends BaseTest {
|
||||||
|
|
||||||
super.testErrors(pair, true);
|
super.testErrors(pair, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test ensures the {@link ErrorType#FRAGMENT_ACTION_IGNORED} warning
|
||||||
|
* is produced as described in the documentation.
|
||||||
|
*/
|
||||||
|
@Test public void testFragmentActionIgnored() {
|
||||||
|
String grammar =
|
||||||
|
"lexer grammar A;\n" +
|
||||||
|
"X1 : 'x' -> more // ok\n" +
|
||||||
|
" ;\n" +
|
||||||
|
"Y1 : 'x' {more();} // ok\n" +
|
||||||
|
" ;\n" +
|
||||||
|
"fragment\n" +
|
||||||
|
"X2 : 'x' -> more // warning 158\n" +
|
||||||
|
" ;\n" +
|
||||||
|
"fragment\n" +
|
||||||
|
"Y2 : 'x' {more();} // warning 158\n" +
|
||||||
|
" ;\n";
|
||||||
|
String expected =
|
||||||
|
"warning(" + ErrorType.FRAGMENT_ACTION_IGNORED.code + "): A.g4:7:12: fragment rule 'X2' contains an action or command which can never be executed\n" +
|
||||||
|
"warning(" + ErrorType.FRAGMENT_ACTION_IGNORED.code + "): A.g4:10:9: fragment rule 'Y2' contains an action or command which can never be executed\n";
|
||||||
|
|
||||||
|
String[] pair = new String[] {
|
||||||
|
grammar,
|
||||||
|
expected
|
||||||
|
};
|
||||||
|
|
||||||
|
super.testErrors(pair, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue