From bd1111ffa3fd39d16acd20fc8542114883bc638b Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Mon, 28 Nov 2016 19:48:35 +0300 Subject: [PATCH 1/9] Fixed issue with duplicated commands in lexer rule. --- .../antlr/v4/test/tool/TestSymbolIssues.java | 23 +++++++++++++++++++ .../antlr/v4/automata/LexerATNFactory.java | 19 ++++++++++++--- tool/src/org/antlr/v4/tool/ErrorType.java | 8 +++++++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java b/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java index 1c31749a9..41aeee815 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java @@ -247,4 +247,27 @@ public class TestSymbolIssues extends BaseJavaToolTest { testErrors(test, false); } + + // https://github.com/antlr/antlr4/issues/1388 + @Test public void testDuplicatedCommands() throws Exception { + String[] test = { + "lexer grammar Lexer;\n" + + "channels { CHANNEL1, CHANNEL2 }\n" + + "tokens { TEST1, TEST2 }\n" + + "TOKEN: 'aaaa' -> mode(MODE1), mode(MODE2);\n" + + "mode MODE1;\n" + + "MODE1_TOKEN: 'bbbb';\n" + + "mode MODE2;\n" + + "MODE2_TOKEN: 'bbbb';\n" + + "MODE2_TOKEN1: 'cccc' -> type(TEST1), type(TEST2);\n" + + "MODE2_TOKEN2: 'dddd' -> channel(CHANNEL1), channel(CHANNEL2), channel(DEFAULT_TOKEN_CHANNEL);", + + "warning(" + ErrorType.DUPLICATED_COMMAND.code + "): Lexer.g4:4:30: duplicated command mode\n" + + "warning(" + ErrorType.DUPLICATED_COMMAND.code + "): Lexer.g4:9:37: duplicated command type\n" + + "warning(" + ErrorType.DUPLICATED_COMMAND.code + "): Lexer.g4:10:43: duplicated command channel\n" + + "warning(" + ErrorType.DUPLICATED_COMMAND.code + "): Lexer.g4:10:62: duplicated command channel\n" + }; + + testErrors(test, false); + } } diff --git a/tool/src/org/antlr/v4/automata/LexerATNFactory.java b/tool/src/org/antlr/v4/automata/LexerATNFactory.java index b9fec8abd..4f706c2b6 100644 --- a/tool/src/org/antlr/v4/automata/LexerATNFactory.java +++ b/tool/src/org/antlr/v4/automata/LexerATNFactory.java @@ -95,6 +95,8 @@ public class LexerATNFactory extends ParserATNFactory { COMMON_CONSTANTS.put("MIN_CHAR_VALUE", Lexer.MIN_CHAR_VALUE); } + private List ruleCommands = new ArrayList(); + /** * Maps from an action index to a {@link LexerAction} object. */ @@ -159,6 +161,12 @@ public class LexerATNFactory extends ParserATNFactory { return atn; } + @Override + public Handle rule(GrammarAST ruleAST, String name, Handle blk) { + ruleCommands.clear(); + return super.rule(ruleAST, name, blk); + } + @Override public Handle action(ActionAST action) { int ruleIndex = currentRule.index; @@ -389,7 +397,7 @@ public class LexerATNFactory extends ParserATNFactory { @Override public Handle tokenRef(TerminalAST node) { // Ref to EOF in lexer yields char transition on -1 - if ( node.getText().equals("EOF") ) { + if (node.getText().equals("EOF") ) { ATNState left = newState(node); ATNState right = newState(node); left.addTransition(new AtomTransition(right, IntStream.EOF)); @@ -398,9 +406,14 @@ public class LexerATNFactory extends ParserATNFactory { return _ruleRef(node); } - - protected LexerAction createLexerAction(GrammarAST ID, GrammarAST arg) { + private LexerAction createLexerAction(GrammarAST ID, GrammarAST arg) { String command = ID.getText(); + + if (ruleCommands.contains(command)) { + g.tool.errMgr.grammarError(ErrorType.DUPLICATED_COMMAND, g.fileName, ID.getToken(), command); + } + ruleCommands.add(command); + if ("skip".equals(command) && arg == null) { return LexerSkipAction.INSTANCE; } diff --git a/tool/src/org/antlr/v4/tool/ErrorType.java b/tool/src/org/antlr/v4/tool/ErrorType.java index 1526a632c..79b6d226c 100644 --- a/tool/src/org/antlr/v4/tool/ErrorType.java +++ b/tool/src/org/antlr/v4/tool/ErrorType.java @@ -975,6 +975,14 @@ public enum ErrorType { *
C: 'test' '';
*/ EMPTY_STRINGS_NOT_ALLOWED(171, "string literals cannot be empty", ErrorSeverity.ERROR), + /* + * Compiler Warning 172. + * + *

lexer rule has a duplicated commands

+ * + *

TOKEN: 'asdf' -> mode(MODE1), mode(MODE2);

+ * */ + DUPLICATED_COMMAND(172, "duplicated command ", ErrorSeverity.WARNING), /* * Backward incompatibility errors From ed7f6f70da9557fb66c0c926f9eced8c92679d39 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 29 Nov 2016 16:00:41 +0300 Subject: [PATCH 2/9] pushMode and popMode commands are not duplicated. --- tool/src/org/antlr/v4/automata/LexerATNFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/src/org/antlr/v4/automata/LexerATNFactory.java b/tool/src/org/antlr/v4/automata/LexerATNFactory.java index 4f706c2b6..f2dfe4518 100644 --- a/tool/src/org/antlr/v4/automata/LexerATNFactory.java +++ b/tool/src/org/antlr/v4/automata/LexerATNFactory.java @@ -409,7 +409,7 @@ public class LexerATNFactory extends ParserATNFactory { private LexerAction createLexerAction(GrammarAST ID, GrammarAST arg) { String command = ID.getText(); - if (ruleCommands.contains(command)) { + if (ruleCommands.contains(command) && !command.equals("pushMode") && !command.equals("popMode")) { g.tool.errMgr.grammarError(ErrorType.DUPLICATED_COMMAND, g.fileName, ID.getToken(), command); } ruleCommands.add(command); From 8fe4def4edcc31fcbe5c3b2a59b1cd18527ea1d1 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 29 Nov 2016 16:02:49 +0300 Subject: [PATCH 3/9] Warnings for incompatible commands, added unit-test, fixes #1388. Improved test for duplicated commands (added pushMode, popMode). --- .../antlr/v4/test/tool/TestSymbolIssues.java | 57 ++++++++++++++++--- .../antlr/v4/automata/LexerATNFactory.java | 17 ++++++ tool/src/org/antlr/v4/tool/ErrorType.java | 7 +++ 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java b/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java index 41aeee815..bc4e72244 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java @@ -254,18 +254,57 @@ public class TestSymbolIssues extends BaseJavaToolTest { "lexer grammar Lexer;\n" + "channels { CHANNEL1, CHANNEL2 }\n" + "tokens { TEST1, TEST2 }\n" + - "TOKEN: 'aaaa' -> mode(MODE1), mode(MODE2);\n" + + "TOKEN: 'a' -> mode(MODE1), mode(MODE2);\n" + + "TOKEN1: 'b' -> pushMode(MODE1), mode(MODE2);\n" + + "TOKEN2: 'c' -> pushMode(MODE1), pushMode(MODE2); // pushMode is not duplicate\n" + + "TOKEN3: 'd' -> popMode, popMode; // popMode is not duplicate\n" + "mode MODE1;\n" + - "MODE1_TOKEN: 'bbbb';\n" + + "MODE1_TOKEN: 'e';\n" + "mode MODE2;\n" + - "MODE2_TOKEN: 'bbbb';\n" + - "MODE2_TOKEN1: 'cccc' -> type(TEST1), type(TEST2);\n" + - "MODE2_TOKEN2: 'dddd' -> channel(CHANNEL1), channel(CHANNEL2), channel(DEFAULT_TOKEN_CHANNEL);", + "MODE2_TOKEN: 'f';\n" + + "MODE2_TOKEN1: 'g' -> type(TEST1), type(TEST2);\n" + + "MODE2_TOKEN2: 'h' -> channel(CHANNEL1), channel(CHANNEL2), channel(DEFAULT_TOKEN_CHANNEL);", - "warning(" + ErrorType.DUPLICATED_COMMAND.code + "): Lexer.g4:4:30: duplicated command mode\n" + - "warning(" + ErrorType.DUPLICATED_COMMAND.code + "): Lexer.g4:9:37: duplicated command type\n" + - "warning(" + ErrorType.DUPLICATED_COMMAND.code + "): Lexer.g4:10:43: duplicated command channel\n" + - "warning(" + ErrorType.DUPLICATED_COMMAND.code + "): Lexer.g4:10:62: duplicated command channel\n" + "warning(" + ErrorType.DUPLICATED_COMMAND.code + "): Lexer.g4:4:27: duplicated command mode\n" + + "warning(" + ErrorType.DUPLICATED_COMMAND.code + "): Lexer.g4:12:34: duplicated command type\n" + + "warning(" + ErrorType.DUPLICATED_COMMAND.code + "): Lexer.g4:13:40: duplicated command channel\n" + + "warning(" + ErrorType.DUPLICATED_COMMAND.code + "): Lexer.g4:13:59: duplicated command channel\n" + }; + + testErrors(test, false); + } + + // https://github.com/antlr/antlr4/issues/1388 + @Test public void testIncompatibleCommands() throws Exception { + String[] test = { + "lexer grammar L;\n" + + "channels { CHANNEL1 }\n" + + "tokens { TYPE1 }\n" + + "// Incompatible\n" + + "T00: 'a00' -> skip, more;\n" + + "T01: 'a01' -> skip, type(TYPE1);\n" + + "T02: 'a02' -> skip, channel(CHANNEL1);\n" + + "T03: 'a03' -> more, type(TYPE1);\n" + + "T04: 'a04' -> more, channel(CHANNEL1);\n" + + "T05: 'a05' -> more, skip;\n" + + "T06: 'a06' -> type(TYPE1), skip;\n" + + "T07: 'a07' -> type(TYPE1), more;\n" + + "T08: 'a08' -> channel(CHANNEL1), skip;\n" + + "T09: 'a09' -> channel(CHANNEL1), more;\n" + + "// Allowed\n" + + "T10: 'a10' -> type(TYPE1), channel(CHANNEL1);\n" + + "T11: 'a11' -> channel(CHANNEL1), type(TYPE1);", + + "warning(" + ErrorType.INCOMPATIBLE_COMMANDS.code + "): L.g4:5:20: incompatible commands skip and more\n" + + "warning(" + ErrorType.INCOMPATIBLE_COMMANDS.code + "): L.g4:6:20: incompatible commands skip and type\n" + + "warning(" + ErrorType.INCOMPATIBLE_COMMANDS.code + "): L.g4:7:20: incompatible commands skip and channel\n" + + "warning(" + ErrorType.INCOMPATIBLE_COMMANDS.code + "): L.g4:8:20: incompatible commands more and type\n" + + "warning(" + ErrorType.INCOMPATIBLE_COMMANDS.code + "): L.g4:9:20: incompatible commands more and channel\n" + + "warning(" + ErrorType.INCOMPATIBLE_COMMANDS.code + "): L.g4:10:20: incompatible commands more and skip\n" + + "warning(" + ErrorType.INCOMPATIBLE_COMMANDS.code + "): L.g4:11:27: incompatible commands type and skip\n" + + "warning(" + ErrorType.INCOMPATIBLE_COMMANDS.code + "): L.g4:12:27: incompatible commands type and more\n" + + "warning(" + ErrorType.INCOMPATIBLE_COMMANDS.code + "): L.g4:13:33: incompatible commands channel and skip\n" + + "warning(" + ErrorType.INCOMPATIBLE_COMMANDS.code + "): L.g4:14:33: incompatible commands channel and more\n" }; testErrors(test, false); diff --git a/tool/src/org/antlr/v4/automata/LexerATNFactory.java b/tool/src/org/antlr/v4/automata/LexerATNFactory.java index f2dfe4518..49b85b9ff 100644 --- a/tool/src/org/antlr/v4/automata/LexerATNFactory.java +++ b/tool/src/org/antlr/v4/automata/LexerATNFactory.java @@ -412,6 +412,23 @@ public class LexerATNFactory extends ParserATNFactory { if (ruleCommands.contains(command) && !command.equals("pushMode") && !command.equals("popMode")) { g.tool.errMgr.grammarError(ErrorType.DUPLICATED_COMMAND, g.fileName, ID.getToken(), command); } + String firstCommand = null; + if ((ruleCommands.contains("skip") && (command.equals("more") || command.equals("type") || command.equals("channel")))) { + firstCommand = "skip"; + } + else if ((ruleCommands.contains("more") && (command.equals("type") || command.equals("channel") || command.equals("skip")))) { + firstCommand = "more"; + } + else if ((ruleCommands.contains("type") && (command.equals("skip") || command.equals("more")))) { + firstCommand = "type"; + } + else if ((ruleCommands.contains("channel") && (command.equals("skip") || command.equals("more")))) { + firstCommand = "channel"; + } + if (firstCommand != null) { + g.tool.errMgr.grammarError(ErrorType.INCOMPATIBLE_COMMANDS, g.fileName, ID.getToken(), firstCommand, command); + } + ruleCommands.add(command); if ("skip".equals(command) && arg == null) { diff --git a/tool/src/org/antlr/v4/tool/ErrorType.java b/tool/src/org/antlr/v4/tool/ErrorType.java index 79b6d226c..a26adc5a0 100644 --- a/tool/src/org/antlr/v4/tool/ErrorType.java +++ b/tool/src/org/antlr/v4/tool/ErrorType.java @@ -983,6 +983,13 @@ public enum ErrorType { *

TOKEN: 'asdf' -> mode(MODE1), mode(MODE2);

* */ DUPLICATED_COMMAND(172, "duplicated command ", ErrorSeverity.WARNING), + /* Compiler Waring 173 + * + *

incompatible commands command1 and command2

+ * + *

T00: 'a00' -> skip, more;

+ */ + INCOMPATIBLE_COMMANDS(173, "incompatible commands and ", ErrorSeverity.WARNING), /* * Backward incompatibility errors From f76ca2276301f4d404da2553625976e1cb5740bd Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 29 Nov 2016 18:13:57 +0300 Subject: [PATCH 4/9] MODE_CONFLICTS_WITH_TOKEN error restored. --- .../antlr/v4/test/tool/TestSymbolIssues.java | 2 +- .../org/antlr/v4/semantics/SymbolChecks.java | 2 +- tool/src/org/antlr/v4/tool/ErrorType.java | 28 ++++++++++++++----- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java b/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java index bc4e72244..8de9fcc86 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java @@ -127,7 +127,7 @@ public class TestSymbolIssues extends BaseJavaToolTest { "M1: 'b';\n", // YIELDS - "error(" + ErrorType.DECLARATION_CONFLICTS_WITH_COMMON_CONSTANTS.code + "): F.g4:3:0: cannot declare mode, token or channel with reserved name M1\n" + "error(" + ErrorType.MODE_CONFLICTS_WITH_TOKEN.code + "): F.g4:3:0: mode M1 conflicts with token with same name\n" }; @Before diff --git a/tool/src/org/antlr/v4/semantics/SymbolChecks.java b/tool/src/org/antlr/v4/semantics/SymbolChecks.java index 0249d5aa7..e2459c6ba 100644 --- a/tool/src/org/antlr/v4/semantics/SymbolChecks.java +++ b/tool/src/org/antlr/v4/semantics/SymbolChecks.java @@ -283,7 +283,7 @@ public class SymbolChecks { if (g.getTokenType(modeName) != Token.INVALID_TYPE) { Rule rule = lexerGrammar.modes.get(modeName).iterator().next(); - g.tool.errMgr.grammarError(ErrorType.DECLARATION_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, rule.ast.parent.getToken(), modeName); + g.tool.errMgr.grammarError(ErrorType.MODE_CONFLICTS_WITH_TOKEN, g.fileName, rule.ast.parent.getToken(), modeName); } } } diff --git a/tool/src/org/antlr/v4/tool/ErrorType.java b/tool/src/org/antlr/v4/tool/ErrorType.java index a26adc5a0..848e51ab7 100644 --- a/tool/src/org/antlr/v4/tool/ErrorType.java +++ b/tool/src/org/antlr/v4/tool/ErrorType.java @@ -960,13 +960,27 @@ public enum ErrorType { /** * Compiler Error 170. * + *
+	 * mode M1;
+	 * A1: 'a'; // ok
+	 * mode M2;
+	 * A2: 'a'; // ok
+	 * M1: 'b'; // error 170
+	 * 
+ * + *

mode name conflicts with token with same name

+ */ + MODE_CONFLICTS_WITH_TOKEN(170, "mode conflicts with token with same name", ErrorSeverity.ERROR), + /** + * Compiler Error 171. + * *

can not declare mode, token or channel with reserved name

* *

Reserved names: HIDDEN, DEFAULT_TOKEN_CHANNEL, DEFAULT_MODE, SKIP, MORE, EOF, MAX_CHAR_VALUE, MIN_CHAR_VALUE. */ - DECLARATION_CONFLICTS_WITH_COMMON_CONSTANTS(170, "cannot declare mode, token or channel with reserved name ", ErrorSeverity.ERROR), + DECLARATION_CONFLICTS_WITH_COMMON_CONSTANTS(171, "cannot declare mode, token or channel with reserved name ", ErrorSeverity.ERROR), /** - * Compiler Error 171. + * Compiler Error 172. * *

string literals cannot be empty

* @@ -974,22 +988,22 @@ public enum ErrorType { *
B: '';
*
C: 'test' '';
*/ - EMPTY_STRINGS_NOT_ALLOWED(171, "string literals cannot be empty", ErrorSeverity.ERROR), + EMPTY_STRINGS_NOT_ALLOWED(172, "string literals cannot be empty", ErrorSeverity.ERROR), /* - * Compiler Warning 172. + * Compiler Warning 173. * *

lexer rule has a duplicated commands

* *

TOKEN: 'asdf' -> mode(MODE1), mode(MODE2);

* */ - DUPLICATED_COMMAND(172, "duplicated command ", ErrorSeverity.WARNING), - /* Compiler Waring 173 + DUPLICATED_COMMAND(173, "duplicated command ", ErrorSeverity.WARNING), + /* Compiler Waring 174. * *

incompatible commands command1 and command2

* *

T00: 'a00' -> skip, more;

*/ - INCOMPATIBLE_COMMANDS(173, "incompatible commands and ", ErrorSeverity.WARNING), + INCOMPATIBLE_COMMANDS(174, "incompatible commands and ", ErrorSeverity.WARNING), /* * Backward incompatibility errors From 44aab113f3f9b69af9af0f24a14e3401b3b078bb Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 29 Nov 2016 18:48:03 +0300 Subject: [PATCH 5/9] Added method checkCommands. commands check micro optimization and code clearing. --- .../antlr/v4/automata/LexerATNFactory.java | 62 ++++++++++++------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/tool/src/org/antlr/v4/automata/LexerATNFactory.java b/tool/src/org/antlr/v4/automata/LexerATNFactory.java index 49b85b9ff..e35b54ac9 100644 --- a/tool/src/org/antlr/v4/automata/LexerATNFactory.java +++ b/tool/src/org/antlr/v4/automata/LexerATNFactory.java @@ -408,28 +408,7 @@ public class LexerATNFactory extends ParserATNFactory { private LexerAction createLexerAction(GrammarAST ID, GrammarAST arg) { String command = ID.getText(); - - if (ruleCommands.contains(command) && !command.equals("pushMode") && !command.equals("popMode")) { - g.tool.errMgr.grammarError(ErrorType.DUPLICATED_COMMAND, g.fileName, ID.getToken(), command); - } - String firstCommand = null; - if ((ruleCommands.contains("skip") && (command.equals("more") || command.equals("type") || command.equals("channel")))) { - firstCommand = "skip"; - } - else if ((ruleCommands.contains("more") && (command.equals("type") || command.equals("channel") || command.equals("skip")))) { - firstCommand = "more"; - } - else if ((ruleCommands.contains("type") && (command.equals("skip") || command.equals("more")))) { - firstCommand = "type"; - } - else if ((ruleCommands.contains("channel") && (command.equals("skip") || command.equals("more")))) { - firstCommand = "channel"; - } - if (firstCommand != null) { - g.tool.errMgr.grammarError(ErrorType.INCOMPATIBLE_COMMANDS, g.fileName, ID.getToken(), firstCommand, command); - } - - ruleCommands.add(command); + checkCommands(command, ID.getToken()); if ("skip".equals(command) && arg == null) { return LexerSkipAction.INSTANCE; @@ -481,6 +460,45 @@ public class LexerATNFactory extends ParserATNFactory { } } + private void checkCommands(String command, Token commandToken) { + if (!command.equals("pushMode") && !command.equals("popMode")) { + if (ruleCommands.contains(command)) { + g.tool.errMgr.grammarError(ErrorType.DUPLICATED_COMMAND, g.fileName, commandToken, command); + } else if (!ruleCommands.equals("mode")) { + String firstCommand = null; + + if (command.equals("skip")) { + if (ruleCommands.contains("more")) { + firstCommand = "more"; + } else if (ruleCommands.contains("type")) { + firstCommand = "type"; + } else if (ruleCommands.contains("channel")) { + firstCommand = "channel"; + } + } else if (command.equals("more")) { + if (ruleCommands.contains("skip")) { + firstCommand = "skip"; + } else if (ruleCommands.contains("type")) { + firstCommand = "type"; + } else if (ruleCommands.contains("channel")) { + firstCommand = "channel"; + } + } else if (command.equals("type") || command.equals("channel")) { + if (ruleCommands.contains("more")) { + firstCommand = "more"; + } else if (ruleCommands.contains("skip")) { + firstCommand = "skip"; + } + } + + if (firstCommand != null) { + g.tool.errMgr.grammarError(ErrorType.INCOMPATIBLE_COMMANDS, g.fileName, commandToken, firstCommand, command); + } + } + } + ruleCommands.add(command); + } + private Integer getModeConstantValue(String modeName, Token token) { if (modeName == null) { return null; From b8585b7eb51ce7ba6cfeaa4eabc9a7a2494f30ca Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Sun, 4 Dec 2016 02:32:39 +0300 Subject: [PATCH 6/9] Fixed some missed cases for checkCommands. --- tool/src/org/antlr/v4/automata/LexerATNFactory.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tool/src/org/antlr/v4/automata/LexerATNFactory.java b/tool/src/org/antlr/v4/automata/LexerATNFactory.java index e35b54ac9..22663f425 100644 --- a/tool/src/org/antlr/v4/automata/LexerATNFactory.java +++ b/tool/src/org/antlr/v4/automata/LexerATNFactory.java @@ -464,7 +464,9 @@ public class LexerATNFactory extends ParserATNFactory { if (!command.equals("pushMode") && !command.equals("popMode")) { if (ruleCommands.contains(command)) { g.tool.errMgr.grammarError(ErrorType.DUPLICATED_COMMAND, g.fileName, commandToken, command); - } else if (!ruleCommands.equals("mode")) { + } + + if (!ruleCommands.equals("mode")) { String firstCommand = null; if (command.equals("skip")) { @@ -496,6 +498,7 @@ public class LexerATNFactory extends ParserATNFactory { } } } + ruleCommands.add(command); } From cb16e369fe27b58d04c64e2b6c6c9c96a0f843dc Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Sun, 4 Dec 2016 04:05:55 +0300 Subject: [PATCH 7/9] Misprint in comment. --- tool/src/org/antlr/v4/tool/ErrorType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/src/org/antlr/v4/tool/ErrorType.java b/tool/src/org/antlr/v4/tool/ErrorType.java index 3834d93b7..6479005a8 100644 --- a/tool/src/org/antlr/v4/tool/ErrorType.java +++ b/tool/src/org/antlr/v4/tool/ErrorType.java @@ -972,7 +972,7 @@ public enum ErrorType { */ MODE_CONFLICTS_WITH_TOKEN(170, "mode conflicts with token with same name", ErrorSeverity.ERROR), /** - * Compiler Error 172. + * Compiler Error 171. * *

can not use or declare token with reserved name

* From bf3bff16e449d7149ca804ae4944c65a8e311a6b Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Sun, 4 Dec 2016 15:06:07 +0300 Subject: [PATCH 8/9] Misprints fixed, code style improved (removed unnecessary else). --- .../antlr/v4/automata/LexerATNFactory.java | 20 +++++++++---------- tool/src/org/antlr/v4/tool/ErrorType.java | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tool/src/org/antlr/v4/automata/LexerATNFactory.java b/tool/src/org/antlr/v4/automata/LexerATNFactory.java index 5fd43d4e8..73c17f215 100644 --- a/tool/src/org/antlr/v4/automata/LexerATNFactory.java +++ b/tool/src/org/antlr/v4/automata/LexerATNFactory.java @@ -510,16 +510,16 @@ public class LexerATNFactory extends ParserATNFactory { if (modeName.equals("DEFAULT_MODE")) { return Lexer.DEFAULT_MODE; } + if (COMMON_CONSTANTS.containsKey(modeName)) { + g.tool.errMgr.grammarError(ErrorType.MODE_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, token, token.getText()); + return null; + } List modeNames = new ArrayList(((LexerGrammar)g).modes.keySet()); int mode = modeNames.indexOf(modeName); if (mode >= 0) { return mode; } - else if (COMMON_CONSTANTS.containsKey(modeName)) { - g.tool.errMgr.grammarError(ErrorType.MODE_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, token, token.getText()); - return null; - } try { return Integer.parseInt(modeName); @@ -537,15 +537,15 @@ public class LexerATNFactory extends ParserATNFactory { if (tokenName.equals("EOF")) { return Lexer.EOF; } + if (COMMON_CONSTANTS.containsKey(tokenName)) { + g.tool.errMgr.grammarError(ErrorType.TOKEN_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, token, token.getText()); + return null; + } int tokenType = g.getTokenType(tokenName); if (tokenType != org.antlr.v4.runtime.Token.INVALID_TYPE) { return tokenType; } - else if (COMMON_CONSTANTS.containsKey(tokenName)) { - g.tool.errMgr.grammarError(ErrorType.TOKEN_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, token, token.getText()); - return null; - } try { return Integer.parseInt(tokenName); @@ -563,10 +563,10 @@ public class LexerATNFactory extends ParserATNFactory { if (channelName.equals("HIDDEN")) { return Lexer.HIDDEN; } - else if (channelName.equals("DEFAULT_TOKEN_CHANNEL")) { + if (channelName.equals("DEFAULT_TOKEN_CHANNEL")) { return Lexer.DEFAULT_TOKEN_CHANNEL; } - else if (COMMON_CONSTANTS.containsKey(channelName)) { + if (COMMON_CONSTANTS.containsKey(channelName)) { g.tool.errMgr.grammarError(ErrorType.CHANNEL_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, token, token.getText()); return null; } diff --git a/tool/src/org/antlr/v4/tool/ErrorType.java b/tool/src/org/antlr/v4/tool/ErrorType.java index 6479005a8..c9401e047 100644 --- a/tool/src/org/antlr/v4/tool/ErrorType.java +++ b/tool/src/org/antlr/v4/tool/ErrorType.java @@ -1024,7 +1024,7 @@ public enum ErrorType { * *

nameis not a recognized mode name

* - *
TOKEN: 'a' -> channel(MODE1); // error 176
+ *
TOKEN: 'a' -> mode(MODE1); // error 176
*/ CONSTANT_VALUE_IS_NOT_A_RECOGNIZED_MODE_NAME(176, " is not a recognized mode name", ErrorSeverity.ERROR), /** @@ -1032,7 +1032,7 @@ public enum ErrorType { * *

name is not a recognized channel name

* - *
TOKEN: 'a' -> mode(TOKEN1); // error 177
+ *
TOKEN: 'a' -> channel(TOKEN1); // error 177
*/ CONSTANT_VALUE_IS_NOT_A_RECOGNIZED_CHANNEL_NAME(177, " is not a recognized channel name", ErrorSeverity.ERROR), /* From e4c765aa27007d6957147997bda9d52ad1841dd3 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Sun, 4 Dec 2016 15:11:25 +0300 Subject: [PATCH 9/9] Added comment. --- tool/src/org/antlr/v4/automata/LexerATNFactory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tool/src/org/antlr/v4/automata/LexerATNFactory.java b/tool/src/org/antlr/v4/automata/LexerATNFactory.java index 73c17f215..03626e059 100644 --- a/tool/src/org/antlr/v4/automata/LexerATNFactory.java +++ b/tool/src/org/antlr/v4/automata/LexerATNFactory.java @@ -461,6 +461,7 @@ public class LexerATNFactory extends ParserATNFactory { } private void checkCommands(String command, Token commandToken) { + // Command combinations list: https://github.com/antlr/antlr4/issues/1388#issuecomment-263344701 if (!command.equals("pushMode") && !command.equals("popMode")) { if (ruleCommands.contains(command)) { g.tool.errMgr.grammarError(ErrorType.DUPLICATED_COMMAND, g.fileName, commandToken, command);