From 40ea6c1f8e39d7debda895f4f32aa7e9d3e8eff2 Mon Sep 17 00:00:00 2001 From: Daniel M Date: Wed, 29 Dec 2021 14:54:25 +0100 Subject: [PATCH] Refactor expr parsing functions --- plang2_lib/src/parser.rs | 127 ++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 76 deletions(-) diff --git a/plang2_lib/src/parser.rs b/plang2_lib/src/parser.rs index d66f4be..87854a0 100644 --- a/plang2_lib/src/parser.rs +++ b/plang2_lib/src/parser.rs @@ -166,22 +166,17 @@ impl Parser { } pub fn parse_expr_or(&mut self) -> PRes { - // Parse the left hand side / the main expression if there is nothing on the right let mut lhs = self.parse_expr_xor()?; - // Parse 0 or more expressions to the right side of the or operators - while matches!(self.curr(), Some(Token::Op(Op::Or))) { - // We successfully matched curr against Some already in the while condition, so unwrap - // is fine - let tok_op = self.advance().unwrap().clone(); + while let Some(Token::Op(optok)) = self.curr() { + let op_type = match optok { + Op::Or => BinOpType::Or, + _ => break + }; + self.advance(); let rhs = self.parse_expr_xor()?; - let op_type = match tok_op { - Token::Op(Op::Or) => BinOpType::Or, - _ => unreachable!(), - }; - lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); } @@ -193,18 +188,15 @@ impl Parser { let mut lhs = self.parse_expr_and()?; // Parse 0 or more expressions to the right side of the xor operators - while matches!(self.curr(), Some(Token::Op(Op::Xor))) { - // We successfully matched curr against Some already in the while condition, so unwrap - // is fine - let tok_op = self.advance().unwrap().clone(); + while let Some(Token::Op(optok)) = self.curr() { + let op_type = match optok { + Op::Xor => BinOpType::Xor, + _ => break + }; + self.advance(); let rhs = self.parse_expr_and()?; - let op_type = match tok_op { - Token::Op(Op::Xor) => BinOpType::Xor, - _ => unreachable!(), - }; - lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); } @@ -216,18 +208,15 @@ impl Parser { let mut lhs = self.parse_expr_equal()?; // Parse 0 or more expressions to the right side of the and operators - while matches!(self.curr(), Some(Token::Op(Op::And))) { - // We successfully matched curr against Some already in the while condition, so unwrap - // is fine - let tok_op = self.advance().unwrap().clone(); + while let Some(Token::Op(optok)) = self.curr() { + let op_type = match optok { + Op::And => BinOpType::And, + _ => break + }; + self.advance(); let rhs = self.parse_expr_equal()?; - let op_type = match tok_op { - Token::Op(Op::And) => BinOpType::And, - _ => unreachable!(), - }; - lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); } @@ -235,23 +224,18 @@ impl Parser { } pub fn parse_expr_equal(&mut self) -> PRes { - // Parse the left hand side / the main expression if there is nothing on the right let mut lhs = self.parse_expr_rel()?; - // Parse 0 or more expressions to the right side of the equality operators - while matches!(self.curr(), Some(Token::Op(Op::Eq | Op::Neq))) { - // We successfully matched curr against Some already in the while condition, so unwrap - // is fine - let tok_op = self.advance().unwrap().clone(); + while let Some(Token::Op(optok)) = self.curr() { + let op_type = match optok { + Op::Eq => BinOpType::Eq, + Op::Neq => BinOpType::Neq, + _ => break + }; + self.advance(); let rhs = self.parse_expr_rel()?; - let op_type = match tok_op { - Token::Op(Op::Eq) => BinOpType::Eq, - Token::Op(Op::Neq) => BinOpType::Neq, - _ => unreachable!(), - }; - lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); } @@ -263,21 +247,18 @@ impl Parser { let mut lhs = self.parse_expr_add()?; // Parse 0 or more expressions to the right side of the relational operators - while matches!(self.curr(), Some(Token::Op(Op::Gt | Op::Lt | Op::Ge | Op::Le))) { - // We successfully matched curr against Some already in the while condition, so unwrap - // is fine - let tok_op = self.advance().unwrap().clone(); + while let Some(Token::Op(optok)) = self.curr() { + let op_type = match optok { + Op::Gt => BinOpType::Gt, + Op::Lt => BinOpType::Lt, + Op::Ge => BinOpType::Ge, + Op::Le => BinOpType::Le, + _ => break + }; + self.advance(); let rhs = self.parse_expr_add()?; - let op_type = match tok_op { - Token::Op(Op::Gt) => BinOpType::Gt, - Token::Op(Op::Lt) => BinOpType::Lt, - Token::Op(Op::Ge) => BinOpType::Ge, - Token::Op(Op::Le) => BinOpType::Le, - _ => unreachable!(), - }; - lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); } @@ -298,19 +279,16 @@ impl Parser { let mut lhs = self.parse_expr_mul()?; // Parse 0 or more expressions to the right side of the add operators - while matches!(self.curr(), Some(Token::Op(Op::Add | Op::Sub))) { - // We successfully matched curr against Some already in the while condition, so unwrap - // is fine - let tok_op = self.advance().unwrap().clone(); + while let Some(Token::Op(optok)) = self.curr() { + let op_type = match optok { + Op::Add => BinOpType::Add, + Op::Sub => BinOpType::Sub, + _ => break + }; + self.advance(); let rhs = self.parse_expr_mul()?; - let op_type = match tok_op { - Token::Op(Op::Add) => BinOpType::Add, - Token::Op(Op::Sub) => BinOpType::Sub, - _ => unreachable!(), - }; - lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); } @@ -327,21 +305,18 @@ impl Parser { // Parse the left hand side / the main expression if there is nothing on the right let mut lhs = self.parse_expr_term()?; - // Parse 0 or more expressions to the right side of the mul operators - while matches!(self.curr(), Some(Token::Op(Op::Mul | Op::Div | Op::Mod))) { - // We successfully matched curr against Some already in the while condition, so unwrap is fine - let tok_op = self.advance().unwrap().clone(); + while let Some(Token::Op(optok)) = self.curr() { + let op_type = match optok { + Op::Mul => BinOpType::Mul, + Op::Div => BinOpType::Div, + Op::Mod => BinOpType::Mod, + _ => break + }; + self.advance(); - let b = self.parse_expr_term()?; + let rhs = self.parse_expr_term()?; - let op_type = match tok_op { - Token::Op(Op::Mul) => BinOpType::Mul, - Token::Op(Op::Div) => BinOpType::Div, - Token::Op(Op::Mod) => BinOpType::Mod, - _ => unreachable!(), - }; - - lhs = Expr::BinOp(op_type, lhs.into(), b.into()); + lhs = Expr::BinOp(op_type, lhs.into(), rhs.into()); } Ok(lhs)