aboutsummaryrefslogtreecommitdiff
path: root/src/parser/event_parser/grammar.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/event_parser/grammar.rs')
-rw-r--r--src/parser/event_parser/grammar.rs121
1 files changed, 58 insertions, 63 deletions
diff --git a/src/parser/event_parser/grammar.rs b/src/parser/event_parser/grammar.rs
index 77596fea6..d09579881 100644
--- a/src/parser/event_parser/grammar.rs
+++ b/src/parser/event_parser/grammar.rs
@@ -1,20 +1,17 @@
1use super::parser::Parser; 1use super::parser::Parser;
2 2use {SyntaxKind};
3use syntax_kinds::*; 3use syntax_kinds::*;
4 4
5// Items // 5// Items //
6 6
7pub fn file(p: &mut Parser) { 7pub fn file(p: &mut Parser) {
8 p.start(FILE); 8 node(p, FILE, |p| {
9 shebang(p); 9 shebang(p);
10 inner_attributes(p); 10 inner_attributes(p);
11 mod_items(p); 11 many(p, |p| skip_to_first(p, item_first, item));
12 p.finish(); 12 })
13} 13}
14 14
15type Result = ::std::result::Result<(), ()>;
16const OK: Result = Ok(());
17const ERR: Result = Err(());
18 15
19fn shebang(_: &mut Parser) { 16fn shebang(_: &mut Parser) {
20 //TODO 17 //TODO
@@ -24,88 +21,86 @@ fn inner_attributes(_: &mut Parser) {
24 //TODO 21 //TODO
25} 22}
26 23
27fn mod_items(p: &mut Parser) { 24fn item_first(p: &Parser) -> bool {
28 loop { 25 match p.current() {
29 skip_until_item(p); 26 Some(STRUCT_KW) => true,
30 if p.is_eof() { 27 _ => false,
31 return;
32 }
33 if item(p).is_err() {
34 skip_one_token(p);
35 }
36 } 28 }
37} 29}
38 30
39fn item(p: &mut Parser) -> Result { 31fn item(p: &mut Parser) {
40 outer_attributes(p)?; 32 outer_attributes(p);
41 visibility(p)?; 33 visibility(p);
42 if p.current_is(STRUCT_KW) { 34 node_if(p, STRUCT_KW, STRUCT_ITEM, struct_item);
43 p.start(STRUCT_ITEM);
44 p.bump();
45 let _ = struct_item(p);
46 p.finish();
47 return OK;
48 }
49 ERR
50} 35}
51 36
52fn struct_item(p: &mut Parser) -> Result { 37fn struct_item(p: &mut Parser) {
53 p.expect(IDENT)?; 38 p.expect(IDENT)
54 p.curly_block(|p| { 39 && p.curly_block(|p| comma_list(p, struct_field));
55 comma_list(p, struct_field)
56 })
57} 40}
58 41
59fn struct_field(p: &mut Parser) -> Result { 42fn struct_field(p: &mut Parser) -> bool {
60 if !p.current_is(IDENT) { 43 node_if(p, IDENT, STRUCT_FIELD, |p| {
61 return ERR; 44 p.expect(COLON) && p.expect(IDENT);
62 } 45 })
63 p.start(STRUCT_FIELD);
64 p.bump();
65 ignore_errors(|| {
66 p.expect(COLON)?;
67 p.expect(IDENT)?;
68 OK
69 });
70 p.finish();
71 OK
72} 46}
73 47
74// Paths, types, attributes, and stuff // 48// Paths, types, attributes, and stuff //
75 49
76fn outer_attributes(_: &mut Parser) -> Result { 50fn outer_attributes(_: &mut Parser) {
77 OK
78} 51}
79 52
80fn visibility(_: &mut Parser) -> Result { 53fn visibility(_: &mut Parser) {
81 OK
82} 54}
83 55
84// Expressions // 56// Expressions //
85 57
86// Error recovery and high-order utils // 58// Error recovery and high-order utils //
87 59
88fn skip_until_item(_: &mut Parser) { 60fn node_if<F: FnOnce(&mut Parser)>(p: &mut Parser, first: SyntaxKind, node_kind: SyntaxKind, rest: F) -> bool {
89 //TODO 61 p.current_is(first) && { node(p, node_kind, |p| { p.bump(); rest(p); }); true }
90} 62}
91 63
92fn skip_one_token(p: &mut Parser) { 64fn node<F: FnOnce(&mut Parser)>(p: &mut Parser, node_kind: SyntaxKind, rest: F) {
93 p.start(ERROR); 65 p.start(node_kind);
94 p.bump().unwrap(); 66 rest(p);
95 p.finish(); 67 p.finish();
96} 68}
97 69
98fn ignore_errors<F: FnOnce() -> Result>(f: F) { 70fn many<F: Fn(&mut Parser) -> bool>(p: &mut Parser, f: F) {
99 drop(f()); 71 while f(p) { }
100} 72}
101 73
102fn comma_list<F: Fn(&mut Parser) -> Result>(p: &mut Parser, element: F) { 74fn comma_list<F: Fn(&mut Parser) -> bool>(p: &mut Parser, f: F) {
75 many(p, |p| {
76 f(p);
77 p.expect(COMMA)
78 })
79}
80
81
82fn skip_to_first<C, F>(p: &mut Parser, cond: C, f: F) -> bool
83where
84 C: Fn(&Parser) -> bool,
85 F: FnOnce(&mut Parser),
86{
103 loop { 87 loop {
104 if element(p).is_err() { 88 if cond(p) {
105 return 89 f(p);
90 return true;
106 } 91 }
107 if p.expect(COMMA).is_err() { 92 if p.bump().is_none() {
108 return 93 return false;
109 } 94 }
110 } 95 }
96}
97
98impl<'p> Parser<'p> {
99 fn current_is(&self, kind: SyntaxKind) -> bool {
100 self.current() == Some(kind)
101 }
102
103 pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool {
104 self.current_is(kind) && { self.bump(); true }
105 }
111} \ No newline at end of file 106} \ No newline at end of file