aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-01-20 20:25:34 +0000
committerAleksey Kladov <[email protected]>2018-01-20 20:25:34 +0000
commit0b5d39f2a204e5ec6cd6205440e4cdc763162814 (patch)
tree8d201ef62b5e4fe48e3cce7b557071e434530801 /src
parentbe60d5aa6669a74e92495288f44b7f9258a8518f (diff)
Markers API
Diffstat (limited to 'src')
-rw-r--r--src/parser/event_parser/grammar/attributes.rs8
-rw-r--r--src/parser/event_parser/grammar/expressions.rs4
-rw-r--r--src/parser/event_parser/grammar/items.rs151
-rw-r--r--src/parser/event_parser/grammar/mod.rs12
-rw-r--r--src/parser/event_parser/grammar/paths.rs17
-rw-r--r--src/parser/event_parser/mod.rs2
-rw-r--r--src/parser/event_parser/parser.rs112
-rw-r--r--src/parser/mod.rs5
-rw-r--r--src/tree/file_builder.rs8
-rw-r--r--src/tree/mod.rs15
10 files changed, 189 insertions, 145 deletions
diff --git a/src/parser/event_parser/grammar/attributes.rs b/src/parser/event_parser/grammar/attributes.rs
index 8b5e5bcfe..2d04a1a41 100644
--- a/src/parser/event_parser/grammar/attributes.rs
+++ b/src/parser/event_parser/grammar/attributes.rs
@@ -19,13 +19,13 @@ fn attribute(p: &mut Parser, kind: AttrKind) -> bool {
19 if kind == AttrKind::Inner && p.raw_lookahead(1) != EXCL { 19 if kind == AttrKind::Inner && p.raw_lookahead(1) != EXCL {
20 return false; 20 return false;
21 } 21 }
22 p.start(ATTR); 22 let attr = p.start();
23 p.bump(); 23 p.bump();
24 if kind == AttrKind::Inner { 24 if kind == AttrKind::Inner {
25 p.bump(); 25 p.bump();
26 } 26 }
27 p.expect(L_BRACK) && meta_item(p) && p.expect(R_BRACK); 27 p.expect(L_BRACK) && meta_item(p) && p.expect(R_BRACK);
28 p.finish(); 28 attr.complete(p, ATTR);
29 true 29 true
30 } else { 30 } else {
31 false 31 false
@@ -34,7 +34,7 @@ fn attribute(p: &mut Parser, kind: AttrKind) -> bool {
34 34
35fn meta_item(p: &mut Parser) -> bool { 35fn meta_item(p: &mut Parser) -> bool {
36 if p.at(IDENT) { 36 if p.at(IDENT) {
37 p.start(META_ITEM); 37 let meta_item = p.start();
38 p.bump(); 38 p.bump();
39 if p.eat(EQ) { 39 if p.eat(EQ) {
40 if !expressions::literal(p) { 40 if !expressions::literal(p) {
@@ -46,7 +46,7 @@ fn meta_item(p: &mut Parser) -> bool {
46 comma_list(p, R_PAREN, meta_item_inner); 46 comma_list(p, R_PAREN, meta_item_inner);
47 p.expect(R_PAREN); 47 p.expect(R_PAREN);
48 } 48 }
49 p.finish(); 49 meta_item.complete(p, META_ITEM);
50 true 50 true
51 } else { 51 } else {
52 false 52 false
diff --git a/src/parser/event_parser/grammar/expressions.rs b/src/parser/event_parser/grammar/expressions.rs
index 0f65193c9..a943b8c81 100644
--- a/src/parser/event_parser/grammar/expressions.rs
+++ b/src/parser/event_parser/grammar/expressions.rs
@@ -6,9 +6,9 @@ pub(super) fn literal(p: &mut Parser) -> bool {
6 INT_NUMBER | FLOAT_NUMBER | 6 INT_NUMBER | FLOAT_NUMBER |
7 BYTE | CHAR | 7 BYTE | CHAR |
8 STRING | RAW_STRING | BYTE_STRING | RAW_BYTE_STRING => { 8 STRING | RAW_STRING | BYTE_STRING | RAW_BYTE_STRING => {
9 p.start(LITERAL); 9 let lit = p.start();
10 p.bump(); 10 p.bump();
11 p.finish(); 11 lit.complete(p, LITERAL);
12 true 12 true
13 } 13 }
14 _ => false 14 _ => false
diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs
index 4514f0dab..c9a890553 100644
--- a/src/parser/event_parser/grammar/items.rs
+++ b/src/parser/event_parser/grammar/items.rs
@@ -8,19 +8,34 @@ pub(super) fn mod_contents(p: &mut Parser) {
8} 8}
9 9
10fn item(p: &mut Parser) { 10fn item(p: &mut Parser) {
11 let attrs_start = p.mark(); 11 let item = p.start();
12 attributes::outer_attributes(p); 12 attributes::outer_attributes(p);
13 visibility(p); 13 visibility(p);
14 let la = p.raw_lookahead(1); 14 let la = p.raw_lookahead(1);
15 let item_start = p.mark(); 15 let item_kind = match p.current() {
16 match p.current() { 16 EXTERN_KW if la == CRATE_KW => {
17 EXTERN_KW if la == CRATE_KW => extern_crate_item(p), 17 extern_crate_item(p);
18 MOD_KW => mod_item(p), 18 EXTERN_CRATE_ITEM
19 USE_KW => use_item(p), 19 }
20 STRUCT_KW => struct_item(p), 20 MOD_KW => {
21 FN_KW => fn_item(p), 21 mod_item(p);
22 MOD_ITEM
23 }
24 USE_KW => {
25 use_item(p);
26 USE_ITEM
27 }
28 STRUCT_KW => {
29 struct_item(p);
30 STRUCT_ITEM
31 }
32 FN_KW => {
33 fn_item(p);
34 FN_ITEM
35 }
22 err_token => { 36 err_token => {
23 p.start(ERROR); 37 item.abandon(p);
38 let err = p.start();
24 let message = if err_token == SEMI { 39 let message = if err_token == SEMI {
25 //TODO: if the item is incomplete, this message is misleading 40 //TODO: if the item is incomplete, this message is misleading
26 "expected item, found `;`\n\ 41 "expected item, found `;`\n\
@@ -32,60 +47,52 @@ fn item(p: &mut Parser) {
32 .message(message) 47 .message(message)
33 .emit(); 48 .emit();
34 p.bump(); 49 p.bump();
35 p.finish(); 50 err.complete(p, ERROR);
36 return; 51 return;
37 } 52 }
38 }; 53 };
39 p.forward_parent(attrs_start, item_start); 54 item.complete(p, item_kind);
40} 55}
41 56
42fn struct_item(p: &mut Parser) { 57fn struct_item(p: &mut Parser) {
43 p.start(STRUCT_ITEM);
44
45 assert!(p.at(STRUCT_KW)); 58 assert!(p.at(STRUCT_KW));
46 p.bump(); 59 p.bump();
47 60
48 struct_inner(p); 61 if !p.expect(IDENT) {
49 p.finish(); 62 return;
50 63 }
51 fn struct_inner(p: &mut Parser) { 64 generic_parameters(p);
52 if !p.expect(IDENT) { 65 match p.current() {
53 p.finish(); 66 WHERE_KW => {
54 return; 67 where_clause(p);
55 } 68 match p.current() {
56 generic_parameters(p); 69 SEMI => {
57 match p.current() { 70 p.bump();
58 WHERE_KW => { 71 return;
59 where_clause(p); 72 }
60 match p.current() { 73 L_CURLY => named_fields(p),
61 SEMI => { 74 _ => { //TODO: special case `(` error message
62 p.bump(); 75 p.error()
63 return; 76 .message("expected `;` or `{`")
64 } 77 .emit();
65 L_CURLY => named_fields(p), 78 return;
66 _ => { //TODO: special case `(` error message
67 p.error()
68 .message("expected `;` or `{`")
69 .emit();
70 return;
71 }
72 } 79 }
73 } 80 }
74 SEMI => { 81 }
75 p.bump(); 82 SEMI => {
76 return; 83 p.bump();
77 } 84 return;
78 L_CURLY => named_fields(p), 85 }
79 L_PAREN => { 86 L_CURLY => named_fields(p),
80 tuple_fields(p); 87 L_PAREN => {
81 p.expect(SEMI); 88 pos_fields(p);
82 } 89 p.expect(SEMI);
83 _ => { 90 }
84 p.error() 91 _ => {
85 .message("expected `;`, `{`, or `(`") 92 p.error()
86 .emit(); 93 .message("expected `;`, `{`, or `(`")
87 return; 94 .emit();
88 } 95 return;
89 } 96 }
90 } 97 }
91} 98}
@@ -97,30 +104,30 @@ fn named_fields(p: &mut Parser) {
97 })); 104 }));
98 105
99 fn named_field(p: &mut Parser) { 106 fn named_field(p: &mut Parser) {
100 p.start(NAMED_FIELD); 107 let field = p.start();
101 visibility(p); 108 visibility(p);
102 if p.expect(IDENT) && p.expect(COLON) { 109 if p.expect(IDENT) && p.expect(COLON) {
103 types::type_ref(p); 110 types::type_ref(p);
104 }; 111 };
105 p.finish() 112 field.complete(p, NAMED_FIELD);
106 } 113 }
107} 114}
108 115
109fn tuple_fields(p: &mut Parser) { 116fn pos_fields(p: &mut Parser) {
110 if !p.expect(L_PAREN) { 117 if !p.expect(L_PAREN) {
111 return; 118 return;
112 } 119 }
113 comma_list(p, R_PAREN, |p| { 120 comma_list(p, R_PAREN, |p| {
114 tuple_field(p); 121 pos_field(p);
115 true 122 true
116 }); 123 });
117 p.expect(R_PAREN); 124 p.expect(R_PAREN);
118 125
119 fn tuple_field(p: &mut Parser) { 126 fn pos_field(p: &mut Parser) {
120 p.start(POS_FIELD); 127 let pos_field = p.start();
121 visibility(p); 128 visibility(p);
122 types::type_ref(p); 129 types::type_ref(p);
123 p.finish(); 130 pos_field.complete(p, POS_FIELD);
124 } 131 }
125} 132}
126 133
@@ -129,28 +136,21 @@ fn generic_parameters(_: &mut Parser) {}
129fn where_clause(_: &mut Parser) {} 136fn where_clause(_: &mut Parser) {}
130 137
131fn extern_crate_item(p: &mut Parser) { 138fn extern_crate_item(p: &mut Parser) {
132 p.start(EXTERN_CRATE_ITEM);
133
134 assert!(p.at(EXTERN_KW)); 139 assert!(p.at(EXTERN_KW));
135 p.bump(); 140 p.bump();
136
137 assert!(p.at(CRATE_KW)); 141 assert!(p.at(CRATE_KW));
138 p.bump(); 142 p.bump();
139 143
140 p.expect(IDENT) && alias(p) && p.expect(SEMI); 144 p.expect(IDENT) && alias(p) && p.expect(SEMI);
141 p.finish();
142} 145}
143 146
144fn mod_item(p: &mut Parser) { 147fn mod_item(p: &mut Parser) {
145 p.start(MOD_ITEM);
146
147 assert!(p.at(MOD_KW)); 148 assert!(p.at(MOD_KW));
148 p.bump(); 149 p.bump();
149 150
150 if p.expect(IDENT) && !p.eat(SEMI) { 151 if p.expect(IDENT) && !p.eat(SEMI) {
151 p.curly_block(mod_contents); 152 p.curly_block(mod_contents);
152 } 153 }
153 p.finish()
154} 154}
155 155
156pub(super) fn is_use_tree_start(kind: SyntaxKind) -> bool { 156pub(super) fn is_use_tree_start(kind: SyntaxKind) -> bool {
@@ -158,28 +158,24 @@ pub(super) fn is_use_tree_start(kind: SyntaxKind) -> bool {
158} 158}
159 159
160fn use_item(p: &mut Parser) { 160fn use_item(p: &mut Parser) {
161 p.start(USE_ITEM);
162
163 assert!(p.at(USE_KW)); 161 assert!(p.at(USE_KW));
164 p.bump(); 162 p.bump();
163
165 use_tree(p); 164 use_tree(p);
166 p.expect(SEMI); 165 p.expect(SEMI);
167 p.finish();
168 166
169 fn use_tree(p: &mut Parser) -> bool { 167 fn use_tree(p: &mut Parser) -> bool {
170 let la = p.raw_lookahead(1); 168 let la = p.raw_lookahead(1);
169 let m = p.start();
171 match (p.current(), la) { 170 match (p.current(), la) {
172 (STAR, _) => { 171 (STAR, _) => {
173 p.start(USE_TREE);
174 p.bump(); 172 p.bump();
175 } 173 }
176 (COLONCOLON, STAR) => { 174 (COLONCOLON, STAR) => {
177 p.start(USE_TREE);
178 p.bump(); 175 p.bump();
179 p.bump(); 176 p.bump();
180 } 177 }
181 (L_CURLY, _) | (COLONCOLON, L_CURLY) => { 178 (L_CURLY, _) | (COLONCOLON, L_CURLY) => {
182 p.start(USE_TREE);
183 if p.at(COLONCOLON) { 179 if p.at(COLONCOLON) {
184 p.bump(); 180 p.bump();
185 } 181 }
@@ -188,7 +184,6 @@ fn use_item(p: &mut Parser) {
188 }); 184 });
189 } 185 }
190 _ if paths::is_path_start(p) => { 186 _ if paths::is_path_start(p) => {
191 p.start(USE_TREE);
192 paths::use_path(p); 187 paths::use_path(p);
193 match p.current() { 188 match p.current() {
194 AS_KW => { 189 AS_KW => {
@@ -216,23 +211,23 @@ fn use_item(p: &mut Parser) {
216 _ => (), 211 _ => (),
217 } 212 }
218 } 213 }
219 _ => return false, 214 _ => {
215 m.abandon(p);
216 return false
217 },
220 } 218 }
221 p.finish(); 219 m.complete(p, USE_TREE);
222 return true; 220 return true;
223 } 221 }
224} 222}
225 223
226 224
227fn fn_item(p: &mut Parser) { 225fn fn_item(p: &mut Parser) {
228 p.start(FN_ITEM);
229
230 assert!(p.at(FN_KW)); 226 assert!(p.at(FN_KW));
231 p.bump(); 227 p.bump();
232 228
233 p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN) 229 p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN)
234 && p.curly_block(|_| ()); 230 && p.curly_block(|_| ());
235 p.finish();
236} 231}
237 232
238 233
diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs
index c3d0c8c10..d3b63c4c1 100644
--- a/src/parser/event_parser/grammar/mod.rs
+++ b/src/parser/event_parser/grammar/mod.rs
@@ -10,15 +10,15 @@ mod types;
10mod paths; 10mod paths;
11 11
12pub(crate) fn file(p: &mut Parser) { 12pub(crate) fn file(p: &mut Parser) {
13 p.start(FILE); 13 let file = p.start();
14 p.eat(SHEBANG); 14 p.eat(SHEBANG);
15 items::mod_contents(p); 15 items::mod_contents(p);
16 p.finish() 16 file.complete(p, FILE);
17} 17}
18 18
19fn visibility(p: &mut Parser) { 19fn visibility(p: &mut Parser) {
20 if p.at(PUB_KW) { 20 if p.at(PUB_KW) {
21 p.start(VISIBILITY); 21 let vis = p.start();
22 p.bump(); 22 p.bump();
23 if p.at(L_PAREN) { 23 if p.at(L_PAREN) {
24 match p.raw_lookahead(1) { 24 match p.raw_lookahead(1) {
@@ -32,16 +32,16 @@ fn visibility(p: &mut Parser) {
32 _ => () 32 _ => ()
33 } 33 }
34 } 34 }
35 p.finish(); 35 vis.complete(p, VISIBILITY);
36 } 36 }
37} 37}
38 38
39fn alias(p: &mut Parser) -> bool { 39fn alias(p: &mut Parser) -> bool {
40 if p.at(AS_KW) { 40 if p.at(AS_KW) {
41 p.start(ALIAS); 41 let alias = p.start();
42 p.bump(); 42 p.bump();
43 p.expect(IDENT); 43 p.expect(IDENT);
44 p.finish(); 44 alias.complete(p, ALIAS);
45 } 45 }
46 true //FIXME: return false if three are errors 46 true //FIXME: return false if three are errors
47} 47}
diff --git a/src/parser/event_parser/grammar/paths.rs b/src/parser/event_parser/grammar/paths.rs
index f5124cfce..b58c59aef 100644
--- a/src/parser/event_parser/grammar/paths.rs
+++ b/src/parser/event_parser/grammar/paths.rs
@@ -8,19 +8,16 @@ pub(crate) fn use_path(p: &mut Parser) {
8 if !is_path_start(p) { 8 if !is_path_start(p) {
9 return; 9 return;
10 } 10 }
11 let mut prev = p.mark(); 11 let path = p.start();
12 p.start(PATH);
13 path_segment(p, true); 12 path_segment(p, true);
14 p.finish(); 13 let mut qual = path.complete(p, PATH);
15 loop { 14 loop {
16 let curr = p.mark();
17 if p.at(COLONCOLON) && !items::is_use_tree_start(p.raw_lookahead(1)) { 15 if p.at(COLONCOLON) && !items::is_use_tree_start(p.raw_lookahead(1)) {
18 p.start(PATH); 16 let path = qual.precede(p);
19 p.bump(); 17 p.bump();
20 path_segment(p, false); 18 path_segment(p, false);
21 p.forward_parent(prev, curr); 19 let path = path.complete(p, PATH);
22 prev = curr; 20 qual = path;
23 p.finish();
24 } else { 21 } else {
25 break; 22 break;
26 } 23 }
@@ -28,7 +25,7 @@ pub(crate) fn use_path(p: &mut Parser) {
28} 25}
29 26
30fn path_segment(p: &mut Parser, first: bool) { 27fn path_segment(p: &mut Parser, first: bool) {
31 p.start(PATH_SEGMENT); 28 let segment = p.start();
32 if first { 29 if first {
33 p.eat(COLONCOLON); 30 p.eat(COLONCOLON);
34 } 31 }
@@ -42,5 +39,5 @@ fn path_segment(p: &mut Parser, first: bool) {
42 .emit(); 39 .emit();
43 } 40 }
44 }; 41 };
45 p.finish(); 42 segment.complete(p, PATH_SEGMENT);
46} 43}
diff --git a/src/parser/event_parser/mod.rs b/src/parser/event_parser/mod.rs
index c89a3ebe7..7c81182e3 100644
--- a/src/parser/event_parser/mod.rs
+++ b/src/parser/event_parser/mod.rs
@@ -23,4 +23,4 @@ pub(crate) fn parse<'t>(text: &'t str, raw_tokens: &'t [Token]) -> Vec<Event> {
23 let mut parser = parser::Parser::new(text, raw_tokens); 23 let mut parser = parser::Parser::new(text, raw_tokens);
24 grammar::file(&mut parser); 24 grammar::file(&mut parser);
25 parser.into_events() 25 parser.into_events()
26} \ No newline at end of file 26}
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 @@
1use {Token, SyntaxKind, TextUnit}; 1use {Token, SyntaxKind, TextUnit};
2use super::{Event}; 2use super::Event;
3use super::super::is_insignificant; 3use super::super::is_insignificant;
4use syntax_kinds::{L_CURLY, R_CURLY, ERROR}; 4use syntax_kinds::{L_CURLY, R_CURLY, ERROR};
5use tree::EOF; 5use tree::{EOF, TOMBSTONE};
6
7pub(crate) struct Marker {
8 pos: u32
9}
10
11impl 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
45impl 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
53pub(crate) struct CompleteMarker {
54 pos: u32
55}
56
57impl 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
8pub(crate) struct Parser<'t> { 71pub(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)]
23pub(crate) struct Pos(u32); 86pub(crate) struct Pos(u32);
24 87
25#[derive(Debug, Clone, Copy,PartialEq, Eq)]
26pub(crate) struct Mark(u32);
27
28impl<'t> Parser<'t> { 88impl<'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
150pub(crate) struct ErrorBuilder<'p, 't: 'p> { 190pub(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
155impl<'t, 'p> ErrorBuilder<'p, 't> { 195impl<'t, 'p> ErrorBuilder<'p, 't> {
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 0c29442f9..5ec4b8e93 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -1,6 +1,7 @@
1use {Token, File, FileBuilder, Sink, SyntaxKind}; 1use {Token, File, FileBuilder, Sink, SyntaxKind};
2 2
3use syntax_kinds::*; 3use syntax_kinds::*;
4use tree::TOMBSTONE;
4 5
5mod event_parser; 6mod event_parser;
6use self::event_parser::Event; 7use self::event_parser::Event;
@@ -29,6 +30,8 @@ fn from_events_to_file(
29 } 30 }
30 31
31 match event { 32 match event {
33 &Event::Start { kind: TOMBSTONE, .. } => (),
34
32 &Event::Start { .. } => { 35 &Event::Start { .. } => {
33 forward_parents.clear(); 36 forward_parents.clear();
34 let mut idx = i; 37 let mut idx = i;
@@ -62,7 +65,7 @@ fn from_events_to_file(
62 } 65 }
63 builder.finish_internal() 66 builder.finish_internal()
64 }, 67 },
65 &Event::Token { kind, mut n_raw_tokens } => loop { 68 &Event::Token { kind: _, mut n_raw_tokens } => loop {
66 let token = tokens[idx]; 69 let token = tokens[idx];
67 if !is_insignificant(token.kind) { 70 if !is_insignificant(token.kind) {
68 n_raw_tokens -= 1; 71 n_raw_tokens -= 1;
diff --git a/src/tree/file_builder.rs b/src/tree/file_builder.rs
index 37bd5b2c8..35702ddd7 100644
--- a/src/tree/file_builder.rs
+++ b/src/tree/file_builder.rs
@@ -48,7 +48,9 @@ impl Sink for FileBuilder {
48 } 48 }
49 49
50 fn finish_internal(&mut self) { 50 fn finish_internal(&mut self) {
51 let (id, _) = self.in_progress.pop().unwrap(); 51 let (id, _) = self.in_progress.pop().expect(
52 "trying to complete a node, but there are no in-progress nodes"
53 );
52 if !self.in_progress.is_empty() { 54 if !self.in_progress.is_empty() {
53 self.add_len(id); 55 self.add_len(id);
54 } 56 }
@@ -77,8 +79,8 @@ impl FileBuilder {
77 self.in_progress.iter().map(|&(idx, _)| self.nodes[idx].kind) 79 self.in_progress.iter().map(|&(idx, _)| self.nodes[idx].kind)
78 .collect::<Vec<_>>() 80 .collect::<Vec<_>>()
79 ); 81 );
80 assert!( 82 assert_eq!(
81 self.pos == (self.text.len() as u32).into(), 83 self.pos, (self.text.len() as u32).into(),
82 "nodes in FileBuilder do not cover the whole file" 84 "nodes in FileBuilder do not cover the whole file"
83 ); 85 );
84 File { 86 File {
diff --git a/src/tree/mod.rs b/src/tree/mod.rs
index d8f843737..3315b926e 100644
--- a/src/tree/mod.rs
+++ b/src/tree/mod.rs
@@ -10,17 +10,24 @@ pub use self::file_builder::{FileBuilder, Sink};
10#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 10#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub struct SyntaxKind(pub(crate) u32); 11pub struct SyntaxKind(pub(crate) u32);
12 12
13pub(crate) const EOF: SyntaxKind = SyntaxKind(10000); 13pub(crate) const EOF: SyntaxKind = SyntaxKind(!0);
14pub(crate) const EOF_INFO: SyntaxInfo = SyntaxInfo { 14pub(crate) const EOF_INFO: SyntaxInfo = SyntaxInfo {
15 name: "EOF" 15 name: "EOF"
16}; 16};
17 17
18pub(crate) const TOMBSTONE: SyntaxKind = SyntaxKind(!0 - 1);
19pub(crate) const TOMBSTONE_INFO: SyntaxInfo = SyntaxInfo {
20 name: "TOMBSTONE"
21};
22
23
18impl SyntaxKind { 24impl SyntaxKind {
19 fn info(self) -> &'static SyntaxInfo { 25 fn info(self) -> &'static SyntaxInfo {
20 if self == EOF { 26 match self {
21 return &EOF_INFO; 27 EOF => &EOF_INFO,
28 TOMBSTONE => &TOMBSTONE_INFO,
29 _ => syntax_info(self),
22 } 30 }
23 syntax_info(self)
24 } 31 }
25} 32}
26 33