aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcushon <cushon@google.com>2018-10-10 17:11:56 -0700
committerLiam Miller-Cushon <cushon@google.com>2018-10-17 20:45:30 -0700
commit74070a25d15bd74e71fac5a8392d39cdaa9a953e (patch)
tree8196c712edfbd5bd89282e545b086aa72196056a
parentb767eadd89c6c94f75d3ffeb49850665a712fe9b (diff)
downloadturbine-74070a25d15bd74e71fac5a8392d39cdaa9a953e.tar.gz
Improve diagnostics for empty and unterminated char literals
MOE_MIGRATED_REVID=216620223
-rw-r--r--java/com/google/turbine/diag/TurbineError.java2
-rw-r--r--java/com/google/turbine/parse/StreamLexer.java18
-rw-r--r--javatests/com/google/turbine/parse/ParseErrorTest.java32
3 files changed, 45 insertions, 7 deletions
diff --git a/java/com/google/turbine/diag/TurbineError.java b/java/com/google/turbine/diag/TurbineError.java
index 01c6c48..f9ddcd5 100644
--- a/java/com/google/turbine/diag/TurbineError.java
+++ b/java/com/google/turbine/diag/TurbineError.java
@@ -34,6 +34,8 @@ public class TurbineError extends Error {
UNEXPECTED_IDENTIFIER("unexpected identifier '%s'"),
UNEXPECTED_EOF("unexpected end of input"),
UNTERMINATED_STRING("unterminated string literal"),
+ UNTERMINATED_CHARACTER_LITERAL("unterminated char literal"),
+ EMPTY_CHARACTER_LITERAL("empty char literal"),
EXPECTED_TOKEN("expected token %s"),
INVALID_LITERAL("invalid literal: %s"),
UNEXPECTED_TYPE_PARAMETER("unexpected type parameter %s"),
diff --git a/java/com/google/turbine/parse/StreamLexer.java b/java/com/google/turbine/parse/StreamLexer.java
index c108332..74b0ce8 100644
--- a/java/com/google/turbine/parse/StreamLexer.java
+++ b/java/com/google/turbine/parse/StreamLexer.java
@@ -339,19 +339,23 @@ public class StreamLexer implements Lexer {
{
eat();
char value;
- if (ch == '\\') {
- eat();
- value = escape();
- } else {
- value = ch;
- eat();
+ switch (ch) {
+ case '\\':
+ eat();
+ value = escape();
+ break;
+ case '\'':
+ throw error(ErrorKind.EMPTY_CHARACTER_LITERAL);
+ default:
+ value = ch;
+ eat();
}
if (ch == '\'') {
saveValue(String.valueOf(value));
eat();
return Token.CHAR_LITERAL;
}
- throw error(ErrorKind.UNEXPECTED_INPUT, ch);
+ throw error(ErrorKind.UNTERMINATED_CHARACTER_LITERAL);
}
case '"':
diff --git a/javatests/com/google/turbine/parse/ParseErrorTest.java b/javatests/com/google/turbine/parse/ParseErrorTest.java
index 30ff061..53864ef 100644
--- a/javatests/com/google/turbine/parse/ParseErrorTest.java
+++ b/javatests/com/google/turbine/parse/ParseErrorTest.java
@@ -170,6 +170,38 @@ public class ParseErrorTest {
}
}
+ @Test
+ public void emptyChar() {
+ String input = "class T { char c = ''; }";
+ try {
+ Parser.parse(input);
+ fail("expected parsing to fail");
+ } catch (TurbineError e) {
+ assertThat(e.getMessage())
+ .isEqualTo(
+ lines(
+ "<>:1: error: empty char literal", //
+ "class T { char c = ''; }",
+ " ^"));
+ }
+ }
+
+ @Test
+ public void unterminatedChar() {
+ String input = "class T { char c = '; }";
+ try {
+ Parser.parse(input);
+ fail("expected parsing to fail");
+ } catch (TurbineError e) {
+ assertThat(e.getMessage())
+ .isEqualTo(
+ lines(
+ "<>:1: error: unterminated char literal", //
+ "class T { char c = '; }",
+ " ^"));
+ }
+ }
+
private static String lines(String... lines) {
return Joiner.on(System.lineSeparator()).join(lines);
}