diff options
Diffstat (limited to 'src/parser/event_parser/parser.rs')
-rw-r--r-- | src/parser/event_parser/parser.rs | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/src/parser/event_parser/parser.rs b/src/parser/event_parser/parser.rs index 07e3ccc23..eafa03521 100644 --- a/src/parser/event_parser/parser.rs +++ b/src/parser/event_parser/parser.rs | |||
@@ -10,7 +10,9 @@ pub struct Parser<'t> { | |||
10 | 10 | ||
11 | pos: usize, | 11 | pos: usize, |
12 | events: Vec<Event>, | 12 | events: Vec<Event>, |
13 | |||
13 | curly_level: i32, | 14 | curly_level: i32, |
15 | curly_limit: Option<i32>, | ||
14 | } | 16 | } |
15 | 17 | ||
16 | impl<'t> Parser<'t> { | 18 | impl<'t> Parser<'t> { |
@@ -32,6 +34,7 @@ impl<'t> Parser<'t> { | |||
32 | pos: 0, | 34 | pos: 0, |
33 | events: Vec::new(), | 35 | events: Vec::new(), |
34 | curly_level: 0, | 36 | curly_level: 0, |
37 | curly_limit: None, | ||
35 | } | 38 | } |
36 | } | 39 | } |
37 | 40 | ||
@@ -41,7 +44,14 @@ impl<'t> Parser<'t> { | |||
41 | } | 44 | } |
42 | 45 | ||
43 | pub(crate) fn is_eof(&self) -> bool { | 46 | pub(crate) fn is_eof(&self) -> bool { |
44 | self.pos == self.non_ws_tokens.len() | 47 | if self.pos == self.non_ws_tokens.len() { |
48 | return true | ||
49 | } | ||
50 | if let Some(limit) = self.curly_limit { | ||
51 | let idx = self.non_ws_tokens[self.pos].0; | ||
52 | return limit == self.curly_level && self.raw_tokens[idx].kind == R_CURLY; | ||
53 | } | ||
54 | false | ||
45 | } | 55 | } |
46 | 56 | ||
47 | pub(crate) fn start(&mut self, kind: SyntaxKind) { | 57 | pub(crate) fn start(&mut self, kind: SyntaxKind) { |
@@ -52,6 +62,10 @@ impl<'t> Parser<'t> { | |||
52 | self.event(Event::Finish); | 62 | self.event(Event::Finish); |
53 | } | 63 | } |
54 | 64 | ||
65 | pub(crate) fn error<'p>(&'p mut self) -> ErrorBuilder<'p, 't> { | ||
66 | ErrorBuilder::new(self) | ||
67 | } | ||
68 | |||
55 | pub(crate) fn current(&self) -> Option<SyntaxKind> { | 69 | pub(crate) fn current(&self) -> Option<SyntaxKind> { |
56 | if self.is_eof() { | 70 | if self.is_eof() { |
57 | return None; | 71 | return None; |
@@ -73,15 +87,18 @@ impl<'t> Parser<'t> { | |||
73 | } | 87 | } |
74 | 88 | ||
75 | pub(crate) fn curly_block<F: FnOnce(&mut Parser)>(&mut self, f: F) -> bool { | 89 | pub(crate) fn curly_block<F: FnOnce(&mut Parser)>(&mut self, f: F) -> bool { |
76 | let level = self.curly_level; | 90 | let old_level = self.curly_level; |
91 | let old_limit = self.curly_limit; | ||
77 | if !self.expect(L_CURLY) { | 92 | if !self.expect(L_CURLY) { |
78 | return false | 93 | return false |
79 | } | 94 | } |
95 | self.curly_limit = Some(self.curly_level); | ||
80 | f(self); | 96 | f(self); |
81 | assert!(self.curly_level > level); | 97 | assert!(self.curly_level > old_level); |
98 | self.curly_limit = old_limit; | ||
82 | if !self.expect(R_CURLY) { | 99 | if !self.expect(R_CURLY) { |
83 | self.start(ERROR); | 100 | self.start(ERROR); |
84 | while self.curly_level > level { | 101 | while self.curly_level > old_level { |
85 | if self.bump().is_none() { | 102 | if self.bump().is_none() { |
86 | break; | 103 | break; |
87 | } | 104 | } |
@@ -94,4 +111,25 @@ impl<'t> Parser<'t> { | |||
94 | fn event(&mut self, event: Event) { | 111 | fn event(&mut self, event: Event) { |
95 | self.events.push(event) | 112 | self.events.push(event) |
96 | } | 113 | } |
97 | } \ No newline at end of file | 114 | } |
115 | |||
116 | pub(crate) struct ErrorBuilder<'p, 't: 'p> { | ||
117 | message: Option<String>, | ||
118 | parser: &'p mut Parser<'t> | ||
119 | } | ||
120 | |||
121 | impl<'t, 'p> ErrorBuilder<'p, 't> { | ||
122 | fn new(parser: &'p mut Parser<'t>) -> Self { | ||
123 | ErrorBuilder { message: None, parser } | ||
124 | } | ||
125 | |||
126 | pub fn message<M: Into<String>>(mut self, m: M) -> Self { | ||
127 | self.message = Some(m.into()); | ||
128 | self | ||
129 | } | ||
130 | |||
131 | pub fn emit(self) { | ||
132 | let message = self.message.expect("Error message not set"); | ||
133 | self.parser.event(Event::Error { message }); | ||
134 | } | ||
135 | } | ||