aboutsummaryrefslogtreecommitdiff
path: root/src/parser_impl/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser_impl/mod.rs')
-rw-r--r--src/parser_impl/mod.rs155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/parser_impl/mod.rs b/src/parser_impl/mod.rs
new file mode 100644
index 000000000..b58094be3
--- /dev/null
+++ b/src/parser_impl/mod.rs
@@ -0,0 +1,155 @@
1mod event;
2mod input;
3
4use {
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
15use SyntaxKind::{self, EOF, TOMBSTONE};
16
17pub(crate) trait Sink {
18 type Tree;
19
20 fn new(text: String) -> 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
30pub(crate) fn parse<S: Sink>(text: String, 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`.
46pub(crate) struct ParserImpl<'t> {
47 inp: &'t ParserInput<'t>,
48
49 pos: InputPosition,
50 events: Vec<Event>,
51}
52
53impl<'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 nth(&self, n: u32) -> SyntaxKind {
69 self.inp.kind(self.pos + n)
70 }
71
72 pub(super) fn at_kw(&self, t: &str) -> bool {
73 self.inp.text(self.pos) == t
74 }
75
76 pub(super) fn start(&mut self) -> u32 {
77 let pos = self.events.len() as u32;
78 self.event(Event::Start {
79 kind: TOMBSTONE,
80 forward_parent: None,
81 });
82 pos
83 }
84
85 pub(super) fn bump(&mut self) {
86 let kind = self.nth(0);
87 if kind == EOF {
88 return;
89 }
90 self.do_bump(kind);
91 }
92
93 pub(super) fn bump_remap(&mut self, kind: SyntaxKind) {
94 if self.nth(0) == EOF {
95 // TODO: panic!?
96 return;
97 }
98 self.do_bump(kind);
99 }
100
101 fn do_bump(&mut self, kind: SyntaxKind) {
102 self.pos += 1;
103 self.event(Event::Token {
104 kind,
105 n_raw_tokens: 1,
106 });
107 }
108
109 pub(super) fn error(&mut self, msg: String) {
110 self.event(Event::Error { msg })
111 }
112
113 pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) {
114 match self.events[pos as usize] {
115 Event::Start {
116 kind: ref mut slot, ..
117 } => {
118 *slot = kind;
119 }
120 _ => unreachable!(),
121 }
122 self.event(Event::Finish);
123 }
124
125 pub(super) fn abandon(&mut self, pos: u32) {
126 let idx = pos as usize;
127 if idx == self.events.len() - 1 {
128 match self.events.pop() {
129 Some(Event::Start {
130 kind: TOMBSTONE,
131 forward_parent: None,
132 }) => (),
133 _ => unreachable!(),
134 }
135 }
136 }
137
138 pub(super) fn precede(&mut self, pos: u32) -> u32 {
139 let new_pos = self.start();
140 match self.events[pos as usize] {
141 Event::Start {
142 ref mut forward_parent,
143 ..
144 } => {
145 *forward_parent = Some(new_pos - pos);
146 }
147 _ => unreachable!(),
148 }
149 new_pos
150 }
151
152 fn event(&mut self, event: Event) {
153 self.events.push(event)
154 }
155}