diff options
author | Aleksey Kladov <[email protected]> | 2018-01-20 20:25:34 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-01-20 20:25:34 +0000 |
commit | 0b5d39f2a204e5ec6cd6205440e4cdc763162814 (patch) | |
tree | 8d201ef62b5e4fe48e3cce7b557071e434530801 /src/parser/event_parser/parser.rs | |
parent | be60d5aa6669a74e92495288f44b7f9258a8518f (diff) |
Markers API
Diffstat (limited to 'src/parser/event_parser/parser.rs')
-rw-r--r-- | src/parser/event_parser/parser.rs | 112 |
1 files changed, 76 insertions, 36 deletions
diff --git a/src/parser/event_parser/parser.rs b/src/parser/event_parser/parser.rs index 6171b3579..2bc9dd34f 100644 --- a/src/parser/event_parser/parser.rs +++ b/src/parser/event_parser/parser.rs | |||
@@ -1,8 +1,71 @@ | |||
1 | use {Token, SyntaxKind, TextUnit}; | 1 | use {Token, SyntaxKind, TextUnit}; |
2 | use super::{Event}; | 2 | use super::Event; |
3 | use super::super::is_insignificant; | 3 | use super::super::is_insignificant; |
4 | use syntax_kinds::{L_CURLY, R_CURLY, ERROR}; | 4 | use syntax_kinds::{L_CURLY, R_CURLY, ERROR}; |
5 | use tree::EOF; | 5 | use tree::{EOF, TOMBSTONE}; |
6 | |||
7 | pub(crate) struct Marker { | ||
8 | pos: u32 | ||
9 | } | ||
10 | |||
11 | impl Marker { | ||
12 | pub fn complete(self, p: &mut Parser, kind: SyntaxKind) -> CompleteMarker { | ||
13 | match self.event(p) { | ||
14 | &mut Event::Start { kind: ref mut slot, ..} => { | ||
15 | *slot = kind; | ||
16 | } | ||
17 | _ => unreachable!(), | ||
18 | } | ||
19 | p.event(Event::Finish); | ||
20 | let result = CompleteMarker { pos: self.pos }; | ||
21 | ::std::mem::forget(self); | ||
22 | result | ||
23 | } | ||
24 | |||
25 | pub fn abandon(self, p: &mut Parser) { | ||
26 | let idx = self.pos as usize; | ||
27 | if idx == p.events.len() - 1 { | ||
28 | match p.events.pop() { | ||
29 | Some(Event::Start { kind: TOMBSTONE, forward_parent: None }) => (), | ||
30 | _ => unreachable!() | ||
31 | } | ||
32 | } | ||
33 | ::std::mem::forget(self); | ||
34 | } | ||
35 | |||
36 | fn event<'p>(&self, p: &'p mut Parser) -> &'p mut Event { | ||
37 | &mut p.events[self.idx()] | ||
38 | } | ||
39 | |||
40 | fn idx(&self) -> usize { | ||
41 | self.pos as usize | ||
42 | } | ||
43 | } | ||
44 | |||
45 | impl Drop for Marker { | ||
46 | fn drop(&mut self) { | ||
47 | if !::std::thread::panicking() { | ||
48 | panic!("Each marker should be eithe completed or abandoned"); | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | |||
53 | pub(crate) struct CompleteMarker { | ||
54 | pos: u32 | ||
55 | } | ||
56 | |||
57 | impl CompleteMarker { | ||
58 | pub(crate) fn precede(self, p: &mut Parser) -> Marker { | ||
59 | let m = p.start(); | ||
60 | match p.events[self.pos as usize] { | ||
61 | Event::Start { ref mut forward_parent, ..} => { | ||
62 | *forward_parent = Some(m.pos - self.pos); | ||
63 | } | ||
64 | _ => unreachable!(), | ||
65 | } | ||
66 | m | ||
67 | } | ||
68 | } | ||
6 | 69 | ||
7 | 70 | ||
8 | pub(crate) struct Parser<'t> { | 71 | pub(crate) struct Parser<'t> { |
@@ -19,12 +82,9 @@ pub(crate) struct Parser<'t> { | |||
19 | curly_limit: Option<i32>, | 82 | curly_limit: Option<i32>, |
20 | } | 83 | } |
21 | 84 | ||
22 | #[derive(Debug, Clone, Copy,PartialEq, Eq)] | 85 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
23 | pub(crate) struct Pos(u32); | 86 | pub(crate) struct Pos(u32); |
24 | 87 | ||
25 | #[derive(Debug, Clone, Copy,PartialEq, Eq)] | ||
26 | pub(crate) struct Mark(u32); | ||
27 | |||
28 | impl<'t> Parser<'t> { | 88 | impl<'t> Parser<'t> { |
29 | pub(crate) fn new(text: &'t str, raw_tokens: &'t [Token]) -> Parser<'t> { | 89 | pub(crate) fn new(text: &'t str, raw_tokens: &'t [Token]) -> Parser<'t> { |
30 | let mut tokens = Vec::new(); | 90 | let mut tokens = Vec::new(); |
@@ -50,31 +110,13 @@ impl<'t> Parser<'t> { | |||
50 | } | 110 | } |
51 | } | 111 | } |
52 | 112 | ||
53 | pub(crate) fn mark(&self) -> Mark { | ||
54 | Mark(self.events.len() as u32) | ||
55 | } | ||
56 | |||
57 | pub(crate) fn forward_parent(&mut self, child: Mark, parent: Mark) { | ||
58 | if child == parent || parent == self.mark() { | ||
59 | return | ||
60 | } | ||
61 | assert!(child.0 < parent.0); | ||
62 | let diff = parent.0 - child.0; | ||
63 | match self.events[child.0 as usize] { | ||
64 | Event::Start { ref mut forward_parent, .. } => { | ||
65 | *forward_parent = Some(diff); | ||
66 | } | ||
67 | _ => unreachable!() | ||
68 | } | ||
69 | } | ||
70 | |||
71 | pub(crate) fn pos(&self) -> Pos { | 113 | pub(crate) fn pos(&self) -> Pos { |
72 | Pos(self.pos as u32) | 114 | Pos(self.pos as u32) |
73 | } | 115 | } |
74 | 116 | ||
75 | pub(crate) fn into_events(self) -> Vec<Event> { | 117 | pub(crate) fn into_events(self) -> Vec<Event> { |
76 | assert!(self.curly_limit.is_none()); | 118 | assert!(self.curly_limit.is_none()); |
77 | assert!(self.current() == EOF); | 119 | assert_eq!(self.current(), EOF); |
78 | self.events | 120 | self.events |
79 | } | 121 | } |
80 | 122 | ||
@@ -85,18 +127,16 @@ impl<'t> Parser<'t> { | |||
85 | let token = self.tokens[self.pos]; | 127 | let token = self.tokens[self.pos]; |
86 | if let Some(limit) = self.curly_limit { | 128 | if let Some(limit) = self.curly_limit { |
87 | if limit == self.curly_level && token.kind == R_CURLY { | 129 | if limit == self.curly_level && token.kind == R_CURLY { |
88 | return EOF | 130 | return EOF; |
89 | } | 131 | } |
90 | } | 132 | } |
91 | token.kind | 133 | token.kind |
92 | } | 134 | } |
93 | 135 | ||
94 | pub(crate) fn start(&mut self, kind: SyntaxKind) { | 136 | pub(crate) fn start(&mut self) -> Marker { |
95 | self.event(Event::Start { kind, forward_parent: None }); | 137 | let m = Marker { pos: self.events.len() as u32 }; |
96 | } | 138 | self.event(Event::Start { kind: TOMBSTONE, forward_parent: None }); |
97 | 139 | m | |
98 | pub(crate) fn finish(&mut self) { | ||
99 | self.event(Event::Finish); | ||
100 | } | 140 | } |
101 | 141 | ||
102 | pub(crate) fn error<'p>(&'p mut self) -> ErrorBuilder<'p, 't> { | 142 | pub(crate) fn error<'p>(&'p mut self) -> ErrorBuilder<'p, 't> { |
@@ -124,20 +164,20 @@ impl<'t> Parser<'t> { | |||
124 | let old_level = self.curly_level; | 164 | let old_level = self.curly_level; |
125 | let old_limit = self.curly_limit; | 165 | let old_limit = self.curly_limit; |
126 | if !self.expect(L_CURLY) { | 166 | if !self.expect(L_CURLY) { |
127 | return false | 167 | return false; |
128 | } | 168 | } |
129 | self.curly_limit = Some(self.curly_level); | 169 | self.curly_limit = Some(self.curly_level); |
130 | f(self); | 170 | f(self); |
131 | assert!(self.curly_level > old_level); | 171 | assert!(self.curly_level > old_level); |
132 | self.curly_limit = old_limit; | 172 | self.curly_limit = old_limit; |
133 | if !self.expect(R_CURLY) { | 173 | if !self.expect(R_CURLY) { |
134 | self.start(ERROR); | 174 | let err = self.start(); |
135 | while self.curly_level > old_level { | 175 | while self.curly_level > old_level { |
136 | if self.bump() == EOF { | 176 | if self.bump() == EOF { |
137 | break; | 177 | break; |
138 | } | 178 | } |
139 | } | 179 | } |
140 | self.finish(); | 180 | err.complete(self, ERROR); |
141 | } | 181 | } |
142 | true | 182 | true |
143 | } | 183 | } |
@@ -149,7 +189,7 @@ impl<'t> Parser<'t> { | |||
149 | 189 | ||
150 | pub(crate) struct ErrorBuilder<'p, 't: 'p> { | 190 | pub(crate) struct ErrorBuilder<'p, 't: 'p> { |
151 | message: Option<String>, | 191 | message: Option<String>, |
152 | parser: &'p mut Parser<'t> | 192 | parser: &'p mut Parser<'t>, |
153 | } | 193 | } |
154 | 194 | ||
155 | impl<'t, 'p> ErrorBuilder<'p, 't> { | 195 | impl<'t, 'p> ErrorBuilder<'p, 't> { |