diff options
Diffstat (limited to 'src/parser/mod.rs')
-rw-r--r-- | src/parser/mod.rs | 91 |
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 @@ | |||
1 | use {File, FileBuilder, Sink, SyntaxKind, Token}; | 1 | use {File, SyntaxKind, Token}; |
2 | 2 | ||
3 | use syntax_kinds::*; | 3 | use syntax_kinds::*; |
4 | 4 | ||
5 | mod event_parser; | 5 | #[macro_use] |
6 | use self::event_parser::Event; | 6 | mod parser; |
7 | mod event; | ||
8 | mod grammar; | ||
9 | use 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 |
9 | pub fn parse(text: String, tokens: &[Token]) -> File { | 12 | pub 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() | |
14 | fn 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 | ||
88 | fn is_insignificant(kind: SyntaxKind) -> bool { | 21 | fn is_insignificant(kind: SyntaxKind) -> bool { |