From b61617f752668d1425133d0bf32d62dd1135c66a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 8 Jan 2018 21:57:19 +0300 Subject: [PATCH] G: special-case C++ semicolon --- src/parser/event_parser/grammar/items.rs | 29 ++++++++++++++++++-- src/parser/event_parser/grammar/mod.rs | 7 +---- tests/data/parser/err/0003_C++_semicolon.rs | 4 +++ tests/data/parser/err/0003_C++_semicolon.txt | 27 ++++++++++++++++++ 4 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 tests/data/parser/err/0003_C++_semicolon.rs create mode 100644 tests/data/parser/err/0003_C++_semicolon.txt diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs index b9eb1934c5..631eb47364 100644 --- a/src/parser/event_parser/grammar/items.rs +++ b/src/parser/event_parser/grammar/items.rs @@ -1,17 +1,40 @@ use super::*; -pub(super) fn item_first(p: &Parser) -> bool { +pub(super) fn mod_items(p: &mut Parser) { + many(p, |p| { + skip_to_first( + p, item_first, mod_item, + "expected item", + ) + }); +} + +fn item_first(p: &Parser) -> bool { match p.current() { STRUCT_KW | FN_KW => true, _ => false, } } -pub(super) fn item(p: &mut Parser) { +fn mod_item(p: &mut Parser) { + if item(p) { + if p.current() == SEMI { + node(p, ERROR, |p| { + p.error() + .message("expected item, found `;`\n\ + consider removing this semicolon") + .emit(); + p.bump(); + }) + } + } +} + +fn item(p: &mut Parser) -> bool { attributes::outer_attributes(p); visibility(p); node_if(p, STRUCT_KW, STRUCT_ITEM, struct_item) - || node_if(p, FN_KW, FN_ITEM, fn_item); + || node_if(p, FN_KW, FN_ITEM, fn_item) } fn struct_item(p: &mut Parser) { diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs index b67ceeb138..274c2cdb46 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) { node(p, FILE, |p| { p.optional(SHEBANG); attributes::inner_attributes(p); - many(p, |p| { - skip_to_first( - p, items::item_first, items::item, - "expected item", - ) - }); + items::mod_items(p); }) } 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 0000000000..009312270f --- /dev/null +++ b/tests/data/parser/err/0003_C++_semicolon.rs @@ -0,0 +1,4 @@ +struct S { + a: i32, + b: String, +}; \ 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 0000000000..9308bb3305 --- /dev/null +++ b/tests/data/parser/err/0003_C++_semicolon.txt @@ -0,0 +1,27 @@ +FILE@[0; 40) + STRUCT_ITEM@[0; 39) + STRUCT_KW@[0; 6) + WHITESPACE@[6; 7) + IDENT@[7; 8) + WHITESPACE@[8; 9) + L_CURLY@[9; 10) + STRUCT_FIELD@[10; 21) + WHITESPACE@[10; 15) + IDENT@[15; 16) + COLON@[16; 17) + WHITESPACE@[17; 18) + IDENT@[18; 21) + COMMA@[21; 22) + STRUCT_FIELD@[22; 36) + WHITESPACE@[22; 27) + IDENT@[27; 28) + COLON@[28; 29) + WHITESPACE@[29; 30) + IDENT@[30; 36) + COMMA@[36; 37) + WHITESPACE@[37; 38) + R_CURLY@[38; 39) + ERROR@[39; 40) + err: `expected item, found `;` +consider removing this semicolon` + SEMI@[39; 40)