Advertisement
mdgaziur001

expr eval

Apr 4th, 2024
843
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 7.05 KB | None | 0 0
  1. use std::f64::consts::PI;
  2. use std::io;
  3. use std::io::Write;
  4. use std::str::Chars;
  5.  
  6. #[derive(Debug)]
  7. struct Tokenizer<'t> {
  8.    iterator: Chars<'t>,
  9. }
  10.  
  11. impl<'t> Tokenizer<'t> {
  12.     pub fn new(source: &'t str) -> Self {
  13.        Self {
  14.            iterator: source.chars(),
  15.        }
  16.    }
  17.  
  18.    pub fn next_token(&mut self) -> Result<Option<Token>, String> {
  19.        let Some(next) = self.iterator.next() else {
  20.            return Ok(None);
  21.        };
  22.  
  23.        match next {
  24.            '(' => Ok(Some(Token::BrOpen)),
  25.            ')' => Ok(Some(Token::BrClose)),
  26.            '^' => Ok(Some(Token::Op(MathOp::Pow))),
  27.            '+' => Ok(Some(Token::Op(MathOp::Add))),
  28.            '-' => Ok(Some(Token::Op(MathOp::Sub))),
  29.            '*' => Ok(Some(Token::Op(MathOp::Mul))),
  30.            '/' => Ok(Some(Token::Op(MathOp::Div))),
  31.            'π' => Ok(Some(Token::Num(PI))),
  32.            ch if ch.is_ascii_digit() || ch == '.' => {
  33.                let mut num = String::from(ch);
  34.                let mut it2 = self.iterator.clone();
  35.  
  36.                while let Some(next_ch) = it2.next() {
  37.                    if !next_ch.is_ascii_digit() && next_ch != '.' {
  38.                        break;
  39.                    }
  40.  
  41.                    num.push(next_ch);
  42.                    self.iterator.next();
  43.                }
  44.  
  45.                Ok(Some(Token::Num(num.parse().map_err(|e| {
  46.                    format!("Encountered error while parsing number: {e}")
  47.                })?)))
  48.            }
  49.            ' ' => self.next_token(),
  50.            _ => Err("Encountered unexpected character".to_string()),
  51.        }
  52.    }
  53. }
  54.  
  55. /// Parser grammar:
  56. ///
  57. /// ```
  58. /// expr = term;
  59. /// term = factor (("+" | "-") factor)*;
  60. /// factor = power (("*" | "/") power)*;
  61. /// power = unary ("^" unary)*;
  62. /// unary = "-"? (unary | primary);
  63. /// primary = Num | "(" expr ")";
  64. /// ```
  65. #[derive(Debug)]
  66. struct Parser<'ecx> {
  67.     tokenizer: Tokenizer<'ecx>,
  68.    current: Option<Token>,
  69. }
  70.  
  71. impl<'ecx> Parser<'ecx> {
  72.    pub fn new(mut tokenizer: Tokenizer<'ecx>) -> Result<Option<Self>, String> {
  73.         let current = tokenizer.next_token()?;
  74.  
  75.         Ok(Some(Self {
  76.             tokenizer,
  77.             current,
  78.         }))
  79.     }
  80.  
  81.     pub fn parse(&mut self) -> Result<AST, String> {
  82.         self.term()
  83.     }
  84.  
  85.     fn term(&mut self) -> Result<AST, String> {
  86.         let mut expr = self.factor()?;
  87.  
  88.         while self.current == Some(Token::Op(MathOp::Add)) || self.current == Some(Token::Op(MathOp::Sub)) {
  89.             let Token::Op(op) = self.current.unwrap() else {
  90.                 unreachable!()
  91.             };
  92.  
  93.             self.next()?;
  94.             expr = AST::Op(Operation {
  95.                 lhs: Box::new(expr),
  96.                 rhs: Box::new(self.factor()?),
  97.                 op,
  98.             })
  99.         }
  100.  
  101.         Ok(expr)
  102.     }
  103.  
  104.     fn factor(&mut self) -> Result<AST, String> {
  105.         let mut expr = self.power()?;
  106.  
  107.         while self.current == Some(Token::Op(MathOp::Mul)) || self.current == Some(Token::Op(MathOp::Div)) {
  108.             let Token::Op(op) = self.current.unwrap() else {
  109.                 unreachable!()
  110.             };
  111.  
  112.             self.next()?;
  113.             expr = AST::Op(Operation {
  114.                 lhs: Box::new(expr),
  115.                 rhs: Box::new(self.power()?),
  116.                 op,
  117.             })
  118.         }
  119.  
  120.         Ok(expr)
  121.     }
  122.  
  123.     fn power(&mut self) -> Result<AST, String> {
  124.         let mut expr = self.unary()?;
  125.  
  126.         while self.current == Some(Token::Op(MathOp::Pow)) {
  127.             self.next()?;
  128.             expr = AST::Op(Operation {
  129.                 lhs: Box::new(expr),
  130.                 rhs: Box::new(self.unary()?),
  131.                 op: MathOp::Pow,
  132.             })
  133.         }
  134.  
  135.         Ok(expr)
  136.     }
  137.  
  138.     fn unary(&mut self) -> Result<AST, String> {
  139.         if matches!(self.current, Some(Token::Op(MathOp::Sub))) {
  140.             let _ = self.next()?;
  141.  
  142.             let operand = self.unary()?;
  143.             Ok(AST::Neg(Box::new(operand)))
  144.         } else {
  145.             self.primary()
  146.         }
  147.     }
  148.  
  149.     fn primary(&mut self) -> Result<AST, String> {
  150.         match self.current {
  151.             Some(Token::Num(num)) => {
  152.                 self.next()?;
  153.                 Ok(AST::Num(num))
  154.             },
  155.             Some(Token::BrOpen) => {
  156.                 // Consume "("
  157.                 let _ = self.next()?;
  158.  
  159.                 // Parse inner expression
  160.                 let parsed = self.parse();
  161.  
  162.                 // Consume ")"
  163.                 let _ = self.expect(Token::BrClose)?;
  164.  
  165.                 parsed
  166.             }
  167.             Some(_) => Err("Unexpected token".to_string()),
  168.             None => Err("Unexpected EOF".to_string())
  169.         }
  170.     }
  171.  
  172.     fn expect(&mut self, expected: Token) -> Result<Token, String> {
  173.         if !matches!(self.current, Some(_expected)) {
  174.             Err(format!("Expected {expected:?}, found {:?}", self.current))
  175.         } else {
  176.             Ok(self.current.unwrap())
  177.         }
  178.     }
  179.  
  180.     fn next(&mut self) -> Result<Option<Token>, String> {
  181.         self.current = self.tokenizer.next_token()?;
  182.         Ok(self.current)
  183.     }
  184. }
  185.  
  186. #[derive(Debug)]
  187. enum AST {
  188.     Num(f64),
  189.     Op(Operation),
  190.     Neg(Box<AST>),
  191. }
  192.  
  193. #[derive(Debug)]
  194. struct Operation {
  195.     lhs: Box<AST>,
  196.     rhs: Box<AST>,
  197.     op: MathOp,
  198. }
  199.  
  200. #[derive(Debug, Copy, Clone, PartialEq)]
  201. enum Token {
  202.     Num(f64),
  203.     BrOpen,
  204.     BrClose,
  205.     Op(MathOp),
  206. }
  207.  
  208. #[derive(Debug, Copy, Clone, PartialEq)]
  209. enum MathOp {
  210.     Add,
  211.     Sub,
  212.     Mul,
  213.     Div,
  214.     Pow,
  215. }
  216.  
  217. fn eval_ast(ast: &AST) -> Result<f64, String> {
  218.     match ast {
  219.         AST::Num(num) => Ok(*num),
  220.         AST::Op(operation) => {
  221.             let lhs = eval_ast(&operation.lhs)?;
  222.             let rhs = eval_ast(&operation.rhs)?;
  223.  
  224.             Ok(match operation.op {
  225.                 MathOp::Add => lhs + rhs,
  226.                 MathOp::Sub => lhs - rhs,
  227.                 MathOp::Mul => lhs * rhs,
  228.                 MathOp::Div => lhs / rhs,
  229.                 MathOp::Pow => lhs.powf(rhs)
  230.             })
  231.         }
  232.         AST::Neg(expr) => Ok(-eval_ast(expr)?)
  233.     }
  234. }
  235.  
  236. fn process_expr(expr: &str) {
  237.     let tokenizer = Tokenizer::new(&expr);
  238.     let mut parser = match Parser::new(tokenizer) {
  239.         Ok(Some(parser)) => parser,
  240.         Ok(None) => return,
  241.         Err(e) => {
  242.             eprintln!("Err: {e}");
  243.             return;
  244.         }
  245.     };
  246.  
  247.     let ast = match parser.parse() {
  248.         Ok(ast) => ast,
  249.         Err(e) => {
  250.             eprintln!("Err: {e}");
  251.             return;
  252.         }
  253.     };
  254.  
  255.     match eval_ast(&ast) {
  256.         Ok(res) => println!("{res}"),
  257.         Err(e) => {
  258.             eprintln!("Err: {e}");
  259.             return;
  260.         }
  261.     }
  262. }
  263.  
  264. fn take_input() -> String {
  265.     print!("> ");
  266.     io::stdout().flush().unwrap();
  267.     let mut buf = String::new();
  268.     io::stdin().read_line(&mut buf).unwrap();
  269.  
  270.     buf.trim().to_string()
  271. }
  272.  
  273. fn main() {
  274.     loop {
  275.         let input = take_input();
  276.         if input == "q" {
  277.             break;
  278.         }
  279.  
  280.         process_expr(&input);
  281.     }
  282. }
  283.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement