aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/parsing/parser_impl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/parsing/parser_impl.rs')
-rw-r--r--crates/ra_syntax/src/parsing/parser_impl.rs165
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 @@
1mod event; 1pub(super) mod event;
2pub(crate) mod input; 2pub(super) mod input;
3 3
4use std::cell::Cell; 4use crate::parsing::{
5 5 TreeSink, TokenSource,
6use 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
16use 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
19pub(super) fn parse_with<S: TreeSink>( 12pub(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`.
38pub(super) struct ParserImpl<'a> {
39 token_source: &'a dyn TokenSource,
40 pos: TokenPos,
41 events: Vec<Event>,
42 steps: Cell<u32>,
43}
44
45impl<'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}