aboutsummaryrefslogtreecommitdiff
path: root/src/parser/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/mod.rs')
-rw-r--r--src/parser/mod.rs41
1 files changed, 35 insertions, 6 deletions
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 742755142..c08d32d08 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -18,10 +18,39 @@ fn from_events_to_file(
18) -> File { 18) -> File {
19 let mut builder = FileBuilder::new(text); 19 let mut builder = FileBuilder::new(text);
20 let mut idx = 0; 20 let mut idx = 0;
21 for event in events { 21
22 let mut holes = Vec::new();
23 let mut forward_parents = Vec::new();
24
25 for (i, event) in events.iter().enumerate() {
26 if holes.last() == Some(&i) {
27 holes.pop();
28 continue
29 }
30
22 match event { 31 match event {
23 Event::Start { kind } => builder.start_internal(kind), 32 &Event::Start { kind, forward_parent } => {
24 Event::Finish => { 33 forward_parents.clear();
34 let mut idx = i;
35 loop {
36 let (kind, fwd) = match events[idx] {
37 Event::Start { kind, forward_parent } => (kind, forward_parent),
38 _ => unreachable!(),
39 };
40 forward_parents.push((idx, kind));
41 if let Some(fwd) = fwd {
42 idx += fwd as usize;
43 } else {
44 break;
45 }
46 }
47 for &(idx, kind) in forward_parents.iter().into_iter().rev() {
48 builder.start_internal(kind);
49 holes.push(idx);
50 }
51 holes.pop();
52 }
53 &Event::Finish => {
25 while idx < tokens.len() { 54 while idx < tokens.len() {
26 let token = tokens[idx]; 55 let token = tokens[idx];
27 if is_insignificant(token.kind) { 56 if is_insignificant(token.kind) {
@@ -33,7 +62,7 @@ fn from_events_to_file(
33 } 62 }
34 builder.finish_internal() 63 builder.finish_internal()
35 }, 64 },
36 Event::Token { kind, mut n_raw_tokens } => loop { 65 &Event::Token { kind, mut n_raw_tokens } => loop {
37 let token = tokens[idx]; 66 let token = tokens[idx];
38 if !is_insignificant(token.kind) { 67 if !is_insignificant(token.kind) {
39 n_raw_tokens -= 1; 68 n_raw_tokens -= 1;
@@ -44,8 +73,8 @@ fn from_events_to_file(
44 break; 73 break;
45 } 74 }
46 }, 75 },
47 Event::Error { message } => builder.error().message(message).emit(), 76 &Event::Error { ref message } =>
48 77 builder.error().message(message.clone()).emit(),
49 } 78 }
50 } 79 }
51 builder.finish() 80 builder.finish()