From a87ac8664bcbc8b365eda38abde0ea921e59566b Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 6 Oct 2015 17:39:01 +0300 Subject: [PATCH] Error in case of mode conflicts with token. fixed #996 --- .../antlr/v4/test/tool/TestSymbolIssues.java | 15 +++++++++++++ .../antlr/v4/semantics/SemanticPipeline.java | 2 ++ .../org/antlr/v4/semantics/SymbolChecks.java | 22 ++++++++++++------- tool/src/org/antlr/v4/tool/ErrorType.java | 6 +++++ 4 files changed, 37 insertions(+), 8 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 6934f2cb1..ec0fc4576 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestSymbolIssues.java @@ -116,10 +116,25 @@ public class TestSymbolIssues extends BaseTest { "warning(" + ErrorType.TOKEN_NAME_REASSIGNMENT.code + "): E.g4:3:4: token name A is already defined\n" }; + static String[] F = { + // INPUT + "lexer grammar F;\n" + + "A: 'a';\n" + + "mode M1;\n" + + "A1: 'a';\n" + + "mode M2;\n" + + "A2: 'a';\n" + + "M1: 'b';\n", + + // YIELDS + "error(" + ErrorType.MODE_CONFLICTS_WITH_TOKEN.code + "): F.g4:3:0: mode M1 conflicts with token with same name\n" + }; + @Test public void testA() { super.testErrors(A, false); } @Test public void testB() { super.testErrors(B, false); } @Test public void testD() { super.testErrors(D, false); } @Test public void testE() { super.testErrors(E, false); } + @Test public void testF() { super.testErrors(F, false); } @Test public void testStringLiteralRedefs() throws Exception { String grammar = diff --git a/tool/src/org/antlr/v4/semantics/SemanticPipeline.java b/tool/src/org/antlr/v4/semantics/SemanticPipeline.java index 3561f91a8..49143d429 100644 --- a/tool/src/org/antlr/v4/semantics/SemanticPipeline.java +++ b/tool/src/org/antlr/v4/semantics/SemanticPipeline.java @@ -128,6 +128,8 @@ public class SemanticPipeline { collector.tokenIDRefs, collector.terminals); } + symcheck.checkForModeConflicts(g); + assignChannelTypes(g, collector.channelDefs); // CHECK RULE REFS NOW (that we've defined rules in grammar) diff --git a/tool/src/org/antlr/v4/semantics/SymbolChecks.java b/tool/src/org/antlr/v4/semantics/SymbolChecks.java index b280f4008..c665ee7b3 100644 --- a/tool/src/org/antlr/v4/semantics/SymbolChecks.java +++ b/tool/src/org/antlr/v4/semantics/SymbolChecks.java @@ -31,14 +31,8 @@ package org.antlr.v4.semantics; import org.antlr.v4.parse.ANTLRParser; -import org.antlr.v4.tool.Alternative; -import org.antlr.v4.tool.Attribute; -import org.antlr.v4.tool.AttributeDict; -import org.antlr.v4.tool.ErrorManager; -import org.antlr.v4.tool.ErrorType; -import org.antlr.v4.tool.Grammar; -import org.antlr.v4.tool.LabelElementPair; -import org.antlr.v4.tool.Rule; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.tool.*; import org.antlr.v4.tool.ast.GrammarAST; import java.util.Collection; @@ -269,6 +263,18 @@ public class SymbolChecks { } } + public void checkForModeConflicts(Grammar g) { + if (g.isLexer()) { + LexerGrammar lexerGrammar = (LexerGrammar)g; + for (String modeName : lexerGrammar.modes.keySet()) { + if (g.getTokenType(modeName) != Token.INVALID_TYPE) { + Rule rule = ((Collection)lexerGrammar.modes.get(modeName)).iterator().next(); + g.tool.errMgr.grammarError(ErrorType.MODE_CONFLICTS_WITH_TOKEN, g.fileName, rule.ast.parent.getToken(), modeName); + } + } + } + } + // CAN ONLY CALL THE TWO NEXT METHODS AFTER GRAMMAR HAS RULE DEFS (see semanticpipeline) public void checkRuleArgs(Grammar g, List rulerefs) { diff --git a/tool/src/org/antlr/v4/tool/ErrorType.java b/tool/src/org/antlr/v4/tool/ErrorType.java index 4868931de..6e39c202f 100644 --- a/tool/src/org/antlr/v4/tool/ErrorType.java +++ b/tool/src/org/antlr/v4/tool/ErrorType.java @@ -955,6 +955,12 @@ public enum ErrorType { *

custom channels are not supported in combined grammars

*/ CHANNELS_BLOCK_IN_COMBINED_GRAMMAR(164, "custom channels are not supported in combined grammars", ErrorSeverity.ERROR), + /** + * Compiler Error 165. + * + *

mode name conflicts with token with same name

+ */ + MODE_CONFLICTS_WITH_TOKEN(165, "mode conflicts with token with same name", ErrorSeverity.ERROR), NONCONFORMING_LR_RULE(169, "rule is left recursive but doesn't conform to a pattern ANTLR can handle", ErrorSeverity.ERROR),