aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-01-08 18:57:19 +0000
committerAleksey Kladov <[email protected]>2018-01-08 18:57:19 +0000
commitb61617f752668d1425133d0bf32d62dd1135c66a (patch)
treefcebd2559edc831d0f9d375d90e85a4252b4c6fd
parentea186fe2c073dfd56f834068ee928a9c875b0279 (diff)
G: special-case C++ semicolon
-rw-r--r--src/parser/event_parser/grammar/items.rs29
-rw-r--r--src/parser/event_parser/grammar/mod.rs7
-rw-r--r--tests/data/parser/err/0003_C++_semicolon.rs4
-rw-r--r--tests/data/parser/err/0003_C++_semicolon.txt27
4 files changed, 58 insertions, 9 deletions
diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs
index b9eb1934c..631eb4736 100644
--- a/src/parser/event_parser/grammar/items.rs
+++ b/src/parser/event_parser/grammar/items.rs
@@ -1,17 +1,40 @@
1use super::*; 1use super::*;
2 2
3pub(super) fn item_first(p: &Parser) -> bool { 3pub(super) fn mod_items(p: &mut Parser) {
4 many(p, |p| {
5 skip_to_first(
6 p, item_first, mod_item,
7 "expected item",
8 )
9 });
10}
11
12fn item_first(p: &Parser) -> bool {
4 match p.current() { 13 match p.current() {
5 STRUCT_KW | FN_KW => true, 14 STRUCT_KW | FN_KW => true,
6 _ => false, 15 _ => false,
7 } 16 }
8} 17}
9 18
10pub(super) fn item(p: &mut Parser) { 19fn mod_item(p: &mut Parser) {
20 if item(p) {
21 if p.current() == SEMI {
22 node(p, ERROR, |p| {
23 p.error()
24 .message("expected item, found `;`\n\
25 consider removing this semicolon")
26 .emit();
27 p.bump();
28 })
29 }
30 }
31}
32
33fn item(p: &mut Parser) -> bool {
11 attributes::outer_attributes(p); 34 attributes::outer_attributes(p);
12 visibility(p); 35 visibility(p);
13 node_if(p, STRUCT_KW, STRUCT_ITEM, struct_item) 36 node_if(p, STRUCT_KW, STRUCT_ITEM, struct_item)
14 || node_if(p, FN_KW, FN_ITEM, fn_item); 37 || node_if(p, FN_KW, FN_ITEM, fn_item)
15} 38}
16 39
17fn struct_item(p: &mut Parser) { 40fn struct_item(p: &mut Parser) {
diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs
index b67ceeb13..274c2cdb4 100644
--- a/src/parser/event_parser/grammar/mod.rs
+++ b/src/parser/event_parser/grammar/mod.rs
@@ -11,12 +11,7 @@ pub(crate) fn file(p: &mut Parser) {
11 node(p, FILE, |p| { 11 node(p, FILE, |p| {
12 p.optional(SHEBANG); 12 p.optional(SHEBANG);
13 attributes::inner_attributes(p); 13 attributes::inner_attributes(p);
14 many(p, |p| { 14 items::mod_items(p);
15 skip_to_first(
16 p, items::item_first, items::item,
17 "expected item",
18 )
19 });
20 }) 15 })
21} 16}
22 17
diff --git a/tests/data/parser/err/0003_C++_semicolon.rs b/tests/data/parser/err/0003_C++_semicolon.rs
new file mode 100644
index 000000000..009312270
--- /dev/null
+++ b/tests/data/parser/err/0003_C++_semicolon.rs
@@ -0,0 +1,4 @@
1struct S {
2 a: i32,
3 b: String,
4}; \ No newline at end of file
diff --git a/tests/data/parser/err/0003_C++_semicolon.txt b/tests/data/parser/err/0003_C++_semicolon.txt
new file mode 100644
index 000000000..9308bb330
--- /dev/null
+++ b/tests/data/parser/err/0003_C++_semicolon.txt
@@ -0,0 +1,27 @@
1FILE@[0; 40)
2 STRUCT_ITEM@[0; 39)
3 STRUCT_KW@[0; 6)
4 WHITESPACE@[6; 7)
5 IDENT@[7; 8)
6 WHITESPACE@[8; 9)
7 L_CURLY@[9; 10)
8 STRUCT_FIELD@[10; 21)
9 WHITESPACE@[10; 15)
10 IDENT@[15; 16)
11 COLON@[16; 17)
12 WHITESPACE@[17; 18)
13 IDENT@[18; 21)
14 COMMA@[21; 22)
15 STRUCT_FIELD@[22; 36)
16 WHITESPACE@[22; 27)
17 IDENT@[27; 28)
18 COLON@[28; 29)
19 WHITESPACE@[29; 30)
20 IDENT@[30; 36)
21 COMMA@[36; 37)
22 WHITESPACE@[37; 38)
23 R_CURLY@[38; 39)
24 ERROR@[39; 40)
25 err: `expected item, found `;`
26consider removing this semicolon`
27 SEMI@[39; 40)