aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/parser/event_parser/grammar.rs121
-rw-r--r--src/parser/event_parser/parser.rs36
-rw-r--r--tests/data/parser/0002_struct_item_field.txt2
-rw-r--r--tests/parser.rs2
4 files changed, 72 insertions, 89 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
diff --git a/src/parser/event_parser/parser.rs b/src/parser/event_parser/parser.rs
index 04ef4fb28..07e3ccc23 100644
--- a/src/parser/event_parser/parser.rs
+++ b/src/parser/event_parser/parser.rs
@@ -60,10 +60,6 @@ impl<'t> Parser<'t> {
60 Some(self.raw_tokens[idx].kind) 60 Some(self.raw_tokens[idx].kind)
61 } 61 }
62 62
63 pub(crate) fn current_is(&self, kind: SyntaxKind) -> bool {
64 self.current() == Some(kind)
65 }
66
67 pub(crate) fn bump(&mut self) -> Option<SyntaxKind> { 63 pub(crate) fn bump(&mut self) -> Option<SyntaxKind> {
68 let kind = self.current()?; 64 let kind = self.current()?;
69 match kind { 65 match kind {
@@ -76,31 +72,23 @@ impl<'t> Parser<'t> {
76 Some(kind) 72 Some(kind)
77 } 73 }
78 74
79 pub(crate) fn expect(&mut self, kind: SyntaxKind) -> Result<(), ()> { 75 pub(crate) fn curly_block<F: FnOnce(&mut Parser)>(&mut self, f: F) -> bool {
80 if kind == self.current().ok_or(())? {
81 self.bump();
82 Ok(())
83 } else {
84 Err(())
85 }
86 }
87
88 pub(crate) fn curly_block<F: FnOnce(&mut Parser)>(&mut self, f: F) -> Result<(), ()> {
89 let level = self.curly_level; 76 let level = self.curly_level;
90 self.expect(L_CURLY)?; 77 if !self.expect(L_CURLY) {
78 return false
79 }
91 f(self); 80 f(self);
92 assert!(self.curly_level > level); 81 assert!(self.curly_level > level);
93 if self.expect(R_CURLY).is_ok() { 82 if !self.expect(R_CURLY) {
94 return Ok(()); 83 self.start(ERROR);
95 } 84 while self.curly_level > level {
96 self.start(ERROR); 85 if self.bump().is_none() {
97 while self.curly_level > level { 86 break;
98 if self.bump().is_none() { 87 }
99 break;
100 } 88 }
89 self.finish();
101 } 90 }
102 self.finish(); 91 true
103 Ok(()) //???
104 } 92 }
105 93
106 fn event(&mut self, event: Event) { 94 fn event(&mut self, event: Event) {
diff --git a/tests/data/parser/0002_struct_item_field.txt b/tests/data/parser/0002_struct_item_field.txt
index b1673ade3..87ab3f7a9 100644
--- a/tests/data/parser/0002_struct_item_field.txt
+++ b/tests/data/parser/0002_struct_item_field.txt
@@ -12,4 +12,4 @@ FILE@[0; 25)
12 WHITESPACE@[19; 20) 12 WHITESPACE@[19; 20)
13 IDENT@[20; 23) 13 IDENT@[20; 23)
14 WHITESPACE@[23; 24) 14 WHITESPACE@[23; 24)
15 R_CURLY@[24; 25) \ No newline at end of file 15 R_CURLY@[24; 25)
diff --git a/tests/parser.rs b/tests/parser.rs
index 5c63be3be..6c31463ad 100644
--- a/tests/parser.rs
+++ b/tests/parser.rs
@@ -49,7 +49,7 @@ fn parser_test_case(path: &Path) {
49 return 49 return
50 } 50 }
51 if expected.trim() == actual.trim() { 51 if expected.trim() == actual.trim() {
52 panic!("Whitespace difference!") 52 panic!("Whitespace difference! {}", path.display())
53 } 53 }
54 assert_diff!(expected, actual, "\n", 0) 54 assert_diff!(expected, actual, "\n", 0)
55} 55}