forked from jasder/antlr
getConstantValue replaced with getModeConstantValue, getTokenConstantValue and getChannelConstantValue methods.
ErrorType simplified, tests fixed. Fixes #1411, added unit-test.
This commit is contained in:
parent
66ea9891aa
commit
a1def96500
|
@ -127,7 +127,7 @@ public class TestSymbolIssues extends BaseJavaToolTest {
|
|||
"M1: 'b';\n",
|
||||
|
||||
// YIELDS
|
||||
"error(" + ErrorType.MODE_CONFLICTS_WITH_TOKEN.code + "): F.g4:3:0: mode M1 conflicts with token with same name\n"
|
||||
"error(" + ErrorType.DECLARATION_CONFLICTS_WITH_COMMON_CONSTANTS.code + "): F.g4:3:0: cannot declare mode, token or channel with reserved name M1\n"
|
||||
};
|
||||
|
||||
@Before
|
||||
|
@ -204,9 +204,9 @@ public class TestSymbolIssues extends BaseJavaToolTest {
|
|||
"C: 'c';",
|
||||
|
||||
"error(" + ErrorType.RESERVED_RULE_NAME.code + "): L.g4:5:0: cannot declare a rule with reserved name MIN_CHAR_VALUE\n" +
|
||||
"error(" + ErrorType.MODE_CONFLICTS_WITH_COMMON_CONSTANTS.code + "): L.g4:4:0: cannot use or declare mode with reserved name MAX_CHAR_VALUE\n" +
|
||||
"error(" + ErrorType.CHANNEL_CONFLICTS_WITH_COMMON_CONSTANTS.code + "): L.g4:2:11: cannot use or declare channel with reserved name SKIP\n" +
|
||||
"error(" + ErrorType.CHANNEL_CONFLICTS_WITH_COMMON_CONSTANTS.code + "): L.g4:2:17: cannot use or declare channel with reserved name HIDDEN\n"
|
||||
"error(" + ErrorType.DECLARATION_CONFLICTS_WITH_COMMON_CONSTANTS.code + "): L.g4:4:0: cannot declare mode, token or channel with reserved name MAX_CHAR_VALUE\n" +
|
||||
"error(" + ErrorType.DECLARATION_CONFLICTS_WITH_COMMON_CONSTANTS.code + "): L.g4:2:11: cannot declare mode, token or channel with reserved name SKIP\n" +
|
||||
"error(" + ErrorType.DECLARATION_CONFLICTS_WITH_COMMON_CONSTANTS.code + "): L.g4:2:17: cannot declare mode, token or channel with reserved name HIDDEN\n"
|
||||
};
|
||||
|
||||
testErrors(test, false);
|
||||
|
@ -222,9 +222,27 @@ public class TestSymbolIssues extends BaseJavaToolTest {
|
|||
"E: 'e' -> type(EOF);\n" +
|
||||
"F: 'f' -> pushMode(DEFAULT_MODE);",
|
||||
|
||||
"error(" + ErrorType.CHANNEL_CONFLICTS_WITH_COMMON_CONSTANTS.code + "): L.g4:2:18: cannot use or declare channel with reserved name SKIP\n" +
|
||||
"error(" + ErrorType.TOKEN_CONFLICTS_WITH_COMMON_CONSTANTS.code + "): L.g4:3:15: cannot use or declare token with reserved name MORE\n" +
|
||||
"error(" + ErrorType.MODE_CONFLICTS_WITH_COMMON_CONSTANTS.code + "): L.g4:4:15: cannot use or declare mode with reserved name SKIP\n"
|
||||
"warning(" + ErrorType.UNKNOWN_OR_WRONG_LEXER_CONSTANT.code + "): L.g4:2:18: rule A contains a lexer command with an unrecognized or wrong constant value; lexer interpreters may produce incorrect output\n" +
|
||||
"warning(" + ErrorType.UNKNOWN_OR_WRONG_LEXER_CONSTANT.code + "): L.g4:3:15: rule B contains a lexer command with an unrecognized or wrong constant value; lexer interpreters may produce incorrect output\n" +
|
||||
"warning(" + ErrorType.UNKNOWN_OR_WRONG_LEXER_CONSTANT.code + "): L.g4:4:15: rule C contains a lexer command with an unrecognized or wrong constant value; lexer interpreters may produce incorrect output\n"
|
||||
};
|
||||
|
||||
testErrors(test, false);
|
||||
}
|
||||
|
||||
// https://github.com/antlr/antlr4/issues/1411
|
||||
@Test public void testWrongIdForTypeChannelModeCommand() throws Exception {
|
||||
String[] test = {
|
||||
"lexer grammar L;\n" +
|
||||
"tokens { TOKEN1 }\n" +
|
||||
"channels { CHANNEL1 }\n" +
|
||||
"TOKEN: 'asdf' -> type(CHANNEL1), channel(MODE1), mode(TOKEN1);\n" +
|
||||
"mode MODE1;\n" +
|
||||
"MODE1_TOKEN: 'qwer';",
|
||||
|
||||
"warning(" + ErrorType.UNKNOWN_OR_WRONG_LEXER_CONSTANT.code + "): L.g4:4:22: rule TOKEN contains a lexer command with an unrecognized or wrong constant value; lexer interpreters may produce incorrect output\n" +
|
||||
"warning(" + ErrorType.UNKNOWN_OR_WRONG_LEXER_CONSTANT.code + "): L.g4:4:41: rule TOKEN contains a lexer command with an unrecognized or wrong constant value; lexer interpreters may produce incorrect output\n" +
|
||||
"warning(" + ErrorType.UNKNOWN_OR_WRONG_LEXER_CONSTANT.code + "): L.g4:4:54: rule TOKEN contains a lexer command with an unrecognized or wrong constant value; lexer interpreters may produce incorrect output\n"
|
||||
};
|
||||
|
||||
testErrors(test, false);
|
||||
|
|
|
@ -657,8 +657,8 @@ public class TestToolSyntaxErrors extends BaseJavaToolTest {
|
|||
"WHITESPACE: [ \\t]+ -> channel(WHITESPACE_CHANNEL);\n";
|
||||
|
||||
String expected =
|
||||
"warning(" + ErrorType.UNKNOWN_LEXER_CONSTANT.code + "): T.g4:10:35: rule COMMENT contains a lexer command with an unrecognized constant value; lexer interpreters may produce incorrect output\n" +
|
||||
"warning(" + ErrorType.UNKNOWN_LEXER_CONSTANT.code + "): T.g4:11:35: rule WHITESPACE contains a lexer command with an unrecognized constant value; lexer interpreters may produce incorrect output\n" +
|
||||
"warning(" + ErrorType.UNKNOWN_OR_WRONG_LEXER_CONSTANT.code + "): T.g4:10:35: rule COMMENT contains a lexer command with an unrecognized or wrong constant value; lexer interpreters may produce incorrect output\n" +
|
||||
"warning(" + ErrorType.UNKNOWN_OR_WRONG_LEXER_CONSTANT.code + "): T.g4:11:35: rule WHITESPACE contains a lexer command with an unrecognized or wrong constant value; lexer interpreters may produce incorrect output\n" +
|
||||
"error(" + ErrorType.CHANNELS_BLOCK_IN_COMBINED_GRAMMAR.code + "): T.g4:3:0: custom channels are not supported in combined grammars\n";
|
||||
|
||||
String[] pair = { grammar, expected };
|
||||
|
@ -686,7 +686,7 @@ public class TestToolSyntaxErrors extends BaseJavaToolTest {
|
|||
|
||||
// WHITESPACE_CHANNEL and COMMENT_CHANNEL are defined, but NEWLINE_CHANNEL is not
|
||||
String expected =
|
||||
"warning(" + ErrorType.UNKNOWN_LEXER_CONSTANT.code + "): T.g4:10:34: rule NEWLINE contains a lexer command with an unrecognized constant value; lexer interpreters may produce incorrect output\n";
|
||||
"warning(" + ErrorType.UNKNOWN_OR_WRONG_LEXER_CONSTANT.code + "): T.g4:10:34: rule NEWLINE contains a lexer command with an unrecognized or wrong constant value; lexer interpreters may produce incorrect output\n";
|
||||
|
||||
String[] pair = { grammar, expected };
|
||||
super.testErrors(pair, true);
|
||||
|
|
|
@ -412,8 +412,7 @@ public class LexerATNFactory extends ParserATNFactory {
|
|||
}
|
||||
else if ("mode".equals(command) && arg != null) {
|
||||
String modeName = arg.getText();
|
||||
checkMode(modeName, arg.token);
|
||||
Integer mode = getConstantValue(modeName, arg.getToken());
|
||||
Integer mode = getModeConstantValue(modeName, arg.getToken());
|
||||
if (mode == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -422,8 +421,7 @@ public class LexerATNFactory extends ParserATNFactory {
|
|||
}
|
||||
else if ("pushMode".equals(command) && arg != null) {
|
||||
String modeName = arg.getText();
|
||||
checkMode(modeName, arg.token);
|
||||
Integer mode = getConstantValue(modeName, arg.getToken());
|
||||
Integer mode = getModeConstantValue(modeName, arg.getToken());
|
||||
if (mode == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -432,8 +430,7 @@ public class LexerATNFactory extends ParserATNFactory {
|
|||
}
|
||||
else if ("type".equals(command) && arg != null) {
|
||||
String typeName = arg.getText();
|
||||
checkToken(typeName, arg.token);
|
||||
Integer type = getConstantValue(typeName, arg.getToken());
|
||||
Integer type = getTokenConstantValue(typeName, arg.getToken());
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -442,8 +439,7 @@ public class LexerATNFactory extends ParserATNFactory {
|
|||
}
|
||||
else if ("channel".equals(command) && arg != null) {
|
||||
String channelName = arg.getText();
|
||||
checkChannel(channelName, arg.token);
|
||||
Integer channel = getConstantValue(channelName, arg.getToken());
|
||||
Integer channel = getChannelConstantValue(channelName, arg.getToken());
|
||||
if (channel == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -455,54 +451,66 @@ public class LexerATNFactory extends ParserATNFactory {
|
|||
}
|
||||
}
|
||||
|
||||
protected void checkMode(String modeName, Token token) {
|
||||
if (!modeName.equals("DEFAULT_MODE") && COMMON_CONSTANTS.containsKey(modeName)) {
|
||||
g.tool.errMgr.grammarError(ErrorType.MODE_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, token, token.getText());
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkToken(String tokenName, Token token) {
|
||||
if (!tokenName.equals("EOF") && COMMON_CONSTANTS.containsKey(tokenName)) {
|
||||
g.tool.errMgr.grammarError(ErrorType.TOKEN_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, token, token.getText());
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkChannel(String channelName, Token token) {
|
||||
if (!channelName.equals("HIDDEN") && !channelName.equals("DEFAULT_TOKEN_CHANNEL") && COMMON_CONSTANTS.containsKey(channelName)) {
|
||||
g.tool.errMgr.grammarError(ErrorType.CHANNEL_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, token, token.getText());
|
||||
}
|
||||
}
|
||||
|
||||
protected Integer getConstantValue(String name, Token token) {
|
||||
if (name == null) {
|
||||
private Integer getModeConstantValue(String modeName, Token token) {
|
||||
if (modeName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Integer commonConstant = COMMON_CONSTANTS.get(name);
|
||||
if (commonConstant != null) {
|
||||
return commonConstant;
|
||||
}
|
||||
|
||||
int tokenType = g.getTokenType(name);
|
||||
if (tokenType != org.antlr.v4.runtime.Token.INVALID_TYPE) {
|
||||
return tokenType;
|
||||
}
|
||||
|
||||
int channelValue = g.getChannelValue(name);
|
||||
if (channelValue >= org.antlr.v4.runtime.Token.MIN_USER_CHANNEL_VALUE) {
|
||||
return channelValue;
|
||||
if (modeName.equals("DEFAULT_MODE")) {
|
||||
return Lexer.DEFAULT_MODE;
|
||||
}
|
||||
|
||||
List<String> modeNames = new ArrayList<String>(((LexerGrammar)g).modes.keySet());
|
||||
int mode = modeNames.indexOf(name);
|
||||
int mode = modeNames.indexOf(modeName);
|
||||
if (mode >= 0) {
|
||||
return mode;
|
||||
}
|
||||
|
||||
return tryParseInt(modeName, token);
|
||||
}
|
||||
|
||||
private Integer getTokenConstantValue(String tokenName, Token token) {
|
||||
if (tokenName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (tokenName.equals("EOF")) {
|
||||
return Lexer.EOF;
|
||||
}
|
||||
|
||||
int tokenType = g.getTokenType(tokenName);
|
||||
if (tokenType != org.antlr.v4.runtime.Token.INVALID_TYPE) {
|
||||
return tokenType;
|
||||
}
|
||||
|
||||
return tryParseInt(tokenName, token);
|
||||
}
|
||||
|
||||
private Integer getChannelConstantValue(String channelName, Token token) {
|
||||
if (channelName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (channelName.equals("HIDDEN")) {
|
||||
return Lexer.HIDDEN;
|
||||
}
|
||||
if (channelName.equals("DEFAULT_TOKEN_CHANNEL")) {
|
||||
return Lexer.DEFAULT_TOKEN_CHANNEL;
|
||||
}
|
||||
|
||||
int channelValue = g.getChannelValue(channelName);
|
||||
if (channelValue >= org.antlr.v4.runtime.Token.MIN_USER_CHANNEL_VALUE) {
|
||||
return channelValue;
|
||||
}
|
||||
|
||||
return tryParseInt(channelName, token);
|
||||
}
|
||||
|
||||
private Integer tryParseInt(String name, Token token) {
|
||||
try {
|
||||
return Integer.parseInt(name);
|
||||
} catch (NumberFormatException ex) {
|
||||
g.tool.errMgr.grammarError(ErrorType.UNKNOWN_LEXER_CONSTANT, g.fileName, token, currentRule.name, token != null ? token.getText() : null);
|
||||
g.tool.errMgr.grammarError(ErrorType.UNKNOWN_OR_WRONG_LEXER_CONSTANT, g.fileName, token, currentRule.name, token != null ? token.getText() : null);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -293,7 +293,7 @@ public class SemanticPipeline {
|
|||
}
|
||||
|
||||
if (LexerATNFactory.COMMON_CONSTANTS.containsKey(channelName)) {
|
||||
g.tool.errMgr.grammarError(ErrorType.CHANNEL_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, channel.token, channelName);
|
||||
g.tool.errMgr.grammarError(ErrorType.DECLARATION_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, channel.token, channelName);
|
||||
}
|
||||
|
||||
if (outermost instanceof LexerGrammar) {
|
||||
|
|
|
@ -278,12 +278,12 @@ public class SymbolChecks {
|
|||
for (String modeName : lexerGrammar.modes.keySet()) {
|
||||
if (!modeName.equals("DEFAULT_MODE") && reservedNames.contains(modeName)) {
|
||||
Rule rule = lexerGrammar.modes.get(modeName).iterator().next();
|
||||
g.tool.errMgr.grammarError(ErrorType.MODE_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, rule.ast.parent.getToken(), modeName);
|
||||
g.tool.errMgr.grammarError(ErrorType.DECLARATION_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, rule.ast.parent.getToken(), modeName);
|
||||
}
|
||||
|
||||
if (g.getTokenType(modeName) != Token.INVALID_TYPE) {
|
||||
Rule rule = lexerGrammar.modes.get(modeName).iterator().next();
|
||||
g.tool.errMgr.grammarError(ErrorType.MODE_CONFLICTS_WITH_TOKEN, g.fileName, rule.ast.parent.getToken(), modeName);
|
||||
g.tool.errMgr.grammarError(ErrorType.DECLARATION_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, rule.ast.parent.getToken(), modeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -831,7 +831,7 @@ public enum ErrorType {
|
|||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
UNKNOWN_LEXER_CONSTANT(155, "rule <arg> contains a lexer command with an unrecognized constant value; lexer interpreters may produce incorrect output", ErrorSeverity.WARNING),
|
||||
UNKNOWN_OR_WRONG_LEXER_CONSTANT(155, "rule <arg> contains a lexer command with an unrecognized or wrong constant value; lexer interpreters may produce incorrect output", ErrorSeverity.WARNING),
|
||||
/**
|
||||
* Compiler Error 156.
|
||||
*
|
||||
|
@ -960,57 +960,21 @@ public enum ErrorType {
|
|||
/**
|
||||
* Compiler Error 170.
|
||||
*
|
||||
* <pre>
|
||||
* mode M1;
|
||||
* A1: 'a'; // ok
|
||||
* mode M2;
|
||||
* A2: 'a'; // ok
|
||||
* M1: 'b'; // error 170
|
||||
* </pre>
|
||||
* <p>can not declare mode, token or channel with reserved name</p>
|
||||
*
|
||||
* <p>mode <em>name</em> conflicts with token with same name</p>
|
||||
* <p>Reserved names: HIDDEN, DEFAULT_TOKEN_CHANNEL, DEFAULT_MODE, SKIP, MORE, EOF, MAX_CHAR_VALUE, MIN_CHAR_VALUE.
|
||||
*/
|
||||
MODE_CONFLICTS_WITH_TOKEN(170, "mode <arg> conflicts with token with same name", ErrorSeverity.ERROR),
|
||||
DECLARATION_CONFLICTS_WITH_COMMON_CONSTANTS(170, "cannot declare mode, token or channel with reserved name <arg>", ErrorSeverity.ERROR),
|
||||
/**
|
||||
* Compiler Error 171.
|
||||
*
|
||||
* <p>can not use or declare token with reserved name</p>
|
||||
*
|
||||
* <p>Reserved names: HIDDEN, DEFAULT_TOKEN_CHANNEL, SKIP, MORE, MAX_CHAR_VALUE, MIN_CHAR_VALUE.
|
||||
*
|
||||
* <p>Can be used but cannot be declared: EOF</p>
|
||||
*/
|
||||
TOKEN_CONFLICTS_WITH_COMMON_CONSTANTS(171, "cannot use or declare token with reserved name <arg>", ErrorSeverity.ERROR),
|
||||
/**
|
||||
* Compiler Error 172.
|
||||
*
|
||||
* <p>can not use or declare channel with reserved name</p>
|
||||
*
|
||||
* <p>Reserved names: DEFAULT_MODE, SKIP, MORE, EOF, MAX_CHAR_VALUE, MIN_CHAR_VALUE.
|
||||
*
|
||||
* <p>Can be used but cannot be declared: HIDDEN, DEFAULT_TOKEN_CHANNEL</p>
|
||||
*/
|
||||
CHANNEL_CONFLICTS_WITH_COMMON_CONSTANTS(172, "cannot use or declare channel with reserved name <arg>", ErrorSeverity.ERROR),
|
||||
/**
|
||||
* Compiler Error 173.
|
||||
*
|
||||
* <p>can not use or declare mode with reserved name</p>
|
||||
*
|
||||
* <p>Reserved names: HIDDEN, DEFAULT_TOKEN_CHANNEL, SKIP, MORE, MAX_CHAR_VALUE, MIN_CHAR_VALUE.
|
||||
*
|
||||
* <p>Can be used and cannot declared: DEFAULT_MODE</p>
|
||||
*/
|
||||
MODE_CONFLICTS_WITH_COMMON_CONSTANTS(173, "cannot use or declare mode with reserved name <arg>", ErrorSeverity.ERROR),
|
||||
/**
|
||||
* Compiler Error 174.
|
||||
*
|
||||
* <p>empty strings not allowed</p>
|
||||
* <p>string literals cannot be empty</p>
|
||||
*
|
||||
* <pre>A: '''test''';</pre>
|
||||
* <pre>B: '';</pre>
|
||||
* <pre>C: 'test' '';</pre>
|
||||
*/
|
||||
EMPTY_STRINGS_NOT_ALLOWED(174, "string literals cannot be empty", ErrorSeverity.ERROR),
|
||||
EMPTY_STRINGS_NOT_ALLOWED(171, "string literals cannot be empty", ErrorSeverity.ERROR),
|
||||
|
||||
/*
|
||||
* Backward incompatibility errors
|
||||
|
|
Loading…
Reference in New Issue