aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-01-28 17:48:37 +0000
committerAleksey Kladov <[email protected]>2018-01-28 17:53:01 +0000
commitd1d47e62445806a7ecfb747989d2cb34989d5d51 (patch)
treec47d0cef58945190e9e5dcf40317450cfe0db797
parent4adf0c20b71f8eb6365893cb1739b1cd33b081cc (diff)
Skip over balanced parens
-rw-r--r--src/parser/event_parser/grammar/items.rs5
-rw-r--r--src/parser/event_parser/grammar/mod.rs17
-rw-r--r--tests/data/parser/err/0008_item_block_recovery.rs13
-rw-r--r--tests/data/parser/err/0008_item_block_recovery.txt61
4 files changed, 96 insertions, 0 deletions
diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs
index 309e4f4de..56e3208ac 100644
--- a/src/parser/event_parser/grammar/items.rs
+++ b/src/parser/event_parser/grammar/items.rs
@@ -36,6 +36,11 @@ fn item(p: &mut Parser) {
36 fn_item(p); 36 fn_item(p);
37 FN_ITEM 37 FN_ITEM
38 } 38 }
39 L_CURLY => {
40 item.abandon(p);
41 error_block(p, "expected item");
42 return;
43 }
39 err_token => { 44 err_token => {
40 item.abandon(p); 45 item.abandon(p);
41 let message = if err_token == SEMI { 46 let message = if err_token == SEMI {
diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs
index 92125acd1..e7f1915d2 100644
--- a/src/parser/event_parser/grammar/mod.rs
+++ b/src/parser/event_parser/grammar/mod.rs
@@ -49,6 +49,23 @@ fn alias(p: &mut Parser) -> bool {
49 true //FIXME: return false if three are errors 49 true //FIXME: return false if three are errors
50} 50}
51 51
52fn error_block(p: &mut Parser, message: &str) {
53 assert!(p.at(L_CURLY));
54 let err = p.start();
55 p.error().message(message).emit();
56 p.bump();
57 let mut level: u32 = 1;
58 while level > 0 && !p.at(EOF) {
59 match p.current() {
60 L_CURLY => level += 1,
61 R_CURLY => level -= 1,
62 _ => (),
63 }
64 p.bump();
65 }
66 err.complete(p, ERROR);
67}
68
52impl<'p> Parser<'p> { 69impl<'p> Parser<'p> {
53 fn at<L: Lookahead>(&self, l: L) -> bool { 70 fn at<L: Lookahead>(&self, l: L) -> bool {
54 l.is_ahead(self) 71 l.is_ahead(self)
diff --git a/tests/data/parser/err/0008_item_block_recovery.rs b/tests/data/parser/err/0008_item_block_recovery.rs
new file mode 100644
index 000000000..9fcac19b5
--- /dev/null
+++ b/tests/data/parser/err/0008_item_block_recovery.rs
@@ -0,0 +1,13 @@
1fn foo() {
2}
3
4bar() {
5 if true {
6 1
7 } else {
8 2 + 3
9 }
10}
11
12fn baz() {
13}
diff --git a/tests/data/parser/err/0008_item_block_recovery.txt b/tests/data/parser/err/0008_item_block_recovery.txt
new file mode 100644
index 000000000..4bb66f56a
--- /dev/null
+++ b/tests/data/parser/err/0008_item_block_recovery.txt
@@ -0,0 +1,61 @@
1FILE@[0; 95)
2 FN_ITEM@[0; 14)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 IDENT@[3; 6)
6 L_PAREN@[6; 7)
7 R_PAREN@[7; 8)
8 WHITESPACE@[8; 9)
9 L_CURLY@[9; 10)
10 WHITESPACE@[10; 11)
11 R_CURLY@[11; 12)
12 WHITESPACE@[12; 14)
13 ERROR@[14; 17)
14 err: `expected item`
15 IDENT@[14; 17)
16 ERROR@[17; 18)
17 err: `expected item`
18 L_PAREN@[17; 18)
19 ERROR@[18; 20)
20 err: `expected item`
21 R_PAREN@[18; 19)
22 WHITESPACE@[19; 20)
23 ERROR@[20; 82)
24 err: `expected item`
25 L_CURLY@[20; 21)
26 WHITESPACE@[21; 26)
27 IDENT@[26; 28)
28 WHITESPACE@[28; 29)
29 TRUE_KW@[29; 33)
30 WHITESPACE@[33; 34)
31 L_CURLY@[34; 35)
32 WHITESPACE@[35; 44)
33 INT_NUMBER@[44; 45)
34 WHITESPACE@[45; 50)
35 R_CURLY@[50; 51)
36 WHITESPACE@[51; 52)
37 IDENT@[52; 56)
38 WHITESPACE@[56; 57)
39 L_CURLY@[57; 58)
40 WHITESPACE@[58; 67)
41 INT_NUMBER@[67; 68)
42 WHITESPACE@[68; 69)
43 PLUS@[69; 70)
44 WHITESPACE@[70; 71)
45 INT_NUMBER@[71; 72)
46 WHITESPACE@[72; 77)
47 R_CURLY@[77; 78)
48 WHITESPACE@[78; 79)
49 R_CURLY@[79; 80)
50 WHITESPACE@[80; 82)
51 FN_ITEM@[82; 95)
52 FN_KW@[82; 84)
53 WHITESPACE@[84; 85)
54 IDENT@[85; 88)
55 L_PAREN@[88; 89)
56 R_PAREN@[89; 90)
57 WHITESPACE@[90; 91)
58 L_CURLY@[91; 92)
59 WHITESPACE@[92; 93)
60 R_CURLY@[93; 94)
61 WHITESPACE@[94; 95)