aboutsummaryrefslogtreecommitdiff
path: root/src/parser/mod.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/mod.rs
parent5e5313a7c71d8aa873b418575f56d23b2eac6e7f (diff)
parentd4179550cd69a23a79ed27a96b93f9f760c02b69 (diff)
Merge #41
41: G: unsafe impl & trait r=matklad a=matklad bors r+
Diffstat (limited to 'src/parser/mod.rs')
-rw-r--r--src/parser/mod.rs91
1 files changed, 12 insertions, 79 deletions
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index c5525ff9c..f17ffbf3a 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -1,88 +1,21 @@
1use {File, FileBuilder, Sink, SyntaxKind, Token}; 1use {File, SyntaxKind, Token};
2 2
3use syntax_kinds::*; 3use syntax_kinds::*;
4 4
5mod event_parser; 5#[macro_use]
6use self::event_parser::Event; 6mod parser;
7mod event;
8mod grammar;
9use self::event::Event;
7 10
8/// Parse a sequence of tokens into the representative node tree 11/// Parse a sequence of tokens into the representative node tree
9pub fn parse(text: String, tokens: &[Token]) -> File { 12pub fn parse(text: String, tokens: &[Token]) -> File {
10 let events = event_parser::parse(&text, tokens); 13 let events = {
11 from_events_to_file(text, tokens, events) 14 let mut parser = parser::Parser::new(&text, tokens);
12} 15 grammar::file(&mut parser);
13 16 parser.into_events()
14fn from_events_to_file(text: String, tokens: &[Token], events: Vec<Event>) -> File { 17 };
15 let mut builder = FileBuilder::new(text); 18 event::to_file(text, tokens, events)
16 let mut idx = 0;
17
18 let mut holes = Vec::new();
19 let mut forward_parents = Vec::new();
20
21 for (i, event) in events.iter().enumerate() {
22 if holes.last() == Some(&i) {
23 holes.pop();
24 continue;
25 }
26
27 match event {
28 &Event::Start {
29 kind: TOMBSTONE, ..
30 } => (),
31
32 &Event::Start { .. } => {
33 forward_parents.clear();
34 let mut idx = i;
35 loop {
36 let (kind, fwd) = match events[idx] {
37 Event::Start {
38 kind,
39 forward_parent,
40 } => (kind, forward_parent),
41 _ => unreachable!(),
42 };
43 forward_parents.push((idx, kind));
44 if let Some(fwd) = fwd {
45 idx += fwd as usize;
46 } else {
47 break;
48 }
49 }
50 for &(idx, kind) in forward_parents.iter().into_iter().rev() {
51 builder.start_internal(kind);
52 holes.push(idx);
53 }
54 holes.pop();
55 }
56 &Event::Finish => {
57 while idx < tokens.len() {
58 let token = tokens[idx];
59 if is_insignificant(token.kind) {
60 idx += 1;
61 builder.leaf(token.kind, token.len);
62 } else {
63 break;
64 }
65 }
66 builder.finish_internal()
67 }
68 &Event::Token {
69 kind: _,
70 mut n_raw_tokens,
71 } => loop {
72 let token = tokens[idx];
73 if !is_insignificant(token.kind) {
74 n_raw_tokens -= 1;
75 }
76 idx += 1;
77 builder.leaf(token.kind, token.len);
78 if n_raw_tokens == 0 {
79 break;
80 }
81 },
82 &Event::Error { ref message } => builder.error().message(message.clone()).emit(),
83 }
84 }
85 builder.finish()
86} 19}
87 20
88fn is_insignificant(kind: SyntaxKind) -> bool { 21fn is_insignificant(kind: SyntaxKind) -> bool {