From 3cc81812e692063fe7522b8e0ac42231d831997e Mon Sep 17 00:00:00 2001 From: Yandrik Date: Mon, 29 Nov 2021 23:22:35 +0100 Subject: [PATCH] feat: completed parser --- src/lib.rs | 4 +-- src/main.rs | 8 ++---- src/parser/mod.rs | 70 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b0a77fc..88d2720 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,6 @@ pub mod lexer; pub mod errors; mod parser; -pub fn test() { - println!("{}", "hi there"); +pub fn calculate(expression: &str) -> Result { + Ok(parser::parse(lexer::Lexer::new(expression))?) } diff --git a/src/main.rs b/src/main.rs index 06d5ee1..a49b4bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,7 @@ use s5_cb_calculator::lexer::Lexer; fn main() { - let mut lexer = Lexer::new("15+(30^2-5)*2/4".chars().collect()); - while let Ok(Some(token)) = lexer.next() { - println!("Token: {:?}", token) - } - println!("Hello, world!"); + println!("Hi there! Welcome to OverComplicatedCalculator v1.0!"); + println!("To have OCC calculate something, just type it in!"); + } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 7ba9655..98ff27d 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -7,7 +7,7 @@ use crate::lexer::tokens; use crate::parser::errors::ParserErrors; use crate::parser::errors::ParserErrors::UnexpectedTokenError; -mod errors; +pub mod errors; type Result = result::Result; @@ -47,6 +47,7 @@ pub fn parse(mut lexer: lexer::Lexer) -> Result { } pub fn s_proc(tbox: &mut TokenBox) -> Result { + println!("Proc S"); let mut result = a_proc(tbox)?; match tbox.read_token()? { None => Ok(result), @@ -55,35 +56,48 @@ pub fn s_proc(tbox: &mut TokenBox) -> Result { } fn a_proc(tbox: &mut TokenBox) -> Result { + println!("Proc A"); let mut result = m_proc(tbox)?; match &tbox.read_token()? { Some(Token::OP(_, OpType::ADD)) => Ok(result + a_proc(tbox)?), Some(Token::OP(_, OpType::SUB)) => Ok(result - a_proc(tbox)?), None => Ok(result), - Some(token) => Err(ParserErrors::UnexpectedTokenError(token.clone(), String::from("A"))) + Some(token) => { + tbox.regress(); + Ok(result) + }, } } fn m_proc(tbox: &mut TokenBox) -> Result { + println!("Proc M"); let mut result = g_proc(tbox)?; match &tbox.read_token()? { Some(Token::OP(_, OpType::MUL)) => Ok(result * m_proc(tbox)?), Some(Token::OP(_, OpType::DIV)) => Ok(result / m_proc(tbox)?), None => Ok(result), - Some(token) => Err(UnexpectedTokenError(token.clone(), String::from("M"))), + Some(token) => { + tbox.regress(); + Ok(result) + }, } } fn g_proc(tbox: &mut TokenBox) -> Result { + println!("Proc G"); let mut result = p_proc(tbox)?; match tbox.read_token()? { Some(Token::OP(_, OpType::POW)) => Ok(result.powf(g_proc(tbox)?)), None => Ok(result), - Some(token) => Err(UnexpectedTokenError(token.clone(), String::from("G"))), + Some(token) => { + tbox.regress(); + Ok(result) + }, } } fn p_proc(tbox: &mut TokenBox) -> Result { + println!("Proc P"); match expect_token(tbox.read_token()?)? { Token::OBR(_) => { let result = a_proc(tbox)?; @@ -103,9 +117,53 @@ mod test { #[test] fn simple_formula() -> Result<()> { - let res = parse(lexer::Lexer::new("15+3"))?; + let res = parse(lexer::Lexer::new("15+3-5*2"))?; println!("res: {}", res); - assert_eq!(res, 18.0); + assert_eq!(res, 8.0); Ok(()) } + + #[test] + fn skript_formula_1() -> Result<()> { + let res = parse(lexer::Lexer::new("2+5/3*2"))?; + assert_eq!(res, 5.3333333); + Ok(()) + } + + #[test] + fn skript_formula_2() -> Result<()> { + let res = parse(lexer::Lexer::new("(2+5)/3"))?; + assert_eq!(res, 2.3333333333333335); + Ok(()) + } + + #[test] + fn skript_formula_3() -> Result<()> { + let res = parse(lexer::Lexer::new("((10-213)*25)+27"))?; + assert_eq!(res, -5048.0); + Ok(()) + } + + #[test] + fn skript_formula_4() -> Result<()> { + let res = parse(lexer::Lexer::new("(7-3)*4^3"))?; + assert_eq!(res, 256.0); + Ok(()) + } + + #[test] + fn skript_error_1() { + assert!(matches!( + parse(lexer::Lexer::new("((1+1)*1-2")), + Err(ParserErrors::MissingTokenError) + )) + } + + #[test] + fn skript_error_2() { + assert!(matches!( + parse(lexer::Lexer::new("a+1*3")), + Err(ParserErrors::LexerError(lexer::errors::LexerErrors::InvalidTokenError { token: _, pos: _ })) + )) + } }