refactor: move newline handling from lexer into parser grammar rules

This change shifts newline tokenization from the lexer's readRawToken into the parser's nextToken, allowing the grammar to selectively ignore newlines in specific contexts (e.g., after operators like "|", "is", "for", "if", "while") while treating them as errors in others (e.g., after "var", "new", "class", "static", before commas in lists). The lexer now emits TOKEN_LINE for semicolons and newlines uniformly, and the parser decides which to elide. Test files are updated to reflect the new error expectations and to remove tests for newlines that are now grammatically allowed.
This commit is contained in:
Bob Nystrom
2014-04-04 14:51:18 +00:00
parent a1365c4183
commit 093da7befb
23 changed files with 151 additions and 165 deletions
+2
View File
@@ -0,0 +1,2 @@
class // expect error
Foo {}
+6
View File
@@ -0,0 +1,6 @@
class Foo {
static // expect error
method {} // expect error
}
// The second error is cascaded.
+1 -1
View File
@@ -1 +1 @@
true ? 1 : // expect error
(true ? 1 :) // expect error
+1 -1
View File
@@ -1 +1 @@
true ? : 2 // expect error
(true ? : 2) // expect error
+7
View File
@@ -0,0 +1,7 @@
// Newline after '?'.
IO.print(true ?
"yes" : "no") // expect: yes
// Newline after ':'.
IO.print(false ? "yes" :
"no") // expect: no
-20
View File
@@ -1,20 +0,0 @@
// Single-expression body.
for (i in [1, 2, 3]) IO.print(i)
// expect: 1
// expect: 2
// expect: 3
// Block body.
for (i in [1, 2, 3]) {
IO.print(i)
}
// expect: 1
// expect: 2
// expect: 3
// Newline after "for".
for
(i in [1, 2, 3]) IO.print(i)
// expect: 1
// expect: 2
// expect: 3
+2
View File
@@ -0,0 +1,2 @@
for // expect error
(i in [1, 2, 3]) IO.print(i)
+2
View File
@@ -0,0 +1,2 @@
for (i // expect error
in [1]) IO.print(i)
+6 -12
View File
@@ -1,20 +1,14 @@
// Single-expression body.
for (i in [1, 2, 3]) IO.print(i)
for (i in [1]) IO.print(i)
// expect: 1
// expect: 2
// expect: 3
// Block body.
for (i in [1, 2, 3]) {
for (i in [1]) {
IO.print(i)
}
// expect: 1
// expect: 2
// expect: 3
// Newline after "for".
for
(i in [1, 2, 3]) IO.print(i)
// expect: 1
// expect: 2
// expect: 3
// Newline after "in".
for (i in
[1]) IO.print(i)
// expect: 1
+1 -1
View File
@@ -1,2 +1,2 @@
new Fn {
IO.print("ok") }.call // expect error
IO.print("ok") } // expect error
-4
View File
@@ -4,7 +4,3 @@ if (false) IO.print("bad") else IO.print("good") // expect: good
// Allow block body.
if (false) null else { IO.print("block") } // expect: block
// Newline after "else".
if (false) IO.print("bad") else
IO.print("good") // expect: good
-4
View File
@@ -8,7 +8,3 @@ if (true) { IO.print("block") } // expect: block
// Assignment in if condition.
var a = false
if (a = true) IO.print(a) // expect: true
// Newline after "if".
if
(true) IO.print("good") // expect: good
+1
View File
@@ -0,0 +1 @@
if (true) "ok" else // expect error
+2
View File
@@ -0,0 +1,2 @@
if // expect error
(true) IO.print("bad")
+4
View File
@@ -30,3 +30,7 @@ IO.print(123 is Class) // expect: false
// TODO: Non-class on RHS.
// TODO: Precedence and associativity.
// Ignore newline after "is".
IO.print(123 is
Num) // expect: true
+2
View File
@@ -0,0 +1,2 @@
var list = ["a"
, "b"] // expect error
+3 -7
View File
@@ -1,14 +1,10 @@
// Allow newlines in most places.
// Allow after '[' and ',', and before ']'.
var list = [
"a"
, "b",
"c", "d"
"a",
"b"
]
IO.print(list[0]) // expect: a
IO.print(list[1]) // expect: b
IO.print(list[2]) // expect: c
IO.print(list[3]) // expect: d
+2
View File
@@ -0,0 +1,2 @@
new // expect error
Fn {}
+2
View File
@@ -0,0 +1,2 @@
var // expect error
foo = 123
+2
View File
@@ -0,0 +1,2 @@
while // expect error
(true) IO.print("bad")
-8
View File
@@ -14,11 +14,3 @@ while (a < 3) {
// expect: 0
// expect: 1
// expect: 2
// Newline after "while".
var d = 0
while
(d < 3) IO.print(d = d + 1)
// expect: 1
// expect: 2
// expect: 3