diff options
author | Aleksey Kladov <[email protected]> | 2018-01-28 17:48:37 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-01-28 17:53:01 +0000 |
commit | d1d47e62445806a7ecfb747989d2cb34989d5d51 (patch) | |
tree | c47d0cef58945190e9e5dcf40317450cfe0db797 | |
parent | 4adf0c20b71f8eb6365893cb1739b1cd33b081cc (diff) |
Skip over balanced parens
-rw-r--r-- | src/parser/event_parser/grammar/items.rs | 5 | ||||
-rw-r--r-- | src/parser/event_parser/grammar/mod.rs | 17 | ||||
-rw-r--r-- | tests/data/parser/err/0008_item_block_recovery.rs | 13 | ||||
-rw-r--r-- | tests/data/parser/err/0008_item_block_recovery.txt | 61 |
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 | ||
52 | fn 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 | |||
52 | impl<'p> Parser<'p> { | 69 | impl<'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 @@ | |||
1 | fn foo() { | ||
2 | } | ||
3 | |||
4 | bar() { | ||
5 | if true { | ||
6 | 1 | ||
7 | } else { | ||
8 | 2 + 3 | ||
9 | } | ||
10 | } | ||
11 | |||
12 | fn 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 @@ | |||
1 | FILE@[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) | ||