aboutsummaryrefslogtreecommitdiff
path: root/src/parser/event_parser/grammar/attributes.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/event_parser/grammar/attributes.rs')
-rw-r--r--src/parser/event_parser/grammar/attributes.rs96
1 files changed, 60 insertions, 36 deletions
diff --git a/src/parser/event_parser/grammar/attributes.rs b/src/parser/event_parser/grammar/attributes.rs
index 2d04a1a41..045840059 100644
--- a/src/parser/event_parser/grammar/attributes.rs
+++ b/src/parser/event_parser/grammar/attributes.rs
@@ -1,60 +1,84 @@
1use super::*; 1use super::*;
2 2
3#[derive(PartialEq, Eq)]
4enum AttrKind {
5 Inner, Outer
6}
7
8pub(super) fn inner_attributes(p: &mut Parser) { 3pub(super) fn inner_attributes(p: &mut Parser) {
9 repeat(p, |p| attribute(p, AttrKind::Inner)) 4 while p.at([POUND, EXCL]) {
5 attribute(p, true)
6 }
10} 7}
11 8
12pub(super) fn outer_attributes(p: &mut Parser) { 9pub(super) fn outer_attributes(p: &mut Parser) {
13 repeat(p, |p| attribute(p, AttrKind::Outer)) 10 while p.at(POUND) {
11 attribute(p, false)
12 }
14} 13}
15 14
16 15
17fn attribute(p: &mut Parser, kind: AttrKind) -> bool { 16fn attribute(p: &mut Parser, inner: bool){
18 if p.at(POUND) { 17 let attr = p.start();
19 if kind == AttrKind::Inner && p.raw_lookahead(1) != EXCL { 18 assert!(p.at(POUND));
20 return false; 19 p.bump();
21 } 20
22 let attr = p.start(); 21 if inner {
22 assert!(p.at(EXCL));
23 p.bump(); 23 p.bump();
24 if kind == AttrKind::Inner {
25 p.bump();
26 }
27 p.expect(L_BRACK) && meta_item(p) && p.expect(R_BRACK);
28 attr.complete(p, ATTR);
29 true
30 } else {
31 false
32 } 24 }
25
26 if p.expect(L_BRACK) {
27 meta_item(p);
28 p.expect(R_BRACK);
29 }
30 attr.complete(p, ATTR);
33} 31}
34 32
35fn meta_item(p: &mut Parser) -> bool { 33fn meta_item(p: &mut Parser) {
36 if p.at(IDENT) { 34 if p.at(IDENT) {
37 let meta_item = p.start(); 35 let meta_item = p.start();
38 p.bump(); 36 p.bump();
39 if p.eat(EQ) { 37 match p.current() {
40 if !expressions::literal(p) { 38 EQ => {
41 p.error() 39 p.bump();
42 .message("expected literal") 40 if !expressions::literal(p) {
43 .emit(); 41 p.error()
42 .message("expected literal")
43 .emit();
44 }
44 } 45 }
45 } else if p.eat(L_PAREN) { 46 L_PAREN => meta_item_arg_list(p),
46 comma_list(p, R_PAREN, meta_item_inner); 47 _ => (),
47 p.expect(R_PAREN);
48 } 48 }
49 meta_item.complete(p, META_ITEM); 49 meta_item.complete(p, META_ITEM);
50 true
51 } else { 50 } else {
52 false 51 p.error()
52 .message("expected attribute value")
53 .emit()
53 } 54 }
54
55} 55}
56 56
57fn meta_item_inner(p: &mut Parser) -> bool { 57fn meta_item_arg_list(p: &mut Parser) {
58 meta_item(p) || expressions::literal(p) 58 assert!(p.at(L_PAREN));
59} 59 p.bump();
60 loop {
61 match p.current() {
62 EOF | R_PAREN => break,
63 IDENT => meta_item(p),
64 c => if !expressions::literal(p) {
65 let message = "expected attribute";
60 66
67 if items::ITEM_FIRST.contains(c) {
68 p.error().message(message).emit();
69 return;
70 }
71
72 let err = p.start();
73 p.error().message(message).emit();
74 p.bump();
75 err.complete(p, ERROR);
76 continue
77 }
78 }
79 if !p.at(R_PAREN) {
80 p.expect(COMMA);
81 }
82 }
83 p.expect(R_PAREN);
84}