aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/grammar.ron2
-rw-r--r--src/grammar/items/mod.rs78
-rw-r--r--src/grammar/items/traits.rs2
-rw-r--r--src/syntax_kinds/generated.rs4
4 files changed, 77 insertions, 9 deletions
diff --git a/src/grammar.ron b/src/grammar.ron
index 9f80b3ebf..0a79eeb95 100644
--- a/src/grammar.ron
+++ b/src/grammar.ron
@@ -109,6 +109,8 @@ Grammar(
109 "TRAIT_ITEM", 109 "TRAIT_ITEM",
110 "IMPL_ITEM", 110 "IMPL_ITEM",
111 "TYPE_ITEM", 111 "TYPE_ITEM",
112 "MACRO_CALL",
113 "TOKEN_TREE",
112 114
113 "PAREN_TYPE", 115 "PAREN_TYPE",
114 "TUPLE_TYPE", 116 "TUPLE_TYPE",
diff --git a/src/grammar/items/mod.rs b/src/grammar/items/mod.rs
index 1ed0aea07..8f766901e 100644
--- a/src/grammar/items/mod.rs
+++ b/src/grammar/items/mod.rs
@@ -5,27 +5,43 @@ mod structs;
5mod traits; 5mod traits;
6mod use_item; 6mod use_item;
7 7
8// test mod_contents
9// fn foo() {}
10// macro_rules! foo {}
11// foo::bar!();
12// super::baz! {}
13// struct S;
8pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { 14pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
9 attributes::inner_attributes(p); 15 attributes::inner_attributes(p);
10 while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { 16 while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) {
11 item(p, stop_on_r_curly) 17 item_or_macro(p, stop_on_r_curly)
12 } 18 }
13} 19}
14 20
15pub(super) fn item(p: &mut Parser, stop_on_r_curly: bool) { 21pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool) {
16 let m = p.start(); 22 let m = p.start();
17 match maybe_item(p) { 23 match maybe_item(p) {
18 MaybeItem::Item(kind) => { 24 MaybeItem::Item(kind) => {
19 m.complete(p, kind); 25 m.complete(p, kind);
20 } 26 }
21 MaybeItem::None => { 27 MaybeItem::None => {
22 m.abandon(p); 28 if paths::is_path_start(p) {
23 if p.at(L_CURLY) { 29 match macro_call(p) {
24 error_block(p, "expected an item"); 30 MacroFlavor::Curly => (),
25 } else if !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { 31 MacroFlavor::NonCurly => {
26 p.err_and_bump("expected an item"); 32 p.expect(SEMI);
33 }
34 }
35 m.complete(p, MACRO_CALL);
27 } else { 36 } else {
28 p.error("expected an item"); 37 m.abandon(p);
38 if p.at(L_CURLY) {
39 error_block(p, "expected an item");
40 } else if !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) {
41 p.err_and_bump("expected an item");
42 } else {
43 p.error("expected an item");
44 }
29 } 45 }
30 } 46 }
31 MaybeItem::Modifiers => { 47 MaybeItem::Modifiers => {
@@ -260,3 +276,49 @@ fn mod_item(p: &mut Parser) {
260 } 276 }
261 } 277 }
262} 278}
279
280enum MacroFlavor {
281 Curly,
282 NonCurly,
283}
284
285fn macro_call(p: &mut Parser) -> MacroFlavor {
286 assert!(paths::is_path_start(p));
287 paths::use_path(p);
288 p.expect(EXCL);
289 p.eat(IDENT);
290 let flavor = match p.current() {
291 L_CURLY => {
292 token_tree(p);
293 MacroFlavor::Curly
294 }
295 L_PAREN | L_BRACK => {
296 token_tree(p);
297 MacroFlavor::NonCurly
298 }
299 _ => {
300 p.error("expected `{`, `[`, `(`");
301 MacroFlavor::NonCurly
302 },
303 };
304
305 flavor
306}
307
308fn token_tree(p: &mut Parser) {
309 let closing_paren_kind = match p.current() {
310 L_CURLY => R_CURLY,
311 L_PAREN => R_PAREN,
312 L_BRACK => R_BRACK,
313 _ => unreachable!(),
314 };
315 p.bump();
316 while !p.at(EOF) && !p.at(closing_paren_kind) {
317 match p.current() {
318 L_CURLY | L_PAREN | L_BRACK => token_tree(p),
319 R_CURLY | R_PAREN | R_BRACK => p.err_and_bump("unmatched brace"),
320 _ => p.bump()
321 }
322 };
323 p.expect(closing_paren_kind);
324}
diff --git a/src/grammar/items/traits.rs b/src/grammar/items/traits.rs
index 0614e8ab6..7c0935371 100644
--- a/src/grammar/items/traits.rs
+++ b/src/grammar/items/traits.rs
@@ -45,7 +45,7 @@ pub(super) fn impl_item(p: &mut Parser) {
45 // fn bar(&self) {} 45 // fn bar(&self) {}
46 // } 46 // }
47 while !p.at(EOF) && !p.at(R_CURLY) { 47 while !p.at(EOF) && !p.at(R_CURLY) {
48 item(p, true); 48 item_or_macro(p, true);
49 } 49 }
50 p.expect(R_CURLY); 50 p.expect(R_CURLY);
51} 51}
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs
index 1d3d3b9c1..8ac13fd63 100644
--- a/src/syntax_kinds/generated.rs
+++ b/src/syntax_kinds/generated.rs
@@ -103,6 +103,8 @@ pub enum SyntaxKind {
103 TRAIT_ITEM, 103 TRAIT_ITEM,
104 IMPL_ITEM, 104 IMPL_ITEM,
105 TYPE_ITEM, 105 TYPE_ITEM,
106 MACRO_CALL,
107 TOKEN_TREE,
106 PAREN_TYPE, 108 PAREN_TYPE,
107 TUPLE_TYPE, 109 TUPLE_TYPE,
108 NEVER_TYPE, 110 NEVER_TYPE,
@@ -322,6 +324,8 @@ impl SyntaxKind {
322 TRAIT_ITEM => &SyntaxInfo { name: "TRAIT_ITEM" }, 324 TRAIT_ITEM => &SyntaxInfo { name: "TRAIT_ITEM" },
323 IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" }, 325 IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" },
324 TYPE_ITEM => &SyntaxInfo { name: "TYPE_ITEM" }, 326 TYPE_ITEM => &SyntaxInfo { name: "TYPE_ITEM" },
327 MACRO_CALL => &SyntaxInfo { name: "MACRO_CALL" },
328 TOKEN_TREE => &SyntaxInfo { name: "TOKEN_TREE" },
325 PAREN_TYPE => &SyntaxInfo { name: "PAREN_TYPE" }, 329 PAREN_TYPE => &SyntaxInfo { name: "PAREN_TYPE" },
326 TUPLE_TYPE => &SyntaxInfo { name: "TUPLE_TYPE" }, 330 TUPLE_TYPE => &SyntaxInfo { name: "TUPLE_TYPE" },
327 NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" }, 331 NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" },