aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parser/event_parser/grammar/attributes.rs96
-rw-r--r--src/parser/event_parser/grammar/items.rs10
-rw-r--r--src/parser/event_parser/grammar/mod.rs6
-rw-r--r--src/parser/event_parser/mod.rs3
-rw-r--r--src/parser/event_parser/parser.rs23
5 files changed, 98 insertions, 40 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}
diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs
index c9a890553..12b6d06c7 100644
--- a/src/parser/event_parser/grammar/items.rs
+++ b/src/parser/event_parser/grammar/items.rs
@@ -7,6 +7,16 @@ pub(super) fn mod_contents(p: &mut Parser) {
7 } 7 }
8} 8}
9 9
10pub(super) const ITEM_FIRST: TokenSet = token_set![
11 EXTERN_KW,
12 MOD_KW,
13 USE_KW,
14 STRUCT_KW,
15 FN_KW,
16 PUB_KW,
17 POUND,
18];
19
10fn item(p: &mut Parser) { 20fn item(p: &mut Parser) {
11 let item = p.start(); 21 let item = p.start();
12 attributes::outer_attributes(p); 22 attributes::outer_attributes(p);
diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs
index d3b63c4c1..32e4db698 100644
--- a/src/parser/event_parser/grammar/mod.rs
+++ b/src/parser/event_parser/grammar/mod.rs
@@ -1,4 +1,4 @@
1use super::parser::Parser; 1use super::parser::{Parser, TokenSet};
2use {SyntaxKind}; 2use {SyntaxKind};
3use tree::EOF; 3use tree::EOF;
4use syntax_kinds::*; 4use syntax_kinds::*;
@@ -80,8 +80,8 @@ fn comma_list<F: Fn(&mut Parser) -> bool>(p: &mut Parser, end: SyntaxKind, f: F)
80 80
81 81
82impl<'p> Parser<'p> { 82impl<'p> Parser<'p> {
83 fn at(&self, kind: SyntaxKind) -> bool { 83 fn at<L: Lookahead>(&self, l: L) -> bool {
84 self.current() == kind 84 l.is_ahead(self)
85 } 85 }
86 86
87 pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool { 87 pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool {
diff --git a/src/parser/event_parser/mod.rs b/src/parser/event_parser/mod.rs
index 7c81182e3..b9ffded9d 100644
--- a/src/parser/event_parser/mod.rs
+++ b/src/parser/event_parser/mod.rs
@@ -1,7 +1,8 @@
1use {Token, SyntaxKind}; 1use {Token, SyntaxKind};
2 2
3mod grammar; 3#[macro_use]
4mod parser; 4mod parser;
5mod grammar;
5 6
6#[derive(Debug)] 7#[derive(Debug)]
7pub(crate) enum Event { 8pub(crate) enum Event {
diff --git a/src/parser/event_parser/parser.rs b/src/parser/event_parser/parser.rs
index 2bc9dd34f..2cbe370be 100644
--- a/src/parser/event_parser/parser.rs
+++ b/src/parser/event_parser/parser.rs
@@ -67,6 +67,29 @@ impl CompleteMarker {
67 } 67 }
68} 68}
69 69
70pub(crate) struct TokenSet {
71 pub tokens: &'static [SyntaxKind]
72}
73
74impl TokenSet {
75 pub fn contains(&self, kind: SyntaxKind) -> bool {
76 self.tokens.contains(&kind)
77 }
78}
79
80#[macro_export]
81macro_rules! token_set {
82 ($($t:ident),*) => {
83 TokenSet {
84 tokens: &[$($t),*],
85 }
86 };
87
88 ($($t:ident),* ,) => {
89 token_set!($($t),*)
90 };
91}
92
70 93
71pub(crate) struct Parser<'t> { 94pub(crate) struct Parser<'t> {
72 #[allow(unused)] 95 #[allow(unused)]