use crate::expr::{Assign, Binary, Expr, Grouping, Unary, Variable, Logical}; use crate::expr::Expr::LogicalExpr; use crate::expr::Literal::{LiteralBool, LiteralNumber, LiteralString}; use crate::token::Token; use crate::token_type::TokenType; use crate::stmt::{BlockStatement, ExpressionStatement, PrintStatement, Statement, VarStatement, IfStatement, WhileStatement}; pub struct Parser { tokens: Vec, current: usize } #[derive(Debug)] pub struct ParseError { message: String } impl Parser { pub fn new( t_init: Vec) -> Self { Parser { tokens: t_init, current: 0 } } fn match_token( &mut self, token_type_list: &[TokenType] ) -> bool { for token_type in token_type_list { if self.check(token_type) { self.advance(); return true; } } return false; } fn check(&self, token_type: &TokenType) -> bool { if self.is_at_end() { return false; } return self.peek().token_type==*token_type; } fn advance(&mut self) -> Token { if !self.is_at_end() { self.current += 1; } return self.previous(); } fn is_at_end(&self) -> bool { return self.peek().token_type==TokenType::Eof; } fn peek(&self) -> Token { return self.tokens[self.current].clone(); } fn previous(&self) -> Token { return self.tokens[self.current - 1].clone(); } fn consume(&mut self, token_type: &TokenType, message: String) -> Result { if self.check(token_type) { Ok(self.advance()) } else { Err(ParseError { message }) } } fn synchronise(&mut self) { self.advance(); while !self.is_at_end() { if self.previous().token_type == TokenType::Semicolon { return; } match self.peek().token_type { TokenType::Class => return, TokenType::Fun => return, TokenType::Var => return, TokenType::For => return, TokenType::If => return, TokenType::While => return, TokenType::Print => return, TokenType::Return => return, _ => (), } self.advance(); } } fn expression(&mut self) -> Result { self.assignment() } fn or(&mut self) -> Result { let mut expr = self.and()?; while self.match_token(&[TokenType::Or]) { let operator = self.previous(); let right = self.and()?; expr = Expr::LogicalExpr(Logical{ left: Box::new(expr), operator, right: Box::new(right) }); } Ok(expr) } fn and(&mut self) -> Result { let mut expr = self.equality()?; while self.match_token(&[TokenType::And]) { let operator = self.previous(); let right = self.equality()?; expr = Expr::LogicalExpr(Logical{ left: Box::new(expr), operator, right: Box::new(right) }); } Ok(expr) } fn assignment(&mut self) -> Result { let expr = self.or()?; if self.match_token(&[TokenType::Equal]) { let value = Box::new(self.assignment()?); // l'assignation a une associativité par la droite match expr { Expr::VariableExpr(v) => { Ok( Expr::AssignExpr(Assign { name: v.name, value })) } _ => Err(ParseError { message: String::from("Invalid assignment target") }) } } else { Ok(expr) } } fn equality(&mut self) -> Result { let mut expr: Expr = self.comparison()?; while self.match_token( &[TokenType::BangEqual, TokenType::EqualEqual]) { let operator: Token = self.previous(); let right: Expr = self.comparison()?; expr = Expr::BinaryExpr(Binary{ left: Box::new(expr), operator, right: Box::new(right) }); } Ok(expr) } fn comparison(&mut self) -> Result { let mut expr = self.term()?; while self.match_token(&[TokenType::Greater, TokenType::GreaterEqual, TokenType::Less, TokenType::LessEqual]) { let operator = self.previous(); let right = self.term()?; expr = Expr::BinaryExpr(Binary{ left: Box::new(expr), operator, right: Box::new(right) }); } return Ok(expr); } fn term(&mut self) -> Result { let mut expr = self.factor()?; while self.match_token(&[TokenType::Minus, TokenType::Plus]) { let operator = self.previous(); let right = self.factor()?; expr = Expr::BinaryExpr(Binary{ left: Box::new(expr), operator, right: Box::new(right) }); } return Ok(expr); } fn factor(&mut self) -> Result { let mut expr = self.unary()?; while self.match_token(&[TokenType::Star, TokenType::Slash]) { let operator = self.previous(); let right = self.unary()?; expr = Expr::BinaryExpr(Binary{ left: Box::new(expr), operator, right: Box::new(right) }); } return Ok(expr); } fn unary(&mut self) -> Result { if self.match_token(&[TokenType::Bang, TokenType::Minus]) { let operator = self.previous(); let right = self.unary()?; return Ok(Expr::UnaryExpr(Unary { operator, right: Box::new(right) })); } self.primary() } fn primary(&mut self) -> Result { if self.match_token(&[TokenType::False]) { return Ok(Expr::LiteralExpr(LiteralBool(false))); } if self.match_token(&[TokenType::True]) { return Ok(Expr::LiteralExpr(LiteralBool(true))); } if self.match_token(&[TokenType::Nil]) { return Ok(Expr::LiteralExpr(LiteralBool(false))); } if self.match_token(&[TokenType::Number]) { return Ok(Expr::LiteralExpr(LiteralNumber(self.previous().literal.parse::().unwrap()))); } if self.match_token(&[TokenType::String]) { return Ok(Expr::LiteralExpr(LiteralString(self.previous().literal))); } if self.match_token(&[TokenType::Identifier]) { return Ok(Expr::VariableExpr(Variable { name: self.previous() } )); } if self.match_token(&[TokenType::LeftParen]) { let expr = self.expression()?; self.consume(&TokenType::RightParen, String::from("Expect ')' after expression."))?; return Ok(Expr::GroupingExpr(Grouping { expression: Box::new(expr) })); } else { Err(ParseError { message: String::from("Unexpected token : expression expected.") }) } } fn statement(&mut self) -> Result { if self.match_token(&[TokenType::If]) { return self.if_statement(); } if self.match_token(&[TokenType::Print]) { return self.print_statement(); } if self.match_token(&[TokenType::While]) { return self.while_statement(); } if self.match_token(&[TokenType::LeftBrace]) { return self.block_statement(); } self.expr_statement() } fn block_statement(&mut self) -> Result { let mut statements: Vec = Vec::new(); while !self.check(&TokenType::RightBrace) && !self.is_at_end() { statements.push(self.declaration()?); } self.consume(&TokenType::RightBrace, String::from("Expect '}' after block"))?; Ok(Statement::Block(BlockStatement::new(statements))) } fn print_statement(&mut self) -> Result { match self.expression() { Ok(e) => { self.consume(&TokenType::Semicolon, String::from("; attendu"))?; Ok(Statement::Print(PrintStatement{ expr: e })) } Err(e ) => { Err(e) } } } fn while_statement(&mut self) -> Result { self.consume(&TokenType::LeftParen, String::from("( attendu"))?; let condition = self.expression()?; self.consume(&TokenType::RightParen, String::from(") attendu"))?; let body = self.statement()?; Ok(Statement::While(WhileStatement{ condition, body: Box::new(body) })) } fn if_statement(&mut self) -> Result { self.consume(&TokenType::LeftParen, String::from("( attendu"))?; let expr = self.expression()?; self.consume(&TokenType::RightParen, String::from(") attendu"))?; let then_stmt = self.statement()?; if self.match_token(&[TokenType::Else]) { let else_stmt = self.statement()?; Ok(Statement::If(IfStatement{ expr, statement_then: Box::new(then_stmt), statement_else: Some(Box::new(else_stmt))})) } else { Ok(Statement::If(IfStatement{ expr, statement_then: Box::new(then_stmt), statement_else: None})) } } fn expr_statement(&mut self) -> Result { match self.expression() { Ok(e) => { self.consume(&TokenType::Semicolon, String::from("; attendu"))?; Ok(Statement::Expression(ExpressionStatement{ expr: e })) } Err(e ) => { Err(e) } } } fn declaration(&mut self) -> Result { if self.match_token(&[TokenType::Var]) { self.var_declaration() } else { self.statement() } } fn var_declaration(&mut self) -> Result { let name = self.consume(&TokenType::Identifier, String::from("nom de variable attendu"))?; let mut initializer: Option = None; if self.match_token(&[TokenType::Equal]) { initializer = Some(self.expression()?); } self.consume(&TokenType::Semicolon, String::from("; attendu"))?; Ok(Statement::Var(VarStatement{ token: name, initializer })) } pub fn parse(&mut self) -> Vec { let mut statements= Vec::new(); while !self.is_at_end() { match self.declaration() { Ok(stmt) => statements.push(stmt), Err(_e) => self.synchronise(), } } statements } }