From ff533c5ae74993ea322c1a17070cc8c395ac6134 Mon Sep 17 00:00:00 2001 From: Araozu Date: Sat, 2 Nov 2024 19:44:54 -0500 Subject: [PATCH] feat: abstract parsing binary operators into a function --- src/syntax/parsers/expression/comparison.rs | 30 ++--------------- src/syntax/parsers/expression/dot_access.rs | 36 +++----------------- src/syntax/parsers/expression/equality.rs | 30 ++--------------- src/syntax/parsers/expression/factor.rs | 36 +++----------------- src/syntax/parsers/expression/term.rs | 34 ++----------------- src/syntax/parsers/expression/utils.rs | 37 +++++++++++++++++++-- 6 files changed, 50 insertions(+), 153 deletions(-) diff --git a/src/syntax/parsers/expression/comparison.rs b/src/syntax/parsers/expression/comparison.rs index 5e41e98..dfbd21b 100644 --- a/src/syntax/parsers/expression/comparison.rs +++ b/src/syntax/parsers/expression/comparison.rs @@ -3,7 +3,7 @@ use crate::{ syntax::{ast::Expression, ParsingError, ParsingResult}, }; -use super::utils::try_binary_op; +use super::utils::parse_many; /// Parses a factor expression. /// @@ -16,33 +16,7 @@ pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { _ => return Err(ParsingError::Unmatched), }; - parse_many(tokens, next_pos, term, 0) -} - -fn parse_many<'a>( - tokens: &'a Vec, - pos: usize, - prev_expr: Expression<'a>, - indentation_level: u32, -) -> ParsingResult<'a, Expression<'a>> { - // comparison = term, ((">" | ">=" | "<" | "<="), term)*; - try_binary_op( - tokens, - pos, - prev_expr, - vec![">", ">=", "<", "<="], - indentation_level, - |tokens, next_pos, prev_expr, token, indent_count: u32| match super::term::try_parse( - tokens, next_pos, - ) { - Ok((expr, next_pos)) => { - let expr = Expression::BinaryOperator(Box::new(prev_expr), Box::new(expr), &token); - - parse_many(tokens, next_pos, expr, indentation_level + indent_count) - } - _ => return Err(ParsingError::Unmatched), - }, - ) + parse_many(tokens, next_pos, term, 0, &vec![">", ">=", "<", "<="]) } #[cfg(test)] diff --git a/src/syntax/parsers/expression/dot_access.rs b/src/syntax/parsers/expression/dot_access.rs index 3e0aa99..6090757 100644 --- a/src/syntax/parsers/expression/dot_access.rs +++ b/src/syntax/parsers/expression/dot_access.rs @@ -1,10 +1,10 @@ use crate::{ lexic::token::Token, - syntax::{ - ast::Expression, parsers::expression::utils::try_binary_op, ParsingError, ParsingResult, - }, + syntax::{ast::Expression, ParsingError, ParsingResult}, }; +use super::utils::parse_many; + /// Parses a dot access /// /// ```ebnf @@ -16,33 +16,5 @@ pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { _ => return Err(ParsingError::Unmatched), }; - parse_many(tokens, next_pos, unary, 0) -} - -fn parse_many<'a>( - tokens: &'a Vec, - pos: usize, - prev_expr: Expression<'a>, - indentation_level: u32, -) -> ParsingResult<'a, Expression<'a>> { - // (("/" | "*" | "%"), unary)* - try_binary_op( - tokens, - pos, - prev_expr, - vec!["."], - indentation_level, - |tokens, next_pos, prev_expr, token, indent_count: u32| { - // match next - match super::unary::try_parse(tokens, next_pos) { - Ok((expr, next_pos)) => { - let expr = - Expression::BinaryOperator(Box::new(prev_expr), Box::new(expr), &token); - - parse_many(tokens, next_pos, expr, indentation_level + indent_count) - } - _ => return Err(ParsingError::Unmatched), - } - }, - ) + parse_many(tokens, next_pos, unary, 0, &vec![".", "?.", "!."]) } diff --git a/src/syntax/parsers/expression/equality.rs b/src/syntax/parsers/expression/equality.rs index cd641e4..ba4be6a 100644 --- a/src/syntax/parsers/expression/equality.rs +++ b/src/syntax/parsers/expression/equality.rs @@ -3,7 +3,7 @@ use crate::{ syntax::{ast::Expression, ParsingError, ParsingResult}, }; -use super::utils::try_binary_op; +use super::utils::parse_many; /// Parses a factor expression. /// @@ -16,33 +16,7 @@ pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { _ => return Err(ParsingError::Unmatched), }; - parse_many(tokens, next_pos, comparison, 0) -} - -fn parse_many<'a>( - tokens: &'a Vec, - pos: usize, - prev_expr: Expression<'a>, - indentation_level: u32, -) -> ParsingResult<'a, Expression<'a>> { - // equality = comparison, (("==" | "!="), comparison )*; - try_binary_op( - tokens, - pos, - prev_expr, - vec!["==", "!="], - indentation_level, - |tokens, next_pos, prev_expr, token, indent_count: u32| match super::comparison::try_parse( - tokens, next_pos, - ) { - Ok((expr, next_pos)) => { - let expr = Expression::BinaryOperator(Box::new(prev_expr), Box::new(expr), &token); - - parse_many(tokens, next_pos, expr, indentation_level + indent_count) - } - _ => return Err(ParsingError::Unmatched), - }, - ) + parse_many(tokens, next_pos, comparison, 0, &vec!["==", "!="]) } #[cfg(test)] diff --git a/src/syntax/parsers/expression/factor.rs b/src/syntax/parsers/expression/factor.rs index 6699111..8d752ea 100644 --- a/src/syntax/parsers/expression/factor.rs +++ b/src/syntax/parsers/expression/factor.rs @@ -1,10 +1,10 @@ use crate::{ lexic::token::Token, - syntax::{ - ast::Expression, parsers::expression::utils::try_binary_op, ParsingError, ParsingResult, - }, + syntax::{ast::Expression, ParsingError, ParsingResult}, }; +use super::utils::parse_many; + /// Parses a factor expression. /// /// ```ebnf @@ -16,35 +16,7 @@ pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { _ => return Err(ParsingError::Unmatched), }; - parse_many(tokens, next_pos, unary, 0) -} - -fn parse_many<'a>( - tokens: &'a Vec, - pos: usize, - prev_expr: Expression<'a>, - indentation_level: u32, -) -> ParsingResult<'a, Expression<'a>> { - // (("/" | "*" | "%"), unary)* - try_binary_op( - tokens, - pos, - prev_expr, - vec!["/", "*", "%"], - indentation_level, - |tokens, next_pos, prev_expr, token, indent_count: u32| { - // match next - match super::unary::try_parse(tokens, next_pos) { - Ok((expr, next_pos)) => { - let expr = - Expression::BinaryOperator(Box::new(prev_expr), Box::new(expr), &token); - - parse_many(tokens, next_pos, expr, indentation_level + indent_count) - } - _ => return Err(ParsingError::Unmatched), - } - }, - ) + parse_many(tokens, next_pos, unary, 0, &vec!["/", "*", "%"]) } #[cfg(test)] diff --git a/src/syntax/parsers/expression/term.rs b/src/syntax/parsers/expression/term.rs index 51673ad..fa7fe0a 100644 --- a/src/syntax/parsers/expression/term.rs +++ b/src/syntax/parsers/expression/term.rs @@ -1,9 +1,10 @@ -use crate::syntax::parsers::expression::utils::try_binary_op; use crate::{ lexic::token::Token, syntax::{ast::Expression, ParsingError, ParsingResult}, }; +use super::utils::parse_many; + /// Parses a factor expression. /// /// ```ebnf @@ -15,36 +16,7 @@ pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { _ => return Err(ParsingError::Unmatched), }; - parse_many(tokens, next_pos, factor, 0) -} - -fn parse_many<'a>( - tokens: &'a Vec, - pos: usize, - prev_expr: Expression<'a>, - indentation_level: u32, -) -> ParsingResult<'a, Expression<'a>> { - // term = factor, (("-" | "+" | "++"), factor)*; - - try_binary_op( - tokens, - pos, - prev_expr, - vec!["+", "-", "++"], - indentation_level, - |tokens, pos, prev_expr, token, indent_count: u32| { - // Parse the next factor - match super::factor::try_parse(tokens, pos) { - Ok((expr, next_pos)) => { - let expr = - Expression::BinaryOperator(Box::new(prev_expr), Box::new(expr), &token); - - parse_many(tokens, next_pos, expr, indentation_level + indent_count) - } - _ => return Err(ParsingError::Unmatched), - } - }, - ) + parse_many(tokens, next_pos, factor, 0, &vec!["-", "+", "++"]) } #[cfg(test)] diff --git a/src/syntax/parsers/expression/utils.rs b/src/syntax/parsers/expression/utils.rs index 0cb5f80..2295dfb 100644 --- a/src/syntax/parsers/expression/utils.rs +++ b/src/syntax/parsers/expression/utils.rs @@ -1,7 +1,7 @@ use crate::lexic::token::Token; use crate::lexic::token::TokenType::{NewLine, DEDENT, INDENT}; use crate::syntax::ast::Expression; -use crate::syntax::parseable::ParsingResult; +use crate::syntax::parseable::{ParsingError, ParsingResult}; /// Parses a binary operator, handles indentation and runs a function on it. /// @@ -15,7 +15,7 @@ pub fn try_binary_op<'a, F>( tokens: &'a Vec, original_pos: usize, prev_expr: Expression<'a>, - operators: Vec<&str>, + operators: &Vec<&str>, indentation_level: u32, fun: F, ) -> ParsingResult<'a, Expression<'a>> @@ -87,3 +87,36 @@ where Ok((new_expr, next_pos)) } + +pub fn parse_many<'a>( + tokens: &'a Vec, + pos: usize, + prev_expr: Expression<'a>, + indentation_level: u32, + operators: &Vec<&str>, +) -> ParsingResult<'a, Expression<'a>> { + // comparison = term, ((">" | ">=" | "<" | "<="), term)*; + try_binary_op( + tokens, + pos, + prev_expr, + operators, + indentation_level, + |tokens, next_pos, prev_expr, token, indent_count: u32| match super::term::try_parse( + tokens, next_pos, + ) { + Ok((expr, next_pos)) => { + let expr = Expression::BinaryOperator(Box::new(prev_expr), Box::new(expr), &token); + + parse_many( + tokens, + next_pos, + expr, + indentation_level + indent_count, + operators, + ) + } + _ => return Err(ParsingError::Unmatched), + }, + ) +}