diff options
author | Aleksey Kladov <[email protected]> | 2019-02-20 19:44:06 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-02-20 19:44:06 +0000 |
commit | 2acb21e8f72896c7a2855ca6042d0ee1870d8643 (patch) | |
tree | 7c297534569dcf2b69d6e7af9032318aa7c8cc23 /crates/ra_syntax/src/parsing/parser_impl.rs | |
parent | e72ad0a2faac98972544dd42316ccf8090717102 (diff) |
merge parse_impl and parser_api
Diffstat (limited to 'crates/ra_syntax/src/parsing/parser_impl.rs')
-rw-r--r-- | crates/ra_syntax/src/parsing/parser_impl.rs | 165 |
1 files changed, 10 insertions, 155 deletions
diff --git a/crates/ra_syntax/src/parsing/parser_impl.rs b/crates/ra_syntax/src/parsing/parser_impl.rs index 89439e074..6eed0e656 100644 --- a/crates/ra_syntax/src/parsing/parser_impl.rs +++ b/crates/ra_syntax/src/parsing/parser_impl.rs | |||
@@ -1,20 +1,13 @@ | |||
1 | mod event; | 1 | pub(super) mod event; |
2 | pub(crate) mod input; | 2 | pub(super) mod input; |
3 | 3 | ||
4 | use std::cell::Cell; | 4 | use crate::parsing::{ |
5 | 5 | TreeSink, TokenSource, | |
6 | use crate::{ | 6 | lexer::Token, |
7 | syntax_error::ParseError, | 7 | parser_api::Parser, |
8 | parsing::{ | 8 | parser_impl::event::EventProcessor, |
9 | TreeSink, TokenSource, TokenPos, | ||
10 | lexer::Token, | ||
11 | parser_api::Parser, | ||
12 | parser_impl::event::{Event, EventProcessor}, | ||
13 | }, | ||
14 | }; | 9 | }; |
15 | 10 | ||
16 | use crate::SyntaxKind::{self, EOF, TOMBSTONE}; | ||
17 | |||
18 | /// Parse a sequence of tokens into the representative node tree | 11 | /// Parse a sequence of tokens into the representative node tree |
19 | pub(super) fn parse_with<S: TreeSink>( | 12 | pub(super) fn parse_with<S: TreeSink>( |
20 | sink: S, | 13 | sink: S, |
@@ -24,147 +17,9 @@ pub(super) fn parse_with<S: TreeSink>( | |||
24 | ) -> S::Tree { | 17 | ) -> S::Tree { |
25 | let mut events = { | 18 | let mut events = { |
26 | let input = input::ParserInput::new(text, tokens); | 19 | let input = input::ParserInput::new(text, tokens); |
27 | let parser_impl = ParserImpl::new(&input); | 20 | let mut parser_api = Parser::new(&input); |
28 | let mut parser_api = Parser(parser_impl); | ||
29 | parser(&mut parser_api); | 21 | parser(&mut parser_api); |
30 | parser_api.0.into_events() | 22 | parser_api.finish() |
31 | }; | 23 | }; |
32 | EventProcessor::new(sink, text, tokens, &mut events).process().finish() | 24 | EventProcessor::new(sink, text, tokens, &mut events).process().finish() |
33 | } | 25 | } |
34 | |||
35 | /// Implementation details of `Parser`, extracted | ||
36 | /// to a separate struct in order not to pollute | ||
37 | /// the public API of the `Parser`. | ||
38 | pub(super) struct ParserImpl<'a> { | ||
39 | token_source: &'a dyn TokenSource, | ||
40 | pos: TokenPos, | ||
41 | events: Vec<Event>, | ||
42 | steps: Cell<u32>, | ||
43 | } | ||
44 | |||
45 | impl<'a> ParserImpl<'a> { | ||
46 | fn new(token_source: &'a dyn TokenSource) -> ParserImpl<'a> { | ||
47 | ParserImpl { | ||
48 | token_source, | ||
49 | pos: TokenPos::default(), | ||
50 | events: Vec::new(), | ||
51 | steps: Cell::new(0), | ||
52 | } | ||
53 | } | ||
54 | |||
55 | fn into_events(self) -> Vec<Event> { | ||
56 | assert_eq!(self.nth(0), EOF); | ||
57 | self.events | ||
58 | } | ||
59 | |||
60 | pub(super) fn current2(&self) -> Option<(SyntaxKind, SyntaxKind)> { | ||
61 | let c1 = self.token_source.token_kind(self.pos); | ||
62 | let c2 = self.token_source.token_kind(self.pos + 1); | ||
63 | if self.token_source.is_token_joint_to_next(self.pos) { | ||
64 | Some((c1, c2)) | ||
65 | } else { | ||
66 | None | ||
67 | } | ||
68 | } | ||
69 | |||
70 | pub(super) fn current3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> { | ||
71 | let c1 = self.token_source.token_kind(self.pos); | ||
72 | let c2 = self.token_source.token_kind(self.pos + 1); | ||
73 | let c3 = self.token_source.token_kind(self.pos + 2); | ||
74 | if self.token_source.is_token_joint_to_next(self.pos) | ||
75 | && self.token_source.is_token_joint_to_next(self.pos + 1) | ||
76 | { | ||
77 | Some((c1, c2, c3)) | ||
78 | } else { | ||
79 | None | ||
80 | } | ||
81 | } | ||
82 | |||
83 | /// Get the syntax kind of the nth token. | ||
84 | pub(super) fn nth(&self, n: u32) -> SyntaxKind { | ||
85 | let steps = self.steps.get(); | ||
86 | assert!(steps <= 10_000_000, "the parser seems stuck"); | ||
87 | self.steps.set(steps + 1); | ||
88 | self.token_source.token_kind(self.pos + n) | ||
89 | } | ||
90 | |||
91 | pub(super) fn at_kw(&self, kw: &str) -> bool { | ||
92 | self.token_source.is_keyword(self.pos, kw) | ||
93 | } | ||
94 | |||
95 | /// Start parsing right behind the last event. | ||
96 | pub(super) fn start(&mut self) -> u32 { | ||
97 | let pos = self.events.len() as u32; | ||
98 | self.push_event(Event::tombstone()); | ||
99 | pos | ||
100 | } | ||
101 | |||
102 | /// Advances the parser by one token unconditionally. | ||
103 | pub(super) fn bump(&mut self) { | ||
104 | let kind = self.nth(0); | ||
105 | if kind == EOF { | ||
106 | return; | ||
107 | } | ||
108 | self.do_bump(kind, 1); | ||
109 | } | ||
110 | |||
111 | pub(super) fn bump_remap(&mut self, kind: SyntaxKind) { | ||
112 | if self.nth(0) == EOF { | ||
113 | // TODO: panic!? | ||
114 | return; | ||
115 | } | ||
116 | self.do_bump(kind, 1); | ||
117 | } | ||
118 | |||
119 | pub(super) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) { | ||
120 | self.do_bump(kind, n); | ||
121 | } | ||
122 | |||
123 | fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) { | ||
124 | self.pos += u32::from(n_raw_tokens); | ||
125 | self.push_event(Event::Token { kind, n_raw_tokens }); | ||
126 | } | ||
127 | |||
128 | /// Append one Error event to the back of events. | ||
129 | pub(super) fn error(&mut self, msg: String) { | ||
130 | self.push_event(Event::Error { msg: ParseError(msg) }) | ||
131 | } | ||
132 | |||
133 | /// Complete an event with appending a `Finish` event. | ||
134 | pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) { | ||
135 | match self.events[pos as usize] { | ||
136 | Event::Start { kind: ref mut slot, .. } => { | ||
137 | *slot = kind; | ||
138 | } | ||
139 | _ => unreachable!(), | ||
140 | } | ||
141 | self.push_event(Event::Finish); | ||
142 | } | ||
143 | |||
144 | /// Ignore the dummy `Start` event. | ||
145 | pub(super) fn abandon(&mut self, pos: u32) { | ||
146 | let idx = pos as usize; | ||
147 | if idx == self.events.len() - 1 { | ||
148 | match self.events.pop() { | ||
149 | Some(Event::Start { kind: TOMBSTONE, forward_parent: None }) => (), | ||
150 | _ => unreachable!(), | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /// Save the relative distance of a completed event to its forward_parent. | ||
156 | pub(super) fn precede(&mut self, pos: u32) -> u32 { | ||
157 | let new_pos = self.start(); | ||
158 | match self.events[pos as usize] { | ||
159 | Event::Start { ref mut forward_parent, .. } => { | ||
160 | *forward_parent = Some(new_pos - pos); | ||
161 | } | ||
162 | _ => unreachable!(), | ||
163 | } | ||
164 | new_pos | ||
165 | } | ||
166 | |||
167 | fn push_event(&mut self, event: Event) { | ||
168 | self.events.push(event) | ||
169 | } | ||
170 | } | ||