Parse binary / *

master
Araozu 2023-11-21 21:29:55 -05:00
parent a54abcc394
commit d4a633f7c0
3 changed files with 41 additions and 3 deletions

View File

@ -19,6 +19,7 @@
- Parse block of code - Parse block of code
- Parse multiple statements inside a block - Parse multiple statements inside a block
- Parse unary operator (`!` & `-`) - Parse unary operator (`!` & `-`)
- Parse binary operators `/`, `*`
## v0.0.7 ## v0.0.7

View File

@ -3,6 +3,42 @@ use crate::{
syntax::{ast::Expression, ParseResult}, syntax::{ast::Expression, ParseResult},
}; };
/// Parses a factor expression.
///
/// ```ebnf
/// factor = unary, (("/" | "*"), unary)*;
/// ```
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> { pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
return super::unary::try_parse(tokens, pos); let (unary, next_pos) = match super::unary::try_parse(tokens, pos) {
ParseResult::Ok(expr, next_pos) => (expr, next_pos),
_ => return ParseResult::Unmatched,
};
parse_many(tokens, next_pos, unary)
}
fn parse_many(
tokens: &Vec<Token>,
pos: usize,
prev_expr: Expression,
) -> ParseResult<Expression, ()> {
// (("/" | "*"), unary)*
match tokens.get(pos) {
Some(token) if token.value == "/" || token.value == "*" => {
match super::unary::try_parse(tokens, pos + 1) {
ParseResult::Ok(expr, next_pos) => {
let expr = Expression::BinaryOperator(
Box::new(prev_expr),
Box::new(expr),
Box::new(token.value.clone()),
);
parse_many(tokens, next_pos, expr)
}
_ => ParseResult::Unmatched,
}
}
_ => ParseResult::Ok(prev_expr, pos),
}
} }

View File

@ -7,7 +7,7 @@ use crate::{
/// ///
/// ```ebnf /// ```ebnf
/// unary = ("!" | "-"), expression /// unary = ("!" | "-"), expression
/// | primary; /// | primary;
/// ``` /// ```
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> { pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
match tokens.get(pos) { match tokens.get(pos) {
@ -20,6 +20,7 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()>
_ => ParseResult::Unmatched, _ => ParseResult::Unmatched,
} }
} }
_ => return primary::try_parse(tokens, pos), _ => primary::try_parse(tokens, pos),
} }
} }