1use std::f64::consts::E;
2
3use crate::language::operators::{
4 Token,
5 TokenType,
6};
7use crate::language::lexer::{
8 AstNode,
9 Lexer,
10};
11use log::{
12 info,
13 error,
14 debug
15};
16
17
18pub struct Parser {
19 tokens: Vec<Token>,
20 current: usize,
21}
22
23impl Parser {
24 pub fn new(tokens: Vec<Token>) -> Self {
25 Parser {
26 tokens,
27 current: 0,
28 }
29 }
30
31 pub fn parse(&mut self) -> Result<AstNode, String> {
32 let mut statements = Vec::new();
33 let mut tls_config = None;
34 let mut global_error_handler = None;
35 let mut config = None;
36 let mut imports = Vec::new();
37
38 while !self.is_at_end() {
39 if self.check(&TokenType::Tls) {
40 if tls_config.is_some() {
41 return Err("Дублирование TLS конфигурации".to_string());
42 }
43 tls_config = Some(Box::new(self.tls_config()?));
44 } else if self.check(&TokenType::GlobalErrorHandler) {
45 if global_error_handler.is_some() {
46 return Err("Дублирование глобального обработчика ошибок".to_string());
47 }
48 global_error_handler = Some(Box::new(self.global_error_handler()?));
49 } else if self.check(&TokenType::Route) {
50 statements.push(Box::new(self.route()?));
51 } else if self.check(&TokenType::Config) {
52 if config.is_some() {
53 return Err("Дублирование блока 'config'".to_string());
54 }
55 config = Some(Box::new(self.config_block()?));
56 } else if self.check(&TokenType::Import) {
57 imports.push(Box::new(self.import()?));
58 } else {
59 return Err(format!("Ожидается 'route', 'tls' или 'config', получено: {:?}", self.peek().token_type));
60 }
61 }
62
63 let has_tls = tls_config.is_some();
64 let has_global_handler = global_error_handler.is_some();
65 let has_config = config.is_some();
66 let program_statements = imports.into_iter().chain(statements.into_iter()).collect();
67
68 if has_tls || has_global_handler || has_config {
69 Ok(AstNode::ServerConfig {
70 routes: program_statements,
71 tls_config,
72 global_error_handler,
73 config_block: config,
74 })
75 } else if !program_statements.is_empty() {
76 Ok(AstNode::Program(program_statements))
77 } else {
78 Ok(AstNode::Program(vec![]))
79 }
80 }
81
82 fn import(&mut self) -> Result<AstNode, String> {
83 self.consume(&TokenType::Import, "Ожидается ключевое слово 'import'")?;
84
85 let path_token = self.consume(&TokenType::String(String::new()), "Ожидается строка пути к плагину")?;
86 let path = match &path_token.token_type {
87 TokenType::String(s) => s.clone(),
88 _ => return Err("Ошибка парсинга пути к плагину".to_string()),
89 };
90
91 self.consume(&TokenType::As, "Ожидается ключевое слово 'as' после пути")?;
92
93 let alias_token = self.consume(&TokenType::Identifier(String::new()), "Ожидается псевдоним плагина")?;
94 let alias = match &alias_token.token_type {
95 TokenType::Identifier(n) => n.clone(),
96 _ => return Err("Ошибка парсинга псевдонима плагина".to_string()),
97 };
98
99 self.consume(&TokenType::Semicolon, "Ожидается ';' после импорта плагина")?;
100
101 Ok(AstNode::Import { path, alias })
102 }
103
104 fn global_error_handler(&mut self) -> Result<AstNode, String> {
105 self.consume(&TokenType::GlobalErrorHandler, "Ожидается ключевое слово 'global_error_handler'")?;
106 self.consume(&TokenType::LParen, "Ожидается '(' после 'global_error_handler'")?;
107
108 let error_var_token = self.consume(&TokenType::Identifier(String::new()), "Ожидается имя переменной")?;
109 let error_var = match &error_var_token.token_type {
110 TokenType::Identifier(name) => name.clone(),
111 _ => return Err("Невозможно получить имя переменной".to_string()),
112 };
113
114 self.consume(&TokenType::RParen, "Ожидается ')' после имени переменной")?;
115
116 let body = self.block()?;
117
118 self.consume(&TokenType::Semicolon, "Ожидается ';' после блока глобального обработчика ошибок")?;
119
120 Ok(AstNode::GlobalErrorHandler {
121 error_var,
122 body: Box::new(body),
123 })
124 }
125
126 fn tls_config(&mut self) -> Result<AstNode, String> {
127 self.consume(&TokenType::Tls, "Ожидается ключевое слово 'tls'")?;
128 self.consume(&TokenType::LBrace, "Ожидается '{' после 'tls'")?;
129
130 let mut enabled = false;
131 let mut cert_path = String::new();
132 let mut key_path = String::new();
133
134 while !self.check(&TokenType::RBrace) && !self.is_at_end() {
135 if self.match_token(&TokenType::Enabled) {
136 self.consume(&TokenType::Equals, "Ожидается '=' после 'enabled'")?;
137 if self.match_token(&TokenType::Identifier(String::new())) {
138 let value = match &self.previous().token_type {
139 TokenType::Identifier(v) => v.clone(),
140 _ => return Err("Ожидается bool значение для enabled".to_string()),
141 };
142 enabled = value == "true";
143 } else {
144 return Err("Ожидается булево значение (true/false) для enabled".to_string());
145 }
146 self.consume(&TokenType::Semicolon, "Ожидается ';' после значения")?;
147 } else if self.match_token(&TokenType::CertPath) {
148 self.consume(&TokenType::Equals, "Ожидается '=' после 'cert_path'")?;
149 if self.match_token(&TokenType::String(String::new())) {
150 cert_path = match &self.previous().token_type {
151 TokenType::String(v) => v.clone(),
152 _ => return Err("Ожидается строка для cert_path".to_string()),
153 };
154 } else {
155 return Err("Ожидается строковое значение для cert_path".to_string());
156 }
157 self.consume(&TokenType::Semicolon, "Ожидается ';' после значения")?;
158 } else if self.match_token(&TokenType::KeyPath) {
159 self.consume(&TokenType::Equals, "Ожидается '=' после 'key_path'")?;
160 if self.match_token(&TokenType::String(String::new())) {
161 key_path = match &self.previous().token_type {
162 TokenType::String(v) => v.clone(),
163 _ => return Err("Ожидается строка для key_path".to_string()),
164 };
165 } else {
166 return Err("Ожидается строковое значение для key_path".to_string());
167 }
168 self.consume(&TokenType::Semicolon, "Ожидается ';' после значения")?;
169 } else {
170 return Err(format!("Неизвестный ключ в TLS конфигурации: {:?}", self.peek().token_type));
171 }
172 }
173
174 self.consume(&TokenType::RBrace, "Ожидается '}' после TLS конфигурации")?;
175 self.consume(&TokenType::Semicolon, "Ожидается ';' после блока TLS конфигурации")?;
176
177 Ok(AstNode::TlsConfig {
178 enabled,
179 cert_path,
180 key_path,
181 })
182 }
183
184 fn config_block(&mut self) -> Result<AstNode, String> {
185 self.consume(&TokenType::Config, "Ожидается ключевое слово 'config'")?;
186 self.consume(&TokenType::LBrace, "Ожидается '{' после 'config'")?;
187
188 let mut type_name = String::new();
189 let mut host = String::new();
190 let mut port = String::new();
191
192 while !self.check(&TokenType::RBrace) && !self.is_at_end() {
193 if self.match_token(&TokenType::TypeName) {
194 self.consume(&TokenType::Equals, "Ожидается '=' после 'type'")?;
195 let value_token = self.advance();
196 match &value_token.token_type {
197 TokenType::String(v) | TokenType::Identifier(v) => {
198 type_name = v.clone();
199 }
200 _ => return Err(format!("Ожидается строка или идентификатор для type, получено {:?}", value_token.token_type)),
201 };
202 self.consume(&TokenType::Semicolon, "Ожидается ';' после значения type")?;
203 } else if self.match_token(&TokenType::Host) {
204 self.consume(&TokenType::Equals, "Ожидается '=' после 'host'")?;
205 let value_token = self.advance();
206 match &value_token.token_type {
207 TokenType::String(v) | TokenType::Identifier(v) => {
208 host = v.clone();
209 }
210 _ => return Err(format!("Ожидается строка или идентификатор для host, получено {:?}", value_token.token_type)),
211 };
212 self.consume(&TokenType::Semicolon, "Ожидается ';' после значения host")?;
213 } else if self.match_token(&TokenType::Port) {
214 self.consume(&TokenType::Equals, "Ожидается '=' после 'port'")?;
215 let value_token = self.advance();
216 match &value_token.token_type {
217 TokenType::String(v) => port = v.clone(),
218 TokenType::Number(n) => port = n.to_string(),
219 TokenType::Identifier(v) => port = v.clone(),
220 _ => return Err(format!("Ожидается строка, число или идентификатор для port, получено {:?}", value_token.token_type)),
221 };
222 self.consume(&TokenType::Semicolon, "Ожидается ';' после значения port")?;
223 } else {
224 return Err(format!("Неизвестный ключ в блоке 'config': {:?} на строке {}", self.peek().token_type, self.peek().line));
225 }
226 }
227
228 self.consume(&TokenType::RBrace, "Ожидается '}' после блока 'config'")?;
229 self.consume(&TokenType::Semicolon, "Ожидается ';' после блока 'config'")?;
230
231 if type_name == "http" && (host.is_empty() || port.is_empty()) {
232 return Err("Для type=\"http\" необходимо указать host и port в блоке 'config'".to_string());
233 }
234 if !port.is_empty() && port.parse::<u16>().is_err() {
235 return Err(format!("Значение port '{}' не является допустимым числом (0-65535)", port));
236 }
237
238
239 Ok(AstNode::ConfigBlock {
240 config_type: type_name,
241 host,
242 port,
243 })
244 }
245
246 fn is_at_end(&self) -> bool {
247 matches!(self.peek().token_type, TokenType::EOF)
248 }
249
250 fn peek(&self) -> &Token {
251 &self.tokens[self.current]
252 }
253
254 fn previous(&self) -> &Token {
255 &self.tokens[self.current - 1]
256 }
257
258 fn advance(&mut self) -> &Token {
259 if !self.is_at_end() {
260 self.current += 1;
261 }
262 self.previous()
263 }
264
265 fn check(&self, token_type: &TokenType) -> bool {
266 if self.is_at_end() {
267 false
268 } else {
269 match (&self.peek().token_type, token_type) {
270 (TokenType::Identifier(_), TokenType::Identifier(_)) => true,
271 (TokenType::String(_), TokenType::String(_)) => true,
272 (TokenType::HttpMethod(_), TokenType::HttpMethod(_)) => true,
273 (TokenType::Comment(_), TokenType::Comment(_)) => true,
274 (a, b) => std::mem::discriminant(a) == std::mem::discriminant(b),
275 }
276 }
277 }
278
279 fn match_token(&mut self, token_type: &TokenType) -> bool {
280 if self.check(token_type) {
281 self.advance();
282 true
283 } else {
284 false
285 }
286 }
287
288 fn consume(&mut self, token_type: &TokenType, error_message: &str) -> Result<&Token, String> {
289 if self.check(token_type) {
290 Ok(self.advance())
291 } else {
292 Err(format!("{}, получено: {:?}, строка: {}, колонка: {}",
293 error_message, self.peek().token_type, self.peek().line, self.peek().column))
294 }
295 }
296
297 fn route(&mut self) -> Result<AstNode, String> {
298 self.consume(&TokenType::Route, "Ожидается ключевое слово 'route'")?;
299
300 let path_token = self.consume(&TokenType::String(String::new()), "Ожидается строка пути маршрута")?;
301 let path = match &path_token.token_type {
302 TokenType::String(s) => s.clone(),
303 _ => return Err("Невозможный случай при парсинге пути маршрута".to_string()),
304 };
305
306 let method_token = self.consume(&TokenType::HttpMethod(String::new()), "Ожидается HTTP метод")?;
307 let method = match &method_token.token_type {
308 TokenType::HttpMethod(m) => m.clone(),
309 _ => return Err("Невозможный случай при парсинге HTTP метода".to_string()),
310 };
311
312 let body = self.block()?;
313
314 let on_error = if self.match_token(&TokenType::OnError) {
315 Some(Box::new(self.error_handler()?))
316 } else {
317 None
318 };
319
320 self.consume(&TokenType::Semicolon, "Ожидается ';' после блока маршрута")?;
321
322 Ok(AstNode::Route {
323 path,
324 method,
325 body: Box::new(body),
326 on_error,
327 })
328 }
329
330 fn error_handler(&mut self) -> Result<AstNode, String> {
331 self.consume(&TokenType::LParen, "Ожидается '(' после 'on_error'")?;
332
333 let error_var_token = self.consume(&TokenType::Identifier(String::new()), "Ожидается имя переменной")?;
334 let error_var = match &error_var_token.token_type {
335 TokenType::Identifier(name) => name.clone(),
336 _ => return Err("Невозможно получить имя переменной ошибки".to_string()),
337 };
338
339 self.consume(&TokenType::RParen, "Ожидается ')' после имени переменной ошибки")?;
340
341 let body = self.block()?;
342
343 Ok(AstNode::ErrorHandlerBlock {
344 error_var,
345 body: Box::new(body),
346 })
347 }
348
349 fn block(&mut self) -> Result<AstNode, String> {
350 if !self.check(&TokenType::LBrace) {
351 return Err(format!(
352 "Ожидается '{{', получено: {:?}, строка: {}, колонка: {}",
353 self.peek().token_type, self.peek().line, self.peek().column
354 ));
355 }
356
357 self.consume(&TokenType::LBrace, "Ожидается '{'")?;
358
359 let mut statements = Vec::new();
360
361 if self.check(&TokenType::RBrace) {
362 self.advance();
363 return Ok(AstNode::Block(statements));
364 }
365
366 while !self.check(&TokenType::RBrace) && !self.is_at_end() {
367 statements.push(Box::new(self.statement()?));
368 }
369
370 if !self.check(&TokenType::RBrace) {
371 return Err(format!(
372 "Ожидается '}}' после блока кода, получено: {:?}, строка: {}, колонка: {}",
373 self.peek().token_type, self.peek().line, self.peek().column
374 ));
375 }
376
377 self.consume(&TokenType::RBrace, "Ожидается '}' после блока")?;
378
379 Ok(AstNode::Block(statements))
380 }
381
382 fn statement(&mut self) -> Result<AstNode, String> {
383 if self.match_token(&TokenType::Val) || self.match_token(&TokenType::Var) {
384 self.var_declaration()
385 } else if self.match_token(&TokenType::If) {
386 self.if_statement()
387 } else {
388 self.expression_statement()
389 }
390 }
391
392 fn var_declaration(&mut self) -> Result<AstNode, String> {
393 let name_token = self.consume(&TokenType::Identifier(String::new()), "Ожидается имя переменной")?;
394 let name = match &name_token.token_type {
395 TokenType::Identifier(n) => n.clone(),
396 _ => return Err("Невозможный случай при парсинге имени переменной".to_string()),
397 };
398
399 self.consume(&TokenType::Equals, "Ожидается '=' после имени переменной")?;
400
401 let value = self.expression()?;
402
403 self.consume(&TokenType::Semicolon, "Ожидается ';' после объявления переменной")?;
404
405 Ok(AstNode::VarDeclaration {
406 name,
407 value: Box::new(value),
408 })
409 }
410
411 fn if_statement(&mut self) -> Result<AstNode, String> {
412 self.consume(&TokenType::LParen, "Ожидается '(' после 'if'")?;
413 let condition = self.expression()?;
414 self.consume(&TokenType::RParen, "Ожидается ')' после условия")?;
415
416 let then_branch = self.block()?;
417
418 let else_branch = if self.match_token(&TokenType::Else) {
419 if self.match_token(&TokenType::If) {
420 let inner_if = self.if_statement_no_semicolon()?;
421 Some(Box::new(inner_if))
422 } else {
423 Some(Box::new(self.block()?))
424 }
425 } else {
426 None
427 };
428
429 if else_branch.is_none() {
430 self.consume(&TokenType::Semicolon, "Ожидается ';' после оператора if")?;
431 }
432
433 Ok(AstNode::IfStatement {
434 condition: Box::new(condition),
435 then_branch: Box::new(then_branch),
436 else_branch,
437 })
438 }
439
440 fn if_statement_no_semicolon(&mut self) -> Result<AstNode, String> {
441 self.consume(&TokenType::LParen, "Ожидается '(' после 'if'")?;
442 let condition = self.expression()?;
443 self.consume(&TokenType::RParen, "Ожидается ')' после условия")?;
444
445 let then_branch = self.block()?;
446
447 let else_branch = if self.match_token(&TokenType::Else) {
448 if self.match_token(&TokenType::If) {
449 Some(Box::new(self.if_statement_no_semicolon()?))
450 } else {
451 Some(Box::new(self.block()?))
452 }
453 } else {
454 None
455 };
456
457 Ok(AstNode::IfStatement {
458 condition: Box::new(condition),
459 then_branch: Box::new(then_branch),
460 else_branch,
461 })
462 }
463
464 fn expression_statement(&mut self) -> Result<AstNode, String> {
465 let expr = self.expression()?;
466 self.consume(&TokenType::Semicolon, "Ожидается ';' после выражения")?;
467 Ok(expr)
468 }
469
470 fn expression(&mut self) -> Result<AstNode, String> {
471 self.comparison()
472 }
473
474 fn comparison(&mut self) -> Result<AstNode, String> {
475 let mut expr = self.additive()?;
476
477 while self.check(&TokenType::DoubleEquals) || self.check(&TokenType::NotEquals) {
478 let operator_type = self.peek().token_type.clone();
479 self.advance();
480
481 let operator = match operator_type {
482 TokenType::DoubleEquals => "==".to_string(),
483 TokenType::NotEquals => "!=".to_string(),
484 _ => unreachable!(),
485 };
486
487 let right = self.additive()?;
488
489 expr = AstNode::BinaryOp {
490 left: Box::new(expr),
491 operator,
492 right: Box::new(right),
493 };
494 }
495
496 Ok(expr)
497 }
498
499 fn additive(&mut self) -> Result<AstNode, String> {
500 let mut expr = self.call_chain()?;
501
502 while self.match_token(&TokenType::Concatenation) {
503 let right = self.call_chain()?;
504
505 expr = AstNode::BinaryOp {
506 left: Box::new(expr),
507 operator: "+".to_string(),
508 right: Box::new(right),
509 };
510 }
511
512 Ok(expr)
513 }
514
515 fn call_chain(&mut self) -> Result<AstNode, String> {
516 let mut expr = self.primary()?;
517
518 loop {
519 if self.match_token(&TokenType::Dot) {
520 let name_token = self.consume(&TokenType::Identifier(String::new()), "Ожидается имя свойства после '.'")?;
521 let name = match &name_token.token_type {
522 TokenType::Identifier(n) => n.clone(),
523 _ => return Err("Невозможный случай при парсинге имени свойства".to_string()),
524 };
525
526 if self.check(&TokenType::LParen) {
527 self.advance();
528 let args = self.arguments()?;
529 let try_operator = self.match_token(&TokenType::TryOperator);
530 let unwrap_operator = self.match_token(&TokenType::UnwrapOperator);
531 expr = AstNode::FunctionCall {
532 object: Some(Box::new(expr)),
533 name,
534 args,
535 try_operator,
536 unwrap_operator,
537 };
538 } else {
539 expr = AstNode::PropertyAccess {
540 object: Box::new(expr),
541 property: name,
542 };
543 }
544 } else if self.match_token(&TokenType::DoubleColon) {
545 let object_name = match expr {
546 AstNode::Identifier(ref n) => n.clone(),
547 _ => return Err(format!("Ожидается идентификатор перед '::', получено: {}", expr)),
548 };
549
550 let fun_name_token = self.consume(&TokenType::Identifier(String::new()),
551 "Ожидается имя функции после '::'")?;
552
553 let fun_name = match &fun_name_token.token_type {
554 TokenType::Identifier(n) => n.clone(),
555 _ => return Err("Невозможный случай при парсинге имени функции плагина".to_string()),
556 };
557
558 self.consume(&TokenType::LParen,
559 "Ожидается '(' после имени функции плагина")?;
560 let args = self.arguments()?;
561 let try_operator = self.match_token(&TokenType::TryOperator);
562 let unwrap_operator = self.match_token(&TokenType::UnwrapOperator);
563
564 expr = AstNode::FunctionCall {
565 object: Some(Box::new(AstNode::Identifier(object_name))),
566 name: fun_name,
567 args,
568 try_operator,
569 unwrap_operator,
570 };
571 } else if self.match_token(&TokenType::LParen) && matches!(expr, AstNode::Identifier(_)) {
572 let name = match &expr {
573 AstNode::Identifier(n) => n.clone(),
574 _ => return Err("Ожидается идентификатор перед '('".to_string()),
575 };
576
577 let args = self.arguments()?;
578
579 let try_operator = self.match_token(&TokenType::TryOperator);
580 let unwrap_operator = self.match_token(&TokenType::UnwrapOperator);
581
582 expr = AstNode::FunctionCall {
583 object: None,
584 name,
585 args,
586 try_operator,
587 unwrap_operator,
588 };
589 } else {
590 break;
591 }
592
593 if let AstNode::FunctionCall { object, name, args, try_operator, unwrap_operator } = &expr {
594 let try_operator = self.match_token(&TokenType::TryOperator);
595 let unwrap_operator = self.match_token(&TokenType::UnwrapOperator);
596
597 if try_operator || unwrap_operator {
598 expr = AstNode::FunctionCall {
599 object: object.clone(),
600 name: name.clone(),
601 args: args.clone(),
602 try_operator,
603 unwrap_operator,
604 }
605 }
606 }
607 }
608
609 Ok(expr)
610 }
611
612 fn primary(&mut self) -> Result<AstNode, String> {
613 if self.match_token(&TokenType::Identifier(String::new())) {
614 let name = match &self.previous().token_type {
615 TokenType::Identifier(n) => n.clone(),
616 _ => return Err("Невозможный случай при парсинге идентификатора".to_string()),
617 };
618 Ok(AstNode::Identifier(name))
619 } else if self.match_token(&TokenType::String(String::new())) {
620 let value = match &self.previous().token_type {
621 TokenType::String(s) => s.clone(),
622 _ => return Err("Невозможный случай при парсинге строки".to_string()),
623 };
624 Ok(AstNode::StringLiteral(value))
625 } else if self.match_token(&TokenType::Number(0)) {
626 let value = match &self.previous().token_type {
627 TokenType::Number(n) => *n,
628 _ => return Err("Невозможный случай при парсинге числа".to_string()),
629 };
630 Ok(AstNode::NumberLiteral(value))
631 } else {
632 Err(format!("Ожидается выражение, получено {:?}", self.peek().token_type))
633 }
634 }
635
636 fn arguments(&mut self) -> Result<Vec<Box<AstNode>>, String> {
637 let mut args = Vec::new();
638
639 if !self.check(&TokenType::RParen) {
640 args.push(Box::new(self.expression()?));
641
642 while self.match_token(&TokenType::Comma) {
643 args.push(Box::new(self.expression()?));
644 }
645 }
646
647 self.consume(&TokenType::RParen, "Ожидается ')' после списка аргументов")?;
648
649 Ok(args)
650 }
651}
652
653pub fn parse(input: &str) -> Result<AstNode, String> {
654 debug!("Начало разбора файла...");
655
656 let mut lexer = Lexer::new(input);
657 let tokens = match lexer.tokenize() {
658 Ok(tokens) => {
659 info!("Токенизация успешна, получено {} токенов", tokens.len());
660 tokens
661 },
662 Err(e) => {
663 error!("Ошибка токенизации: {}", e);
664 return Err(e);
665 }
666 };
667
668 let mut parser = Parser::new(tokens);
669
670 match parser.parse() {
671 Ok(ast) => {
672 info!("Парсинг успешен");
673 Ok(ast)
674 },
675 Err(e) => {
676 error!("Ошибка парсинга: {}", e);
677 Err(e)
678 }
679 }
680}