Parse binary operators

This commit is contained in:
Araozu 2023-11-21 21:40:11 -05:00
parent d4a633f7c0
commit dcffe062a1
4 changed files with 117 additions and 4 deletions

View File

@ -19,7 +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 `/`, `*` - Parse binary operators
## v0.0.7 ## v0.0.7

View File

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

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

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