aboutsummaryrefslogtreecommitdiff
path: root/src/parser/parser.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-02-04 11:04:02 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-02-04 11:04:02 +0000
commitaa36ad008eae28d1251a4bf276b1d13398fcf89f (patch)
tree838d2875f00d1d0c4b3d747dfd7c314abf9ac404 /src/parser/parser.rs
parent5e5313a7c71d8aa873b418575f56d23b2eac6e7f (diff)
parentd4179550cd69a23a79ed27a96b93f9f760c02b69 (diff)
Merge #41
41: G: unsafe impl & trait r=matklad a=matklad bors r+
Diffstat (limited to 'src/parser/parser.rs')
-rw-r--r--src/parser/parser.rs201
1 files changed, 201 insertions, 0 deletions
diff --git a/src/parser/parser.rs b/src/parser/parser.rs
new file mode 100644
index 000000000..3f4c8a07d
--- /dev/null
+++ b/src/parser/parser.rs
@@ -0,0 +1,201 @@
1use {SyntaxKind, TextUnit, Token};
2use super::Event;
3use super::is_insignificant;
4use SyntaxKind::{EOF, TOMBSTONE};
5
6pub(crate) struct Marker {
7 pos: u32,
8}
9
10impl Marker {
11 pub fn complete(self, p: &mut Parser, kind: SyntaxKind) -> CompleteMarker {
12 match self.event(p) {
13 &mut Event::Start {
14 kind: ref mut slot, ..
15 } => {
16 *slot = kind;
17 }
18 _ => unreachable!(),
19 }
20 p.event(Event::Finish);
21 let result = CompleteMarker { pos: self.pos };
22 ::std::mem::forget(self);
23 result
24 }
25
26 pub fn abandon(self, p: &mut Parser) {
27 let idx = self.pos as usize;
28 if idx == p.events.len() - 1 {
29 match p.events.pop() {
30 Some(Event::Start {
31 kind: TOMBSTONE,
32 forward_parent: None,
33 }) => (),
34 _ => unreachable!(),
35 }
36 }
37 ::std::mem::forget(self);
38 }
39
40 fn event<'p>(&self, p: &'p mut Parser) -> &'p mut Event {
41 &mut p.events[self.idx()]
42 }
43
44 fn idx(&self) -> usize {
45 self.pos as usize
46 }
47}
48
49impl Drop for Marker {
50 fn drop(&mut self) {
51 if !::std::thread::panicking() {
52 panic!("Each marker should be eithe completed or abandoned");
53 }
54 }
55}
56
57pub(crate) struct CompleteMarker {
58 pos: u32,
59}
60
61impl CompleteMarker {
62 pub(crate) fn precede(self, p: &mut Parser) -> Marker {
63 let m = p.start();
64 match p.events[self.pos as usize] {
65 Event::Start {
66 ref mut forward_parent,
67 ..
68 } => {
69 *forward_parent = Some(m.pos - self.pos);
70 }
71 _ => unreachable!(),
72 }
73 m
74 }
75}
76
77pub(crate) struct TokenSet {
78 pub tokens: &'static [SyntaxKind],
79}
80
81impl TokenSet {
82 pub fn contains(&self, kind: SyntaxKind) -> bool {
83 self.tokens.contains(&kind)
84 }
85}
86
87#[macro_export]
88macro_rules! token_set {
89 ($($t:ident),*) => {
90 TokenSet {
91 tokens: &[$($t),*],
92 }
93 };
94
95 ($($t:ident),* ,) => {
96 token_set!($($t),*)
97 };
98}
99
100pub(crate) struct Parser<'t> {
101 #[allow(unused)]
102 text: &'t str,
103 #[allow(unused)]
104 start_offsets: Vec<TextUnit>,
105 tokens: Vec<Token>, // non-whitespace tokens
106
107 pos: usize,
108 events: Vec<Event>,
109}
110
111impl<'t> Parser<'t> {
112 pub(crate) fn new(text: &'t str, raw_tokens: &'t [Token]) -> Parser<'t> {
113 let mut tokens = Vec::new();
114 let mut start_offsets = Vec::new();
115 let mut len = TextUnit::new(0);
116 for &token in raw_tokens.iter() {
117 if !is_insignificant(token.kind) {
118 tokens.push(token);
119 start_offsets.push(len);
120 }
121 len += token.len;
122 }
123
124 Parser {
125 text,
126 start_offsets,
127 tokens,
128
129 pos: 0,
130 events: Vec::new(),
131 }
132 }
133
134 pub(crate) fn into_events(self) -> Vec<Event> {
135 assert_eq!(self.current(), EOF);
136 self.events
137 }
138
139 pub(crate) fn start(&mut self) -> Marker {
140 let m = Marker {
141 pos: self.events.len() as u32,
142 };
143 self.event(Event::Start {
144 kind: TOMBSTONE,
145 forward_parent: None,
146 });
147 m
148 }
149
150 pub(crate) fn error<'p>(&'p mut self) -> ErrorBuilder<'p, 't> {
151 ErrorBuilder::new(self)
152 }
153
154 pub(crate) fn bump(&mut self) {
155 let kind = self.current();
156 if kind == EOF {
157 return;
158 }
159 self.pos += 1;
160 self.event(Event::Token {
161 kind,
162 n_raw_tokens: 1,
163 });
164 }
165
166 pub(crate) fn nth(&self, n: usize) -> SyntaxKind {
167 self.tokens.get(self.pos + n).map(|t| t.kind).unwrap_or(EOF)
168 }
169
170 pub(crate) fn current(&self) -> SyntaxKind {
171 self.nth(0)
172 }
173
174 fn event(&mut self, event: Event) {
175 self.events.push(event)
176 }
177}
178
179pub(crate) struct ErrorBuilder<'p, 't: 'p> {
180 message: Option<String>,
181 parser: &'p mut Parser<'t>,
182}
183
184impl<'t, 'p> ErrorBuilder<'p, 't> {
185 fn new(parser: &'p mut Parser<'t>) -> Self {
186 ErrorBuilder {
187 message: None,
188 parser,
189 }
190 }
191
192 pub fn message<M: Into<String>>(mut self, m: M) -> Self {
193 self.message = Some(m.into());
194 self
195 }
196
197 pub fn emit(self) {
198 let message = self.message.expect("Error message not set");
199 self.parser.event(Event::Error { message });
200 }
201}