diff --git a/tool/src/org/antlr/v4/parse/ANTLRLexer.g b/tool/src/org/antlr/v4/parse/ANTLRLexer.g index 975c8d21b..71e03573b 100644 --- a/tool/src/org/antlr/v4/parse/ANTLRLexer.g +++ b/tool/src/org/antlr/v4/parse/ANTLRLexer.g @@ -656,8 +656,11 @@ ESC_SEQ | // An illegal escape seqeunce // { - // TODO: Issue error message - // + Token t = new CommonToken(input, state.type, state.channel, getCharIndex()-1, getCharIndex()); + t.setText(t.getText()); + t.setLine(input.getLine()); + t.setCharPositionInLine(input.getCharPositionInLine()-1); + grammarError(ErrorType.INVALID_ESCAPE_SEQUENCE, t); } ) ; @@ -708,9 +711,12 @@ UNICODE_ESC // Now check the digit count and issue an error if we need to // { - if (hCount != 4) { - - // TODO: Issue error message + if (hCount != 4) { + Token t = new CommonToken(input, state.type, state.channel, getCharIndex()-3-hCount, getCharIndex()-1); + t.setText(t.getText()); + t.setLine(input.getLine()); + t.setCharPositionInLine(input.getCharPositionInLine()-hCount-2); + grammarError(ErrorType.INVALID_ESCAPE_SEQUENCE, t); } } ; diff --git a/tool/src/org/antlr/v4/tool/ErrorType.java b/tool/src/org/antlr/v4/tool/ErrorType.java index 451a03a41..f20f8f48c 100644 --- a/tool/src/org/antlr/v4/tool/ErrorType.java +++ b/tool/src/org/antlr/v4/tool/ErrorType.java @@ -809,6 +809,23 @@ public enum ErrorType { * @since 4.2 */ UNKNOWN_LEXER_CONSTANT(155, "rule '' contains a lexer command with an unrecognized constant value; lexer interpreters may produce incorrect output", ErrorSeverity.WARNING), + /** + * Compiler Error 156. + * + *

invalid escape sequence

+ * + *

The grammar contains a string literal with an invalid escape sequence.

+ * + *

The following rule produces this error.

+ * + *
+	 * x : 'x';  // ok
+	 * y : '\u005Cu'; // error 156
+	 * 
+ * + * @since 4.2.1 + */ + INVALID_ESCAPE_SEQUENCE(156, "invalid escape sequence", ErrorSeverity.ERROR), /* * Backward incompatibility errors diff --git a/tool/test/org/antlr/v4/test/TestToolSyntaxErrors.java b/tool/test/org/antlr/v4/test/TestToolSyntaxErrors.java index ee5b4e08b..ddf96d585 100644 --- a/tool/test/org/antlr/v4/test/TestToolSyntaxErrors.java +++ b/tool/test/org/antlr/v4/test/TestToolSyntaxErrors.java @@ -409,4 +409,46 @@ public class TestToolSyntaxErrors extends BaseTest { super.testErrors(pair, true); } + + /** + * This test ensures that the {@link ErrorType#INVALID_ESCAPE_SEQUENCE} + * error is not reported for escape sequences that are known to be valid. + */ + @Test public void testValidEscapeSequences() { + String grammar = + "lexer grammar A;\n" + + "NORMAL_ESCAPE : '\\b \\t \\n \\f \\r \\\" \\' \\\\';\n" + + "UNICODE_ESCAPE : '\\u0001 \\u00A1 \\u00a1 \\uaaaa \\uAAAA';\n"; + String expected = + ""; + + String[] pair = new String[] { + grammar, + expected + }; + + super.testErrors(pair, true); + } + + /** + * This is a regression test for antlr/antlr4#507 "NullPointerException When + * Generating Code from Grammar". + * https://github.com/antlr/antlr4/issues/507 + */ + @Test public void testInvalidEscapeSequences() { + String grammar = + "lexer grammar A;\n" + + "RULE : 'Foo \\uAABG \\x \\u';\n"; + String expected = + "error(" + ErrorType.INVALID_ESCAPE_SEQUENCE.code + "): A.g4:2:12: invalid escape sequence\n" + + "error(" + ErrorType.INVALID_ESCAPE_SEQUENCE.code + "): A.g4:2:19: invalid escape sequence\n" + + "error(" + ErrorType.INVALID_ESCAPE_SEQUENCE.code + "): A.g4:2:22: invalid escape sequence\n"; + + String[] pair = new String[] { + grammar, + expected + }; + + super.testErrors(pair, true); + } }