aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/parser/event_parser/grammar/attributes.rs42
-rw-r--r--src/parser/event_parser/grammar/expressions.rs5
-rw-r--r--src/parser/event_parser/grammar/items.rs33
-rw-r--r--src/parser/event_parser/grammar/mod.rs88
4 files changed, 85 insertions, 83 deletions
diff --git a/src/parser/event_parser/grammar/attributes.rs b/src/parser/event_parser/grammar/attributes.rs
new file mode 100644
index 000000000..c80f782ab
--- /dev/null
+++ b/src/parser/event_parser/grammar/attributes.rs
@@ -0,0 +1,42 @@
1use super::*;
2
3pub(super) fn inner_attributes(p: &mut Parser) {
4 many(p, |p| attribute(p, true))
5}
6
7pub(super) fn outer_attributes(_: &mut Parser) {
8}
9
10
11fn attribute(p: &mut Parser, inner: bool) -> bool {
12 let attr_start = inner && p.lookahead(&[POUND, EXCL, L_BRACK])
13 || !inner && p.lookahead(&[POUND, L_BRACK]);
14 if !attr_start {
15 return false;
16 }
17 node(p, ATTR, |p| {
18 p.bump_n(if inner { 3 } else { 2 });
19 meta_item(p) && p.expect(R_BRACK);
20 });
21 true
22}
23
24fn meta_item(p: &mut Parser) -> bool {
25 node_if(p, IDENT, META_ITEM, |p| {
26 if p.eat(EQ) {
27 if !expressions::literal(p) {
28 p.error()
29 .message("expected literal")
30 .emit();
31 }
32 } else if p.eat(L_PAREN) {
33 comma_list(p, R_PAREN, meta_item_inner);
34 p.expect(R_PAREN);
35 }
36 })
37}
38
39fn meta_item_inner(p: &mut Parser) -> bool {
40 meta_item(p) || expressions::literal(p)
41}
42
diff --git a/src/parser/event_parser/grammar/expressions.rs b/src/parser/event_parser/grammar/expressions.rs
new file mode 100644
index 000000000..9b43bdf2a
--- /dev/null
+++ b/src/parser/event_parser/grammar/expressions.rs
@@ -0,0 +1,5 @@
1use super::*;
2
3pub(super) fn literal(p: &mut Parser) -> bool {
4 p.eat(INT_NUMBER) || p.eat(FLOAT_NUMBER)
5} \ No newline at end of file
diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs
new file mode 100644
index 000000000..b9eb1934c
--- /dev/null
+++ b/src/parser/event_parser/grammar/items.rs
@@ -0,0 +1,33 @@
1use super::*;
2
3pub(super) fn item_first(p: &Parser) -> bool {
4 match p.current() {
5 STRUCT_KW | FN_KW => true,
6 _ => false,
7 }
8}
9
10pub(super) fn item(p: &mut Parser) {
11 attributes::outer_attributes(p);
12 visibility(p);
13 node_if(p, STRUCT_KW, STRUCT_ITEM, struct_item)
14 || node_if(p, FN_KW, FN_ITEM, fn_item);
15}
16
17fn struct_item(p: &mut Parser) {
18 p.expect(IDENT)
19 && p.curly_block(|p| comma_list(p, EOF, struct_field));
20}
21
22fn struct_field(p: &mut Parser) -> bool {
23 node_if(p, IDENT, STRUCT_FIELD, |p| {
24 p.expect(COLON) && p.expect(IDENT);
25 })
26}
27
28fn fn_item(p: &mut Parser) {
29 p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN)
30 && p.curly_block(|p| ());
31}
32
33
diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs
index acf27aec9..b67ceeb13 100644
--- a/src/parser/event_parser/grammar/mod.rs
+++ b/src/parser/event_parser/grammar/mod.rs
@@ -3,104 +3,26 @@ use {SyntaxKind};
3use tree::EOF; 3use tree::EOF;
4use syntax_kinds::*; 4use syntax_kinds::*;
5 5
6// Items // 6mod items;
7mod attributes;
8mod expressions;
7 9
8pub(crate) fn file(p: &mut Parser) { 10pub(crate) fn file(p: &mut Parser) {
9 node(p, FILE, |p| { 11 node(p, FILE, |p| {
10 p.optional(SHEBANG); 12 p.optional(SHEBANG);
11 inner_attributes(p); 13 attributes::inner_attributes(p);
12 many(p, |p| { 14 many(p, |p| {
13 skip_to_first( 15 skip_to_first(
14 p, item_first, item, 16 p, items::item_first, items::item,
15 "expected item", 17 "expected item",
16 ) 18 )
17 }); 19 });
18 }) 20 })
19} 21}
20 22
21fn item_first(p: &Parser) -> bool {
22 match p.current() {
23 STRUCT_KW | FN_KW => true,
24 _ => false,
25 }
26}
27
28fn item(p: &mut Parser) {
29 outer_attributes(p);
30 visibility(p);
31 node_if(p, STRUCT_KW, STRUCT_ITEM, struct_item)
32 || node_if(p, FN_KW, FN_ITEM, fn_item);
33}
34
35fn struct_item(p: &mut Parser) {
36 p.expect(IDENT)
37 && p.curly_block(|p| comma_list(p, EOF, struct_field));
38}
39
40fn struct_field(p: &mut Parser) -> bool {
41 node_if(p, IDENT, STRUCT_FIELD, |p| {
42 p.expect(COLON) && p.expect(IDENT);
43 })
44}
45
46fn fn_item(p: &mut Parser) {
47 p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN)
48 && p.curly_block(|p| ());
49}
50
51
52// Paths, types, attributes, and stuff //
53
54fn inner_attributes(p: &mut Parser) {
55 many(p, |p| attribute(p, true))
56}
57
58fn attribute(p: &mut Parser, inner: bool) -> bool {
59 let attr_start = inner && p.lookahead(&[POUND, EXCL, L_BRACK])
60 || !inner && p.lookahead(&[POUND, L_BRACK]);
61 if !attr_start {
62 return false;
63 }
64 node(p, ATTR, |p| {
65 p.bump_n(if inner { 3 } else { 2 });
66 meta_item(p) && p.expect(R_BRACK);
67 });
68 true
69}
70
71fn meta_item(p: &mut Parser) -> bool {
72 node_if(p, IDENT, META_ITEM, |p| {
73 if p.eat(EQ) {
74 if !literal(p) {
75 p.error()
76 .message("expected literal")
77 .emit();
78 }
79 } else if p.eat(L_PAREN) {
80 comma_list(p, R_PAREN, meta_item_inner);
81 p.expect(R_PAREN);
82 }
83 })
84}
85
86fn meta_item_inner(p: &mut Parser) -> bool {
87 meta_item(p) || literal(p)
88}
89
90fn literal(p: &mut Parser) -> bool {
91 p.eat(INT_NUMBER) || p.eat(FLOAT_NUMBER)
92}
93
94fn outer_attributes(_: &mut Parser) {
95}
96
97fn visibility(_: &mut Parser) { 23fn visibility(_: &mut Parser) {
98} 24}
99 25
100// Expressions //
101
102// Error recovery and high-order utils //
103
104fn node_if<F: FnOnce(&mut Parser)>( 26fn node_if<F: FnOnce(&mut Parser)>(
105 p: &mut Parser, 27 p: &mut Parser,
106 first: SyntaxKind, 28 first: SyntaxKind,