1pub mod element_type;
3
4use crate::{language::GoLanguage, lexer::GoLexer};
5use oak_core::{
6 OakError,
7 parser::{Associativity, ParseCache, ParseOutput, Parser, ParserState, Pratt, PrattParser, binary, parse_with_lexer, unary},
8 source::{Source, TextEdit},
9 tree::GreenNode,
10};
11
12pub(crate) type State<'a, S> = ParserState<'a, GoLanguage, S>;
14
15pub struct GoParser<'config> {
17 pub(crate) config: &'config GoLanguage,
19}
20
21impl<'config> GoParser<'config> {
22 pub fn new(config: &'config GoLanguage) -> Self {
24 Self { config }
25 }
26
27 fn skip_trivia<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) {
28 while state.not_at_end() {
29 if let Some(kind) = state.peek_kind() {
30 if kind.is_ignored() {
31 state.bump();
32 continue;
33 };
34 }
35 break;
36 }
37 }
38
39 pub(crate) fn parse_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
40 use crate::{GoElementType as E, GoTokenType as T};
41 self.skip_trivia(state);
42 match state.peek_kind() {
43 Some(T::Package) => self.parse_package_clause(state)?,
44 Some(T::Import) => self.parse_import_declaration(state)?,
45 Some(T::Func) => self.parse_function_declaration(state)?,
46 Some(T::Var) => self.parse_variable_declaration(state)?,
47 Some(T::Const) => self.parse_const_declaration(state)?,
48 Some(T::Type) => self.parse_type_declaration(state)?,
49 Some(T::If) => self.parse_if_statement(state)?,
50 Some(T::For) => self.parse_for_statement(state)?,
51 Some(T::Switch) => self.parse_switch_statement(state)?,
52 Some(T::Return) => self.parse_return_statement(state)?,
53 Some(T::LeftBrace) => self.parse_block(state)?,
54 _ => {
55 let cp = state.checkpoint();
56 PrattParser::parse(state, 0, self);
57
58 self.skip_trivia(state);
59 match state.peek_kind() {
60 Some(T::Assign) => {
61 state.bump();
62 self.skip_trivia(state);
63 PrattParser::parse(state, 0, self);
64 state.finish_at(cp, E::AssignmentStatement);
65 }
66 Some(T::ColonAssign) => {
67 state.bump();
68 self.skip_trivia(state);
69 PrattParser::parse(state, 0, self);
70 state.finish_at(cp, E::ShortVarDecl);
71 }
72 _ => {
73 }
75 }
76 self.skip_trivia(state);
77 state.eat(T::Semicolon);
78 }
79 }
80 self.skip_trivia(state);
81 Ok(())
82 }
83
84 fn parse_package_clause<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
85 use crate::{GoElementType as E, GoTokenType as T};
86 let cp = state.checkpoint();
87 state.expect(T::Package).ok();
88 self.skip_trivia(state);
89 state.expect(T::Identifier).ok();
90 state.finish_at(cp, E::PackageClause);
91 Ok(())
92 }
93
94 fn parse_import_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
95 use crate::{GoElementType as E, GoTokenType as T};
96 let cp = state.checkpoint();
97 state.expect(T::Import).ok();
98 if state.eat(T::LeftParen) {
99 while state.not_at_end() && !state.at(T::RightParen) {
100 state.advance();
101 }
102 state.expect(T::RightParen).ok();
103 }
104 else {
105 state.advance();
106 }
107 state.finish_at(cp, E::ImportDeclaration);
108 Ok(())
109 }
110
111 fn parse_function_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
112 use crate::{GoElementType as E, GoTokenType as T};
113 let cp = state.checkpoint();
114 state.expect(T::Func).ok();
115 self.skip_trivia(state);
116
117 if state.at(T::LeftParen) {
119 let rcp = state.checkpoint();
120 self.parse_parameter_list(state)?;
121 state.finish_at(rcp, E::Receiver);
122 self.skip_trivia(state);
123 }
124
125 if state.at(T::Identifier) {
127 state.bump();
128 self.skip_trivia(state);
129 }
130
131 self.parse_parameter_list(state)?;
133 self.skip_trivia(state);
134
135 if state.at(T::LeftParen) {
137 self.parse_parameter_list(state)?;
138 self.skip_trivia(state);
139 }
140 else if state.at(T::Identifier) || state.at(T::Star) {
141 let rtcp = state.checkpoint();
143 if state.eat(T::Star) {
144 self.skip_trivia(state);
145 }
146 state.expect(T::Identifier).ok();
147 state.finish_at(rtcp, E::Identifier); self.skip_trivia(state);
149 }
150
151 if state.at(T::LeftBrace) {
152 self.parse_block(state)?;
153 }
154 state.finish_at(cp, E::FunctionDeclaration);
155 Ok(())
156 }
157
158 fn parse_parameter_list<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
159 use crate::{GoElementType as E, GoTokenType as T};
160 let cp = state.checkpoint();
161 state.expect(T::LeftParen).ok();
162 self.skip_trivia(state);
163 while state.not_at_end() && !state.at(T::RightParen) {
164 let pcp = state.checkpoint();
165 while state.at(T::Identifier) {
167 state.bump();
168 self.skip_trivia(state);
169 if !state.eat(T::Comma) {
170 break;
171 }
172 self.skip_trivia(state);
173 }
174 if state.not_at_end() && !state.at(T::Comma) && !state.at(T::RightParen) {
176 if state.eat(T::Star) {
177 self.skip_trivia(state);
178 }
179 if state.at(T::Identifier) {
180 state.bump();
181 self.skip_trivia(state);
182 }
183 }
184 state.finish_at(pcp, E::ParameterDecl);
185 self.skip_trivia(state);
186 if !state.eat(T::Comma) {
187 break;
188 }
189 self.skip_trivia(state);
190 }
191 state.expect(T::RightParen).ok();
192 state.finish_at(cp, E::ParameterList);
193 Ok(())
194 }
195
196 fn parse_variable_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
197 use crate::{GoElementType as E, GoTokenType as T};
198 let cp = state.checkpoint();
199 state.expect(T::Var).ok();
200 self.skip_trivia(state);
201
202 while state.at(T::Identifier) {
203 let vcp = state.checkpoint();
204 state.bump(); self.skip_trivia(state);
206
207 if state.at(T::Identifier) {
209 state.bump();
210 self.skip_trivia(state);
211 }
212
213 if state.eat(T::Assign) {
215 self.skip_trivia(state);
216 PrattParser::parse(state, 0, self);
217 }
218
219 state.finish_at(vcp, E::VariableSpec);
220 self.skip_trivia(state);
221
222 if !state.eat(T::Comma) {
223 break;
224 }
225 self.skip_trivia(state);
226 }
227
228 state.eat(T::Semicolon);
229 state.finish_at(cp, E::VariableDeclaration);
230 Ok(())
231 }
232
233 fn parse_const_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
234 use crate::{GoElementType as E, GoTokenType as T};
235 let cp = state.checkpoint();
236 state.expect(T::Const).ok();
237 while state.at(T::Identifier) {
238 state.bump();
239 if !state.eat(T::Semicolon) {
240 break;
241 }
242 }
243 state.eat(T::Semicolon);
244 state.finish_at(cp, E::ConstDeclaration);
245 Ok(())
246 }
247
248 fn parse_type_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
249 use crate::{GoElementType as E, GoTokenType as T};
250 let cp = state.checkpoint();
251 state.expect(T::Type).ok();
252 while state.at(T::Identifier) {
253 state.bump();
254 if !state.eat(T::Semicolon) {
255 break;
256 }
257 }
258 state.eat(T::Semicolon);
259 state.finish_at(cp, E::TypeDeclaration);
260 Ok(())
261 }
262
263 fn parse_if_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
264 use crate::{GoElementType as E, GoTokenType as T};
265 let cp = state.checkpoint();
266 state.expect(T::If).ok();
267 self.skip_trivia(state);
268
269 if !state.at(T::LeftBrace) {
271 PrattParser::parse(state, 0, self);
272 self.skip_trivia(state);
273 }
274
275 self.parse_block(state)?;
276 self.skip_trivia(state);
277
278 if state.eat(T::Else) {
279 self.skip_trivia(state);
280 if state.at(T::If) {
281 self.parse_if_statement(state)?;
282 }
283 else {
284 self.parse_block(state)?;
285 }
286 self.skip_trivia(state);
287 }
288 state.finish_at(cp, E::IfStatement);
289 Ok(())
290 }
291
292 fn parse_for_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
293 use crate::{GoElementType as E, GoTokenType as T};
294 let cp = state.checkpoint();
295 state.expect(T::For).ok();
296 self.skip_trivia(state);
297
298 if !state.at(T::LeftBrace) {
300 PrattParser::parse(state, 0, self);
302 self.skip_trivia(state);
303
304 if state.eat(T::Semicolon) {
305 self.skip_trivia(state);
306 if !state.at(T::Semicolon) {
308 PrattParser::parse(state, 0, self);
309 self.skip_trivia(state);
310 }
311 state.expect(T::Semicolon).ok();
312 self.skip_trivia(state);
313 if !state.at(T::LeftBrace) {
315 PrattParser::parse(state, 0, self);
316 self.skip_trivia(state);
317 }
318 }
319 }
320
321 self.parse_block(state)?;
322 self.skip_trivia(state);
323 state.finish_at(cp, E::ForStatement);
324 Ok(())
325 }
326
327 fn parse_switch_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
328 use crate::{GoElementType as E, GoTokenType as T};
329 let cp = state.checkpoint();
330 state.expect(T::Switch).ok();
331 while state.not_at_end() && !state.at(T::LeftBrace) {
332 state.advance();
333 }
334 self.parse_block(state)?;
335 state.finish_at(cp, E::SwitchStatement);
336 Ok(())
337 }
338
339 fn parse_return_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
340 use crate::{GoElementType as E, GoTokenType as T};
341 let cp = state.checkpoint();
342 state.expect(T::Return).ok();
343 if !state.at(T::Semicolon) {
344 PrattParser::parse(state, 0, self);
345 }
346 state.eat(T::Semicolon);
347 state.finish_at(cp, E::ReturnStatement);
348 Ok(())
349 }
350
351 fn parse_block<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
352 use crate::{GoElementType as E, GoTokenType as T};
353 let cp = state.checkpoint();
354 state.expect(T::LeftBrace).ok();
355 self.skip_trivia(state);
356 while state.not_at_end() && !state.at(T::RightBrace) {
357 self.parse_statement(state)?;
358 self.skip_trivia(state);
359 }
360 state.expect(T::RightBrace).ok();
361 state.finish_at(cp, E::Block);
362 Ok(())
363 }
364}
365
366impl<'config> Pratt<GoLanguage> for GoParser<'config> {
367 fn primary<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> &'a GreenNode<'a, GoLanguage> {
368 use crate::{GoElementType as E, GoTokenType as T};
369 self.skip_trivia(state);
370 let cp = state.checkpoint();
371 let kind = match state.peek_kind() {
372 Some(k) => k,
373 None => {
374 return state.finish_at(cp, E::Error);
375 }
376 };
377
378 match kind {
379 T::Identifier => {
380 state.bump();
381 state.finish_at(cp, E::Identifier)
382 }
383 T::IntLiteral | T::FloatLiteral | T::StringLiteral | T::RuneLiteral | T::BoolLiteral | T::NilLiteral => {
384 state.bump();
385 state.finish_at(cp, kind.into())
386 }
387 T::LeftParen => {
388 state.bump();
389 self.skip_trivia(state);
390 PrattParser::parse(state, 0, self);
391 self.skip_trivia(state);
392 state.expect(T::RightParen).ok();
393 state.finish_at(cp, E::BinaryExpression) }
395 T::RightBrace | T::Semicolon => {
396 state.finish_at(cp, E::Error)
398 }
399 _ => {
400 state.bump();
401 state.finish_at(cp, E::Error)
402 }
403 }
404 }
405
406 fn prefix<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> &'a GreenNode<'a, GoLanguage> {
407 use crate::{GoElementType as E, GoTokenType as T};
408 let kind = match state.peek_kind() {
409 Some(k) => k,
410 None => return self.primary(state),
411 };
412
413 let prec = match kind {
414 T::Plus | T::Minus | T::LogicalNot | T::Caret | T::Star | T::Ampersand | T::Arrow => 7,
415 _ => return self.primary(state),
416 };
417
418 unary(state, kind, prec, E::BinaryExpression.into(), |st, p| PrattParser::parse(st, p, self))
419 }
420
421 fn infix<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, left: &'a GreenNode<'a, GoLanguage>, min_precedence: u8) -> Option<&'a GreenNode<'a, GoLanguage>> {
422 use crate::{GoElementType as E, GoTokenType as T};
423 self.skip_trivia(state);
424 let kind = state.peek_kind()?;
425
426 if kind == T::LeftParen {
427 let prec = 8;
428 if prec < min_precedence {
429 return None;
430 }
431 let cp = state.checkpoint_before(left);
432 state.bump(); self.skip_trivia(state);
434
435 let arg_cp = state.checkpoint();
436 let mut has_args = false;
437 while state.not_at_end() && !state.at(T::RightParen) {
438 PrattParser::parse(state, 0, self);
439 has_args = true;
440 self.skip_trivia(state);
441 if !state.eat(T::Comma) {
442 break;
443 }
444 self.skip_trivia(state);
445 }
446 if has_args {
447 state.finish_at(arg_cp, E::ExpressionList);
448 }
449
450 state.expect(T::RightParen).ok();
451 return Some(state.finish_at(cp, E::CallExpression));
452 }
453
454 let (prec, assoc) = match kind {
455 T::Assign | T::ColonAssign => (1, Associativity::Right),
456 T::LogicalOr => (2, Associativity::Left),
457 T::LogicalAnd => (3, Associativity::Left),
458 T::Equal | T::NotEqual | T::Less | T::LessEqual | T::Greater | T::GreaterEqual => (4, Associativity::Left),
459 T::Plus | T::Minus | T::Pipe | T::Caret => (5, Associativity::Left),
460 T::Star | T::Slash | T::Percent | T::LeftShift | T::RightShift | T::Ampersand | T::AmpersandCaret => (6, Associativity::Left),
461 T::Dot => (8, Associativity::Left),
462 _ => return None,
463 };
464
465 if prec < min_precedence {
466 return None;
467 }
468
469 Some(binary(state, left, kind, prec, assoc, E::BinaryExpression.into(), |st, p| PrattParser::parse(st, p, self)))
470 }
471}
472
473impl<'config> Parser<GoLanguage> for GoParser<'config> {
474 fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl ParseCache<GoLanguage>) -> ParseOutput<'a, GoLanguage> {
475 let lexer = GoLexer::new(self.config);
476 parse_with_lexer(&lexer, text, edits, cache, |state| {
477 let cp = state.checkpoint();
478 while state.not_at_end() {
479 self.parse_statement(state)?
480 }
481 Ok(state.finish_at(cp, crate::parser::element_type::GoElementType::SourceFile))
482 })
483 }
484}