1pub mod ast;
2
3#[cfg(test)]
4mod tests;
5
6use crate::lexer::{CodePosition, Lexer, Token, TokenType};
7use crate::parser::ast::{
8 ClassDefinition, ClassMember, ConditionalNode, Constructor, FunctionDefinition,
9 Method, Node, NodeData, OperationExpression, Operator, OperatorType,
10 StructDefinition, StructMember, Visibility, AST
11};
12use crate::{regex_patterns, utils};
13
14use std::collections::VecDeque;
15use std::fmt::{Display, Formatter};
16use std::mem;
17use std::str::FromStr;
18
19#[derive(Debug, Clone, Eq, PartialEq)]
20pub enum ParsingError {
21 BracketMismatch,
22 ContFlowArgMissing,
23 Eof,
24 InvalidConPart,
25 InvalidAssignment,
26 InvalidParameter,
27 LexerError,
28}
29
30impl ParsingError {
31 pub fn error_code(&self) -> i32 {
32 match self {
33 ParsingError::BracketMismatch => -1,
34 ParsingError::ContFlowArgMissing => -2,
35 ParsingError::Eof => -3,
36 ParsingError::InvalidConPart => -4,
37 ParsingError::InvalidAssignment => -5,
38 ParsingError::InvalidParameter => -6,
39 ParsingError::LexerError => -7,
40 }
41 }
42
43 pub fn error_text(&self) -> &'static str {
44 match self {
45 ParsingError::BracketMismatch => "Bracket mismatch",
46 ParsingError::ContFlowArgMissing => "Control flow statement condition(s) or argument(s) is/are missing",
47 ParsingError::Eof => "End of file was reached early",
48 ParsingError::InvalidConPart => "Invalid statement part in control flow statement",
49 ParsingError::InvalidAssignment => "Invalid assignment operation",
50 ParsingError::InvalidParameter => "Invalid function parameter",
51 ParsingError::LexerError => "Error during lexical parsing",
52 }
53 }
54}
55
56impl Display for ParsingError {
57 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
58 f.write_str(match self {
59 ParsingError::BracketMismatch => "BRACKET_MISMATCH",
60 ParsingError::ContFlowArgMissing => "CONT_FLOW_ARG_MISSING",
61 ParsingError::Eof => "EOF",
62 ParsingError::InvalidConPart => "INVALID_CON_PART",
63 ParsingError::InvalidAssignment => "INVALID_ASSIGNMENT",
64 ParsingError::InvalidParameter => "INVALID_PARAMETER",
65 ParsingError::LexerError => "LEXER_ERROR",
66 })
67 }
68}
69
70#[derive(Debug)]
71pub struct Parser {
72 lexer: Lexer,
73 lang_doc_comment: Option<String>,
74}
75
76impl Parser {
77 pub fn new() -> Self {
78 Self {
79 lexer: Lexer::new(),
80 lang_doc_comment: None,
81 }
82 }
83
84 pub fn reset_position_vars(&mut self) {
85 self.lexer.reset_position_vars();
86 self.lang_doc_comment = None;
87 }
88
89 pub fn line_number(&self) -> usize {
90 self.lexer.line_number()
91 }
92
93 pub fn set_line_number(&mut self, line_number: usize) {
94 self.lexer.set_line_number(line_number);
95 self.lexer.set_column(1);
96 }
97
98 pub fn parse_lines(&mut self, lines: impl Into<String>) -> Option<AST> {
99 let tokens = VecDeque::from(self.lexer.read_tokens(lines));
100
101 self.parse_tokens(tokens)
102 }
103
104 pub fn parse_tokens(&mut self, mut tokens: VecDeque<Token>) -> Option<AST> {
105 Self::remove_line_continuation_and_single_line_text_quotes_tokens(&mut tokens);
106
107 self.parse_tokens_internal(&mut tokens).map(|mut ast| {
108 ast.optimize_ast();
109
110 ast
111 })
112 }
113
114 fn parse_tokens_internal(&mut self, tokens: &mut VecDeque<Token>) -> Option<AST> {
115 if tokens.is_empty() {
116 return None;
117 }
118
119 let mut ast = AST::new();
120 let mut block_pos = 0;
121
122 let mut error_nodes = Vec::new();
123
124 while !tokens.is_empty() {
125 Self::trim_first_line(tokens);
126
127 self.parse_comment_tokens(tokens, &mut error_nodes);
128 if !error_nodes.is_empty() {
129 if !error_nodes.is_empty() {
130 error_nodes.into_iter().for_each(|token| ast.add_child(token));
131 }
132
133 break;
134 }
135
136 Self::trim_first_line(tokens);
137
138 if tokens.is_empty() {
139 break;
140 }
141
142 if matches!(tokens[0].token_type(), TokenType::Eol) {
143 tokens.pop_front();
144
145 continue;
146 }
147
148 if matches!(tokens[0].token_type(), TokenType::Eof) {
149 let token = tokens.pop_front().unwrap();
150
151 if !tokens.is_empty() {
152 ast.add_child(Node::new_parsing_error_node(
153 token.pos(),
154 ParsingError::LexerError,
155 "Tokens after EOF are not allowed",
156 ));
157 }
158
159 break;
160 }
161
162 let current_token = &tokens[0];
163
164 if matches!(current_token.token_type(), TokenType::OpeningBlockBracket) {
166 tokens.pop_front();
167
168 block_pos += 1;
169
170 continue;
171 }else if matches!(current_token.token_type(), TokenType::ClosingBlockBracket) {
172 tokens.pop_front();
173
174 if block_pos == 0 {
175 break;
176 }
177
178 block_pos -= 1;
179
180 continue;
181 }
182
183 if !matches!(current_token.token_type(), TokenType::Other) || !(
185 current_token.value() == "return" || current_token.value() == "throw") {
186 let returned_node = self.parse_assignment(tokens, false);
187 if let Some(returned_node) = returned_node {
188 ast.add_child(returned_node);
189
190 continue;
191 }
192 }
193
194 let returned_ast = self.parse_line(tokens);
196 if let Some(returned_ast) = returned_ast {
197 ast.add_child(returned_ast.into_node());
198 }else {
199 return Some(ast);
201 }
202 }
203
204 Some(ast)
205 }
206
207 #[inline(always)]
208 fn parse_condition_expr(&mut self, tokens: &mut VecDeque<Token>) -> Option<Node> {
209 self.parse_operator_expr(tokens, OperatorType::Condition)
210 }
211
212 #[inline(always)]
213 fn parse_math_expr(&mut self, tokens: &mut VecDeque<Token>) -> Option<Node> {
214 self.parse_operator_expr(tokens, OperatorType::Math)
215 }
216
217 #[inline(always)]
218 fn parse_operation_expr(&mut self, tokens: &mut VecDeque<Token>) -> Option<Node> {
219 self.parse_operator_expr(tokens, OperatorType::General)
220 }
221
222 #[inline(always)]
223 fn parse_operator_expr(&mut self, tokens: &mut VecDeque<Token>, operator_type: OperatorType) -> Option<Node> {
224 self.parse_operator_expression(tokens, &mut None, &mut None, 0, operator_type)
225 }
226
227 fn parse_operator_expression(
228 &mut self,
229 tokens: &mut VecDeque<Token>,
230 tokens_left: &mut Option<&mut VecDeque<Token>>,
231 tokens_left_behind_middle_part_end: &mut Option<&mut VecDeque<Token>>,
232 current_operator_precedence: isize,
233 operator_type: OperatorType,
234 ) -> Option<Node> {
235 let non_operator = match operator_type {
236 OperatorType::Math => Operator::MathNon,
237 OperatorType::Condition => Operator::ConditionalNon,
238 OperatorType::General => Operator::Non,
239 OperatorType::All => {
240 return None;
241 },
242 };
243
244 Self::trim_first_line(tokens);
245
246 let mut operator = None;
247 let mut left_nodes = Vec::new();
248 let mut middle_node = None;
249 let mut right_node = None;
250
251 let mut whitespaces = VecDeque::new();
252
253 let mut other_tokens = VecDeque::new();
254
255 'tokenProcessing:
256 while !tokens.is_empty() {
257 let t = tokens[0].clone();
258
259 match t.token_type() {
260 TokenType::Eol | TokenType::Eof => {
261 break 'tokenProcessing;
262 },
263
264 TokenType::StartComment | TokenType::StartDocComment => {
265 self.parse_comment_tokens(tokens, &mut left_nodes);
266 },
267
268 TokenType::LiteralNull | TokenType::LiteralText | TokenType::LiteralNumber |
269 TokenType::EscapeSequence | TokenType::Assignment | TokenType::ClosingBracket |
270 TokenType::LexerError => {
271 if !whitespaces.is_empty() {
272 other_tokens.append(&mut whitespaces);
273 }
274
275 if !other_tokens.is_empty() {
276 self.parse_text_and_char_value(&mut other_tokens, &mut left_nodes);
277 other_tokens.clear();
278 }
279
280 tokens.pop_front();
281
282 match t.token_type() {
283 TokenType::LiteralNull => {
284 left_nodes.push(Node::new_null_value_node(t.pos()));
285 },
286
287 TokenType::LiteralText | TokenType::Assignment | TokenType::ClosingBracket => {
288 left_nodes.push(Node::new_text_value_node(t.pos(), t.value()));
289 },
290
291 TokenType::LiteralNumber => {
292 self.parse_number_token(t, &mut left_nodes);
293 },
294
295 TokenType::EscapeSequence => {
296 self.parse_escape_sequence_token(t, &mut left_nodes);
297 },
298
299 TokenType::LexerError => {
300 self.parse_lexer_error_token(t, &mut left_nodes);
301 },
302
303 _ => {},
304 }
305 },
306
307 TokenType::StartMultilineText => {
308 if !whitespaces.is_empty() {
309 other_tokens.append(&mut whitespaces);
310 }
311
312 if !other_tokens.is_empty() {
313 self.parse_text_and_char_value(&mut other_tokens, &mut left_nodes);
314 other_tokens.clear();
315 }
316
317 tokens.pop_front();
318
319 loop {
320 if let Some(t) = tokens.pop_front() {
321 if matches!(t.token_type(), TokenType::EndMultilineText) {
322 break;
323 }
324
325 if matches!(t.token_type(), TokenType::LiteralText | TokenType::Eol) {
326 left_nodes.push(Node::new_text_value_node(t.pos(), t.value()));
327 }else if matches!(t.token_type(), TokenType::EscapeSequence) {
328 self.parse_escape_sequence_token(t, &mut left_nodes);
329 }else if matches!(t.token_type(), TokenType::LexerError) {
330 left_nodes.push(Node::new_parsing_error_node(
331 t.pos(),
332 ParsingError::LexerError,
333 t.value()
334 ));
335 }else {
336 left_nodes.push(Node::new_parsing_error_node(
337 CodePosition::EMPTY,
338 ParsingError::Eof,
339 format!(
340 "Invalid token type ({}) in multiline text during operator parsing",
341 t.token_type(),
342 ),
343 ));
344 }
345 }else {
346 left_nodes.push(Node::new_parsing_error_node(
347 CodePosition::EMPTY,
348 ParsingError::Eof,
349 "Missing multiline text end token during operator parsing",
350 ));
351
352 break 'tokenProcessing;
353 }
354 }
355 },
356
357 TokenType::Whitespace => {
358 tokens.pop_front();
359
360 whitespaces.push_back(t);
361 },
362
363 TokenType::Identifier | TokenType::ParserFunctionIdentifier => {
364 self.parse_operator_expression_variable_name_and_function_call(
365 tokens, operator_type, &mut other_tokens, &mut left_nodes, t, &mut whitespaces,
366 );
367 },
368
369 TokenType::OpeningBracket | TokenType::Operator | TokenType::ArgumentSeparator => {
370 let mut t = t;
371 let mut value = t.value();
372
373 if matches!(t.token_type(), TokenType::ArgumentSeparator) {
375 let byte_index = value.find(",").unwrap();
376
377 if byte_index > 0 {
378 whitespaces.push_back(Token::new(t.pos(), &value[..byte_index], TokenType::Whitespace));
379 }
380
381 if byte_index < value.len() - 1 {
382 tokens.insert(1, Token::new(t.pos(), &value[byte_index+1..], TokenType::Whitespace));
383 }
384
385 t = Token::new(t.pos(), ",", TokenType::Operator);
386 value = t.value();
387 tokens[0] = t.clone();
388 }
389
390 if matches!(t.token_type(), TokenType::OpeningBracket) && value == "(" {
392 let end_index = utils::get_index_of_matching_bracket_tok(
393 tokens.make_contiguous(), 0, usize::MAX, "(", ")", true,
394 );
395 let Some(end_index) = end_index else {
396 left_nodes.push(Node::new_parsing_error_node(
397 CodePosition::EMPTY,
398 ParsingError::BracketMismatch,
399 "Bracket in operator expression is missing",
400 ));
401
402 break 'tokenProcessing;
403 };
404
405 if other_tokens.is_empty() && left_nodes.is_empty() {
407 if !whitespaces.is_empty() {
408 whitespaces.clear();
409 }
410
411 let mut parameter_tokens = utils::split_off_arguments(tokens, end_index);
412
413 left_nodes.push(self.parse_operator_expr(&mut parameter_tokens, operator_type).unwrap());
414 }else {
415 if !whitespaces.is_empty() {
416 whitespaces.clear();
417 }
418
419 if !other_tokens.is_empty() {
420 self.parse_text_and_char_value(&mut other_tokens, &mut left_nodes);
421 other_tokens.clear();
422 }
423
424 let opening_bracket_token = &tokens[0];
425 let closing_bracket_token = &tokens[end_index];
426 let pos = opening_bracket_token.pos().combine(&closing_bracket_token.pos());
427
428 let mut function_call_tokens = utils::split_off_arguments(tokens, end_index);
429
430 let node = self.parse_operator_expr(&mut function_call_tokens, operator_type).unwrap();
431 left_nodes.push(Node::new_function_call_previous_node_value_node(
432 pos, "", "",
433 Self::convert_comma_operators_to_argument_separators(node),
434 ));
435 }
436
437 continue 'tokenProcessing;
438 }
439
440 if (matches!(t.token_type(), TokenType::OpeningBracket) && value == "[") ||
442 (matches!(t.token_type(), TokenType::Operator) && value == "?." &&
443 tokens.len() > 2 && matches!(tokens[1].token_type(), TokenType::OpeningBracket) &&
444 tokens[1].value() == "[") {
445 let starts_with_optional_marker = matches!(t.token_type(), TokenType::Operator);
446 let end_index = utils::get_index_of_matching_bracket_tok(
447 tokens.make_contiguous(),
448 if starts_with_optional_marker { 1 } else { 0 }, usize::MAX,
449 "[", "]", true,
450 );
451 let Some(end_index) = end_index else {
452 left_nodes.push(Node::new_parsing_error_node(
453 CodePosition::EMPTY,
454 ParsingError::BracketMismatch,
455 "Bracket in operator expression is missing",
456 ));
457
458 break 'tokenProcessing;
459 };
460
461 if OperatorType::All.is_compatible_with(operator_type) &&
463 (!other_tokens.is_empty() || !left_nodes.is_empty()) {
464 let old_operator = operator.replace(
465 if starts_with_optional_marker {
466 Operator::OptionalGetItem
467 }else {
468 Operator::GetItem
469 }
470 );
471
472 if current_operator_precedence <= operator.unwrap().precedence()
473 && let Some(tokens_left) = tokens_left {
474 tokens_left.append(tokens);
475
476 if !whitespaces.is_empty() {
477 whitespaces.clear();
478 }
479
480 operator = old_operator;
481
482 break 'tokenProcessing;
483 }
484
485 if !whitespaces.is_empty() {
486 whitespaces.clear();
487 }
488
489 if !other_tokens.is_empty() {
490 self.parse_text_and_char_value(&mut other_tokens, &mut left_nodes);
491 other_tokens.clear();
492 }
493
494 let mut inner_tokens_left_behind_middle_part_end = VecDeque::new();
496
497 inner_tokens_left_behind_middle_part_end.push_back(Token::new(
499 CodePosition::EMPTY,
500 "DUMMY-A",
501 TokenType::Whitespace,
502 ));
503
504 let start_index = if starts_with_optional_marker { 2 } else { 1 };
505 let mut tokens_list = VecDeque::from_iter(
506 tokens.make_contiguous()[start_index..end_index].iter().cloned(),
507 );
508
509 let inner_middle_node_ret = self.parse_operator_expression(
510 &mut tokens_list,
511 &mut None,
512 &mut Some(&mut inner_tokens_left_behind_middle_part_end),
513 0,
514 operator_type,
515 );
516 if let Some(inner_middle_node_ret) = inner_middle_node_ret {
517 operator.replace(
520 if starts_with_optional_marker {
521 Operator::OptionalSlice
522 }else {
523 Operator::Slice
524 }
525 );
526
527 inner_tokens_left_behind_middle_part_end.pop_front();
529
530 tokens.drain(..=end_index);
531
532 let mut tokens_list = inner_tokens_left_behind_middle_part_end;
533
534 let inner_right_node_ret = self.parse_operator_expr(
535 &mut tokens_list, operator_type,
536 ).unwrap();
537 if tokens.is_empty() {
538 if inner_middle_node_ret.operator() == Some(non_operator) {
540 middle_node = inner_middle_node_ret.into_left_side_operand();
541 }else {
542 middle_node = Some(inner_middle_node_ret);
543 }
544
545 if inner_right_node_ret.operator() == Some(non_operator) {
547 right_node = inner_right_node_ret.into_left_side_operand();
548 }else {
549 right_node = Some(inner_right_node_ret);
550 }
551
552 break 'tokenProcessing;
553 }else {
554 let middle_node = if inner_middle_node_ret.operator() == Some(non_operator) {
556 inner_middle_node_ret.into_left_side_operand().unwrap()
557 }else {
558 inner_middle_node_ret
559 };
560
561 let right_node = if inner_right_node_ret.operator() == Some(non_operator) {
563 inner_right_node_ret.into_left_side_operand().unwrap()
564 }else {
565 inner_right_node_ret
566 };
567
568 let left_node = if left_nodes.len() == 1 {
569 left_nodes.pop().unwrap()
570 }else {
571 Node::new_list_node(Vec::from_iter(left_nodes.drain(..)))
572 };
573
574 left_nodes.push(Node::new_operation_statement_node(
575 left_node.pos().combine(&right_node.pos()),
576 OperationExpression::new(
577 Some(Box::new(left_node)),
578 Some(Box::new(middle_node)),
579 Some(Box::new(right_node)),
580 operator.take().unwrap(), operator_type,
581 ),
582 ));
583 }
584
585 continue 'tokenProcessing;
586 }
587
588 let mut tokens_list = utils::split_off_arguments(tokens, end_index);
589 if starts_with_optional_marker {
590 tokens_list.pop_front();
592 }
593
594 let node = self.parse_operator_expr(&mut tokens_list, operator_type).unwrap();
595 if tokens.is_empty() {
596 if node.operator() == Some(non_operator) {
598 right_node = node.into_left_side_operand();
599 }else {
600 right_node = Some(node);
601 }
602
603 break 'tokenProcessing;
604 }else {
605 let right_node = if node.operator() == Some(non_operator) {
607 node.into_left_side_operand().unwrap()
608 }else {
609 node
610 };
611
612 let left_node = if left_nodes.len() == 1 {
613 left_nodes.pop().unwrap()
614 }else {
615 Node::new_list_node(Vec::from_iter(left_nodes.drain(..)))
616 };
617
618 left_nodes.push(Node::new_operation_statement_node(
619 left_node.pos().combine(&right_node.pos()),
620 OperationExpression::new(
621 Some(Box::new(left_node)),
622 None,
623 Some(Box::new(right_node)),
624 operator.take().unwrap(), operator_type,
625 ),
626 ));
627
628 continue 'tokenProcessing;
629 }
630 }else if OperatorType::All.is_compatible_with(operator_type) && !starts_with_optional_marker {
631 if !whitespaces.is_empty() {
632 whitespaces.clear();
633 }
634
635 if !other_tokens.is_empty() {
636 self.parse_text_and_char_value(&mut other_tokens, &mut left_nodes);
637 other_tokens.clear();
638 }
639
640 let pos = t.pos().combine(&tokens[end_index].pos());
642
643 let mut tokens_list = utils::split_off_arguments(tokens, end_index);
644
645 let node = self.parse_operator_expr(&mut tokens_list, operator_type).unwrap();
646 left_nodes.push(Node::new_array_value_node(
647 pos,
648 Self::convert_comma_operators_to_argument_separators(node),
649 ));
650
651 if tokens.is_empty() {
652 operator = None;
653
654 break 'tokenProcessing;
655 }
656
657 continue 'tokenProcessing;
658 }else {
659 if !whitespaces.is_empty() {
661 other_tokens.append(&mut whitespaces);
662 }
663 }
664 }
665
666 if value == "**" {
667 let old_operator = operator.replace(Operator::Pow);
668
669 if operator.unwrap().operator_type().is_compatible_with(operator_type) &&
671 (!other_tokens.is_empty() || !left_nodes.is_empty()) {
672 if current_operator_precedence < operator.unwrap().precedence()
674 && let Some(tokens_left) = tokens_left {
675 tokens_left.append(tokens);
676
677 if !whitespaces.is_empty() {
678 whitespaces.clear();
679 }
680
681 operator = old_operator;
682
683 break 'tokenProcessing;
684 }
685
686 if tokens.len() == 1 {
688 if !whitespaces.is_empty() {
689 other_tokens.append(&mut whitespaces);
690 }
691
692 operator = None;
693 other_tokens.push_back(t);
694 tokens.pop_front();
695
696 break 'tokenProcessing;
697 }
698
699 if !whitespaces.is_empty() {
700 whitespaces.clear();
701 }
702
703 if !other_tokens.is_empty() {
704 self.parse_text_and_char_value(&mut other_tokens, &mut left_nodes);
705 other_tokens.clear();
706 }
707
708 let mut inner_tokens_left = VecDeque::new();
709 let mut tokens_list = VecDeque::from_iter(
710 tokens.make_contiguous()[1..].iter().cloned(),
711 );
712
713 let node = self.parse_operator_expression(
715 &mut tokens_list,
716 &mut Some(&mut inner_tokens_left),
717 tokens_left_behind_middle_part_end,
718 operator.unwrap().precedence(),
719 operator_type,
720 )?;
721
722 *tokens = inner_tokens_left;
723
724 if tokens.is_empty() {
725 if node.operator() == Some(non_operator) {
727 right_node = node.into_left_side_operand();
728 }else {
729 right_node = Some(node);
730 }
731
732 break 'tokenProcessing;
733 }else {
734 let right_node = if node.operator() == Some(non_operator) {
736 node.into_left_side_operand().unwrap()
737 }else {
738 node
739 };
740
741 let left_node = if left_nodes.len() == 1 {
742 left_nodes.pop().unwrap()
743 }else {
744 Node::new_list_node(Vec::from_iter(left_nodes.drain(..)))
745 };
746
747 left_nodes.push(Node::new_operation_statement_node(
748 left_node.pos().combine(&right_node.pos()),
749 OperationExpression::new(
750 Some(Box::new(left_node)),
751 None,
752 Some(Box::new(right_node)),
753 operator.take().unwrap(), operator_type,
754 ),
755 ));
756
757 continue 'tokenProcessing;
758 }
759 }else {
760 operator = old_operator;
761
762 if !whitespaces.is_empty() {
764 other_tokens.append(&mut whitespaces);
765 }
766 }
767 }
768
769 if matches!(
770 value,
771 "!==" | "!=~" | "!=" | "===" | "=~" | "==" | "<=>" | "<=" | ">=" | "<" |
772 ">" | "|||" | "&&" | "||" | "!" | "&" | "~~" | "~/" | "~" | "\u{25b2}" |
773 "\u{25bc}" | "*" | "//" | "^/" | "/" | "%" | "^" | "|" | "<<" | ">>>" |
774 ">>" | "+|" | "-|" | "+" | "->" | "-" | "@" | "?:" | "??" | "," | "?::" |
775 "::"
776 ) {
777 let something_before_operator = !other_tokens.is_empty() || !left_nodes.is_empty();
778
779 let old_operator = operator.take();
780
781 if operator.is_none() && OperatorType::All.is_compatible_with(operator_type) {
782 match value {
783 "?::" => {
784 operator = Some(Operator::OptionalMemberAccess);
785 },
786 "::" => {
787 if something_before_operator {
788 operator = Some(Operator::MemberAccess);
789 }else {
790 operator = Some(Operator::MemberAccessThis);
791 }
792 },
793 "->" => {
794 operator = Some(Operator::MemberAccessPointer);
795 },
796 "," => {
797 operator = Some(Operator::Comma);
798 },
799
800 _ => {},
801 }
802 }
803
804 if operator.is_none() && OperatorType::General.is_compatible_with(operator_type) {
805 match value {
806 "|||" => {
807 operator = Some(Operator::Concat);
808 },
809 "@" => {
810 operator = Some(Operator::Len);
811 },
812 "?:" => {
813 operator = Some(Operator::Elvis);
814 },
815 "??" => {
816 operator = Some(Operator::NullCoalescing);
817 },
818 "^" => {
819 if !something_before_operator {
820 operator = Some(Operator::DeepCopy);
821 }
822 },
823
824 _ => {},
825 }
826 }
827
828 if operator.is_none() && OperatorType::Math.is_compatible_with(operator_type) {
829 match value {
830 "<<" => {
831 operator = Some(Operator::Lshift);
832 },
833 ">>>" => {
834 operator = Some(Operator::Rzshift);
835 },
836 ">>" => {
837 operator = Some(Operator::Rshift);
838 },
839 "<=>" => {
840 operator = Some(Operator::Spaceship);
841 },
842 "&" => {
843 operator = Some(Operator::BitwiseAnd);
844 },
845 "~/" => {
846 operator = Some(Operator::TruncDiv);
847 },
848 "~" => {
849 operator = Some(Operator::BitwiseNot);
850 },
851 "+|" | "\u{25b2}" => {
852 operator = Some(Operator::Inc);
853 },
854 "-|" | "\u{25bc}" => {
855 operator = Some(Operator::Dec);
856 },
857 "*" => {
858 operator = Some(Operator::Mul);
859 },
860 "^/" => {
861 operator = Some(Operator::CeilDiv);
862 },
863 "//" => {
864 operator = Some(Operator::FloorDiv);
865 },
866 "/" => {
867 operator = Some(Operator::Div);
868 },
869 "%" => {
870 operator = Some(Operator::Mod);
871 },
872 "|" => {
873 operator = Some(Operator::BitwiseOr);
874 },
875 "+" => {
876 if something_before_operator {
877 operator = Some(Operator::Add);
878 }else {
879 operator = Some(Operator::Pos);
880 }
881 },
882 "-" => {
883 if something_before_operator {
884 operator = Some(Operator::Sub);
885 }else {
886 operator = Some(Operator::Inv);
887 }
888 },
889 "^" => {
890 if something_before_operator {
891 operator = Some(Operator::BitwiseXor);
892 }
893 },
894
895 _ => {},
896 }
897 }
898
899 if operator.is_none() && OperatorType::Condition.is_compatible_with(operator_type) {
900 match value {
901 "!==" => {
902 operator = Some(Operator::StrictNotEquals);
903 },
904 "!=~" => {
905 operator = Some(Operator::NotMatches);
906 },
907 "!=" => {
908 operator = Some(Operator::NotEquals);
909 },
910 "===" => {
911 operator = Some(Operator::StrictEquals);
912 },
913 "=~" => {
914 operator = Some(Operator::Matches);
915 },
916 "==" => {
917 operator = Some(Operator::Equals);
918 },
919 "<=" => {
920 operator = Some(Operator::LessThanOrEquals);
921 },
922 ">=" => {
923 operator = Some(Operator::GreaterThanOrEquals);
924 },
925 "<" => {
926 operator = Some(Operator::LessThan);
927 },
928 ">" => {
929 operator = Some(Operator::GreaterThan);
930 },
931 "&&" => {
932 operator = Some(Operator::And);
933 },
934 "||" => {
935 operator = Some(Operator::Or);
936 },
937 "!" => {
938 operator = Some(Operator::Not);
939 },
940 "~~" => {
941 operator = Some(Operator::InstanceOf);
942 },
943
944 _ => {},
945 }
946 }
947
948 match operator {
949 Some(op) if op.is_binary() && something_before_operator => {
950 if current_operator_precedence <= op.precedence()
951 && let Some(tokens_left) = tokens_left {
952 tokens_left.append(tokens);
953
954 if !whitespaces.is_empty() {
955 whitespaces.clear();
956 }
957
958 operator = old_operator;
959
960 break 'tokenProcessing;
961 }
962
963 if tokens.len() == 1 {
965 other_tokens.append(&mut whitespaces);
966
967 operator = None;
968 other_tokens.push_back(t);
969 tokens.pop_front();
970
971 break 'tokenProcessing;
972 }
973
974 if !whitespaces.is_empty() {
975 whitespaces.clear();
976 }
977
978 if !other_tokens.is_empty() {
979 self.parse_text_and_char_value(&mut other_tokens, &mut left_nodes);
980 other_tokens.clear();
981 }
982
983 let mut inner_tokens_left = VecDeque::new();
984 let mut tokens_list = VecDeque::from_iter(
985 tokens.make_contiguous()[1..].iter().cloned(),
986 );
987
988 let node = self.parse_operator_expression(
990 &mut tokens_list,
991 &mut Some(&mut inner_tokens_left),
992 tokens_left_behind_middle_part_end,
993 operator.unwrap().precedence(),
994 operator_type,
995 )?;
996
997 *tokens = inner_tokens_left;
998
999 if tokens.is_empty() {
1000 if node.operator() == Some(non_operator) {
1002 right_node = node.into_left_side_operand();
1003 }else {
1004 right_node = Some(node);
1005 }
1006
1007 break 'tokenProcessing;
1008 }else {
1009 let right_node = if node.operator() == Some(non_operator) {
1011 node.into_left_side_operand().unwrap()
1012 }else {
1013 node
1014 };
1015
1016 let left_node = if left_nodes.len() == 1 {
1017 left_nodes.pop().unwrap()
1018 }else {
1019 Node::new_list_node(Vec::from_iter(left_nodes.drain(..)))
1020 };
1021
1022 left_nodes.push(Node::new_operation_statement_node(
1023 left_node.pos().combine(&right_node.pos()),
1024 OperationExpression::new(
1025 Some(Box::new(left_node)),
1026 None,
1027 Some(Box::new(right_node)),
1028 operator.take().unwrap(), operator_type,
1029 ),
1030 ));
1031
1032 continue 'tokenProcessing;
1033 }
1034 },
1035
1036 Some(op) if op.is_unary() && !something_before_operator => {
1037 if !whitespaces.is_empty() {
1038 whitespaces.clear();
1039 }
1040
1041 let pos_start = t.pos();
1042
1043 let mut inner_tokens_left = VecDeque::new();
1044 let mut tokens_list = VecDeque::from_iter(
1045 tokens.make_contiguous()[1..].iter().cloned(),
1046 );
1047
1048 let node = self.parse_operator_expression(
1050 &mut tokens_list,
1051 &mut Some(&mut inner_tokens_left),
1052 tokens_left_behind_middle_part_end,
1053 operator.unwrap().precedence(),
1054 operator_type,
1055 )?;
1056
1057 *tokens = inner_tokens_left;
1058
1059 let left_node = if node.operator() == Some(non_operator) {
1061 node.into_left_side_operand().unwrap()
1062 }else {
1063 node
1064 };
1065
1066 left_nodes.push(Node::new_operation_statement_node(
1067 pos_start.combine(&left_node.pos()),
1068 OperationExpression::new(
1069 Some(Box::new(left_node)),
1070 None,
1071 None,
1072 operator.take().unwrap(), operator_type,
1073 ),
1074 ));
1075
1076 if tokens.is_empty() {
1077 break 'tokenProcessing;
1078 }else {
1079 continue 'tokenProcessing;
1080 }
1081 },
1082
1083 _ => {
1084 operator = old_operator;
1085
1086 if !whitespaces.is_empty() {
1088 other_tokens.append(&mut whitespaces);
1089 }
1090 },
1091 }
1092 }
1093
1094 if value == "?" {
1095 let old_operator = operator.replace(Operator::InlineIf);
1096
1097 if operator.unwrap().operator_type().is_compatible_with(operator_type) &&
1100 (!other_tokens.is_empty() || !left_nodes.is_empty()) {
1101 if current_operator_precedence < operator.unwrap().precedence()
1103 && let Some(tokens_left) = tokens_left {
1104 tokens_left.append(tokens);
1105
1106 if !whitespaces.is_empty() {
1107 whitespaces.clear();
1108 }
1109
1110 operator = old_operator;
1111
1112 break 'tokenProcessing;
1113 }
1114
1115 let mut inner_tokens_left_behind_middle_part_end = VecDeque::new();
1117 let mut tokens_list = VecDeque::from_iter(
1118 tokens.make_contiguous()[1..].iter().cloned(),
1119 );
1120
1121 let inner_middle_node_ret = self.parse_operator_expression(
1122 &mut tokens_list,
1123 &mut None,
1124 &mut Some(&mut inner_tokens_left_behind_middle_part_end),
1125 0,
1126 operator_type,
1127 );
1128 if let Some(inner_middle_node_ret) = inner_middle_node_ret {
1129 if inner_tokens_left_behind_middle_part_end.is_empty() {
1133 if !whitespaces.is_empty() {
1134 other_tokens.append(&mut whitespaces);
1135 }
1136
1137 operator = None;
1138 other_tokens.push_back(t);
1139
1140 break 'tokenProcessing;
1141 }
1142
1143 *tokens = inner_tokens_left_behind_middle_part_end;
1144
1145 if !whitespaces.is_empty() {
1146 whitespaces.clear();
1147 }
1148
1149 if !other_tokens.is_empty() {
1150 self.parse_text_and_char_value(&mut other_tokens, &mut left_nodes);
1151 other_tokens.clear();
1152 }
1153
1154 let mut inner_tokens_left = VecDeque::new();
1155
1156 let inner_right_node_ret = self.parse_operator_expression(
1157 tokens,
1158 &mut Some(&mut inner_tokens_left),
1159 tokens_left_behind_middle_part_end,
1160 operator.unwrap().precedence(),
1161 operator_type,
1162 ).unwrap();
1163
1164 *tokens = inner_tokens_left;
1165
1166 if tokens.is_empty() {
1167 if inner_middle_node_ret.operator() == Some(non_operator) {
1169 middle_node = inner_middle_node_ret.into_left_side_operand();
1170 }else {
1171 middle_node = Some(inner_middle_node_ret);
1172 }
1173
1174 if inner_right_node_ret.operator() == Some(non_operator) {
1176 right_node = inner_right_node_ret.into_left_side_operand();
1177 }else {
1178 right_node = Some(inner_right_node_ret);
1179 }
1180
1181 break 'tokenProcessing;
1182 }else {
1183 let middle_node = if inner_middle_node_ret.operator() == Some(non_operator) {
1185 inner_middle_node_ret.into_left_side_operand().unwrap()
1186 }else {
1187 inner_middle_node_ret
1188 };
1189
1190 let right_node = if inner_right_node_ret.operator() == Some(non_operator) {
1192 inner_right_node_ret.into_left_side_operand().unwrap()
1193 }else {
1194 inner_right_node_ret
1195 };
1196
1197 let left_node = if left_nodes.len() == 1 {
1198 left_nodes.pop().unwrap()
1199 }else {
1200 Node::new_list_node(Vec::from_iter(left_nodes.drain(..)))
1201 };
1202
1203 left_nodes.push(Node::new_operation_statement_node(
1204 left_node.pos().combine(&right_node.pos()),
1205 OperationExpression::new(
1206 Some(Box::new(left_node)),
1207 Some(Box::new(middle_node)),
1208 Some(Box::new(right_node)),
1209 operator.take().unwrap(), operator_type,
1210 ),
1211 ));
1212
1213 continue 'tokenProcessing;
1214 }
1215 }else {
1216 operator = old_operator;
1217
1218 if !whitespaces.is_empty() {
1220 other_tokens.append(&mut whitespaces);
1221 }
1222 }
1223 }else {
1224 operator = old_operator;
1225
1226 if !whitespaces.is_empty() {
1228 other_tokens.append(&mut whitespaces);
1229 }
1230 }
1231 }
1232
1233 if value == ":"
1234 && let Some(tokens_left_behind_middle_part_end) = tokens_left_behind_middle_part_end {
1235 if tokens_left_behind_middle_part_end.front().is_some_and(|token|
1239 matches!(token.token_type(), TokenType::Whitespace) && token.value() == "DUMMY-A") {
1240 tokens_left_behind_middle_part_end[0] = Token::new(CodePosition::EMPTY, "DUMMY-B", TokenType::Whitespace);
1241 }
1242
1243 if !whitespaces.is_empty() {
1244 whitespaces.clear();
1245 }
1246
1247 tokens.pop_front();
1248 tokens_left_behind_middle_part_end.append(tokens);
1249
1250 if let Some(tokens_left) = tokens_left
1252 && !tokens_left.is_empty() {
1253 tokens_left.clear();
1254 }
1255
1256 break 'tokenProcessing;
1257 }
1258
1259 tokens.pop_front();
1260
1261 if !whitespaces.is_empty() {
1262 other_tokens.append(&mut whitespaces);
1263 }
1264
1265 if !other_tokens.is_empty() {
1266 self.parse_text_and_char_value(&mut other_tokens, &mut left_nodes);
1267 other_tokens.clear();
1268 }
1269
1270 if other_tokens.is_empty() && left_nodes.is_empty() && matches!(t.value(), "+" | "-") &&
1272 !tokens.is_empty() && matches!(tokens[0].token_type(), TokenType::LiteralNumber) {
1273 let number_token = tokens.pop_front().unwrap();
1274
1275 let combined_number_token = Token::new(
1276 t.pos().combine(&number_token.pos()),
1277 &(t.value().to_string() + number_token.value()),
1278 TokenType::LiteralNumber,
1279 );
1280
1281 self.parse_number_token(combined_number_token, &mut left_nodes);
1282 }else {
1283 left_nodes.push(Node::new_text_value_node(t.pos(), value));
1284 }
1285 },
1286
1287 TokenType::Other => {
1288 if !whitespaces.is_empty() {
1289 whitespaces.clear();
1290 }
1291
1292 if !other_tokens.is_empty() {
1293 self.parse_text_and_char_value(&mut other_tokens, &mut left_nodes);
1294 other_tokens.clear();
1295 }
1296
1297 let ret = self.parse_function_call_without_prefix(tokens, Some(operator_type));
1298 if let Some(ret) = ret {
1299 left_nodes.push(ret);
1300 }else {
1301 tokens.pop_front();
1302 other_tokens.push_back(t);
1303 }
1304 },
1305
1306 TokenType::OpeningBlockBracket | TokenType::ClosingBlockBracket |
1307 TokenType::LineContinuation | TokenType::EndComment | TokenType::EndMultilineText |
1308 TokenType::SingleLineTextQuotes => {
1309 left_nodes.push(Node::new_parsing_error_node(
1310 CodePosition::EMPTY,
1311 ParsingError::LexerError,
1312 format!(
1313 "Invalid token type in operator expression: \"{}\"",
1314 t.token_type(),
1315 ),
1316 ));
1317
1318 break 'tokenProcessing;
1319 },
1320 }
1321 }
1322
1323 if let Some(tokens_left_behind_middle_part_end) = tokens_left_behind_middle_part_end {
1325 if tokens_left_behind_middle_part_end.front().is_some_and(|token|
1326 matches!(token.token_type(), TokenType::Whitespace) && token.value() == "DUMMY-A") {
1327 tokens_left_behind_middle_part_end.pop_front();
1328 }
1329
1330 if tokens_left_behind_middle_part_end.is_empty() {
1332 return None;
1333 }
1334 }
1335
1336 if !whitespaces.is_empty() {
1337 other_tokens.append(&mut whitespaces);
1338 }
1339
1340 if !other_tokens.is_empty() {
1341 self.parse_text_and_char_value(&mut other_tokens, &mut left_nodes);
1342 other_tokens.clear();
1343 }
1344
1345 let operator = operator.unwrap_or(non_operator);
1346
1347 let left_node = if left_nodes.len() == 1 {
1348 left_nodes.pop().unwrap()
1349 }else {
1350 Node::new_list_node(Vec::from_iter(left_nodes.drain(..)))
1351 };
1352
1353 if let Some(tokens_left) = tokens_left
1354 && !tokens.is_empty() {
1355 tokens_left.append(tokens);
1356 }
1357
1358 let pos = left_node.pos().combine(&right_node.as_ref().map(Node::pos).unwrap_or(left_node.pos()));
1359
1360 Some(Node::new_operation_statement_node(
1361 pos,
1362 OperationExpression::new(
1363 Some(Box::new(left_node)),
1364 middle_node.map(Box::new),
1365 right_node.map(Box::new),
1366 operator, operator_type,
1367 ),
1368 ))
1369 }
1370
1371 fn parse_operator_expression_variable_name_and_function_call(
1372 &mut self,
1373 tokens: &mut VecDeque<Token>,
1374 operator_type: OperatorType,
1375 other_tokens: &mut VecDeque<Token>,
1376 left_nodes: &mut Vec<Node>,
1377 t: Token,
1378 whitespaces: &mut VecDeque<Token>,
1379 ) {
1380 if (!other_tokens.is_empty() || !left_nodes.is_empty()) && t.value().starts_with("&") {
1383 tokens[0] = Token::new(t.pos(), "&", TokenType::Operator);
1384 tokens.insert(1, self.lexer.tokenize_other_value(&t.value()[1..], t.pos()));
1385
1386 return;
1387 }
1388
1389 if !whitespaces.is_empty() {
1390 other_tokens.append(whitespaces);
1391 }
1392
1393 if !other_tokens.is_empty() {
1394 self.parse_text_and_char_value(other_tokens, left_nodes);
1395 other_tokens.clear();
1396 }
1397
1398 let is_identifier = matches!(t.token_type(), TokenType::Identifier);
1399 let ret = if is_identifier {
1400 self.parse_variable_name_and_function_call(tokens, Some(operator_type))
1401 }else {
1402 self.parse_parser_function_call(tokens)
1403 };
1404
1405 if let Some(ret) = ret {
1406 if let NodeData::UnprocessedVariableName(variable_name) = ret.node_data() {
1407 if is_identifier && tokens.front().is_some_and(|token|
1408 matches!(token.token_type(), TokenType::Operator) && token.value() == "...") {
1409 let array_unpacking_operator_token = tokens.pop_front().unwrap();
1410 left_nodes.push(Node::new_unprocessed_variable_name_node(
1411 ret.pos().combine(&array_unpacking_operator_token.pos()),
1412 variable_name.to_string() + array_unpacking_operator_token.value(),
1413 ));
1414 }else {
1415 left_nodes.push(ret);
1416 }
1417 }else {
1418 left_nodes.push(ret);
1419 }
1420 }
1421 }
1422
1423 fn convert_comma_operators_to_argument_separators(operator_node: Node) -> Vec<Node> {
1424 let mut nodes = Vec::new();
1425
1426 if let Some(operator) = operator_node.operator() {
1427 match operator {
1428 Operator::Non | Operator::MathNon | Operator::ConditionalNon => {
1429 let operand = operator_node.into_left_side_operand().unwrap();
1431
1432 if matches!(
1433 operand.node_data(),
1434 NodeData::Operation {..} | NodeData::Math {..} | NodeData::Condition {..},
1435 ) {
1436 nodes.append(&mut Self::convert_comma_operators_to_argument_separators(operand));
1437 }else {
1438 nodes.push(operand);
1439 }
1440 },
1441
1442 Operator::Comma => {
1443 let argument_separator_pos = operator_node.pos();
1445 let (left_side_operand, _, right_side_operand) = operator_node.into_operands();
1446 let left_side_operand = left_side_operand.unwrap();
1447 let right_side_operand = right_side_operand.unwrap();
1448
1449 if matches!(
1451 left_side_operand.node_data(),
1452 NodeData::Operation {..} | NodeData::Math {..} | NodeData::Condition {..},
1453 ) {
1454 nodes.append(&mut Self::convert_comma_operators_to_argument_separators(left_side_operand));
1455 }else {
1456 nodes.push(left_side_operand);
1457 }
1458
1459 nodes.push(Node::new_argument_separator_node(argument_separator_pos, ", "));
1461
1462 nodes.push(right_side_operand);
1464 },
1465
1466 _ => {
1467 nodes.push(operator_node);
1468 }
1469 }
1470 }
1471
1472 nodes
1473 }
1474
1475 fn parse_assignment(&mut self, tokens: &mut VecDeque<Token>, inner_assignment: bool) -> Option<Node> {
1476 if tokens.is_empty() {
1477 return None;
1478 }
1479
1480 Self::trim_first_line(tokens);
1481
1482 let mut assignment_index = None;
1483 let mut token_count_first_line = None;
1484 for (i, token) in tokens.iter().
1485 enumerate() {
1486 if matches!(token.token_type(), TokenType::Eol | TokenType::Eof) {
1487 token_count_first_line = Some(i);
1488
1489 break;
1490 }
1491
1492 if assignment_index.is_none() {
1493 if i + 2 < tokens.len() && matches!(token.token_type(), TokenType::ClosingBracket) &&
1495 token.value() == ")" && matches!(tokens[i + 1].token_type(), TokenType::Whitespace) &&
1496 matches!(tokens[i + 2].token_type(), TokenType::Operator) && tokens[i + 2].value() == "->" {
1497 return None;
1498 }
1499
1500 if matches!(token.token_type(), TokenType::Assignment) {
1501 assignment_index = Some(i);
1502 }
1503 }
1504 }
1505
1506 let token_count_first_line = token_count_first_line.unwrap_or(tokens.len());
1507
1508 let Some(assignment_index) = assignment_index else {
1509 if inner_assignment || token_count_first_line != 1 || !matches!(tokens[0].token_type(), TokenType::Identifier) {
1510 return None;
1511 }
1512
1513 if regex_patterns::VAR_NAME_FULL.is_match(tokens[0].value()) {
1514 let variable_name_token = tokens.pop_front().unwrap();
1515
1516 return Some(Node::new_assignment_node(
1517 Node::new_unprocessed_variable_name_node(variable_name_token.pos(), variable_name_token.value()),
1518 Node::new_null_value_node(variable_name_token.pos()),
1519 ));
1520 }
1521
1522 return None;
1523 };
1524
1525 let mut lvalue_tokens = VecDeque::from_iter(
1526 tokens.make_contiguous()[..assignment_index].iter().cloned(),
1527 );
1528
1529 Self::trim_first_line(&mut lvalue_tokens);
1530
1531 if lvalue_tokens.is_empty() {
1532 return None;
1533 }
1534
1535 let assignment_token = &tokens[assignment_index];
1536
1537 let is_simple_assignment = assignment_token.value() == "=";
1538 if is_simple_assignment || assignment_token.value() == " = " {
1539 let pos = lvalue_tokens[0].pos().combine(&lvalue_tokens[lvalue_tokens.len() - 1].pos());
1540
1541 let regex = if is_simple_assignment {
1542 ®ex_patterns::PARSING_SIMPLE_ASSIGNMENT_VARIABLE_NAME_LVALUE
1543 }else {
1544 ®ex_patterns::VAR_NAME_FULL
1545 };
1546
1547 if lvalue_tokens.len() == 1 && matches!(lvalue_tokens[0].token_type(), TokenType::Identifier) &&
1548 regex.is_match(lvalue_tokens[0].value()) {
1549 tokens.drain(..=assignment_index);
1550 Self::trim_first_line(tokens);
1551
1552 if is_simple_assignment {
1553 return Some(Node::new_assignment_node(
1555 Node::new_unprocessed_variable_name_node(pos, lvalue_tokens[0].value()),
1556 self.parse_simple_assignment_value(tokens).into_node(),
1557 ));
1558 }
1559
1560 let returned_node = self.parse_assignment(tokens, true);
1561 let rvalue_node = returned_node.
1562 unwrap_or_else(|| self.parse_lrvalue(tokens, true).into_node());
1563 return Some(Node::new_assignment_node(
1564 Node::new_unprocessed_variable_name_node(pos, lvalue_tokens[0].value()),
1565 rvalue_node,
1566 ));
1567 }
1568
1569 let lvalue = lvalue_tokens.iter().
1570 map(|token| token.to_raw_string().to_string()).
1571 collect::<Vec<String>>().
1572 join("");
1573 if regex_patterns::PARSING_PARSER_FLAG.is_match(&lvalue) {
1574 let mut rvalue_tokens = VecDeque::from_iter(
1575 tokens.make_contiguous()[assignment_index + 1..token_count_first_line].iter().cloned(),
1576 );
1577
1578 Self::trim_first_line(&mut rvalue_tokens);
1579
1580 let ast = if is_simple_assignment {
1581 self.parse_simple_assignment_value(&mut rvalue_tokens)
1582 }else {
1583 self.parse_lrvalue(&mut rvalue_tokens, true)
1584 };
1585
1586 self.parse_parser_flags(lvalue, ast.into_node());
1587
1588 tokens.drain(..token_count_first_line);
1589
1590 return None;
1591 }
1592
1593 if regex_patterns::PARSING_SIMPLE_TRANSLATION_KEY.is_match(&lvalue) {
1594 tokens.drain(..=assignment_index);
1595
1596 let ast = if is_simple_assignment {
1598 self.parse_simple_assignment_value(tokens)
1599 }else {
1600 self.parse_lrvalue(tokens, true)
1601 };
1602
1603 return Some(Node::new_assignment_node(
1604 Node::new_text_value_node(pos, lvalue),
1605 ast.into_node(),
1606 ));
1607 }
1608 }
1609
1610 let is_variable_assignment = lvalue_tokens.len() == 1 &&
1611 matches!(lvalue_tokens[0].token_type(), TokenType::Identifier) &&
1612 regex_patterns::VAR_NAME_FULL.is_match(lvalue_tokens[0].value());
1613
1614 if assignment_token.value() == " =" {
1615 let pos = assignment_token.pos();
1616
1617 tokens.drain(..token_count_first_line);
1618
1619 let ast = if is_variable_assignment {
1620 self.parse_lrvalue(&mut lvalue_tokens, false)
1621 }else {
1622 self.parse_translation_key(&mut lvalue_tokens)
1623 };
1624
1625 return Some(Node::new_assignment_node(
1626 ast.into_node(),
1627 Node::new_null_value_node(pos),
1628 ));
1629 }
1630
1631 if regex_patterns::PARSING_ASSIGNMENT_OPERATOR.is_match(assignment_token.value()) {
1632 let assignment_token_pos = assignment_token.pos();
1633 let assignment_operator = assignment_token.value();
1634 let assignment_operator = assignment_operator[1..assignment_operator.len()-2].to_string();
1635
1636 tokens.drain(..=assignment_index);
1637
1638 let mut operator = None;
1639 if !assignment_operator.is_empty() {
1640 match assignment_operator.as_str() {
1641 "**" => {
1642 operator = Some(Operator::Pow);
1643 },
1644 "*" => {
1645 operator = Some(Operator::Mul);
1646 },
1647 "/" => {
1648 operator = Some(Operator::Div);
1649 },
1650 "~/" => {
1651 operator = Some(Operator::TruncDiv);
1652 },
1653 "//" => {
1654 operator = Some(Operator::FloorDiv);
1655 },
1656 "^/" => {
1657 operator = Some(Operator::CeilDiv);
1658 },
1659 "%" => {
1660 operator = Some(Operator::Mod);
1661 },
1662 "+" => {
1663 operator = Some(Operator::Add);
1664 },
1665 "-" => {
1666 operator = Some(Operator::Sub);
1667 },
1668 "<<" => {
1669 operator = Some(Operator::Lshift);
1670 },
1671 ">>" => {
1672 operator = Some(Operator::Rshift);
1673 },
1674 ">>>" => {
1675 operator = Some(Operator::Rzshift);
1676 },
1677 "&" => {
1678 operator = Some(Operator::BitwiseAnd);
1679 },
1680 "^" => {
1681 operator = Some(Operator::BitwiseXor);
1682 },
1683 "|" => {
1684 operator = Some(Operator::BitwiseOr);
1685 },
1686 "|||" => {
1687 operator = Some(Operator::Concat);
1688 },
1689 "?:" => {
1690 operator = Some(Operator::Elvis);
1691 },
1692 "??" => {
1693 operator = Some(Operator::NullCoalescing);
1694 },
1695 "?" => {
1696 operator = Some(Operator::ConditionalNon);
1697 },
1698 ":" => {
1699 operator = Some(Operator::MathNon);
1700 },
1701 "$" => {
1702 operator = Some(Operator::Non);
1703 },
1704
1705 _ => {}
1706 }
1707 }
1708
1709 let lvalue_node = match operator {
1710 _ if is_variable_assignment => {
1711 self.parse_lrvalue(&mut lvalue_tokens, false).into_node()
1712 },
1713
1714 Some(Operator::ConditionalNon) => {
1715 self.parse_condition_expr(&mut lvalue_tokens).unwrap()
1716 },
1717
1718 Some(Operator::MathNon) => {
1719 self.parse_math_expr(&mut lvalue_tokens).unwrap()
1720 },
1721
1722 _ => {
1723 self.parse_operation_expr(&mut lvalue_tokens).unwrap()
1724 },
1725 };
1726
1727 let rvalue_node = match operator {
1728 _ if assignment_operator == "::" => {
1729 let returned_node = self.parse_assignment(tokens, true);
1730
1731 returned_node.unwrap_or_else(|| self.parse_lrvalue(tokens, true).into_node())
1732 },
1733
1734 None => {
1735 Node::new_parsing_error_node(
1736 assignment_token_pos,
1737 ParsingError::InvalidAssignment,
1738 format!("Invalid assignment operator: \" {}= \"", assignment_operator),
1739 )
1740 },
1741
1742 Some(Operator::ConditionalNon) => {
1743 self.parse_condition_expr(tokens).unwrap()
1744 },
1745
1746 Some(Operator::MathNon) => {
1747 self.parse_math_expr(tokens).unwrap()
1748 },
1749
1750 Some(Operator::Non) => {
1751 self.parse_operation_expr(tokens).unwrap()
1752 },
1753
1754 Some(operator) => {
1755 let left_side_operand = lvalue_node.clone();
1756 let right_side_operand = self.parse_operation_expr(tokens).unwrap();
1757
1758 Node::new_operation_statement_node(
1759 left_side_operand.pos().combine(&right_side_operand.pos()),
1760 OperationExpression::new(
1761 Some(Box::new(left_side_operand)),
1762 None,
1763 Some(Box::new(right_side_operand)),
1764 operator, operator.operator_type(),
1765 ),
1766 )
1767 },
1768 };
1769
1770 return Some(Node::new_assignment_node(lvalue_node, rvalue_node));
1771 }
1772
1773 if assignment_token.value() == " = " {
1775 tokens.drain(..=assignment_index);
1776
1777 return Some(Node::new_assignment_node(
1779 self.parse_translation_key(&mut lvalue_tokens).into_node(),
1780 self.parse_lrvalue(tokens, true).into_node(),
1781 ));
1782 }
1783
1784 None
1785 }
1786
1787 fn parse_line(&mut self, tokens: &mut VecDeque<Token>) -> Option<AST> {
1788 let mut ast = AST::new();
1789 let nodes = ast.nodes_mut();
1790
1791 Self::trim_first_line(tokens);
1792
1793 let mut token_count_first_line = Self::get_token_count_first_line(tokens.make_contiguous());
1794
1795 let starts_with_con_expression = tokens.front().is_some_and(|token|
1797 matches!(token.token_type(), TokenType::Other) && token.value().starts_with("con."));
1798 let ends_with_opening_bracket = tokens.get(token_count_first_line - 1).is_some_and(|token|
1799 matches!(token.token_type(), TokenType::OpeningBlockBracket));
1800 if starts_with_con_expression || ends_with_opening_bracket {
1801 let mut con_expression = tokens[0].value().to_string();
1802 let original_con_expression = con_expression.clone();
1803
1804 if ends_with_opening_bracket && !starts_with_con_expression {
1806 con_expression = "con.".to_string() + &con_expression;
1807 }
1808
1809 match con_expression.as_str() {
1810 "con.continue" | "con.break" if !ends_with_opening_bracket => {
1811 let con_expression_token = tokens.pop_front().unwrap();
1812 let mut pos_last_token = con_expression_token.pos();
1813
1814 let number_node = if token_count_first_line > 1 && matches!(tokens[0].token_type(), TokenType::OpeningBracket) &&
1815 tokens[0].value() == "(" {
1816 let arguments_end_index = utils::get_index_of_matching_bracket_tok(
1817 tokens.make_contiguous(),
1818 0, usize::MAX,
1819 "(", ")", true,
1820 );
1821 let Some(arguments_end_index) = arguments_end_index else {
1822 nodes.push(Node::new_parsing_error_node(
1823 tokens[0].pos(),
1824 ParsingError::BracketMismatch,
1825 "Bracket for con.break or con.continue is missing",
1826 ));
1827
1828 return Some(ast);
1829 };
1830
1831 pos_last_token = tokens[arguments_end_index].pos();
1832
1833 let mut argument_tokens = utils::split_off_arguments(tokens, arguments_end_index);
1834
1835 Some(self.parse_function_parameter_list(&mut argument_tokens, false).into_node())
1836 }else {
1837 None
1838 };
1839
1840 let pos = con_expression_token.pos().combine(&pos_last_token);
1841 nodes.push(Node::new_continue_break_statement_node(
1842 pos,
1843 number_node.map(Box::new),
1844 con_expression_token.value() == "con.continue",
1845 ));
1846
1847 return Some(ast);
1848 },
1849
1850 "con.try" | "con.softtry" | "con.nontry" => {
1851 let mut try_statement_parts = Vec::new();
1852
1853 let block_bracket_flag = ends_with_opening_bracket;
1854 while !tokens.is_empty() {
1855 Self::trim_first_line(tokens);
1856
1857 let mut token_count_first_line = Self::get_token_count_first_line(tokens.make_contiguous());
1858 if token_count_first_line == 0 {
1859 break;
1860 }
1861
1862 let ends_with_opening_bracket = matches!(tokens[token_count_first_line - 1].token_type(), TokenType::OpeningBlockBracket);
1863
1864 con_expression = tokens[0].value().to_string();
1865
1866 if ends_with_opening_bracket && !starts_with_con_expression {
1868 con_expression = "con.".to_string() + &con_expression;
1869 }
1870
1871 if block_bracket_flag {
1872 let pos = tokens[token_count_first_line - 1].pos();
1874
1875 if !ends_with_opening_bracket {
1876 nodes.push(Node::new_parsing_error_node(
1877 pos,
1878 ParsingError::InvalidConPart,
1879 "Missing \"{\" token after con statement",
1880 ));
1881 }
1882
1883 tokens.remove(token_count_first_line - 1);
1884
1885 token_count_first_line -= 1;
1886
1887 if token_count_first_line == 0 || !matches!(tokens[0].token_type(), TokenType::Other) {
1888 nodes.push(Node::new_parsing_error_node(
1889 pos,
1890 ParsingError::InvalidConPart,
1891 "Missing con statement",
1892 ));
1893 }
1894
1895 con_expression = tokens[0].value().to_string();
1896
1897 if !con_expression.starts_with("con.") {
1899 con_expression = "con.".to_string() + &con_expression;
1900 }
1901
1902 Self::trim_first_line(tokens);
1903
1904 token_count_first_line = Self::get_token_count_first_line(tokens.make_contiguous());
1905 }
1906
1907 let mut try_arguments;
1908 match con_expression.as_str() {
1909 "con.try" | "con.softtry" | "con.nontry" | "con.else" | "con.finally" => {
1910 let try_statement_token = tokens.pop_front().unwrap();
1911 token_count_first_line -= 1;
1912
1913 if token_count_first_line >= 1 && matches!(tokens[0].token_type(), TokenType::OpeningBracket) &&
1914 tokens[0].value() == "(" {
1915 nodes.push(Node::new_parsing_error_node(
1916 try_statement_token.pos(),
1917 ParsingError::InvalidConPart,
1918 "Try/Softtry/Nontry/Finally/Else part with arguments",
1919 ));
1920
1921 return Some(ast);
1922 }
1923
1924 try_arguments = None;
1925 },
1926
1927 "con.catch" => {
1928 if token_count_first_line == 1 {
1929 try_arguments = None;
1930 }else {
1931 tokens.pop_front().unwrap();
1932 token_count_first_line -= 1;
1933
1934 if token_count_first_line > 1 && matches!(tokens[0].token_type(), TokenType::OpeningBracket) &&
1935 tokens[0].value() == "(" {
1936 let arguments_end_index = utils::get_index_of_matching_bracket_tok(
1937 tokens.make_contiguous(),
1938 0, usize::MAX,
1939 "(", ")", true,
1940 );
1941 let Some(arguments_end_index) = arguments_end_index else {
1942 nodes.push(Node::new_parsing_error_node(
1943 tokens[0].pos(),
1944 ParsingError::BracketMismatch,
1945 "Missing catch statement arguments",
1946 ));
1947
1948 return Some(ast);
1949 };
1950
1951 try_arguments = Some(utils::split_off_arguments(tokens, arguments_end_index));
1952 token_count_first_line -= arguments_end_index + 1;
1953 }else {
1954 try_arguments = None;
1955 }
1956
1957 if token_count_first_line != 0 {
1958 nodes.push(Node::new_parsing_error_node(
1959 tokens[0].pos(),
1960 ParsingError::InvalidConPart,
1961 "Trailing stuff behind arguments",
1962 ));
1963
1964 return Some(ast);
1965 }
1966 }
1967 },
1968
1969 "con.endtry" if !block_bracket_flag => {
1970 tokens.pop_front();
1971
1972 break;
1973 },
1974
1975 _ => {
1976 nodes.push(Node::new_parsing_error_node(
1978 CodePosition::EMPTY,
1979 ParsingError::InvalidConPart,
1980 format!("Try statement part is invalid: \"{}\"", con_expression),
1981 ));
1982
1983 return Some(ast);
1984 },
1985 };
1986
1987 let try_body = self.parse_tokens_internal(tokens);
1988 let Some(try_body) = try_body else {
1989 nodes.push(Node::new_try_statement_node(CodePosition::EMPTY, try_statement_parts));
1991 nodes.push(Node::new_parsing_error_node(
1992 CodePosition::EMPTY,
1993 ParsingError::Eof,
1994 "In try body",
1995 ));
1996
1997 return Some(ast);
1998 };
1999
2000 match con_expression.as_str() {
2002 "con.try" => {
2003 try_statement_parts.push(Node::new_try_statement_part_try_node(
2004 CodePosition::EMPTY,
2005 try_body,
2006 ));
2007 },
2008
2009 "con.softtry" => {
2010 try_statement_parts.push(Node::new_try_statement_part_soft_try_node(
2011 CodePosition::EMPTY,
2012 try_body,
2013 ));
2014 },
2015
2016 "con.nontry" => {
2017 try_statement_parts.push(Node::new_try_statement_part_non_try_node(
2018 CodePosition::EMPTY,
2019 try_body,
2020 ));
2021 },
2022
2023 "con.catch" => {
2024 try_statement_parts.push(Node::new_try_statement_part_catch_node(
2025 CodePosition::EMPTY,
2026 try_body,
2027 try_arguments.as_mut().map(|tokens|
2028 self.parse_function_parameter_list(tokens, false).
2029 into_nodes()),
2030 ));
2031 },
2032
2033 "con.else" => {
2034 try_statement_parts.push(Node::new_try_statement_part_else_node(
2035 CodePosition::EMPTY,
2036 try_body,
2037 ));
2038 },
2039
2040 "con.finally" => {
2041 try_statement_parts.push(Node::new_try_statement_part_finally_node(
2042 CodePosition::EMPTY,
2043 try_body,
2044 ));
2045 },
2046
2047 _ => {},
2048 }
2049 }
2050
2051 nodes.push(Node::new_try_statement_node(CodePosition::EMPTY, try_statement_parts));
2053 return Some(ast);
2054 },
2055
2056 "con.loop" | "con.while" | "con.until" | "con.repeat" | "con.foreach" => {
2057 let mut loop_statement_parts = Vec::new();
2058
2059 let block_bracket_flag = ends_with_opening_bracket;
2060 while !tokens.is_empty() {
2061 Self::trim_first_line(tokens);
2062
2063 let mut token_count_first_line = Self::get_token_count_first_line(tokens.make_contiguous());
2064 if token_count_first_line == 0 {
2065 break;
2066 }
2067
2068 let ends_with_opening_bracket = matches!(tokens[token_count_first_line - 1].token_type(), TokenType::OpeningBlockBracket);
2069
2070 con_expression = tokens[0].value().to_string();
2071
2072 if ends_with_opening_bracket && !starts_with_con_expression {
2074 con_expression = "con.".to_string() + &con_expression;
2075 }
2076
2077 if block_bracket_flag {
2078 let pos = tokens[token_count_first_line - 1].pos();
2080
2081 if !ends_with_opening_bracket {
2082 nodes.push(Node::new_parsing_error_node(
2083 pos,
2084 ParsingError::InvalidConPart,
2085 "Missing \"{\" token after con statement",
2086 ));
2087 }
2088
2089 tokens.remove(token_count_first_line - 1);
2090
2091 token_count_first_line -= 1;
2092
2093 if token_count_first_line == 0 || !matches!(tokens[0].token_type(), TokenType::Other) {
2094 nodes.push(Node::new_parsing_error_node(
2095 pos,
2096 ParsingError::InvalidConPart,
2097 "Missing con statement",
2098 ));
2099 }
2100
2101 con_expression = tokens[0].value().to_string();
2102
2103 if !con_expression.starts_with("con.") {
2105 con_expression = "con.".to_string() + &con_expression;
2106 }
2107
2108 Self::trim_first_line(tokens);
2109
2110 token_count_first_line = Self::get_token_count_first_line(tokens.make_contiguous());
2111 }
2112
2113 let loop_condition;
2114 match con_expression.as_str() {
2115 "con.else" | "con.loop" => {
2116 let try_statement_token = tokens.pop_front().unwrap();
2117 token_count_first_line -= 1;
2118
2119 if token_count_first_line >= 1 && matches!(tokens[0].token_type(), TokenType::OpeningBracket) &&
2120 tokens[0].value() == "(" {
2121 nodes.push(Node::new_parsing_error_node(
2122 try_statement_token.pos(),
2123 ParsingError::InvalidConPart,
2124 "Loop/Else part with arguments",
2125 ));
2126
2127 return Some(ast);
2128 }
2129
2130 loop_condition = None;
2131 },
2132
2133 "con.while" | "con.until" | "con.repeat" | "con.foreach" => {
2134 tokens.pop_front().unwrap();
2135 token_count_first_line -= 1;
2136
2137 if token_count_first_line > 1 && matches!(tokens[0].token_type(), TokenType::OpeningBracket) &&
2138 tokens[0].value() == "(" {
2139 let arguments_end_index = utils::get_index_of_matching_bracket_tok(
2140 tokens.make_contiguous(),
2141 0, usize::MAX,
2142 "(", ")", true,
2143 );
2144 let Some(arguments_end_index) = arguments_end_index else {
2145 nodes.push(Node::new_parsing_error_node(
2146 tokens[0].pos(),
2147 ParsingError::BracketMismatch,
2148 "Missing loop statement arguments",
2149 ));
2150
2151 return Some(ast);
2152 };
2153
2154 loop_condition = Some(utils::split_off_arguments(tokens, arguments_end_index));
2155 token_count_first_line -= arguments_end_index + 1;
2156 }else {
2157 nodes.push(Node::new_parsing_error_node(
2158 tokens[0].pos(),
2159 ParsingError::BracketMismatch,
2160 "Bracket for loop statement missing",
2161 ));
2162
2163 return Some(ast);
2164 }
2165
2166 if token_count_first_line != 0 {
2167 nodes.push(Node::new_parsing_error_node(
2168 tokens[0].pos(),
2169 ParsingError::InvalidConPart,
2170 "Trailing stuff behind arguments",
2171 ));
2172
2173 return Some(ast);
2174 }
2175 },
2176
2177 "con.endloop" if !block_bracket_flag => {
2178 tokens.pop_front();
2179
2180 break;
2181 },
2182
2183 _ => {
2184 nodes.push(Node::new_parsing_error_node(
2186 CodePosition::EMPTY,
2187 ParsingError::InvalidConPart,
2188 format!("Loop statement part is invalid: \"{}\"", con_expression),
2189 ));
2190
2191 return Some(ast);
2192 },
2193 }
2194
2195 let loop_body = self.parse_tokens_internal(tokens);
2196 let Some(loop_body) = loop_body else {
2197 nodes.push(Node::new_loop_statement_node(CodePosition::EMPTY, loop_statement_parts));
2199 nodes.push(Node::new_parsing_error_node(
2200 CodePosition::EMPTY,
2201 ParsingError::Eof,
2202 "In loop body",
2203 ));
2204
2205 return Some(ast);
2206 };
2207
2208 match con_expression.as_str() {
2210 "con.else" => {
2211 loop_statement_parts.push(Node::new_loop_statement_part_else_node(
2212 CodePosition::EMPTY,
2213 loop_body,
2214 ));
2215 },
2216
2217 "con.loop" => {
2218 loop_statement_parts.push(Node::new_loop_statement_part_loop_node(
2219 CodePosition::EMPTY,
2220 loop_body,
2221 ));
2222 },
2223
2224 "con.while" => {
2225 let operand = self.parse_operation_expr(&mut loop_condition.unwrap()).
2226 unwrap();
2227
2228 let conditional_non_node = ConditionalNode::new(Node::new_operation_statement_node(
2229 operand.pos(),
2230 OperationExpression::new(
2231 Some(Box::new(operand)),
2232 None,
2233 None,
2234 Operator::ConditionalNon, OperatorType::Condition,
2235 ),
2236 ));
2237
2238 loop_statement_parts.push(Node::new_loop_statement_part_while_node(
2239 CodePosition::EMPTY,
2240 loop_body,
2241 conditional_non_node,
2242 ));
2243 },
2244
2245 "con.until" => {
2246 let operand = self.parse_operation_expr(&mut loop_condition.unwrap()).
2247 unwrap();
2248
2249 let conditional_non_node = ConditionalNode::new(Node::new_operation_statement_node(
2250 operand.pos(),
2251 OperationExpression::new(
2252 Some(Box::new(operand)),
2253 None,
2254 None,
2255 Operator::ConditionalNon, OperatorType::Condition,
2256 ),
2257 ));
2258
2259 loop_statement_parts.push(Node::new_loop_statement_part_until_node(
2260 CodePosition::EMPTY,
2261 loop_body,
2262 conditional_non_node,
2263 ));
2264 },
2265
2266 "con.repeat" | "con.foreach" => {
2267 let arguments = self.parse_operation_expr(&mut loop_condition.unwrap()).unwrap();
2268 let arguments = Self::convert_comma_operators_to_argument_separators(arguments);
2269
2270 let mut argument_iter = arguments.into_iter();
2271
2272 let mut var_pointer_node = None;
2273 let mut flag = false;
2274 for node in argument_iter.by_ref() {
2275 if matches!(node.node_data(), NodeData::ArgumentSeparator(_)) ||
2276 var_pointer_node.is_some() {
2277 flag = true;
2278 break;
2279 }
2280
2281 var_pointer_node = Some(node);
2282 }
2283 if !flag {
2284 nodes.push(Node::new_parsing_error_node(
2285 CodePosition::EMPTY,
2286 ParsingError::InvalidConPart,
2287 "con.repeat or con.foreach arguments are invalid",
2288 ));
2289
2290 return Some(ast);
2291 }
2292
2293 let mut repeat_count_argument = Vec::new();
2294 for node in argument_iter {
2295 if matches!(node.node_data(), NodeData::ArgumentSeparator(_)) {
2296 nodes.push(Node::new_parsing_error_node(
2297 CodePosition::EMPTY,
2298 ParsingError::InvalidConPart,
2299 "con.repeat or con.foreach arguments are invalid",
2300 ));
2301
2302 return Some(ast);
2303 }
2304
2305 repeat_count_argument.push(node);
2306 }
2307
2308 let repeat_count_or_array_or_text_node = if repeat_count_argument.len() == 1 {
2309 repeat_count_argument.into_iter().next().unwrap()
2310 }else {
2311 Node::new_list_node(repeat_count_argument)
2312 };
2313
2314 if con_expression == "con.repeat" {
2315 loop_statement_parts.push(Node::new_loop_statement_part_repeat_node(
2316 CodePosition::EMPTY,
2317 loop_body,
2318 var_pointer_node.unwrap(),
2319 repeat_count_or_array_or_text_node,
2320 ));
2321 }else {
2322 loop_statement_parts.push(Node::new_loop_statement_part_for_each_node(
2323 CodePosition::EMPTY,
2324 loop_body,
2325 var_pointer_node.unwrap(),
2326 repeat_count_or_array_or_text_node,
2327 ));
2328 }
2329 },
2330
2331 _ => {},
2332 }
2333 }
2334
2335 nodes.push(Node::new_loop_statement_node(CodePosition::EMPTY, loop_statement_parts));
2337 return Some(ast);
2338 },
2339
2340 "con.if" => {
2341 let mut if_statement_parts = Vec::new();
2342
2343 let block_bracket_flag = ends_with_opening_bracket;
2344 while !tokens.is_empty() {
2345 Self::trim_first_line(tokens);
2346
2347 let mut token_count_first_line = Self::get_token_count_first_line(tokens.make_contiguous());
2348 if token_count_first_line == 0 {
2349 break;
2350 }
2351
2352 let ends_with_opening_bracket = matches!(tokens[token_count_first_line - 1].token_type(), TokenType::OpeningBlockBracket);
2353
2354 con_expression = tokens[0].value().to_string();
2355
2356 if ends_with_opening_bracket && !starts_with_con_expression {
2358 con_expression = "con.".to_string() + &con_expression;
2359 }
2360
2361 if block_bracket_flag {
2362 let pos = tokens[token_count_first_line - 1].pos();
2364
2365 if !ends_with_opening_bracket {
2366 nodes.push(Node::new_parsing_error_node(
2367 pos,
2368 ParsingError::InvalidConPart,
2369 "Missing \"{\" token after con statement",
2370 ));
2371 }
2372
2373 tokens.remove(token_count_first_line - 1);
2374
2375 token_count_first_line -= 1;
2376
2377 if token_count_first_line == 0 || !matches!(tokens[0].token_type(), TokenType::Other) {
2378 nodes.push(Node::new_parsing_error_node(
2379 pos,
2380 ParsingError::InvalidConPart,
2381 "Missing con statement",
2382 ));
2383 }
2384
2385 con_expression = tokens[0].value().to_string();
2386
2387 if !con_expression.starts_with("con.") {
2389 con_expression = "con.".to_string() + &con_expression;
2390 }
2391
2392 Self::trim_first_line(tokens);
2393
2394 token_count_first_line = Self::get_token_count_first_line(tokens.make_contiguous());
2395 }
2396
2397 let mut if_condition;
2398 match con_expression.as_str() {
2399 "con.else" => {
2400 let try_statement_token = tokens.pop_front().unwrap();
2401 token_count_first_line -= 1;
2402
2403 if token_count_first_line >= 1 && matches!(tokens[0].token_type(), TokenType::OpeningBracket) &&
2404 tokens[0].value() == "(" {
2405 nodes.push(Node::new_parsing_error_node(
2406 try_statement_token.pos(),
2407 ParsingError::InvalidConPart,
2408 "Else part with arguments",
2409 ));
2410
2411 return Some(ast);
2412 }
2413
2414 if_condition = None;
2415 },
2416
2417 "con.if" | "con.elif" => {
2418 tokens.pop_front().unwrap();
2419 token_count_first_line -= 1;
2420
2421 if token_count_first_line > 1 && matches!(tokens[0].token_type(), TokenType::OpeningBracket) &&
2422 tokens[0].value() == "(" {
2423 let arguments_end_index = utils::get_index_of_matching_bracket_tok(
2424 tokens.make_contiguous(),
2425 0, usize::MAX,
2426 "(", ")", true,
2427 );
2428 let Some(arguments_end_index) = arguments_end_index else {
2429 nodes.push(Node::new_parsing_error_node(
2430 tokens[0].pos(),
2431 ParsingError::BracketMismatch,
2432 "Missing if statement arguments",
2433 ));
2434
2435 return Some(ast);
2436 };
2437
2438 if_condition = Some(utils::split_off_arguments(tokens, arguments_end_index));
2439 token_count_first_line -= arguments_end_index + 1;
2440 }else {
2441 nodes.push(Node::new_parsing_error_node(
2442 tokens[0].pos(),
2443 ParsingError::BracketMismatch,
2444 "Bracket for if statement missing",
2445 ));
2446
2447 return Some(ast);
2448 }
2449
2450 if token_count_first_line != 0 {
2451 nodes.push(Node::new_parsing_error_node(
2452 tokens[0].pos(),
2453 ParsingError::InvalidConPart,
2454 "Trailing stuff behind arguments",
2455 ));
2456
2457 return Some(ast);
2458 }
2459 },
2460
2461 "con.endif" if !block_bracket_flag => {
2462 tokens.pop_front();
2463
2464 break;
2465 },
2466
2467 _ => {
2468 nodes.push(Node::new_parsing_error_node(
2470 CodePosition::EMPTY,
2471 ParsingError::InvalidConPart,
2472 format!("If statement part is invalid: \"{}\"", con_expression),
2473 ));
2474
2475 return Some(ast);
2476 },
2477 }
2478
2479 let if_body = self.parse_tokens_internal(tokens);
2480 let Some(if_body) = if_body else {
2481 nodes.push(Node::new_if_statement_node(CodePosition::EMPTY, if_statement_parts));
2483 nodes.push(Node::new_parsing_error_node(
2484 CodePosition::EMPTY,
2485 ParsingError::Eof,
2486 "In if body",
2487 ));
2488
2489 return Some(ast);
2490 };
2491
2492 if let Some(ref mut if_condition) = if_condition {
2494 let operand = self.parse_operation_expr(if_condition).
2495 unwrap();
2496
2497 let conditional_non_node = ConditionalNode::new(Node::new_operation_statement_node(
2498 operand.pos(),
2499 OperationExpression::new(
2500 Some(Box::new(operand)),
2501 None,
2502 None,
2503 Operator::ConditionalNon, OperatorType::Condition,
2504 ),
2505 ));
2506
2507 if_statement_parts.push(Node::new_if_statement_part_if_node(
2508 CodePosition::EMPTY,
2509 if_body,
2510 conditional_non_node,
2511 ));
2512 }else {
2513 if_statement_parts.push(Node::new_if_statement_part_else_node(
2514 CodePosition::EMPTY,
2515 if_body,
2516 ));
2517 }
2518 }
2519
2520 nodes.push(Node::new_if_statement_node(CodePosition::EMPTY, if_statement_parts));
2522 return Some(ast);
2523 }
2524
2525 _ if original_con_expression.starts_with("con.") => {
2526 return None;
2527 },
2528
2529 _ => {},
2530 }
2531 }
2532
2533 if token_count_first_line >= 1 && matches!(tokens[0].token_type(), TokenType::Other) &&
2535 tokens[0].value() == "return" {
2536 let return_statement_token_pos = tokens.front().unwrap().pos();
2537
2538 if token_count_first_line == 1 {
2540 nodes.push(Node::new_return_statement_node(return_statement_token_pos, None));
2541 tokens.pop_front();
2542
2543 return Some(ast);
2544 }
2545
2546 tokens.pop_front();
2548
2549 if matches!(tokens[0].token_type(), TokenType::Whitespace) {
2550 let node = self.parse_assignment(tokens, true).
2551 unwrap_or_else(|| self.parse_lrvalue(tokens, true).into_node());
2552 nodes.push(Node::new_return_statement_node(
2553 return_statement_token_pos.combine(&node.pos()),
2554 Some(node),
2555 ));
2556
2557 return Some(ast);
2558 }
2559 }
2560
2561 if token_count_first_line > 1 && matches!(tokens[0].token_type(), TokenType::Other) &&
2563 tokens[0].value() == "throw" {
2564 let throw_statement_token_pos = tokens.pop_front().unwrap().pos();
2565
2566 let arguments = self.parse_operation_expr(tokens).unwrap();
2567 let arguments = Self::convert_comma_operators_to_argument_separators(arguments);
2568
2569 let mut argument_iter = arguments.into_iter();
2570
2571 let mut error_nodes = Vec::new();
2572 let mut flag = false;
2573 for node in argument_iter.by_ref() {
2574 if matches!(node.node_data(), NodeData::ArgumentSeparator(_)) {
2575 flag = true;
2576 break;
2577 }
2578
2579 error_nodes.push(node);
2580 }
2581 if !flag && error_nodes.is_empty() {
2582 nodes.push(Node::new_parsing_error_node(
2583 throw_statement_token_pos,
2584 ParsingError::LexerError,
2585 "throw arguments are invalid",
2586 ));
2587
2588 return Some(ast);
2589 }
2590
2591 let mut message_nodes = Vec::new();
2592 for node in argument_iter {
2593 if matches!(node.node_data(), NodeData::ArgumentSeparator(_)) {
2594 nodes.push(Node::new_parsing_error_node(
2595 CodePosition::EMPTY,
2596 ParsingError::LexerError,
2597 "throw arguments are invalid",
2598 ));
2599
2600 return Some(ast);
2601 }
2602
2603 message_nodes.push(node);
2604 }
2605
2606 let error_node = if error_nodes.len() == 1 {
2607 error_nodes.into_iter().next().unwrap()
2608 }else {
2609 Node::new_list_node(error_nodes)
2610 };
2611
2612 let message_node = if message_nodes.is_empty() {
2613 None
2614 }else if message_nodes.len() == 1 {
2615 message_nodes.into_iter().next()
2616 }else {
2617 Some(Node::new_list_node(message_nodes))
2618 };
2619
2620 let pos = throw_statement_token_pos.combine(&message_node.as_ref().unwrap_or(&error_node).pos());
2621
2622 nodes.push(Node::new_throw_statement_node(pos, error_node, message_node));
2623
2624 return Some(ast);
2625 }
2626
2627 if token_count_first_line > 3 && matches!(tokens[0].token_type(), TokenType::Other) &&
2629 tokens[0].value() == "function" && ends_with_opening_bracket {
2630 let function_definition_start_token = tokens.pop_front().unwrap();
2631 token_count_first_line -= 1;
2632
2633 if !matches!(tokens[0].token_type(), TokenType::Whitespace) {
2634 nodes.push(Node::new_parsing_error_node(
2635 function_definition_start_token.pos(),
2636 ParsingError::LexerError,
2637 "Invalid function definition: Whitespace is missing after \"function\"",
2638 ));
2639
2640 return Some(ast);
2641 }
2642
2643 tokens.pop_front();
2644 token_count_first_line -= 1;
2645
2646 let overloaded = matches!(tokens[0].token_type(), TokenType::Other) &&
2647 tokens[0].value() == "overload" && matches!(tokens[1].token_type(), TokenType::Whitespace);
2648 if overloaded {
2649 tokens.pop_front();
2650 tokens.pop_front();
2651 token_count_first_line -= 2;
2652 }
2653
2654 let combinator = matches!(tokens[0].token_type(), TokenType::Other) &&
2655 tokens[0].value() == "combinator" && matches!(tokens[1].token_type(), TokenType::Whitespace);
2656 if combinator {
2657 tokens.pop_front();
2658 tokens.pop_front();
2659 token_count_first_line -= 2;
2660 }
2661
2662 #[expect(clippy::nonminimal_bool)]
2663 if !(matches!(tokens[0].token_type(), TokenType::Identifier) &&
2664 regex_patterns::VAR_NAME_NORMAL_FUNCTION_WITHOUT_PREFIX.is_match(tokens[0].value())) &&
2665 !(matches!(tokens[0].token_type(), TokenType::Other) &&
2666 regex_patterns::WORD.is_match(tokens[0].value())) {
2667 nodes.push(Node::new_parsing_error_node(
2668 function_definition_start_token.pos(),
2669 ParsingError::LexerError,
2670 format!(
2671 "Invalid function definition: Invalid function identifier: {}",
2672 tokens[0].value(),
2673 ),
2674 ));
2675
2676 return Some(ast);
2677 }
2678
2679 let function_name_token = tokens.pop_front().unwrap();
2680 token_count_first_line -= 1;
2681
2682 let mut function_name = function_name_token.value().to_string();
2683 if !function_name.starts_with("fp.") && !function_name.starts_with("$") {
2684 function_name = "fp.".to_string() + &function_name;
2685 }
2686
2687 if matches!(tokens[0].token_type(), TokenType::Whitespace) {
2688 tokens.pop_front();
2689 token_count_first_line -= 1;
2690 }
2691
2692 if !matches!(tokens[0].token_type(), TokenType::OpeningBracket) ||
2693 tokens[0].value() != "(" {
2694 nodes.push(Node::new_parsing_error_node(
2695 function_definition_start_token.pos(),
2696 ParsingError::BracketMismatch,
2697 "Bracket is missing in parameter list in function definition",
2698 ));
2699
2700 return Some(ast);
2701 }
2702
2703 let bracket_end_index = utils::get_index_of_matching_bracket_tok(
2704 tokens.make_contiguous(),
2705 0, usize::MAX,
2706 "(", ")", true,
2707 );
2708 let Some(bracket_end_index) = bracket_end_index else {
2709 nodes.push(Node::new_parsing_error_node(
2710 function_definition_start_token.pos(),
2711 ParsingError::BracketMismatch,
2712 "Bracket is missing in parameter list in function definition",
2713 ));
2714
2715 return Some(ast);
2716 };
2717
2718 let mut parameter_list = utils::split_off_arguments(tokens, bracket_end_index);
2719 token_count_first_line -= bracket_end_index + 1;
2720
2721 let type_constraint = if token_count_first_line > 2 &&
2722 matches!(tokens[0].token_type(), TokenType::Operator) && tokens[0].value() == ":" &&
2723 matches!(tokens[1].token_type(), TokenType::OpeningBracket) && tokens[1].value() == "{" {
2724 tokens.pop_front();
2725 token_count_first_line -= 1;
2726
2727 let bracket_end_index = utils::get_index_of_matching_bracket_tok(
2728 tokens.make_contiguous(),
2729 0, usize::MAX,
2730 "{", "}", true,
2731 );
2732 let Some(bracket_end_index) = bracket_end_index else {
2733 nodes.push(Node::new_parsing_error_node(
2734 function_definition_start_token.pos(),
2735 ParsingError::BracketMismatch,
2736 "Bracket is missing in return type constraint in function definition",
2737 ));
2738
2739 return Some(ast);
2740 };
2741
2742 let mut type_constraint_tokens = tokens.split_off(bracket_end_index + 1);
2743 mem::swap(tokens, &mut type_constraint_tokens);
2744 token_count_first_line -= bracket_end_index + 1;
2745
2746 self.parse_type_constraint(&mut type_constraint_tokens, false, nodes)
2747 }else {
2748 None
2749 };
2750
2751 if matches!(tokens[0].token_type(), TokenType::Whitespace) {
2752 tokens.pop_front();
2753 token_count_first_line -= 1;
2754 }
2755
2756 if token_count_first_line != 1 {
2757 nodes.push(Node::new_parsing_error_node(
2758 function_definition_start_token.pos(),
2759 ParsingError::LexerError,
2760 "Invalid tokens after function return type constraint",
2761 ));
2762
2763 return Some(ast);
2764 }
2765
2766 tokens.pop_front();
2767
2768 if !tokens.is_empty() && matches!(tokens[0].token_type(), TokenType::Eol) {
2769 tokens.pop_front();
2770 }
2771
2772 nodes.append(&mut self.parse_function_definition(
2773 Some(function_name),
2774 overloaded,
2775 combinator,
2776 &mut parameter_list,
2777 type_constraint,
2778 tokens,
2779 ).into_nodes());
2780
2781 return Some(ast);
2782 }
2783
2784 if token_count_first_line > 1 && matches!(tokens[0].token_type(), TokenType::Other) &&
2786 tokens[0].value() == "struct" && ends_with_opening_bracket {
2787 let struct_definition_start_token = tokens.pop_front().unwrap();
2788 token_count_first_line -= 1;
2789
2790 if !matches!(tokens[0].token_type(), TokenType::Whitespace) {
2791 nodes.push(Node::new_parsing_error_node(
2792 struct_definition_start_token.pos(),
2793 ParsingError::LexerError,
2794 "Invalid struct definition: Whitespace is missing after \"struct\"",
2795 ));
2796
2797 return Some(ast);
2798 }
2799
2800 tokens.pop_front();
2801 token_count_first_line -= 1;
2802
2803 if !matches!(tokens[0].token_type(), TokenType::Identifier) ||
2804 !regex_patterns::VAR_NAME_NORMAL_ARRAY_WITHOUT_PREFIX.is_match(tokens[0].value()) {
2805 nodes.push(Node::new_parsing_error_node(
2806 struct_definition_start_token.pos(),
2807 ParsingError::LexerError,
2808 format!("Invalid struct definition: Invalid struct identifier: \"{}\"", tokens[0]),
2809 ));
2810
2811 return Some(ast);
2812 }
2813
2814 let struct_name_token = tokens.pop_front().unwrap();
2815 token_count_first_line -= 1;
2816
2817 let struct_name = struct_name_token.value().to_string();
2818
2819 if matches!(tokens[0].token_type(), TokenType::Whitespace) {
2820 tokens.pop_front();
2821 token_count_first_line -= 1;
2822 }
2823
2824 if token_count_first_line != 1 {
2825 nodes.push(Node::new_parsing_error_node(
2826 struct_definition_start_token.pos(),
2827 ParsingError::LexerError,
2828 "Invalid tokens after struct identifier",
2829 ));
2830
2831 return Some(ast);
2832 }
2833
2834 tokens.pop_front();
2835
2836 if !tokens.is_empty() && matches!(tokens[0].token_type(), TokenType::Eol) {
2837 tokens.pop_front();
2838 }
2839
2840 nodes.append(&mut self.parse_struct_definition(
2841 struct_definition_start_token.pos(),
2842 Some(struct_name),
2843 tokens,
2844 ).into_nodes());
2845
2846 return Some(ast);
2847 }
2848
2849 if token_count_first_line > 1 && matches!(tokens[0].token_type(), TokenType::Other) &&
2851 tokens[0].value() == "class" && ends_with_opening_bracket {
2852 let class_definition_start_token = tokens.pop_front().unwrap();
2853 token_count_first_line -= 1;
2854
2855 if !matches!(tokens[0].token_type(), TokenType::Whitespace) {
2856 nodes.push(Node::new_parsing_error_node(
2857 class_definition_start_token.pos(),
2858 ParsingError::LexerError,
2859 "Invalid class definition: Whitespace is missing after \"class\"",
2860 ));
2861
2862 return Some(ast);
2863 }
2864
2865 tokens.pop_front();
2866 token_count_first_line -= 1;
2867
2868 if !matches!(tokens[0].token_type(), TokenType::Identifier) ||
2869 !regex_patterns::VAR_NAME_NORMAL_ARRAY_WITHOUT_PREFIX.is_match(tokens[0].value()) {
2870 nodes.push(Node::new_parsing_error_node(
2871 class_definition_start_token.pos(),
2872 ParsingError::LexerError,
2873 format!("Invalid class definition: Invalid class identifier: \"{}\"", tokens[0]),
2874 ));
2875
2876 return Some(ast);
2877 }
2878
2879 let class_name_token = tokens.pop_front().unwrap();
2880 token_count_first_line -= 1;
2881
2882 let class_name = class_name_token.value().to_string();
2883
2884 if matches!(tokens[0].token_type(), TokenType::Whitespace) {
2885 tokens.pop_front();
2886 token_count_first_line -= 1;
2887 }
2888
2889 let mut parent_class_tokens = if matches!(tokens[0].token_type(), TokenType::Operator) &&
2890 tokens[0].value() == "<" && ends_with_opening_bracket {
2891 let mut parent_class_end_index = None;
2894 for i in (0..token_count_first_line).rev() {
2895 if matches!(tokens[i].token_type(), TokenType::Operator) &&
2896 tokens[i].value() == ">" && ends_with_opening_bracket {
2897 parent_class_end_index = Some(i);
2898
2899 break;
2900 }
2901 }
2902
2903 let Some(parent_class_end_index) = parent_class_end_index else {
2904 nodes.push(Node::new_parsing_error_node(
2905 class_definition_start_token.pos(),
2906 ParsingError::BracketMismatch,
2907 "Bracket is missing in class definition",
2908 ));
2909
2910 return Some(ast);
2911 };
2912
2913 let parent_class_tokens = utils::split_off_arguments(tokens, parent_class_end_index);
2914 token_count_first_line -= parent_class_end_index + 1;
2915
2916 if matches!(tokens[0].token_type(), TokenType::Whitespace) {
2917 tokens.pop_front();
2918 token_count_first_line -= 1;
2919 }
2920
2921 parent_class_tokens
2922 }else {
2923 VecDeque::new()
2924 };
2925
2926 if token_count_first_line != 1 {
2927 nodes.push(Node::new_parsing_error_node(
2928 class_definition_start_token.pos(),
2929 ParsingError::LexerError,
2930 "Invalid tokens after class definition",
2931 ));
2932
2933 return Some(ast);
2934 }
2935
2936 tokens.pop_front();
2937
2938 if !tokens.is_empty() && matches!(tokens[0].token_type(), TokenType::Eol) {
2939 tokens.pop_front();
2940 }
2941
2942 nodes.append(&mut self.parse_class_definition(
2943 class_definition_start_token.pos(),
2944 Some(class_name),
2945 &mut parent_class_tokens,
2946 tokens,
2947 ).into_nodes());
2948
2949 return Some(ast);
2950 }
2951
2952 nodes.append(&mut self.parse_token(tokens).into_nodes());
2953
2954 Some(ast)
2955 }
2956
2957 fn parse_parser_flags(&mut self, _parse_flag: impl Into<String>, _value: Node) -> bool {
2961 false
2964 }
2965
2966 fn parse_translation_key(&mut self, tokens: &mut VecDeque<Token>) -> AST {
2967 let mut ast = AST::new();
2968 let nodes = ast.nodes_mut();
2969
2970 let mut pos = tokens.front().map(|token| token.pos()).
2971 unwrap_or(CodePosition::EMPTY);
2972
2973 Self::trim_first_line(tokens);
2974
2975 if pos == CodePosition::EMPTY {
2976 pos = tokens.front().map(|token| token.pos()).unwrap_or(CodePosition::EMPTY);
2977 }
2978
2979 nodes.push(Node::new_text_value_node(pos, ""));
2980
2981 if tokens.len() >= 2 && matches!(tokens[0].token_type(), TokenType::Operator) &&
2982 tokens[0].value() == "%" && matches!(tokens[1].token_type(), TokenType::Identifier) &&
2983 tokens[1].value().starts_with("$") {
2984 tokens.pop_front();
2986 }
2987
2988 'tokenProcessing:
2989 while !tokens.is_empty() {
2990 let t = tokens[0].clone();
2991
2992 match t.token_type() {
2993 TokenType::Eol | TokenType::Eof => {
2994 break 'tokenProcessing;
2995 },
2996
2997 TokenType::StartComment | TokenType::StartDocComment => {
2998 self.parse_comment_tokens(tokens, nodes);
2999 },
3000
3001 TokenType::LiteralNull | TokenType::LiteralText | TokenType::LiteralNumber |
3002 TokenType::ArgumentSeparator | TokenType::Assignment | TokenType::Operator |
3003 TokenType::OpeningBracket | TokenType::ClosingBracket | TokenType::OpeningBlockBracket |
3004 TokenType::ClosingBlockBracket | TokenType::Whitespace | TokenType::Other => {
3005 tokens.pop_front();
3006
3007 nodes.push(Node::new_text_value_node(pos, t.value()));
3008 },
3009
3010 TokenType::EscapeSequence => {
3011 tokens.pop_front();
3012
3013 self.parse_escape_sequence_token(t, nodes);
3014 },
3015
3016 TokenType::LexerError => {
3017 tokens.pop_front();
3018
3019 self.parse_lexer_error_token(t, nodes);
3020 },
3021
3022 TokenType::StartMultilineText => {
3023 tokens.pop_front();
3024
3025 loop {
3026 if let Some(t) = tokens.pop_front() {
3027 if matches!(t.token_type(), TokenType::EndMultilineText) {
3028 break;
3029 }
3030
3031 if matches!(t.token_type(), TokenType::LiteralText | TokenType::Eol) {
3032 nodes.push(Node::new_text_value_node(t.pos(), t.value()));
3033 }else if matches!(t.token_type(), TokenType::EscapeSequence) {
3034 self.parse_escape_sequence_token(t, nodes);
3035 }else if matches!(t.token_type(), TokenType::LexerError) {
3036 nodes.push(Node::new_parsing_error_node(
3037 t.pos(),
3038 ParsingError::LexerError,
3039 t.value()
3040 ));
3041 }else {
3042 nodes.push(Node::new_parsing_error_node(
3043 CodePosition::EMPTY,
3044 ParsingError::Eof,
3045 format!(
3046 "Invalid token type ({}) in multiline text during translation key parsing",
3047 t.token_type(),
3048 ),
3049 ));
3050 }
3051 }else {
3052 nodes.push(Node::new_parsing_error_node(
3053 CodePosition::EMPTY,
3054 ParsingError::Eof,
3055 "Missing multiline text end token during translation key parsing",
3056 ));
3057
3058 break 'tokenProcessing;
3059 }
3060 }
3061 },
3062
3063 TokenType::Identifier | TokenType::ParserFunctionIdentifier => {
3064 if matches!(t.token_type(), TokenType::Identifier) &&
3065 !regex_patterns::VAR_NAME_FULL.is_match(t.value()) {
3066 tokens.pop_front();
3067
3068 nodes.push(Node::new_text_value_node(pos, t.value()));
3069 }
3070
3071 let ret = if matches!(t.token_type(), TokenType::Identifier) {
3072 self.parse_variable_name_and_function_call(tokens, None)
3073 }else {
3074 self.parse_parser_function_call(tokens)
3075 };
3076
3077 if let Some(ret) = ret {
3078 nodes.push(ret);
3079 }
3080 },
3081
3082 TokenType::LineContinuation | TokenType::EndComment | TokenType::EndMultilineText |
3083 TokenType::SingleLineTextQuotes => {
3084 nodes.push(Node::new_parsing_error_node(
3085 CodePosition::EMPTY,
3086 ParsingError::LexerError,
3087 format!(
3088 "Invalid token type in translation key expression: \"{}\"",
3089 t.token_type(),
3090 ),
3091 ));
3092
3093 break 'tokenProcessing;
3094 },
3095 }
3096 }
3097
3098 ast
3099 }
3100
3101 fn parse_lrvalue(&mut self, tokens: &mut VecDeque<Token>, is_rvalue: bool) -> AST {
3102 let mut ast = AST::new();
3103 let nodes = ast.nodes_mut();
3104
3105 Self::trim_first_line(tokens);
3106
3107 if is_rvalue {
3108 let mut token_count_first_line = Self::get_token_count_first_line(tokens.make_contiguous());
3109
3110 if token_count_first_line >= 1 && matches!(tokens[0].token_type(), TokenType::OpeningBracket) &&
3111 tokens[0].value() == "(" {
3112 let parameter_end_index = utils::get_index_of_matching_bracket_tok(
3115 tokens.make_contiguous(), 0, usize::MAX, "(", ")", true,
3116 );
3117 let Some(parameter_end_index) = parameter_end_index else {
3118 nodes.push(Node::new_parsing_error_node(
3119 CodePosition::EMPTY,
3120 ParsingError::BracketMismatch,
3121 "Bracket is missing in function definition",
3122 ));
3123
3124 return ast;
3125 };
3126
3127 let mut parameter_list_tokens = utils::split_off_arguments(tokens, parameter_end_index);
3128 let parameter_list = self.parse_function_parameter_list(&mut parameter_list_tokens, true).into_nodes();
3129
3130 token_count_first_line -= parameter_end_index + 1;
3131
3132 let mut return_type_constraint = None;
3133 if token_count_first_line >= 2 && matches!(tokens[0].token_type(), TokenType::Operator) &&
3134 tokens[0].value() == ":" && matches!(tokens[1].token_type(), TokenType::OpeningBracket) &&
3135 tokens[1].value() == "{" {
3136 tokens.pop_front();
3137 token_count_first_line -= 1;
3138
3139 let return_type_constraint_end_index = utils::get_index_of_matching_bracket_tok(
3140 tokens.make_contiguous(), 0, usize::MAX, "{", "}", true,
3141 );
3142 let Some(return_type_constraint_end_index) = return_type_constraint_end_index else {
3143 nodes.push(Node::new_parsing_error_node(
3144 CodePosition::EMPTY,
3145 ParsingError::BracketMismatch,
3146 "Bracket is missing in return type constraint of function definition",
3147 ));
3148
3149 return ast;
3150 };
3151
3152 let mut type_constraint_tokens = tokens.split_off(return_type_constraint_end_index + 1);
3153 mem::swap(tokens, &mut type_constraint_tokens);
3154
3155 token_count_first_line -= return_type_constraint_end_index + 1;
3156
3157 return_type_constraint = self.parse_type_constraint(
3158 &mut type_constraint_tokens,
3159 false,
3160 nodes,
3161 );
3162 }
3163
3164 if token_count_first_line >= 3 && matches!(tokens[0].token_type(), TokenType::Whitespace) &&
3165 matches!(tokens[1].token_type(), TokenType::Operator) && tokens[1].value() == "->" &&
3166 matches!(tokens[2].token_type(), TokenType::Whitespace) {
3167 tokens.pop_front();
3168 tokens.pop_front();
3169 tokens.pop_front();
3170 token_count_first_line -= 3;
3171
3172 if token_count_first_line >= 1 && matches!(tokens[0].token_type(), TokenType::OpeningBlockBracket) {
3174 tokens.pop_front();
3175
3176 nodes.push(Node::new_function_definition_node(
3177 CodePosition::EMPTY,
3178 FunctionDefinition::new(
3179 None, false, false,
3180 self.lang_doc_comment.take().map(Box::from),
3181 return_type_constraint.map(Box::from),
3182 self.parse_tokens_internal(tokens).unwrap(),
3183 ),
3184 parameter_list,
3185 ));
3186 }else {
3187 let mut function_body = tokens.split_off(token_count_first_line);
3188 mem::swap(tokens, &mut function_body);
3189
3190 nodes.push(Node::new_function_definition_node(
3191 CodePosition::EMPTY,
3192 FunctionDefinition::new(
3193 None, false, false,
3194 self.lang_doc_comment.take().map(Box::from),
3195 return_type_constraint.map(Box::from),
3196 self.parse_tokens_internal(&mut function_body).unwrap(),
3197 ),
3198 parameter_list,
3199 ));
3200 }
3201
3202 return ast;
3203 }
3204 }
3205
3206 if token_count_first_line == 1 && matches!(tokens[0].token_type(), TokenType::Identifier) &&
3207 regex_patterns::VAR_NAME_FUNC_PTR_WITH_FUNCS.is_match(tokens[0].value()) {
3208 let t = tokens.pop_front().unwrap();
3211
3212 nodes.push(Node::new_unprocessed_variable_name_node(t.pos(), t.value()));
3213
3214 return ast;
3215 }else if token_count_first_line == 1 && tokens.len() > token_count_first_line &&
3216 matches!(tokens[0].token_type(), TokenType::OpeningBlockBracket) {
3217 let start_pos = tokens[0].pos();
3220
3221 tokens.pop_front();
3222 tokens.pop_front();
3223
3224 nodes.append(&mut self.parse_struct_definition(
3225 start_pos,
3226 None,
3227 tokens
3228 ).into_nodes());
3229
3230 return ast;
3231 }else if token_count_first_line > 3 && tokens.len() > token_count_first_line &&
3232 matches!(tokens[0].token_type(), TokenType::Operator) && tokens[0].value() == "<" &&
3233 matches!(tokens[token_count_first_line - 2].token_type(), TokenType::Operator) &&
3234 tokens[token_count_first_line - 2].value() == ">" &&
3235 matches!(tokens[token_count_first_line - 1].token_type(), TokenType::OpeningBlockBracket) {
3236 let start_pos = tokens[0].pos();
3239
3240 let mut parent_class_tokens = utils::split_off_arguments(tokens, token_count_first_line - 2);
3242 tokens.pop_front();
3244 tokens.pop_front();
3245
3246 nodes.append(&mut self.parse_class_definition(
3247 start_pos,
3248 None,
3249 &mut parent_class_tokens,
3250 tokens,
3251 ).into_nodes());
3252
3253 return ast;
3254 }
3255 }
3256
3257 nodes.append(&mut self.parse_token(tokens).into_nodes());
3258
3259 ast
3260 }
3261
3262 fn parse_function_definition(
3263 &mut self,
3264 function_name: Option<String>,
3265 overloaded: bool,
3266 combinator: bool,
3267 parameter_list_tokens: &mut VecDeque<Token>,
3268 return_value_type_constraint: Option<String>,
3269 tokens: &mut VecDeque<Token>,
3270 ) -> AST {
3271 let mut ast = AST::new();
3272 let nodes = ast.nodes_mut();
3273
3274 Self::trim_first_line(tokens);
3275
3276 let parameter_list_nodes = self.parse_function_parameter_list(
3277 parameter_list_tokens,
3278 true,
3279 ).into_nodes();
3280
3281 nodes.push(Node::new_function_definition_node(
3283 CodePosition::EMPTY,
3284 FunctionDefinition::new(
3285 function_name.map(Box::from),
3286 overloaded,
3287 combinator,
3288 self.lang_doc_comment.take().map(Box::from),
3289 return_value_type_constraint.map(Box::from),
3290 self.parse_tokens_internal(tokens).unwrap(),
3291 ),
3292 parameter_list_nodes,
3293 ));
3294
3295 ast
3296 }
3297
3298 fn parse_struct_definition(
3299 &mut self,
3300 start_pos: CodePosition,
3301 struct_name: Option<String>,
3302 tokens: &mut VecDeque<Token>,
3303 ) -> AST {
3304 let mut ast = AST::new();
3305 let nodes = ast.nodes_mut();
3306
3307 Self::trim_first_line(tokens);
3308
3309 let mut has_end_brace = false;
3310
3311 let mut members = Vec::new();
3312
3313 let mut end_pos = CodePosition::EMPTY;
3314
3315 'tokenProcessing:
3316 while !tokens.is_empty() {
3317 let t = tokens[0].clone();
3318 end_pos = t.pos();
3319
3320 match t.token_type() {
3321 TokenType::Eof => {
3322 break 'tokenProcessing;
3323 },
3324
3325 TokenType::Eol => {
3326 tokens.pop_front();
3327
3328 Self::trim_first_line(tokens);
3329 },
3330
3331 TokenType::Whitespace => {
3332 tokens.pop_front();
3333 },
3334
3335 TokenType::StartComment | TokenType::StartDocComment => {
3336 self.parse_comment_tokens(tokens, nodes);
3337 },
3338
3339 TokenType::ClosingBlockBracket => {
3340 tokens.pop_front();
3341
3342 has_end_brace = true;
3343
3344 break 'tokenProcessing;
3345 },
3346
3347 TokenType::Identifier => {
3348 if !regex_patterns::VAR_NAME_WITHOUT_PREFIX.is_match(t.value()) {
3349 nodes.push(Node::new_parsing_error_node(
3350 t.pos(),
3351 ParsingError::InvalidAssignment,
3352 format!(
3353 "Invalid struct member name: \"{}\"",
3354 t.value(),
3355 ),
3356 ));
3357
3358 return ast;
3359 }
3360
3361 let identifier_token = tokens.pop_front().unwrap();
3362
3363 let mut type_constraint = None;
3364 if !tokens.is_empty() && matches!(tokens[0].token_type(), TokenType::OpeningBracket) &&
3365 tokens[0].value() == "{" {
3366 let bracket_end_index = utils::get_index_of_matching_bracket_tok(
3367 tokens.make_contiguous(),
3368 0, usize::MAX,
3369 "{", "}", true,
3370 );
3371 let Some(bracket_end_index) = bracket_end_index else {
3372 nodes.push(Node::new_parsing_error_node(
3373 identifier_token.pos(),
3374 ParsingError::BracketMismatch,
3375 format!(
3376 "Bracket is missing in type constraint in struct definition for member: \"{}\"",
3377 identifier_token.value(),
3378 ),
3379 ));
3380
3381 return ast;
3382 };
3383
3384 let mut type_constraint_tokens = tokens.split_off(bracket_end_index + 1);
3385 mem::swap(tokens, &mut type_constraint_tokens);
3386
3387 type_constraint = self.parse_type_constraint(
3388 &mut type_constraint_tokens,
3389 false,
3390 nodes,
3391 );
3392 }
3393
3394 if members.iter().any(|member: &StructMember| member.name() == identifier_token.value()) {
3395 nodes.push(Node::new_parsing_error_node(
3396 identifier_token.pos(),
3397 ParsingError::InvalidAssignment,
3398 format!(
3399 "Duplicated struct member name: \"{}\"", identifier_token.value(),
3400 ),
3401 ));
3402
3403 return ast;
3404 };
3405
3406 members.push(StructMember::new(Box::from(identifier_token.value()), type_constraint.map(Box::from)));
3407 },
3408
3409 TokenType::LexerError => {
3410 tokens.pop_front();
3411
3412 self.parse_lexer_error_token(t, nodes);
3413
3414 break 'tokenProcessing;
3415 },
3416
3417 TokenType::ParserFunctionIdentifier | TokenType::LiteralNull | TokenType::LiteralNumber |
3418 TokenType::LiteralText | TokenType::ArgumentSeparator | TokenType::Assignment |
3419 TokenType::Other | TokenType::Operator | TokenType::OpeningBracket | TokenType::ClosingBracket |
3420 TokenType::OpeningBlockBracket | TokenType::EscapeSequence | TokenType::StartMultilineText |
3421 TokenType::LineContinuation | TokenType::EndComment | TokenType::EndMultilineText |
3422 TokenType::SingleLineTextQuotes => {
3423 nodes.push(Node::new_parsing_error_node(
3424 CodePosition::EMPTY,
3425 ParsingError::LexerError,
3426 format!(
3427 "Invalid token type for struct definition expression: \"{}\"",
3428 t.token_type(),
3429 ),
3430 ));
3431
3432 return ast;
3433 },
3434 }
3435 }
3436
3437 let pos = start_pos.combine(&end_pos);
3438
3439 if !has_end_brace {
3440 nodes.push(Node::new_parsing_error_node(
3441 pos,
3442 ParsingError::Eof,
3443 "\"}\" is missing in struct definition",
3444 ));
3445
3446 return ast;
3447 }
3448
3449 nodes.push(Node::new_struct_definition_node(pos, StructDefinition::new(
3450 struct_name.map(Box::from),
3451 members,
3452 )));
3453
3454 ast
3455 }
3456
3457 fn parse_class_definition(
3458 &mut self,
3459 start_pos: CodePosition,
3460 class_name: Option<String>,
3461 parent_class_tokens: &mut VecDeque<Token>,
3462 tokens: &mut VecDeque<Token>,
3463 ) -> AST {
3464 let mut ast = AST::new();
3465 let nodes = ast.nodes_mut();
3466
3467 Self::trim_first_line(tokens);
3468
3469 let parent_classes = self.parse_function_parameter_list(parent_class_tokens, false).into_nodes();
3470
3471 let mut has_end_brace = false;
3472
3473 let mut static_members: Vec<ClassMember> = Vec::new();
3474 let mut members = Vec::new();
3475 let mut methods = Vec::new();
3476 let mut constructors = Vec::new();
3477
3478 let mut end_pos = CodePosition::EMPTY;
3479
3480 'tokenProcessing:
3481 while !tokens.is_empty() {
3482 let t = tokens[0].clone();
3483 end_pos = t.pos();
3484
3485 match t.token_type() {
3486 TokenType::Eof => {
3487 break 'tokenProcessing;
3488 },
3489
3490 TokenType::Eol => {
3491 tokens.pop_front();
3492
3493 Self::trim_first_line(tokens);
3494 },
3495
3496 TokenType::Whitespace => {
3497 tokens.pop_front();
3498 },
3499
3500 TokenType::StartComment | TokenType::StartDocComment => {
3501 self.parse_comment_tokens(tokens, nodes);
3502 },
3503
3504 TokenType::ClosingBlockBracket => {
3505 tokens.pop_front();
3506
3507 has_end_brace = true;
3508
3509 break 'tokenProcessing;
3510 },
3511
3512 TokenType::Other | TokenType::Operator => {
3513 let visibility = if t.value().len() == 1 {
3514 let visibility_symbol = t.value().as_bytes()[0];
3515 let visibility = Visibility::from_symbol(visibility_symbol);
3516
3517 if visibility.is_none() {
3518 nodes.push(Node::new_parsing_error_node(
3519 t.pos(),
3520 ParsingError::LexerError,
3521 "Invalid visibility symbol (One of [\"-\", \"~\", or \"+\"] must be used)"
3522 ));
3523
3524 return ast;
3525 }
3526
3527 tokens.pop_front();
3528
3529 visibility.unwrap()
3530 }else {
3531 let visibility_keyword = t.value();
3532 let visibility = Visibility::from_keyword(visibility_keyword);
3533
3534 if visibility.is_none() {
3535 nodes.push(Node::new_parsing_error_node(
3536 t.pos(),
3537 ParsingError::LexerError,
3538 "Invalid visibility keyword (One of [\"private\", \"protected\", or \"public\"] must be used)"
3539 ));
3540
3541 return ast;
3542 }
3543
3544 tokens.pop_front();
3545
3546 if tokens.front().is_none_or(|token|
3547 !matches!(token.token_type(), TokenType::Whitespace)) {
3548 nodes.push(Node::new_parsing_error_node(
3549 t.pos(),
3550 ParsingError::Eof,
3551 "Missing whitespace after visibility keyword specifier"
3552 ));
3553
3554 return ast;
3555 }
3556
3557 tokens.pop_front();
3558
3559 visibility.unwrap()
3560 };
3561
3562 let Some(mut t) = tokens.front().cloned() else {
3563 nodes.push(Node::new_parsing_error_node(
3564 t.pos(),
3565 ParsingError::Eof,
3566 "Missing value after visibility specifier"
3567 ));
3568
3569 return ast;
3570 };
3571
3572 if matches!(t.token_type(), TokenType::Other) && t.value() == "construct" {
3574 tokens.pop_front();
3575
3576 let Some(t) = tokens.front() else {
3577 nodes.push(Node::new_parsing_error_node(
3578 t.pos(),
3579 ParsingError::Eof,
3580 "Missing value after construct method"
3581 ));
3582
3583 return ast;
3584 };
3585
3586 if !matches!(t.token_type(), TokenType::Assignment) || t.value() != " = " {
3587 nodes.push(Node::new_parsing_error_node(
3588 t.pos(),
3589 ParsingError::InvalidAssignment,
3590 "Invalid assignment for constructor (only \" = \" is allowed)"
3591 ));
3592
3593 return ast;
3594 }
3595
3596 tokens.pop_front();
3597
3598 constructors.push(Constructor::new(
3599 self.parse_lrvalue(tokens, true).into_node(),
3600 visibility,
3601 ));
3602
3603 continue 'tokenProcessing;
3604 }
3605
3606 let is_override_method = tokens.len() >= 2 && matches!(t.token_type(), TokenType::Other) &&
3608 t.value() == "override" && matches!(tokens[1].token_type(), TokenType::Operator) &&
3609 tokens[1].value() == ":";
3610 if is_override_method {
3611 tokens.pop_front();
3612 tokens.pop_front();
3613
3614 if tokens.is_empty() {
3615 nodes.push(Node::new_parsing_error_node(
3616 t.pos(),
3617 ParsingError::Eof,
3618 "Missing identifier after override keyword"
3619 ));
3620
3621 return ast;
3622 }
3623
3624 t = tokens[0].clone();
3625 }
3626
3627 if matches!(t.token_type(), TokenType::Identifier) && t.value().starts_with("op:") {
3628 if !matches!(visibility, Visibility::Public) {
3629 nodes.push(Node::new_parsing_error_node(
3630 t.pos(),
3631 ParsingError::InvalidAssignment,
3632 "Operator method must be public"
3633 ));
3634
3635 return ast;
3636 }
3637
3638 let method_name_token = tokens.pop_front().unwrap();
3639 let method_name = method_name_token.value();
3640 if !regex_patterns::OPERATOR_METHOD_NAME.is_match(method_name) {
3641 nodes.push(Node::new_parsing_error_node(
3642 t.pos(),
3643 ParsingError::InvalidAssignment,
3644 format!(
3645 "Invalid operator method name: \"{}\"",
3646 method_name,
3647 ),
3648 ));
3649
3650 return ast;
3651 }
3652
3653 if tokens.is_empty() {
3654 nodes.push(Node::new_parsing_error_node(
3655 t.pos(),
3656 ParsingError::Eof,
3657 "Missing value after operator method",
3658 ));
3659
3660 return ast;
3661 }
3662
3663 let t = tokens[0].clone();
3664 if !matches!(t.token_type(), TokenType::Assignment) || t.value() != " = " {
3665 nodes.push(Node::new_parsing_error_node(
3666 t.pos(),
3667 ParsingError::InvalidAssignment,
3668 "Invalid assignment for operator method (only \" = \" is allowed)",
3669 ));
3670
3671 return ast;
3672 }
3673
3674 tokens.pop_front();
3675
3676 methods.push(Method::new(
3677 Box::from(method_name),
3678 self.parse_lrvalue(tokens, true).into_node(),
3679 is_override_method,
3680 visibility,
3681 ));
3682
3683 continue 'tokenProcessing;
3684 }
3685
3686 if matches!(t.token_type(), TokenType::Identifier) && t.value().starts_with("to:") {
3687 if !matches!(visibility, Visibility::Public) {
3688 nodes.push(Node::new_parsing_error_node(
3689 t.pos(),
3690 ParsingError::InvalidAssignment,
3691 "Conversion method must be public"
3692 ));
3693
3694 return ast;
3695 }
3696
3697 let method_name_token = tokens.pop_front().unwrap();
3698 let method_name = method_name_token.value();
3699 if !regex_patterns::CONVERSION_METHOD_NAME.is_match(method_name) {
3700 nodes.push(Node::new_parsing_error_node(
3701 t.pos(),
3702 ParsingError::InvalidAssignment,
3703 format!(
3704 "Invalid conversion method name: \"{}\"",
3705 method_name,
3706 ),
3707 ));
3708
3709 return ast;
3710 }
3711
3712 if tokens.is_empty() {
3713 nodes.push(Node::new_parsing_error_node(
3714 t.pos(),
3715 ParsingError::Eof,
3716 "Missing value after conversion method",
3717 ));
3718
3719 return ast;
3720 }
3721
3722 let t = tokens[0].clone();
3723 if !matches!(t.token_type(), TokenType::Assignment) || t.value() != " = " {
3724 nodes.push(Node::new_parsing_error_node(
3725 t.pos(),
3726 ParsingError::InvalidAssignment,
3727 "Invalid assignment for conversion method (only \" = \" is allowed)",
3728 ));
3729
3730 return ast;
3731 }
3732
3733 tokens.pop_front();
3734
3735 methods.push(Method::new(
3736 Box::from(method_name),
3737 self.parse_lrvalue(tokens, true).into_node(),
3738 is_override_method,
3739 visibility,
3740 ));
3741
3742 continue 'tokenProcessing;
3743 }
3744
3745 if matches!(t.token_type(), TokenType::Identifier) &&
3746 regex_patterns::METHOD_NAME.is_match(t.value()) {
3747 let method_name_token = tokens.pop_front().unwrap();
3748 let method_name = method_name_token.value();
3749
3750 if tokens.is_empty() {
3751 nodes.push(Node::new_parsing_error_node(
3752 t.pos(),
3753 ParsingError::Eof,
3754 "Missing value after normal method",
3755 ));
3756
3757 return ast;
3758 }
3759
3760 let t = tokens[0].clone();
3761 if !matches!(t.token_type(), TokenType::Assignment) || t.value() != " = " {
3762 nodes.push(Node::new_parsing_error_node(
3763 t.pos(),
3764 ParsingError::InvalidAssignment,
3765 "Invalid assignment for conversion method (only \" = \" is allowed)",
3766 ));
3767
3768 return ast;
3769 }
3770
3771 tokens.pop_front();
3772
3773 methods.push(Method::new(
3774 Box::from(method_name),
3775 self.parse_lrvalue(tokens, true).into_node(),
3776 is_override_method,
3777 visibility,
3778 ));
3779
3780 continue 'tokenProcessing;
3781 }
3782
3783 if is_override_method {
3784 nodes.push(Node::new_parsing_error_node(
3785 t.pos(),
3786 ParsingError::LexerError,
3787 "The override keyword can only be used for methods",
3788 ));
3789
3790 return ast;
3791 }
3792
3793 let mut is_static_member = tokens.len() >= 2 && matches!(t.token_type(), TokenType::Other) &&
3795 t.value() == "static" && matches!(tokens[1].token_type(), TokenType::Operator) &&
3796 tokens[1].value() == ":";
3797 if is_static_member {
3798 tokens.pop_front();
3799 tokens.pop_front();
3800
3801 if tokens.is_empty() {
3802 nodes.push(Node::new_parsing_error_node(
3803 t.pos(),
3804 ParsingError::Eof,
3805 "Missing identifier after static keyword",
3806 ));
3807
3808 return ast;
3809 }
3810
3811 t = tokens[0].clone();
3812 }
3813
3814 let is_final_member = tokens.len() >= 2 && matches!(t.token_type(), TokenType::Other) &&
3815 t.value() == "final" && matches!(tokens[1].token_type(), TokenType::Operator) &&
3816 tokens[1].value() == ":";
3817 if is_final_member {
3818 tokens.pop_front();
3819 tokens.pop_front();
3820
3821 if tokens.is_empty() {
3822 nodes.push(Node::new_parsing_error_node(
3823 t.pos(),
3824 ParsingError::Eof,
3825 "Missing identifier after final keyword",
3826 ));
3827
3828 return ast;
3829 }
3830
3831 t = tokens[0].clone();
3832 }
3833
3834 if !is_static_member && is_final_member && tokens.len() >= 2 &&
3835 matches!(t.token_type(), TokenType::Other) && t.value() == "static" &&
3836 matches!(tokens[1].token_type(), TokenType::Operator) && tokens[1].value() == ":" {
3837 is_static_member = true;
3838
3839 tokens.pop_front();
3840 tokens.pop_front();
3841
3842 if tokens.is_empty() {
3843 nodes.push(Node::new_parsing_error_node(
3844 t.pos(),
3845 ParsingError::Eof,
3846 "Missing identifier after static keyword",
3847 ));
3848
3849 return ast;
3850 }
3851
3852 t = tokens[0].clone();
3853 }
3854
3855 if !matches!(t.token_type(), TokenType::Identifier) {
3856 nodes.push(Node::new_parsing_error_node(
3857 t.pos(),
3858 ParsingError::LexerError,
3859 format!(
3860 "Invalid token type for class definition expression: \"{}\"",
3861 t.token_type(),
3862 ),
3863 ));
3864
3865 return ast;
3866 }
3867
3868 if !regex_patterns::VAR_NAME_WITHOUT_PREFIX.is_match(t.value()) {
3869 nodes.push(Node::new_parsing_error_node(
3870 t.pos(),
3871 ParsingError::InvalidAssignment,
3872 format!(
3873 "Invalid {}member name: \"{}\"",
3874 if is_static_member {
3875 "static "
3876 }else {
3877 ""
3878 },
3879 t.value(),
3880 ),
3881 ));
3882
3883 return ast;
3884 }
3885
3886 let member_name_token = tokens.pop_front().unwrap();
3887 let member_name = member_name_token.value();
3888
3889 let mut type_constraint = None;
3890 if !tokens.is_empty() && matches!(tokens[0].token_type(), TokenType::OpeningBracket) &&
3891 tokens[0].value() == "{" {
3892 let bracket_end_index = utils::get_index_of_matching_bracket_tok(
3893 tokens.make_contiguous(),
3894 0, usize::MAX,
3895 "{", "}", true,
3896 );
3897 let Some(bracket_end_index) = bracket_end_index else {
3898 nodes.push(Node::new_parsing_error_node(
3899 member_name_token.pos(),
3900 ParsingError::BracketMismatch,
3901 format!(
3902 "Bracket is missing in type constraint in class definition for {}member: \"{}\"",
3903 if is_static_member {
3904 "static"
3905 }else {
3906 ""
3907 },
3908 member_name,
3909 ),
3910 ));
3911
3912 return ast;
3913 };
3914
3915 let mut type_constraint_tokens = tokens.split_off(bracket_end_index + 1);
3916 mem::swap(tokens, &mut type_constraint_tokens);
3917
3918 type_constraint = self.parse_type_constraint(
3919 &mut type_constraint_tokens,
3920 false,
3921 nodes,
3922 );
3923 }
3924
3925 let is_duplicate = if is_static_member {
3926 static_members.iter()
3927 }else {
3928 members.iter()
3929 }.any(|member| member.name() == member_name);
3930 if is_duplicate {
3931 nodes.push(Node::new_parsing_error_node(
3932 t.pos(),
3933 ParsingError::InvalidAssignment,
3934 format!(
3935 "Duplicated {}member name: \"{}\"",
3936 if is_static_member {
3937 "static "
3938 }else {
3939 ""
3940 },
3941 member_name,
3942 ),
3943 ));
3944
3945 return ast;
3946 }
3947
3948 if is_static_member {
3949 let mut static_member_value = None;
3950 if !tokens.is_empty() && matches!(tokens[0].token_type(), TokenType::Assignment) {
3951 let assignment_token = tokens.pop_front().unwrap();
3952 let assignment_operator = assignment_token.value();
3953
3954 if tokens.is_empty() ||
3955 matches!(tokens[0].token_type(), TokenType::Eol | TokenType::Eof) {
3956 if assignment_operator != "=" && assignment_operator != " =" {
3957 nodes.push(Node::new_parsing_error_node(
3958 t.pos(),
3959 ParsingError::InvalidAssignment,
3960 "Rvalue is missing in member assignment",
3961 ));
3962
3963 return ast;
3964 }
3965
3966 static_member_value = Some(if assignment_operator == "=" {
3967 Node::new_text_value_node(assignment_token.pos(), "")
3968 }else {
3969 Node::new_null_value_node(assignment_token.pos())
3970 });
3971 }else {
3972 match assignment_operator {
3973 "=" => {
3974 static_member_value = Some(self.parse_simple_assignment_value(
3975 tokens,
3976 ).into_node());
3977 },
3978
3979 " = " => {
3980 static_member_value = Some(self.parse_lrvalue(
3981 tokens, true,
3982 ).into_node());
3983 },
3984
3985 " ?= " => {
3986 static_member_value = Some(self.parse_condition_expr(
3987 tokens
3988 ).unwrap());
3989 },
3990
3991 " := " => {
3992 static_member_value = Some(self.parse_math_expr(
3993 tokens
3994 ).unwrap());
3995 },
3996
3997 " $= " => {
3998 static_member_value = Some(self.parse_operation_expr(
3999 tokens
4000 ).unwrap());
4001 },
4002
4003 _ => {
4004 nodes.push(Node::new_parsing_error_node(
4005 t.pos(),
4006 ParsingError::InvalidAssignment,
4007 "Invalid assignment for static member (only the following operators are allowed: \"=\", \" = \", \" ?= \", \" := \", and \" $= \")",
4008 ));
4009
4010 return ast;
4011 },
4012 }
4013 }
4014 }
4015
4016 static_members.push(ClassMember::new(
4017 Box::from(member_name),
4018 type_constraint.map(Box::from),
4019 static_member_value,
4020 is_final_member,
4021 visibility,
4022 ));
4023
4024 continue 'tokenProcessing;
4025 }
4026
4027 members.push(ClassMember::new(
4028 Box::from(member_name),
4029 type_constraint.map(Box::from),
4030 None,
4031 is_final_member,
4032 visibility,
4033 ));
4034 },
4035
4036 TokenType::LexerError => {
4037 tokens.pop_front();
4038
4039 self.parse_lexer_error_token(t, nodes);
4040
4041 break 'tokenProcessing;
4042 },
4043
4044 TokenType::Identifier | TokenType::ParserFunctionIdentifier | TokenType::LiteralNull |
4045 TokenType::LiteralNumber | TokenType::LiteralText | TokenType::ArgumentSeparator |
4046 TokenType::Assignment | TokenType::OpeningBracket | TokenType::ClosingBracket |
4047 TokenType::OpeningBlockBracket | TokenType::EscapeSequence | TokenType::StartMultilineText |
4048 TokenType::LineContinuation | TokenType::EndComment | TokenType::EndMultilineText |
4049 TokenType::SingleLineTextQuotes => {
4050 nodes.push(Node::new_parsing_error_node(
4051 CodePosition::EMPTY,
4052 ParsingError::LexerError,
4053 format!(
4054 "Invalid token type for class definition expression: \"{}\"",
4055 t.token_type(),
4056 ),
4057 ));
4058
4059 return ast;
4060 },
4061 }
4062 }
4063
4064 let pos = start_pos.combine(&end_pos);
4065
4066 if !has_end_brace {
4067 nodes.push(Node::new_parsing_error_node(
4068 pos,
4069 ParsingError::Eof,
4070 "\"}\" is missing in class definition",
4071 ));
4072
4073 return ast;
4074 }
4075
4076 nodes.push(Node::new_class_definition_node(pos, ClassDefinition::new(
4077 class_name.map(Box::from),
4078 static_members,
4079 members,
4080 methods,
4081 constructors,
4082 parent_classes,
4083 )));
4084
4085 ast
4086 }
4087
4088 fn parse_token(
4089 &mut self,
4090 tokens: &mut VecDeque<Token>,
4091 ) -> AST {
4092 let mut ast = AST::new();
4093 let nodes = ast.nodes_mut();
4094
4095 Self::trim_first_line(tokens);
4096
4097 'tokenProcessing:
4098 while !tokens.is_empty() {
4099 let t = tokens[0].clone();
4100
4101 match t.token_type() {
4102 TokenType::Eol | TokenType::Eof => {
4103 break 'tokenProcessing;
4104 },
4105
4106 TokenType::StartComment | TokenType::StartDocComment => {
4107 self.parse_comment_tokens(tokens, nodes);
4108 },
4109
4110 TokenType::LiteralNull => {
4111 tokens.pop_front();
4112
4113 nodes.push(Node::new_null_value_node(t.pos()));
4114 },
4115
4116 TokenType::LiteralText | TokenType::ArgumentSeparator | TokenType::Assignment |
4117 TokenType::ClosingBracket | TokenType::OpeningBlockBracket | TokenType::ClosingBlockBracket |
4118 TokenType::Whitespace => {
4119 tokens.pop_front();
4120
4121 nodes.push(Node::new_text_value_node(t.pos(), t.value()));
4122 },
4123
4124 TokenType::Other => {
4125 tokens.pop_front();
4126
4127 self.parse_text_and_char_value(&mut VecDeque::from([t]), nodes);
4128 },
4129
4130 TokenType::Operator => {
4131 tokens.pop_front();
4132
4133 if nodes.is_empty() && matches!(t.value(), "+" | "-") &&
4134 !tokens.is_empty() && matches!(tokens[0].token_type(), TokenType::LiteralNumber) {
4135 let number_token = tokens.pop_front().unwrap();
4136
4137 let combined_number_token = Token::new(
4138 t.pos().combine(&number_token.pos()),
4139 &(t.value().to_string() + number_token.value()),
4140 TokenType::LiteralNumber,
4141 );
4142
4143 self.parse_number_token(combined_number_token, nodes);
4144
4145 continue 'tokenProcessing;
4146 }
4147
4148 nodes.push(Node::new_text_value_node(t.pos(), t.value()));
4149 },
4150
4151 TokenType::LiteralNumber => {
4152 tokens.pop_front();
4153
4154 self.parse_number_token(t, nodes);
4155 },
4156
4157 TokenType::OpeningBracket => {
4158 if t.value() == "(" {
4159 let end_index = utils::get_index_of_matching_bracket_tok(
4160 tokens.make_contiguous(), 0, usize::MAX, "(", ")", true,
4161 );
4162 if let Some(end_index) = end_index {
4163 let opening_bracket_token = &tokens[0];
4164 let closing_bracket_token = &tokens[end_index];
4165 let pos = opening_bracket_token.pos().combine(&closing_bracket_token.pos());
4166
4167 let mut function_call = utils::split_off_arguments(tokens, end_index);
4168
4169 nodes.push(Node::new_function_call_previous_node_value_node(
4170 pos, "", "",
4171 self.parse_function_parameter_list(&mut function_call, false).into_nodes(),
4172 ));
4173
4174 continue 'tokenProcessing;
4175 }
4176 }
4177
4178 tokens.pop_front();
4179
4180 nodes.push(Node::new_text_value_node(t.pos(), t.value()));
4181 },
4182
4183 TokenType::EscapeSequence => {
4184 tokens.pop_front();
4185
4186 self.parse_escape_sequence_token(t, nodes);
4187 },
4188
4189 TokenType::LexerError => {
4190 tokens.pop_front();
4191
4192 self.parse_lexer_error_token(t, nodes);
4193 },
4194
4195 TokenType::StartMultilineText => {
4196 tokens.pop_front();
4197
4198 loop {
4199 if let Some(t) = tokens.pop_front() {
4200 if matches!(t.token_type(), TokenType::EndMultilineText) {
4201 break;
4202 }
4203
4204 if matches!(t.token_type(), TokenType::LiteralText | TokenType::Eol) {
4205 nodes.push(Node::new_text_value_node(t.pos(), t.value()));
4206 }else if matches!(t.token_type(), TokenType::EscapeSequence) {
4207 self.parse_escape_sequence_token(t, nodes);
4208 }else if matches!(t.token_type(), TokenType::LexerError) {
4209 nodes.push(Node::new_parsing_error_node(
4210 t.pos(),
4211 ParsingError::LexerError,
4212 t.value()
4213 ));
4214 }else {
4215 nodes.push(Node::new_parsing_error_node(
4216 CodePosition::EMPTY,
4217 ParsingError::Eof,
4218 format!(
4219 "Invalid token type ({}) in multiline text during token value parsing",
4220 t.token_type(),
4221 ),
4222 ));
4223 }
4224 }else {
4225 nodes.push(Node::new_parsing_error_node(
4226 CodePosition::EMPTY,
4227 ParsingError::Eof,
4228 "Missing multiline text end token during token value parsing",
4229 ));
4230
4231 break 'tokenProcessing;
4232 }
4233 }
4234 },
4235
4236 TokenType::Identifier | TokenType::ParserFunctionIdentifier => {
4237 let ret = if matches!(t.token_type(), TokenType::Identifier) {
4238 self.parse_variable_name_and_function_call(tokens, None)
4239 }else {
4240 self.parse_parser_function_call(tokens)
4241 };
4242 if let Some(ret) = ret {
4243 nodes.push(ret);
4244 }
4245 },
4246
4247 TokenType::LineContinuation | TokenType::EndComment | TokenType::EndMultilineText |
4248 TokenType::SingleLineTextQuotes => {
4249 nodes.push(Node::new_parsing_error_node(
4250 CodePosition::EMPTY,
4251 ParsingError::LexerError,
4252 format!(
4253 "Invalid token type in token value expression: \"{}\"",
4254 t.token_type(),
4255 ),
4256 ));
4257
4258 break 'tokenProcessing;
4259 },
4260 }
4261 }
4262
4263 ast
4264 }
4265
4266 fn parse_simple_assignment_value(&mut self, tokens: &mut VecDeque<Token>) -> AST {
4267 let mut ast = AST::new();
4268 let nodes = ast.nodes_mut();
4269
4270 Self::trim_first_line(tokens);
4271
4272 let token_count_first_line = Self::get_token_count_first_line(tokens.make_contiguous());
4273 if token_count_first_line == 0 || token_count_first_line != tokens.len() {
4274 nodes.push(Node::new_text_value_node(CodePosition::EMPTY, ""));
4275 }
4276
4277
4278 'tokenProcessing:
4279 while !tokens.is_empty() {
4280 let t = tokens[0].clone();
4281
4282 match t.token_type() {
4283 TokenType::Eol | TokenType::Eof => {
4284 break 'tokenProcessing;
4285 },
4286
4287 TokenType::StartComment | TokenType::StartDocComment => {
4288 self.parse_comment_tokens(tokens, nodes);
4289 },
4290
4291 TokenType::LiteralNull | TokenType::LiteralText | TokenType::LiteralNumber |
4292 TokenType::ArgumentSeparator | TokenType::Identifier | TokenType::ParserFunctionIdentifier |
4293 TokenType::Assignment | TokenType::Operator | TokenType::OpeningBracket |
4294 TokenType::ClosingBracket | TokenType::OpeningBlockBracket | TokenType::ClosingBlockBracket |
4295 TokenType::Whitespace | TokenType::Other => {
4296 tokens.pop_front();
4297
4298 nodes.push(Node::new_text_value_node(t.pos(), t.value()));
4299 },
4300
4301 TokenType::EscapeSequence => {
4302 tokens.pop_front();
4303
4304 self.parse_escape_sequence_token(t, nodes);
4305 },
4306
4307 TokenType::LexerError => {
4308 tokens.pop_front();
4309
4310 self.parse_lexer_error_token(t, nodes);
4311 },
4312
4313 TokenType::StartMultilineText => {
4314 tokens.pop_front();
4315
4316 loop {
4317 if let Some(t) = tokens.pop_front() {
4318 if matches!(t.token_type(), TokenType::EndMultilineText) {
4319 break;
4320 }
4321
4322 if matches!(t.token_type(), TokenType::LiteralText | TokenType::Eol) {
4323 nodes.push(Node::new_text_value_node(t.pos(), t.value()));
4324 }else if matches!(t.token_type(), TokenType::EscapeSequence) {
4325 self.parse_escape_sequence_token(t, nodes);
4326 }else if matches!(t.token_type(), TokenType::LexerError) {
4327 nodes.push(Node::new_parsing_error_node(
4328 t.pos(),
4329 ParsingError::LexerError,
4330 t.value()
4331 ));
4332 }else {
4333 nodes.push(Node::new_parsing_error_node(
4334 CodePosition::EMPTY,
4335 ParsingError::Eof,
4336 format!(
4337 "Invalid token type ({}) in multiline text during simple assignment value parsing",
4338 t.token_type(),
4339 ),
4340 ));
4341 }
4342 }else {
4343 nodes.push(Node::new_parsing_error_node(
4344 CodePosition::EMPTY,
4345 ParsingError::Eof,
4346 "Missing multiline text end token during simple assignment value parsing",
4347 ));
4348
4349 break 'tokenProcessing;
4350 }
4351 }
4352 },
4353
4354 TokenType::LineContinuation | TokenType::EndComment | TokenType::EndMultilineText |
4355 TokenType::SingleLineTextQuotes => {
4356 nodes.push(Node::new_parsing_error_node(
4357 CodePosition::EMPTY,
4358 ParsingError::LexerError,
4359 format!(
4360 "Invalid token type for simple assignment value expression: \"{}\"",
4361 t.token_type(),
4362 ),
4363 ));
4364
4365 break 'tokenProcessing;
4366 },
4367 }
4368 }
4369
4370 ast
4371 }
4372
4373 fn parse_text_and_char_value(&mut self, value_tokens: &mut VecDeque<Token>, nodes: &mut Vec<Node>) {
4374 if value_tokens.is_empty() {
4375 return;
4376 }
4377
4378 let pos = value_tokens[0].pos().combine(&value_tokens[value_tokens.len() - 1].pos());
4379 let value = value_tokens.iter().
4380 map(|token| token.to_raw_string().to_string()).
4381 collect::<Vec<String>>().
4382 join("");
4383
4384 if !value.is_empty() {
4385 let code_point = value.chars().next().unwrap();
4386
4387 if value.chars().count() == 1 {
4389 nodes.push(Node::new_char_value_node(pos, code_point));
4390
4391 return;
4392 }
4393 }
4394
4395 nodes.push(Node::new_text_value_node(pos, value));
4397 }
4398
4399 fn parse_escape_sequence_token(&mut self, escape_sequence_token: Token, nodes: &mut Vec<Node>) {
4400 if matches!(escape_sequence_token.value().len(), 5..=10) {
4401 if !escape_sequence_token.value().starts_with("\\u{") ||
4402 !escape_sequence_token.value().ends_with("}") {
4403 nodes.push(Node::new_parsing_error_node(
4404 escape_sequence_token.pos(),
4405 ParsingError::LexerError,
4406 format!(
4407 "Invalid unicode escape sequence: {}",
4408 escape_sequence_token.value(),
4409 ),
4410 ));
4411
4412 return;
4413 }
4414
4415 let hex_codepoint = &escape_sequence_token.value()[3..escape_sequence_token.value().len() - 1];
4416 for c in hex_codepoint.bytes() {
4417 if !(c.is_ascii_digit() || matches!(c, b'a'..=b'f') || matches!(c, b'A'..=b'F')) {
4418 nodes.push(Node::new_parsing_error_node(
4419 escape_sequence_token.pos(),
4420 ParsingError::LexerError,
4421 format!(
4422 "Invalid unicode escape sequence: {}",
4423 escape_sequence_token.value(),
4424 ),
4425 ));
4426
4427 return;
4428 }
4429 }
4430
4431 nodes.push(Node::new_unicode_escape_sequence_node(
4432 escape_sequence_token.pos(),
4433 hex_codepoint,
4434 ));
4435
4436 return;
4437 }
4438
4439 if escape_sequence_token.value().chars().count() != 2 || escape_sequence_token.value().as_bytes()[0] != b'\\' {
4440 nodes.push(Node::new_parsing_error_node(
4441 escape_sequence_token.pos(),
4442 ParsingError::LexerError,
4443 format!(
4444 "Invalid escape sequence: {}",
4445 escape_sequence_token.value(),
4446 ),
4447 ));
4448
4449 return;
4450 }
4451
4452 nodes.push(Node::new_escape_sequence_node(
4453 escape_sequence_token.pos(),
4454 escape_sequence_token.value().chars().nth(1).unwrap(),
4455 ));
4456 }
4457
4458 fn parse_number_token(&mut self, number_token: Token, nodes: &mut Vec<Node>) {
4459 let token = number_token.value();
4460
4461 if let Ok(value) = i32::from_str(token) {
4463 nodes.push(Node::new_int_value_node(number_token.pos(), value));
4464
4465 return;
4466 }
4467
4468 if token.ends_with("l") || token.ends_with("L") {
4470 if let Ok(value) = i64::from_str(&token[..token.len() - 1]) {
4471 nodes.push(Node::new_long_value_node(number_token.pos(), value));
4472
4473 return;
4474 }
4475 }else if let Ok(value) = i64::from_str(token) {
4476 nodes.push(Node::new_long_value_node(number_token.pos(), value));
4477
4478 return;
4479 }
4480
4481 if (token.ends_with("f") || token.ends_with("F"))
4483 && let Ok(value) = f32::from_str(&token[..token.len() - 1]) {
4484 nodes.push(Node::new_float_value_node(number_token.pos(), value));
4485
4486 return;
4487 }
4488
4489 #[expect(clippy::needless_return)]
4491 if let Ok(value) = f64::from_str(token) {
4492 nodes.push(Node::new_double_value_node(number_token.pos(), value));
4493
4494 return;
4495 }
4496 }
4497
4498 fn parse_lexer_error_token(&mut self, lexer_error_token: Token, nodes: &mut Vec<Node>) {
4499 if matches!(lexer_error_token.token_type(), TokenType::LexerError) {
4500 nodes.push(Node::new_parsing_error_node(
4501 lexer_error_token.pos(),
4502 ParsingError::LexerError,
4503 lexer_error_token.value(),
4504 ));
4505 }
4506 }
4507
4508 fn parse_function_parameter_list(&mut self, tokens: &mut VecDeque<Token>, function_definition: bool) -> AST {
4509 let mut ast = AST::new();
4510 let nodes = ast.nodes_mut();
4511
4512 Self::trim_first_line(tokens);
4513
4514 if function_definition {
4515 'tokenProcessing:
4516 while !tokens.is_empty() {
4517 let t = tokens[0].clone();
4518
4519 match t.token_type() {
4520 TokenType::Eol | TokenType::Eof => {
4521 break 'tokenProcessing;
4522 },
4523
4524 TokenType::StartComment | TokenType::StartDocComment => {
4525 self.parse_comment_tokens(tokens, nodes);
4526 },
4527
4528 TokenType::ArgumentSeparator => {
4529 tokens.pop_front();
4530
4531 if nodes.is_empty() {
4532 nodes.push(Node::new_parsing_error_node(
4533 t.pos(),
4534 ParsingError::InvalidParameter,
4535 "Empty function parameter"
4536 ));
4537 }
4538
4539 if tokens.is_empty() || matches!(tokens[0].token_type(), TokenType::Eol | TokenType::Eof) {
4540 nodes.push(Node::new_parsing_error_node(
4541 t.pos(),
4542 ParsingError::InvalidParameter,
4543 "Empty function parameter"
4544 ));
4545 }
4546 },
4547
4548 TokenType::Identifier => {
4549 tokens.pop_front();
4550
4551 let mut variable_name = t.value().to_string();
4552 let mut pos = t.pos();
4553
4554 let mut type_constraint = None;
4555 if !tokens.is_empty() && matches!(tokens[0].token_type(), TokenType::OpeningBracket) &&
4556 tokens[0].value() == "{" {
4557 let bracket_end_index = utils::get_index_of_matching_bracket_tok(
4558 tokens.make_contiguous(),
4559 0, usize::MAX,
4560 "{", "}", true,
4561 );
4562 let Some(bracket_end_index) = bracket_end_index else {
4563 nodes.push(Node::new_parsing_error_node(
4564 t.pos(),
4565 ParsingError::BracketMismatch,
4566 format!(
4567 "Bracket is missing in return type constraint in function parameter list definition for parameter \"{}\"",
4568 variable_name,
4569 ),
4570 ));
4571
4572 return ast;
4573 };
4574
4575 pos = pos.combine(&tokens.get(bracket_end_index).unwrap().pos());
4576
4577 let mut type_constraint_tokens = tokens.split_off(bracket_end_index + 1);
4578 mem::swap(tokens, &mut type_constraint_tokens);
4579
4580 type_constraint = self.parse_type_constraint(
4581 &mut type_constraint_tokens,
4582 true,
4583 nodes,
4584 );
4585 }
4586
4587 if !tokens.is_empty() && matches!(tokens[0].token_type(), TokenType::Operator) &&
4588 tokens[0].value() == "..." {
4589 pos = pos.combine(&tokens[0].pos());
4590
4591 tokens.pop_front();
4593
4594 variable_name += "...";
4595 }
4596
4597 nodes.push(Node::new_variable_name_node(
4598 pos,
4599 variable_name,
4600 type_constraint.map(Box::from),
4601 ));
4602 },
4603
4604 TokenType::LexerError => {
4605 tokens.pop_front();
4606
4607 self.parse_lexer_error_token(t, nodes);
4608 },
4609
4610 TokenType::LiteralNull | TokenType::LiteralNumber | TokenType::LiteralText |
4611 TokenType::Assignment | TokenType::ClosingBracket | TokenType::Whitespace |
4612 TokenType::Other | TokenType::Operator | TokenType::OpeningBracket |
4613 TokenType::OpeningBlockBracket | TokenType::ClosingBlockBracket |
4614 TokenType::EscapeSequence | TokenType::ParserFunctionIdentifier |
4615 TokenType::StartMultilineText | TokenType::LineContinuation | TokenType::EndComment |
4616 TokenType::EndMultilineText | TokenType::SingleLineTextQuotes => {
4617 nodes.push(Node::new_parsing_error_node(
4618 CodePosition::EMPTY,
4619 ParsingError::LexerError,
4620 format!(
4621 "Invalid token type for function parameter list expression: \"{}\"",
4622 t.token_type(),
4623 ),
4624 ));
4625
4626 return ast;
4627 },
4628 }
4629 }
4630 }else {'tokenProcessing:
4631 while !tokens.is_empty() {
4632 let t = tokens[0].clone();
4633
4634 match t.token_type() {
4635 TokenType::Eol | TokenType::Eof => {
4636 break 'tokenProcessing;
4637 },
4638
4639 TokenType::StartComment | TokenType::StartDocComment => {
4640 self.parse_comment_tokens(tokens, nodes);
4641 },
4642
4643 TokenType::ArgumentSeparator => {
4644 tokens.pop_front();
4645
4646 if nodes.is_empty() ||
4647 matches!(nodes[nodes.len() - 1].node_data(), NodeData::ArgumentSeparator(..)) {
4648 nodes.push(Node::new_text_value_node(t.pos(), ""));
4650 }
4651
4652 nodes.push(Node::new_argument_separator_node(
4653 t.pos(),
4654 t.value(),
4655 ));
4656
4657 if tokens.is_empty() || matches!(tokens[0].token_type(), TokenType::Eol | TokenType::Eof) {
4658 nodes.push(Node::new_text_value_node(t.pos(), ""));
4660 }
4661 },
4662
4663 TokenType::LiteralNull => {
4664 tokens.pop_front();
4665
4666 nodes.push(Node::new_null_value_node(t.pos()));
4667 },
4668
4669 TokenType::LiteralText | TokenType::Assignment | TokenType::ClosingBracket |
4670 TokenType::Whitespace => {
4671 tokens.pop_front();
4672
4673 nodes.push(Node::new_text_value_node(t.pos(), t.value()));
4674 },
4675
4676 TokenType::Other => {
4677 tokens.pop_front();
4678
4679 self.parse_text_and_char_value(&mut VecDeque::from([t]), nodes);
4680 },
4681
4682 TokenType::Operator => {
4683 tokens.pop_front();
4684
4685 if (nodes.is_empty() || matches!(nodes[nodes.len() - 1].node_data(), NodeData::ArgumentSeparator(..))) &&
4686 matches!(t.value(), "+" | "-") && !tokens.is_empty() &&
4687 matches!(tokens[0].token_type(), TokenType::LiteralNumber) {
4688 let number_token = tokens.pop_front().unwrap();
4689
4690 let combined_number_token = Token::new(
4691 t.pos().combine(&number_token.pos()),
4692 &(t.value().to_string() + number_token.value()),
4693 TokenType::LiteralNumber,
4694 );
4695
4696 self.parse_number_token(combined_number_token, nodes);
4697
4698 continue 'tokenProcessing;
4699 }
4700
4701 nodes.push(Node::new_text_value_node(t.pos(), t.value()));
4702 },
4703
4704 TokenType::LiteralNumber => {
4705 tokens.pop_front();
4706
4707 self.parse_number_token(t, nodes);
4708 },
4709
4710 TokenType::OpeningBracket => {
4711 if t.value() == "(" {
4712 let end_index = utils::get_index_of_matching_bracket_tok(
4713 tokens.make_contiguous(), 0, usize::MAX, "(", ")", true,
4714 );
4715 if let Some(end_index) = end_index {
4716 let opening_bracket_token = &tokens[0];
4717 let closing_bracket_token = &tokens[end_index];
4718 let pos = opening_bracket_token.pos().combine(&closing_bracket_token.pos());
4719
4720 let mut function_call = utils::split_off_arguments(tokens, end_index);
4721
4722 nodes.push(Node::new_function_call_previous_node_value_node(
4723 pos, "", "",
4724 self.parse_function_parameter_list(&mut function_call, false).into_nodes(),
4725 ));
4726
4727 continue 'tokenProcessing;
4728 }
4729 }
4730
4731 tokens.pop_front();
4732
4733 nodes.push(Node::new_text_value_node(t.pos(), t.value()));
4734 },
4735
4736 TokenType::EscapeSequence => {
4737 tokens.pop_front();
4738
4739 self.parse_escape_sequence_token(t, nodes);
4740 },
4741
4742 TokenType::LexerError => {
4743 tokens.pop_front();
4744
4745 self.parse_lexer_error_token(t, nodes);
4746 },
4747
4748 TokenType::StartMultilineText => {
4749 tokens.pop_front();
4750
4751 loop {
4752 if let Some(t) = tokens.pop_front() {
4753 if matches!(t.token_type(), TokenType::EndMultilineText) {
4754 break;
4755 }
4756
4757 if matches!(t.token_type(), TokenType::LiteralText | TokenType::Eol) {
4758 nodes.push(Node::new_text_value_node(t.pos(), t.value()));
4759 }else if matches!(t.token_type(), TokenType::EscapeSequence) {
4760 self.parse_escape_sequence_token(t, nodes);
4761 }else if matches!(t.token_type(), TokenType::LexerError) {
4762 nodes.push(Node::new_parsing_error_node(
4763 t.pos(),
4764 ParsingError::LexerError,
4765 t.value()
4766 ));
4767 }else {
4768 nodes.push(Node::new_parsing_error_node(
4769 CodePosition::EMPTY,
4770 ParsingError::Eof,
4771 format!(
4772 "Invalid token type ({}) in multiline text during simple assignment value parsing",
4773 t.token_type(),
4774 ),
4775 ));
4776 }
4777 }else {
4778 nodes.push(Node::new_parsing_error_node(
4779 CodePosition::EMPTY,
4780 ParsingError::Eof,
4781 "Missing multiline text end token during simple assignment value parsing",
4782 ));
4783
4784 break 'tokenProcessing;
4785 }
4786 }
4787 },
4788
4789 TokenType::Identifier | TokenType::ParserFunctionIdentifier => {
4790 let is_identifier = matches!(t.token_type(), TokenType::Identifier);
4791
4792 if is_identifier && tokens.len() >= 2 &&
4793 matches!(tokens[1].token_type(), TokenType::Operator) &&
4794 tokens[1].value() == "..." {
4795 let identifier_token = tokens.pop_front().unwrap();
4798 let operator_token = tokens.pop_front().unwrap();
4799
4800 let pos = identifier_token.pos().combine(&operator_token.pos());
4801
4802 nodes.push(Node::new_unprocessed_variable_name_node(
4803 pos,
4804 identifier_token.value().to_string() + operator_token.value(),
4805 ));
4806 }else {
4807 let ret = if is_identifier {
4808 self.parse_variable_name_and_function_call(tokens, None)
4809 }else {
4810 self.parse_parser_function_call(tokens)
4811 };
4812 if let Some(ret) = ret {
4813 nodes.push(ret);
4814 }
4815 }
4816 },
4817
4818 TokenType::OpeningBlockBracket | TokenType::ClosingBlockBracket |
4819 TokenType::LineContinuation | TokenType::EndComment | TokenType::EndMultilineText |
4820 TokenType::SingleLineTextQuotes => {
4821 nodes.push(Node::new_parsing_error_node(
4822 CodePosition::EMPTY,
4823 ParsingError::LexerError,
4824 format!(
4825 "Invalid token type for function argument expression: \"{}\"",
4826 t.token_type(),
4827 ),
4828 ));
4829
4830 break 'tokenProcessing;
4831 },
4832 }
4833 }
4834 }
4835
4836 ast
4837 }
4838
4839 fn parse_function_call_without_prefix(&mut self, tokens: &mut VecDeque<Token>, operator_type: Option<OperatorType>) -> Option<Node> {
4840 if tokens.len() < 2 {
4841 return None;
4842 }
4843
4844 let identifier_token = tokens.front().unwrap().clone();
4845 if !matches!(identifier_token.token_type(), TokenType::Other) ||
4846 !regex_patterns::WORD.is_match(identifier_token.value()) ||
4847 !matches!(tokens[1].token_type(), TokenType::OpeningBracket) ||
4848 tokens[1].value() != "(" {
4849 return None;
4850 }
4851
4852 tokens.pop_front();
4853
4854 self.parse_function_call(identifier_token, tokens, operator_type)
4855 }
4856
4857 fn parse_variable_name_and_function_call(&mut self, tokens: &mut VecDeque<Token>, operator_type: Option<OperatorType>) -> Option<Node> {
4858 if tokens.is_empty() {
4859 return None;
4860 }
4861
4862 let identifier_token = tokens.front().unwrap().clone();
4863 if !matches!(identifier_token.token_type(), TokenType::Identifier) {
4864 return None;
4865 }
4866
4867 tokens.pop_front();
4868
4869 if tokens.is_empty() || !matches!(tokens[0].token_type(), TokenType::OpeningBracket) ||
4870 tokens[0].value() != "(" || !regex_patterns::VAR_NAME_FUNCS_WITH_OPERATOR_AND_CONVERSION_METHOD.is_match(identifier_token.value()) {
4871 return Some(Node::new_unprocessed_variable_name_node(
4872 identifier_token.pos(),
4873 identifier_token.value(),
4874 ));
4875 }
4876
4877 self.parse_function_call(identifier_token, tokens, operator_type)
4878 }
4879
4880 fn parse_function_call(&mut self, identifier_token: Token, tokens: &mut VecDeque<Token>, operator_type: Option<OperatorType>) -> Option<Node> {
4881 let end_index = utils::get_index_of_matching_bracket_tok(
4882 tokens.make_contiguous(),
4883 0, usize::MAX,
4884 "(", ")", true,
4885 );
4886 let Some(end_index) = end_index else {
4887 return Some(Node::new_parsing_error_node(
4888 identifier_token.pos(),
4889 ParsingError::BracketMismatch,
4890 "Bracket is missing in function call",
4891 ));
4892 };
4893
4894 let pos = identifier_token.pos().combine(&tokens[end_index].pos());
4895
4896 let mut function_parameter_tokens = utils::split_off_arguments(tokens, end_index);
4897
4898 if let Some(operator_type) = operator_type {
4899 let raw_function_args = self.parse_operator_expr(&mut function_parameter_tokens, operator_type).unwrap();
4900
4901 return Some(Node::new_function_call_node(
4902 pos,
4903 Self::convert_comma_operators_to_argument_separators(raw_function_args),
4904 identifier_token.value(),
4905 ));
4906 }
4907
4908 Some(Node::new_function_call_node(
4909 pos,
4910 self.parse_function_parameter_list(&mut function_parameter_tokens, false).into_nodes(),
4911 identifier_token.value(),
4912 ))
4913 }
4914
4915 fn parse_parser_function_call(&mut self, tokens: &mut VecDeque<Token>) -> Option<Node> {
4916 if tokens.is_empty() {
4917 return None;
4918 }
4919
4920 let parser_function_identifier_token = tokens.front().unwrap().clone();
4921 if !matches!(parser_function_identifier_token.token_type(), TokenType::ParserFunctionIdentifier) {
4922 return None;
4923 }
4924
4925 tokens.pop_front();
4926
4927 let end_index = utils::get_index_of_matching_bracket_tok(
4928 tokens.make_contiguous(),
4929 0, usize::MAX,
4930 "(", ")", true,
4931 );
4932 let Some(end_index) = end_index else {
4933 return Some(Node::new_parsing_error_node(
4934 parser_function_identifier_token.pos(),
4935 ParsingError::BracketMismatch,
4936 "Bracket is missing in parser function call",
4937 ));
4938 };
4939
4940 let mut parameter_tokens = utils::split_off_arguments(tokens, end_index);
4941
4942 match parser_function_identifier_token.value() {
4943 "parser.con" => Some(self.parse_condition_expr(&mut parameter_tokens).unwrap()),
4944 "parser.math" => Some(self.parse_math_expr(&mut parameter_tokens).unwrap()),
4945 "parser.norm" => Some(self.parse_token(&mut parameter_tokens).into_node()),
4946 "parser.op" => Some(self.parse_operation_expr(&mut parameter_tokens).unwrap()),
4947
4948 _ => {
4949 Some(Node::new_parsing_error_node(
4950 parser_function_identifier_token.pos(),
4951 ParsingError::InvalidParameter,
4952 format!(
4953 "Invalid parser function: \"{}\"",
4954 parser_function_identifier_token.value(),
4955 ),
4956 ))
4957 },
4958 }
4959 }
4960
4961 fn parse_type_constraint(
4962 &mut self,
4963 tokens: &mut VecDeque<Token>,
4964 allow_special_type_constraints: bool,
4965 error_nodes: &mut Vec<Node>,
4966 ) -> Option<String> {
4967 if tokens.is_empty() {
4968 return None;
4969 }
4970
4971 let mut type_constraint = tokens.iter().
4972 map(|token| token.to_raw_string().to_string()).
4973 collect::<Vec<String>>().
4974 join("");
4975 let regex = if allow_special_type_constraints {
4976 ®ex_patterns::TYPE_CONSTRAINT_WITH_SPECIAL_TYPES
4977 }else {
4978 ®ex_patterns::PARSING_TYPE_CONSTRAINT
4979 };
4980 if !regex.is_match(&type_constraint) {
4981 let pos = tokens[0].pos().combine(&tokens[tokens.len() - 1].pos());
4982
4983 error_nodes.push(Node::new_parsing_error_node(
4984 pos,
4985 ParsingError::LexerError,
4986 "Invalid type constraint syntax"
4987 ));
4988
4989 return None;
4990 }
4991
4992 type_constraint.remove(0);
4994 type_constraint.remove(type_constraint.len() - 1);
4995
4996 Some(type_constraint)
4997 }
4998
4999 fn parse_comment_tokens(&mut self, tokens: &mut VecDeque<Token>, error_nodes: &mut Vec<Node>) {
5000 if tokens.is_empty() {
5001 return;
5002 }
5003
5004 let mut current_token = tokens[0].clone();
5005 while matches!(current_token.token_type(), TokenType::StartComment | TokenType::StartDocComment) {
5006 tokens.pop_front();
5007
5008 let is_doc_comment = matches!(current_token.token_type(), TokenType::StartDocComment);
5009 let mut comment = String::new();
5010
5011 while !matches!(current_token.token_type(), TokenType::EndComment) {
5012 if tokens.is_empty() {
5013 break;
5014 }
5015
5016 current_token = tokens.pop_front().unwrap();
5017 if matches!(current_token.token_type(), TokenType::LexerError) {
5018 error_nodes.push(Node::new_parsing_error_node(
5019 current_token.pos(),
5020 ParsingError::LexerError,
5021 current_token.value(),
5022 ));
5023 }
5024
5025 if is_doc_comment {
5026 match current_token.token_type() {
5027 TokenType::LiteralText | TokenType::EscapeSequence => {
5028 comment += current_token.value();
5029 },
5030
5031 TokenType::Eol => {
5032 comment += "\n";
5033 },
5034
5035 _ => {},
5036 }
5037 }
5038 }
5039
5040 if is_doc_comment {
5041 if let Some(ref mut lang_doc_comment) = self.lang_doc_comment {
5042 *lang_doc_comment += "\n";
5043 *lang_doc_comment += comment.as_str();
5044 }else {
5045 self.lang_doc_comment = Some(comment);
5046 }
5047 }
5048
5049 if tokens.is_empty() {
5050 break;
5051 }
5052
5053 current_token = tokens[0].clone();
5054 }
5055 }
5056
5057 fn trim_first_line(tokens: &mut VecDeque<Token>) {
5058 while !tokens.is_empty() && matches!(tokens[0].token_type(), TokenType::Whitespace) {
5059 tokens.pop_front();
5060 }
5061
5062 let token_count_first_line = Self::get_token_count_first_line(tokens.make_contiguous());
5063
5064 if token_count_first_line == 0 {
5065 return;
5066 }
5067
5068 let mut i = token_count_first_line - 1;
5069 while matches!(tokens[i].token_type(), TokenType::Whitespace | TokenType::EndComment) {
5070 if matches!(tokens[i].token_type(), TokenType::EndComment) {
5072 while !matches!(tokens[i].token_type(), TokenType::StartComment | TokenType::StartDocComment) {
5073 if i == 0 {
5074 break;
5075 }
5076
5077 i -= 1;
5078 }
5079
5080 if i == 0 {
5081 break;
5082 }
5083
5084 i -= 1;
5085
5086 continue;
5087 }
5088
5089 tokens.remove(i);
5090
5091 if i == 0 {
5092 break;
5093 }
5094
5095 i -= 1;
5096 }
5097 }
5098
5099 fn remove_line_continuation_and_single_line_text_quotes_tokens(tokens: &mut VecDeque<Token>) {
5100 let mut i = 0;
5101 while i < tokens.len() {
5102 let token = &tokens[i];
5103
5104 if matches!(token.token_type(), TokenType::LineContinuation) {
5105 tokens.remove(i);
5106
5107 if tokens.get(i).is_some_and(|token| matches!(token.token_type(), TokenType::Eol)) {
5108 tokens.remove(i);
5109 }
5110
5111 i = i.wrapping_sub(1);
5112 }else if matches!(token.token_type(), TokenType::SingleLineTextQuotes) {
5113 tokens.remove(i);
5114 i = i.wrapping_sub(1);
5115 }
5116
5117 i = i.wrapping_add(1);
5118 }
5119
5120 tokens.make_contiguous();
5121 }
5122
5123 fn get_token_count_first_line(tokens: &[Token]) -> usize {
5124 for (i, token) in tokens.iter().enumerate() {
5125 if matches!(token.token_type(), TokenType::Eol | TokenType::Eof) {
5126 return i;
5127 }
5128 }
5129
5130 tokens.len()
5131 }
5132}
5133
5134impl Default for Parser {
5135 fn default() -> Self {
5136 Self::new()
5137 }
5138}