aboutsummaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-02-11 13:53:57 +0000
committerAleksey Kladov <[email protected]>2018-02-11 13:53:57 +0000
commit9e2c0564783aa91f6440e7cadcc1a4dfda785de0 (patch)
tree4a6ef12405bf0562f4875b48cc1c834195ce7920 /src/parser
parent7a0ada860b57acd44b1d53e944ae621e438652da (diff)
Separate parser API from implementation
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/event.rs6
-rw-r--r--src/parser/grammar/mod.rs3
-rw-r--r--src/parser/mod.rs37
-rw-r--r--src/parser/parser.rs193
-rw-r--r--src/parser/parser/imp.rs118
-rw-r--r--src/parser/parser/mod.rs100
-rw-r--r--src/parser/token_set.rs25
7 files changed, 252 insertions, 230 deletions
diff --git a/src/parser/event.rs b/src/parser/event.rs
index 90348398e..30fe5c6d7 100644
--- a/src/parser/event.rs
+++ b/src/parser/event.rs
@@ -61,7 +61,7 @@ pub(crate) enum Event {
61 }, 61 },
62 62
63 Error { 63 Error {
64 message: String, 64 msg: String,
65 }, 65 },
66} 66}
67 67
@@ -140,8 +140,8 @@ pub(super) fn to_file(text: String, tokens: &[Token], events: Vec<Event>) -> Fil
140 } 140 }
141 builder.leaf(kind, len); 141 builder.leaf(kind, len);
142 } 142 }
143 &Event::Error { ref message } => builder.error(ErrorMsg { 143 &Event::Error { ref msg } => builder.error(ErrorMsg {
144 message: message.clone(), 144 msg: msg.clone(),
145 }), 145 }),
146 } 146 }
147 } 147 }
diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs
index f5b63aaab..e29cf9b02 100644
--- a/src/parser/grammar/mod.rs
+++ b/src/parser/grammar/mod.rs
@@ -1,4 +1,5 @@
1use super::parser::{Parser, TokenSet}; 1use parser::parser::{Parser};
2use parser::token_set::TokenSet;
2use SyntaxKind; 3use SyntaxKind;
3use syntax_kinds::*; 4use syntax_kinds::*;
4 5
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index c23ed3349..3814837e1 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -3,19 +3,20 @@ use {File, SyntaxKind, Token};
3use syntax_kinds::*; 3use syntax_kinds::*;
4 4
5#[macro_use] 5#[macro_use]
6mod token_set;
6mod parser; 7mod parser;
7mod input; 8mod input;
8mod event; 9mod event;
9mod grammar; 10mod grammar;
10use self::event::Event;
11 11
12/// Parse a sequence of tokens into the representative node tree 12/// Parse a sequence of tokens into the representative node tree
13pub fn parse(text: String, tokens: &[Token]) -> File { 13pub fn parse(text: String, tokens: &[Token]) -> File {
14 let events = { 14 let events = {
15 let input = input::ParserInput::new(&text, tokens); 15 let input = input::ParserInput::new(&text, tokens);
16 let mut parser = parser::Parser::new(&input); 16 let parser_impl = parser::imp::ParserImpl::new(&input);
17 let mut parser = parser::Parser(parser_impl);
17 grammar::file(&mut parser); 18 grammar::file(&mut parser);
18 parser.into_events() 19 parser.0.into_events()
19 }; 20 };
20 event::to_file(text, tokens, events) 21 event::to_file(text, tokens, events)
21} 22}
@@ -26,33 +27,3 @@ fn is_insignificant(kind: SyntaxKind) -> bool {
26 _ => false, 27 _ => false,
27 } 28 }
28} 29}
29
30impl<'p> parser::Parser<'p> {
31 fn at(&self, kind: SyntaxKind) -> bool {
32 self.current() == kind
33 }
34
35 fn err_and_bump(&mut self, message: &str) {
36 let err = self.start();
37 self.error(message);
38 self.bump();
39 err.complete(self, ERROR);
40 }
41
42 fn expect(&mut self, kind: SyntaxKind) -> bool {
43 if self.at(kind) {
44 self.bump();
45 true
46 } else {
47 self.error(format!("expected {:?}", kind));
48 false
49 }
50 }
51
52 fn eat(&mut self, kind: SyntaxKind) -> bool {
53 self.at(kind) && {
54 self.bump();
55 true
56 }
57 }
58}
diff --git a/src/parser/parser.rs b/src/parser/parser.rs
deleted file mode 100644
index 7c8e47cb6..000000000
--- a/src/parser/parser.rs
+++ /dev/null
@@ -1,193 +0,0 @@
1use super::Event;
2use super::input::{InputPosition, ParserInput};
3use SyntaxKind::{self, EOF, TOMBSTONE};
4
5pub(crate) struct Marker {
6 pos: u32,
7}
8
9impl Marker {
10 pub fn complete(self, p: &mut Parser, kind: SyntaxKind) -> CompleteMarker {
11 match self.event(p) {
12 &mut Event::Start {
13 kind: ref mut slot, ..
14 } => {
15 *slot = kind;
16 }
17 _ => unreachable!(),
18 }
19 p.event(Event::Finish);
20 let result = CompleteMarker { pos: self.pos };
21 ::std::mem::forget(self);
22 result
23 }
24
25 pub fn abandon(self, p: &mut Parser) {
26 let idx = self.pos as usize;
27 if idx == p.events.len() - 1 {
28 match p.events.pop() {
29 Some(Event::Start {
30 kind: TOMBSTONE,
31 forward_parent: None,
32 }) => (),
33 _ => unreachable!(),
34 }
35 }
36 ::std::mem::forget(self);
37 }
38
39 fn event<'p>(&self, p: &'p mut Parser) -> &'p mut Event {
40 &mut p.events[self.idx()]
41 }
42
43 fn idx(&self) -> usize {
44 self.pos as usize
45 }
46}
47
48impl Drop for Marker {
49 fn drop(&mut self) {
50 if !::std::thread::panicking() {
51 panic!("Each marker should be eithe completed or abandoned");
52 }
53 }
54}
55
56pub(crate) struct CompleteMarker {
57 pos: u32,
58}
59
60impl CompleteMarker {
61 pub(crate) fn precede(self, p: &mut Parser) -> Marker {
62 let m = p.start();
63 match p.events[self.pos as usize] {
64 Event::Start {
65 ref mut forward_parent,
66 ..
67 } => {
68 *forward_parent = Some(m.pos - self.pos);
69 }
70 _ => unreachable!(),
71 }
72 m
73 }
74}
75
76pub(crate) struct TokenSet {
77 pub tokens: &'static [SyntaxKind],
78}
79
80impl TokenSet {
81 pub fn contains(&self, kind: SyntaxKind) -> bool {
82 self.tokens.contains(&kind)
83 }
84}
85
86#[macro_export]
87macro_rules! token_set {
88 ($($t:ident),*) => {
89 TokenSet {
90 tokens: &[$($t),*],
91 }
92 };
93
94 ($($t:ident),* ,) => {
95 token_set!($($t),*)
96 };
97}
98
99pub(crate) struct Parser<'t> {
100 inp: &'t ParserInput<'t>,
101
102 pos: InputPosition,
103 events: Vec<Event>,
104}
105
106impl<'t> Parser<'t> {
107 pub(crate) fn new(inp: &'t ParserInput<'t>) -> Parser<'t> {
108 Parser {
109 inp,
110
111 pos: InputPosition::new(),
112 events: Vec::new(),
113 }
114 }
115
116 pub(crate) fn into_events(self) -> Vec<Event> {
117 assert_eq!(self.current(), EOF);
118 self.events
119 }
120
121 pub(crate) fn start(&mut self) -> Marker {
122 let m = Marker {
123 pos: self.events.len() as u32,
124 };
125 self.event(Event::Start {
126 kind: TOMBSTONE,
127 forward_parent: None,
128 });
129 m
130 }
131
132 pub(crate) fn error<'p, T: Into<String>>(&'p mut self, msg: T) -> ErrorBuilder<'p, 't> {
133 ErrorBuilder::new(self, msg.into())
134 }
135
136 pub(crate) fn bump(&mut self) {
137 let kind = self.current();
138 if kind == EOF {
139 return;
140 }
141 self.pos += 1;
142 self.event(Event::Token {
143 kind,
144 n_raw_tokens: 1,
145 });
146 }
147
148 pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) {
149 if self.current() == EOF {
150 // TODO: panic!?
151 return;
152 }
153 self.pos += 1;
154 self.event(Event::Token {
155 kind,
156 n_raw_tokens: 1,
157 });
158 }
159
160 pub(crate) fn nth(&self, n: u32) -> SyntaxKind {
161 self.inp.kind(self.pos + n)
162 }
163
164 pub(crate) fn at_kw(&self, t: &str) -> bool {
165 self.inp.text(self.pos) == t
166 }
167
168 pub(crate) fn current(&self) -> SyntaxKind {
169 self.nth(0)
170 }
171
172 fn event(&mut self, event: Event) {
173 self.events.push(event)
174 }
175}
176
177pub(crate) struct ErrorBuilder<'p, 't: 'p> {
178 message: String,
179 parser: &'p mut Parser<'t>,
180}
181
182impl<'p, 't: 'p> Drop for ErrorBuilder<'p, 't> {
183 fn drop(&mut self) {
184 let message = ::std::mem::replace(&mut self.message, String::new());
185 self.parser.event(Event::Error { message });
186 }
187}
188
189impl<'t, 'p> ErrorBuilder<'p, 't> {
190 fn new(parser: &'p mut Parser<'t>, message: String) -> Self {
191 ErrorBuilder { message, parser }
192 }
193}
diff --git a/src/parser/parser/imp.rs b/src/parser/parser/imp.rs
new file mode 100644
index 000000000..2b16e11b9
--- /dev/null
+++ b/src/parser/parser/imp.rs
@@ -0,0 +1,118 @@
1use parser::input::{ParserInput, InputPosition};
2use parser::event::Event;
3
4use SyntaxKind;
5use syntax_kinds::{TOMBSTONE, EOF};
6
7pub(crate) struct ParserImpl<'t> {
8 inp: &'t ParserInput<'t>,
9
10 pos: InputPosition,
11 events: Vec<Event>,
12}
13
14impl<'t> ParserImpl<'t> {
15 pub(crate) fn new(inp: &'t ParserInput<'t>) -> ParserImpl<'t> {
16 ParserImpl {
17 inp,
18
19 pos: InputPosition::new(),
20 events: Vec::new(),
21 }
22 }
23
24 pub(crate) fn into_events(self) -> Vec<Event> {
25 assert_eq!(self.nth(0), EOF);
26 self.events
27 }
28
29
30 pub(super) fn nth(&self, n: u32) -> SyntaxKind {
31 self.inp.kind(self.pos + n)
32 }
33
34 pub(super) fn at_kw(&self, t: &str) -> bool {
35 self.inp.text(self.pos) == t
36 }
37
38 pub(super) fn start(&mut self) -> u32 {
39 let pos = self.events.len() as u32;
40 self.event(Event::Start {
41 kind: TOMBSTONE,
42 forward_parent: None,
43 });
44 pos
45 }
46
47 pub(super) fn bump(&mut self) {
48 let kind = self.nth(0);
49 if kind == EOF {
50 return;
51 }
52 self.do_bump(kind);
53 }
54
55 pub(super) fn bump_remap(&mut self, kind: SyntaxKind) {
56 if self.nth(0) == EOF {
57 // TODO: panic!?
58 return;
59 }
60 self.do_bump(kind);
61 }
62
63 fn do_bump(&mut self, kind: SyntaxKind) {
64 self.pos += 1;
65 self.event(Event::Token {
66 kind,
67 n_raw_tokens: 1,
68 });
69 }
70
71 pub(super) fn error(&mut self, msg: String) {
72 self.event(Event::Error { msg })
73 }
74
75 pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) {
76 match self.events[pos as usize] {
77 Event::Start {
78 kind: ref mut slot, ..
79 } => {
80 *slot = kind;
81 }
82 _ => unreachable!(),
83 }
84 self.event(Event::Finish);
85 }
86
87 pub(super) fn abandon(&mut self, pos: u32) {
88 let idx = pos as usize;
89 if idx == self.events.len() - 1 {
90 match self.events.pop() {
91 Some(Event::Start {
92 kind: TOMBSTONE,
93 forward_parent: None,
94 }) => (),
95 _ => unreachable!(),
96 }
97 }
98 }
99
100 pub(super) fn precede(&mut self, pos: u32) -> u32 {
101 let new_pos = self.start();
102 match self.events[pos as usize] {
103 Event::Start {
104 ref mut forward_parent,
105 ..
106 } => {
107 *forward_parent = Some(new_pos - pos);
108 }
109 _ => unreachable!(),
110 }
111 new_pos
112 }
113
114
115 fn event(&mut self, event: Event) {
116 self.events.push(event)
117 }
118}
diff --git a/src/parser/parser/mod.rs b/src/parser/parser/mod.rs
new file mode 100644
index 000000000..c8db20918
--- /dev/null
+++ b/src/parser/parser/mod.rs
@@ -0,0 +1,100 @@
1use SyntaxKind;
2use syntax_kinds::ERROR;
3
4pub(super) mod imp;
5use self::imp::ParserImpl;
6
7pub(crate) struct Parser<'t>(pub(super) ParserImpl<'t>);
8
9
10impl<'t> Parser<'t> {
11 pub(crate) fn current(&self) -> SyntaxKind {
12 self.nth(0)
13 }
14
15 pub(crate) fn nth(&self, n: u32) -> SyntaxKind {
16 self.0.nth(n)
17 }
18
19 pub(crate) fn at(&self, kind: SyntaxKind) -> bool {
20 self.current() == kind
21 }
22
23 pub(crate) fn at_kw(&self, t: &str) -> bool {
24 self.0.at_kw(t)
25 }
26
27 pub(crate) fn start(&mut self) -> Marker {
28 Marker(self.0.start())
29 }
30
31 pub(crate) fn bump(&mut self) {
32 self.0.bump();
33 }
34
35 pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) {
36 self.0.bump_remap(kind);
37 }
38
39 pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
40 self.0.error(message.into())
41 }
42
43 pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool {
44 if self.at(kind) {
45 self.bump();
46 return true;
47 }
48 self.error(format!("expected {:?}", kind));
49 false
50 }
51
52 pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool {
53 if !self.at(kind) {
54 return false;
55 }
56 self.bump();
57 true
58 }
59
60 pub(crate) fn err_and_bump(&mut self, message: &str) {
61 let m = self.start();
62 self.error(message);
63 self.bump();
64 m.complete(self, ERROR);
65 }
66}
67
68pub(crate) struct Marker(u32);
69
70impl Marker {
71 pub(crate) fn complete(self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {
72 let pos = self.0;
73 ::std::mem::forget(self);
74 p.0.complete(pos, kind);
75 CompletedMarker(pos)
76 }
77
78 pub(crate) fn abandon(self, p: &mut Parser) {
79 let pos = self.0;
80 ::std::mem::forget(self);
81 p.0.abandon(pos);
82 }
83}
84
85impl Drop for Marker {
86 fn drop(&mut self) {
87 if !::std::thread::panicking() {
88 panic!("Marker must be either completed or abandoned");
89 }
90 }
91}
92
93
94pub(crate) struct CompletedMarker(u32);
95
96impl CompletedMarker {
97 pub(crate) fn precede(self, p: &mut Parser) -> Marker {
98 Marker(p.0.precede(self.0))
99 }
100}
diff --git a/src/parser/token_set.rs b/src/parser/token_set.rs
new file mode 100644
index 000000000..82558fa2e
--- /dev/null
+++ b/src/parser/token_set.rs
@@ -0,0 +1,25 @@
1use SyntaxKind;
2
3pub(crate) struct TokenSet {
4 pub tokens: &'static [SyntaxKind],
5}
6
7impl TokenSet {
8 pub fn contains(&self, kind: SyntaxKind) -> bool {
9 self.tokens.contains(&kind)
10 }
11}
12
13#[macro_export]
14macro_rules! token_set {
15 ($($t:ident),*) => {
16 TokenSet {
17 tokens: &[$($t),*],
18 }
19 };
20
21 ($($t:ident),* ,) => {
22 token_set!($($t),*)
23 };
24}
25