aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/parser_api.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-02-20 12:47:32 +0000
committerAleksey Kladov <[email protected]>2019-02-20 12:47:32 +0000
commit5222b8aba3b1c2c68706aacf6869423a8e4fe6d5 (patch)
treec8a6e999b8ac5f1f29bde86a2e0b3a53466bb369 /crates/ra_syntax/src/parser_api.rs
parent9d0cda4bc84350961f3884e75a1c20e62c449ede (diff)
move all parsing related bits to a separate module
Diffstat (limited to 'crates/ra_syntax/src/parser_api.rs')
-rw-r--r--crates/ra_syntax/src/parser_api.rs193
1 files changed, 0 insertions, 193 deletions
diff --git a/crates/ra_syntax/src/parser_api.rs b/crates/ra_syntax/src/parser_api.rs
deleted file mode 100644
index dc556190d..000000000
--- a/crates/ra_syntax/src/parser_api.rs
+++ /dev/null
@@ -1,193 +0,0 @@
1use drop_bomb::DropBomb;
2
3use crate::{
4 parser_impl::ParserImpl,
5 token_set::TokenSet,
6 SyntaxKind::{self, ERROR},
7};
8
9/// `Parser` struct provides the low-level API for
10/// navigating through the stream of tokens and
11/// constructing the parse tree. The actual parsing
12/// happens in the `grammar` module.
13///
14/// However, the result of this `Parser` is not a real
15/// tree, but rather a flat stream of events of the form
16/// "start expression, consume number literal,
17/// finish expression". See `Event` docs for more.
18pub(crate) struct Parser<'t>(pub(super) ParserImpl<'t>);
19
20impl<'t> Parser<'t> {
21 /// Returns the kind of the current token.
22 /// If parser has already reached the end of input,
23 /// the special `EOF` kind is returned.
24 pub(crate) fn current(&self) -> SyntaxKind {
25 self.nth(0)
26 }
27
28 /// Returns the kinds of the current two tokens, if they are not separated
29 /// by trivia.
30 ///
31 /// Useful for parsing things like `>>`.
32 pub(crate) fn current2(&self) -> Option<(SyntaxKind, SyntaxKind)> {
33 self.0.current2()
34 }
35
36 /// Returns the kinds of the current three tokens, if they are not separated
37 /// by trivia.
38 ///
39 /// Useful for parsing things like `=>>`.
40 pub(crate) fn current3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> {
41 self.0.current3()
42 }
43
44 /// Lookahead operation: returns the kind of the next nth
45 /// token.
46 pub(crate) fn nth(&self, n: u32) -> SyntaxKind {
47 self.0.nth(n)
48 }
49
50 /// Checks if the current token is `kind`.
51 pub(crate) fn at(&self, kind: SyntaxKind) -> bool {
52 self.current() == kind
53 }
54
55 /// Checks if the current token is in `kinds`.
56 pub(crate) fn at_ts(&self, kinds: TokenSet) -> bool {
57 kinds.contains(self.current())
58 }
59
60 /// Checks if the current token is contextual keyword with text `t`.
61 pub(crate) fn at_contextual_kw(&self, t: &str) -> bool {
62 self.0.at_kw(t)
63 }
64
65 /// Starts a new node in the syntax tree. All nodes and tokens
66 /// consumed between the `start` and the corresponding `Marker::complete`
67 /// belong to the same node.
68 pub(crate) fn start(&mut self) -> Marker {
69 Marker::new(self.0.start())
70 }
71
72 /// Advances the parser by one token unconditionally.
73 pub(crate) fn bump(&mut self) {
74 self.0.bump();
75 }
76
77 /// Advances the parser by one token, remapping its kind.
78 /// This is useful to create contextual keywords from
79 /// identifiers. For example, the lexer creates an `union`
80 /// *identifier* token, but the parser remaps it to the
81 /// `union` keyword, and keyword is what ends up in the
82 /// final tree.
83 pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) {
84 self.0.bump_remap(kind);
85 }
86
87 /// Advances the parser by `n` tokens, remapping its kind.
88 /// This is useful to create compound tokens from parts. For
89 /// example, an `<<` token is two consecutive remapped `<` tokens
90 pub(crate) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) {
91 self.0.bump_compound(kind, n);
92 }
93
94 /// Emit error with the `message`
95 /// TODO: this should be much more fancy and support
96 /// structured errors with spans and notes, like rustc
97 /// does.
98 pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
99 self.0.error(message.into())
100 }
101
102 /// Consume the next token if `kind` matches.
103 pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool {
104 if !self.at(kind) {
105 return false;
106 }
107 self.bump();
108 true
109 }
110
111 /// Consume the next token if it is `kind` or emit an error
112 /// otherwise.
113 pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool {
114 if self.eat(kind) {
115 return true;
116 }
117 self.error(format!("expected {:?}", kind));
118 false
119 }
120
121 /// Create an error node and consume the next token.
122 pub(crate) fn err_and_bump(&mut self, message: &str) {
123 self.err_recover(message, TokenSet::empty());
124 }
125
126 /// Create an error node and consume the next token.
127 pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
128 if self.at(SyntaxKind::L_CURLY) || self.at(SyntaxKind::R_CURLY) || self.at_ts(recovery) {
129 self.error(message);
130 } else {
131 let m = self.start();
132 self.error(message);
133 self.bump();
134 m.complete(self, ERROR);
135 };
136 }
137}
138
139/// See `Parser::start`.
140pub(crate) struct Marker {
141 pos: u32,
142 bomb: DropBomb,
143}
144
145impl Marker {
146 fn new(pos: u32) -> Marker {
147 Marker { pos, bomb: DropBomb::new("Marker must be either completed or abandoned") }
148 }
149
150 /// Finishes the syntax tree node and assigns `kind` to it,
151 /// and mark the create a `CompletedMarker` for possible future
152 /// operation like `.precede()` to deal with forward_parent.
153 pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {
154 self.bomb.defuse();
155 p.0.complete(self.pos, kind);
156 CompletedMarker::new(self.pos, kind)
157 }
158
159 /// Abandons the syntax tree node. All its children
160 /// are attached to its parent instead.
161 pub(crate) fn abandon(mut self, p: &mut Parser) {
162 self.bomb.defuse();
163 p.0.abandon(self.pos);
164 }
165}
166
167pub(crate) struct CompletedMarker(u32, SyntaxKind);
168
169impl CompletedMarker {
170 fn new(pos: u32, kind: SyntaxKind) -> Self {
171 CompletedMarker(pos, kind)
172 }
173
174 /// This method allows to create a new node which starts
175 /// *before* the current one. That is, parser could start
176 /// node `A`, then complete it, and then after parsing the
177 /// whole `A`, decide that it should have started some node
178 /// `B` before starting `A`. `precede` allows to do exactly
179 /// that. See also docs about `forward_parent` in `Event::Start`.
180 ///
181 /// Given completed events `[START, FINISH]` and its corresponding
182 /// `CompletedMarker(pos: 0, _)`.
183 /// Append a new `START` events as `[START, FINISH, NEWSTART]`,
184 /// then mark `NEWSTART` as `START`'s parent with saving its relative
185 /// distance to `NEWSTART` into forward_parent(=2 in this case);
186 pub(crate) fn precede(self, p: &mut Parser) -> Marker {
187 Marker::new(p.0.precede(self.0))
188 }
189
190 pub(crate) fn kind(&self) -> SyntaxKind {
191 self.1
192 }
193}