diff options
author | Aleksey Kladov <[email protected]> | 2018-08-10 20:33:29 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-10 20:33:29 +0100 |
commit | 7c67612b8a894187fa3b64725531a5459f9211bf (patch) | |
tree | 9e2a536efa0c880d921fd8d4d74423afc9451fd4 /src/parser_impl/mod.rs | |
parent | 26262aaf05983c5b7f41cc438e287523268fe1eb (diff) |
organizize
Diffstat (limited to 'src/parser_impl/mod.rs')
-rw-r--r-- | src/parser_impl/mod.rs | 170 |
1 files changed, 0 insertions, 170 deletions
diff --git a/src/parser_impl/mod.rs b/src/parser_impl/mod.rs deleted file mode 100644 index 06c16cdb4..000000000 --- a/src/parser_impl/mod.rs +++ /dev/null | |||
@@ -1,170 +0,0 @@ | |||
1 | mod event; | ||
2 | mod input; | ||
3 | |||
4 | use { | ||
5 | grammar, | ||
6 | lexer::Token, | ||
7 | parser_api::Parser, | ||
8 | parser_impl::{ | ||
9 | event::{process, Event}, | ||
10 | input::{InputPosition, ParserInput}, | ||
11 | }, | ||
12 | TextUnit, | ||
13 | }; | ||
14 | |||
15 | use SyntaxKind::{self, EOF, TOMBSTONE}; | ||
16 | |||
17 | pub(crate) trait Sink<'a> { | ||
18 | type Tree; | ||
19 | |||
20 | fn new(text: &'a str) -> Self; | ||
21 | |||
22 | fn leaf(&mut self, kind: SyntaxKind, len: TextUnit); | ||
23 | fn start_internal(&mut self, kind: SyntaxKind); | ||
24 | fn finish_internal(&mut self); | ||
25 | fn error(&mut self, err: String); | ||
26 | fn finish(self) -> Self::Tree; | ||
27 | } | ||
28 | |||
29 | /// Parse a sequence of tokens into the representative node tree | ||
30 | pub(crate) fn parse<'a, S: Sink<'a>>(text: &'a str, tokens: &[Token]) -> S::Tree { | ||
31 | let events = { | ||
32 | let input = input::ParserInput::new(text, tokens); | ||
33 | let parser_impl = ParserImpl::new(&input); | ||
34 | let mut parser_api = Parser(parser_impl); | ||
35 | grammar::file(&mut parser_api); | ||
36 | parser_api.0.into_events() | ||
37 | }; | ||
38 | let mut sink = S::new(text); | ||
39 | process(&mut sink, tokens, events); | ||
40 | sink.finish() | ||
41 | } | ||
42 | |||
43 | /// Implementation details of `Parser`, extracted | ||
44 | /// to a separate struct in order not to pollute | ||
45 | /// the public API of the `Parser`. | ||
46 | pub(crate) struct ParserImpl<'t> { | ||
47 | inp: &'t ParserInput<'t>, | ||
48 | |||
49 | pos: InputPosition, | ||
50 | events: Vec<Event>, | ||
51 | } | ||
52 | |||
53 | impl<'t> ParserImpl<'t> { | ||
54 | pub(crate) fn new(inp: &'t ParserInput<'t>) -> ParserImpl<'t> { | ||
55 | ParserImpl { | ||
56 | inp, | ||
57 | |||
58 | pos: InputPosition::new(), | ||
59 | events: Vec::new(), | ||
60 | } | ||
61 | } | ||
62 | |||
63 | pub(crate) fn into_events(self) -> Vec<Event> { | ||
64 | assert_eq!(self.nth(0), EOF); | ||
65 | self.events | ||
66 | } | ||
67 | |||
68 | pub(super) fn at_compound2(&self, c1: SyntaxKind, c2: SyntaxKind) -> bool { | ||
69 | self.inp.kind(self.pos) == c1 && self.inp.kind(self.pos + 1) == c2 | ||
70 | && self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) | ||
71 | } | ||
72 | |||
73 | pub(super) fn at_compound3(&self, c1: SyntaxKind, c2: SyntaxKind, c3: SyntaxKind) -> bool { | ||
74 | self.inp.kind(self.pos) == c1 && self.inp.kind(self.pos + 1) == c2 && self.inp.kind(self.pos + 2) == c3 | ||
75 | && self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) | ||
76 | && self.inp.start(self.pos + 2) == self.inp.start(self.pos + 1) + self.inp.len(self.pos + 1) | ||
77 | } | ||
78 | |||
79 | pub(super) fn nth(&self, n: u32) -> SyntaxKind { | ||
80 | self.inp.kind(self.pos + n) | ||
81 | } | ||
82 | |||
83 | pub(super) fn at_kw(&self, t: &str) -> bool { | ||
84 | self.inp.text(self.pos) == t | ||
85 | } | ||
86 | |||
87 | pub(super) fn start(&mut self) -> u32 { | ||
88 | let pos = self.events.len() as u32; | ||
89 | self.event(Event::Start { | ||
90 | kind: TOMBSTONE, | ||
91 | forward_parent: None, | ||
92 | }); | ||
93 | pos | ||
94 | } | ||
95 | |||
96 | pub(super) fn bump(&mut self) { | ||
97 | let kind = self.nth(0); | ||
98 | if kind == EOF { | ||
99 | return; | ||
100 | } | ||
101 | self.do_bump(kind, 1); | ||
102 | } | ||
103 | |||
104 | pub(super) fn bump_remap(&mut self, kind: SyntaxKind) { | ||
105 | if self.nth(0) == EOF { | ||
106 | // TODO: panic!? | ||
107 | return; | ||
108 | } | ||
109 | self.do_bump(kind, 1); | ||
110 | } | ||
111 | |||
112 | pub(super) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) { | ||
113 | self.do_bump(kind, n); | ||
114 | } | ||
115 | |||
116 | fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) { | ||
117 | self.pos += u32::from(n_raw_tokens); | ||
118 | self.event(Event::Token { | ||
119 | kind, | ||
120 | n_raw_tokens, | ||
121 | }); | ||
122 | } | ||
123 | |||
124 | pub(super) fn error(&mut self, msg: String) { | ||
125 | self.event(Event::Error { msg }) | ||
126 | } | ||
127 | |||
128 | pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) { | ||
129 | match self.events[pos as usize] { | ||
130 | Event::Start { | ||
131 | kind: ref mut slot, .. | ||
132 | } => { | ||
133 | *slot = kind; | ||
134 | } | ||
135 | _ => unreachable!(), | ||
136 | } | ||
137 | self.event(Event::Finish); | ||
138 | } | ||
139 | |||
140 | pub(super) fn abandon(&mut self, pos: u32) { | ||
141 | let idx = pos as usize; | ||
142 | if idx == self.events.len() - 1 { | ||
143 | match self.events.pop() { | ||
144 | Some(Event::Start { | ||
145 | kind: TOMBSTONE, | ||
146 | forward_parent: None, | ||
147 | }) => (), | ||
148 | _ => unreachable!(), | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | |||
153 | pub(super) fn precede(&mut self, pos: u32) -> u32 { | ||
154 | let new_pos = self.start(); | ||
155 | match self.events[pos as usize] { | ||
156 | Event::Start { | ||
157 | ref mut forward_parent, | ||
158 | .. | ||
159 | } => { | ||
160 | *forward_parent = Some(new_pos - pos); | ||
161 | } | ||
162 | _ => unreachable!(), | ||
163 | } | ||
164 | new_pos | ||
165 | } | ||
166 | |||
167 | fn event(&mut self, event: Event) { | ||
168 | self.events.push(event) | ||
169 | } | ||
170 | } | ||