netter_core/language/
parser.rs

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}