feat: abstract parsing binary operators into a function
This commit is contained in:
parent
cef4459648
commit
ff533c5ae7
@ -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<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
_ => return Err(ParsingError::Unmatched),
|
||||
};
|
||||
|
||||
parse_many(tokens, next_pos, term, 0)
|
||||
}
|
||||
|
||||
fn parse_many<'a>(
|
||||
tokens: &'a Vec<Token>,
|
||||
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)]
|
||||
|
@ -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<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
_ => return Err(ParsingError::Unmatched),
|
||||
};
|
||||
|
||||
parse_many(tokens, next_pos, unary, 0)
|
||||
}
|
||||
|
||||
fn parse_many<'a>(
|
||||
tokens: &'a Vec<Token>,
|
||||
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![".", "?.", "!."])
|
||||
}
|
||||
|
@ -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<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
_ => return Err(ParsingError::Unmatched),
|
||||
};
|
||||
|
||||
parse_many(tokens, next_pos, comparison, 0)
|
||||
}
|
||||
|
||||
fn parse_many<'a>(
|
||||
tokens: &'a Vec<Token>,
|
||||
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)]
|
||||
|
@ -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<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
_ => return Err(ParsingError::Unmatched),
|
||||
};
|
||||
|
||||
parse_many(tokens, next_pos, unary, 0)
|
||||
}
|
||||
|
||||
fn parse_many<'a>(
|
||||
tokens: &'a Vec<Token>,
|
||||
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)]
|
||||
|
@ -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<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
_ => return Err(ParsingError::Unmatched),
|
||||
};
|
||||
|
||||
parse_many(tokens, next_pos, factor, 0)
|
||||
}
|
||||
|
||||
fn parse_many<'a>(
|
||||
tokens: &'a Vec<Token>,
|
||||
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)]
|
||||
|
@ -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<Token>,
|
||||
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<Token>,
|
||||
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),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user