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},
|
syntax::{ast::Expression, ParsingError, ParsingResult},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::utils::try_binary_op;
|
use super::utils::parse_many;
|
||||||
|
|
||||||
/// Parses a factor expression.
|
/// Parses a factor expression.
|
||||||
///
|
///
|
||||||
@ -16,33 +16,7 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
|||||||
_ => return Err(ParsingError::Unmatched),
|
_ => return Err(ParsingError::Unmatched),
|
||||||
};
|
};
|
||||||
|
|
||||||
parse_many(tokens, next_pos, term, 0)
|
parse_many(tokens, next_pos, term, 0, &vec![">", ">=", "<", "<="])
|
||||||
}
|
|
||||||
|
|
||||||
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),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
lexic::token::Token,
|
lexic::token::Token,
|
||||||
syntax::{
|
syntax::{ast::Expression, ParsingError, ParsingResult},
|
||||||
ast::Expression, parsers::expression::utils::try_binary_op, ParsingError, ParsingResult,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::utils::parse_many;
|
||||||
|
|
||||||
/// Parses a dot access
|
/// Parses a dot access
|
||||||
///
|
///
|
||||||
/// ```ebnf
|
/// ```ebnf
|
||||||
@ -16,33 +16,5 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
|||||||
_ => return Err(ParsingError::Unmatched),
|
_ => return Err(ParsingError::Unmatched),
|
||||||
};
|
};
|
||||||
|
|
||||||
parse_many(tokens, next_pos, unary, 0)
|
parse_many(tokens, next_pos, unary, 0, &vec![".", "?.", "!."])
|
||||||
}
|
|
||||||
|
|
||||||
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),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use crate::{
|
|||||||
syntax::{ast::Expression, ParsingError, ParsingResult},
|
syntax::{ast::Expression, ParsingError, ParsingResult},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::utils::try_binary_op;
|
use super::utils::parse_many;
|
||||||
|
|
||||||
/// Parses a factor expression.
|
/// Parses a factor expression.
|
||||||
///
|
///
|
||||||
@ -16,33 +16,7 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
|||||||
_ => return Err(ParsingError::Unmatched),
|
_ => return Err(ParsingError::Unmatched),
|
||||||
};
|
};
|
||||||
|
|
||||||
parse_many(tokens, next_pos, comparison, 0)
|
parse_many(tokens, next_pos, comparison, 0, &vec!["==", "!="])
|
||||||
}
|
|
||||||
|
|
||||||
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),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
lexic::token::Token,
|
lexic::token::Token,
|
||||||
syntax::{
|
syntax::{ast::Expression, ParsingError, ParsingResult},
|
||||||
ast::Expression, parsers::expression::utils::try_binary_op, ParsingError, ParsingResult,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::utils::parse_many;
|
||||||
|
|
||||||
/// Parses a factor expression.
|
/// Parses a factor expression.
|
||||||
///
|
///
|
||||||
/// ```ebnf
|
/// ```ebnf
|
||||||
@ -16,35 +16,7 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
|||||||
_ => return Err(ParsingError::Unmatched),
|
_ => return Err(ParsingError::Unmatched),
|
||||||
};
|
};
|
||||||
|
|
||||||
parse_many(tokens, next_pos, unary, 0)
|
parse_many(tokens, next_pos, unary, 0, &vec!["/", "*", "%"])
|
||||||
}
|
|
||||||
|
|
||||||
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),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
use crate::syntax::parsers::expression::utils::try_binary_op;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
lexic::token::Token,
|
lexic::token::Token,
|
||||||
syntax::{ast::Expression, ParsingError, ParsingResult},
|
syntax::{ast::Expression, ParsingError, ParsingResult},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::utils::parse_many;
|
||||||
|
|
||||||
/// Parses a factor expression.
|
/// Parses a factor expression.
|
||||||
///
|
///
|
||||||
/// ```ebnf
|
/// ```ebnf
|
||||||
@ -15,36 +16,7 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
|||||||
_ => return Err(ParsingError::Unmatched),
|
_ => return Err(ParsingError::Unmatched),
|
||||||
};
|
};
|
||||||
|
|
||||||
parse_many(tokens, next_pos, factor, 0)
|
parse_many(tokens, next_pos, factor, 0, &vec!["-", "+", "++"])
|
||||||
}
|
|
||||||
|
|
||||||
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),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::lexic::token::Token;
|
use crate::lexic::token::Token;
|
||||||
use crate::lexic::token::TokenType::{NewLine, DEDENT, INDENT};
|
use crate::lexic::token::TokenType::{NewLine, DEDENT, INDENT};
|
||||||
use crate::syntax::ast::Expression;
|
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.
|
/// 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>,
|
tokens: &'a Vec<Token>,
|
||||||
original_pos: usize,
|
original_pos: usize,
|
||||||
prev_expr: Expression<'a>,
|
prev_expr: Expression<'a>,
|
||||||
operators: Vec<&str>,
|
operators: &Vec<&str>,
|
||||||
indentation_level: u32,
|
indentation_level: u32,
|
||||||
fun: F,
|
fun: F,
|
||||||
) -> ParsingResult<'a, Expression<'a>>
|
) -> ParsingResult<'a, Expression<'a>>
|
||||||
@ -87,3 +87,36 @@ where
|
|||||||
|
|
||||||
Ok((new_expr, next_pos))
|
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