aboutsummaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/event_parser/grammar.rs52
1 files changed, 43 insertions, 9 deletions
diff --git a/src/parser/event_parser/grammar.rs b/src/parser/event_parser/grammar.rs
index 64c6718cb..acf27aec9 100644
--- a/src/parser/event_parser/grammar.rs
+++ b/src/parser/event_parser/grammar.rs
@@ -34,7 +34,7 @@ fn item(p: &mut Parser) {
34 34
35fn struct_item(p: &mut Parser) { 35fn struct_item(p: &mut Parser) {
36 p.expect(IDENT) 36 p.expect(IDENT)
37 && p.curly_block(|p| comma_list(p, struct_field)); 37 && p.curly_block(|p| comma_list(p, EOF, struct_field));
38} 38}
39 39
40fn struct_field(p: &mut Parser) -> bool { 40fn struct_field(p: &mut Parser) -> bool {
@@ -52,19 +52,45 @@ fn fn_item(p: &mut Parser) {
52// Paths, types, attributes, and stuff // 52// Paths, types, attributes, and stuff //
53 53
54fn inner_attributes(p: &mut Parser) { 54fn inner_attributes(p: &mut Parser) {
55 many(p, inner_attribute) 55 many(p, |p| attribute(p, true))
56} 56}
57 57
58fn inner_attribute(p: &mut Parser) -> bool { 58fn attribute(p: &mut Parser, inner: bool) -> bool {
59 if !(p.lookahead(&[EXCL, POUND])) { 59 let attr_start = inner && p.lookahead(&[POUND, EXCL, L_BRACK])
60 || !inner && p.lookahead(&[POUND, L_BRACK]);
61 if !attr_start {
60 return false; 62 return false;
61 } 63 }
62 node(p, ATTR, |p| { 64 node(p, ATTR, |p| {
63 p.bump_n(2); 65 p.bump_n(if inner { 3 } else { 2 });
66 meta_item(p) && p.expect(R_BRACK);
64 }); 67 });
65 true 68 true
66} 69}
67 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
68fn outer_attributes(_: &mut Parser) { 94fn outer_attributes(_: &mut Parser) {
69} 95}
70 96
@@ -75,7 +101,12 @@ fn visibility(_: &mut Parser) {
75 101
76// Error recovery and high-order utils // 102// Error recovery and high-order utils //
77 103
78fn node_if<F: FnOnce(&mut Parser)>(p: &mut Parser, first: SyntaxKind, node_kind: SyntaxKind, rest: F) -> bool { 104fn node_if<F: FnOnce(&mut Parser)>(
105 p: &mut Parser,
106 first: SyntaxKind,
107 node_kind: SyntaxKind,
108 rest: F
109) -> bool {
79 p.current() == first && { node(p, node_kind, |p| { p.bump(); rest(p); }); true } 110 p.current() == first && { node(p, node_kind, |p| { p.bump(); rest(p); }); true }
80} 111}
81 112
@@ -89,10 +120,9 @@ fn many<F: Fn(&mut Parser) -> bool>(p: &mut Parser, f: F) {
89 while f(p) { } 120 while f(p) { }
90} 121}
91 122
92fn comma_list<F: Fn(&mut Parser) -> bool>(p: &mut Parser, f: F) { 123fn comma_list<F: Fn(&mut Parser) -> bool>(p: &mut Parser, end: SyntaxKind, f: F) {
93 many(p, |p| { 124 many(p, |p| {
94 f(p); 125 if !f(p) || p.current() == end {
95 if p.current() == EOF {
96 false 126 false
97 } else { 127 } else {
98 p.expect(COMMA); 128 p.expect(COMMA);
@@ -157,4 +187,8 @@ impl<'p> Parser<'p> {
157 self.bump(); 187 self.bump();
158 } 188 }
159 } 189 }
190
191 fn eat(&mut self, kind: SyntaxKind) -> bool {
192 self.current() == kind && { self.bump(); true }
193 }
160} \ No newline at end of file 194} \ No newline at end of file