From cef44596480a286364b66a1f41613f0b39e6496e Mon Sep 17 00:00:00 2001 From: Araozu Date: Fri, 1 Nov 2024 19:24:46 -0500 Subject: [PATCH] feat: parse dot operator --- src/syntax/parsers/expression/dot_access.rs | 48 +++++++++++++++++++++ src/syntax/parsers/expression/factor.rs | 4 +- src/syntax/parsers/expression/mod.rs | 1 + 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 src/syntax/parsers/expression/dot_access.rs diff --git a/src/syntax/parsers/expression/dot_access.rs b/src/syntax/parsers/expression/dot_access.rs new file mode 100644 index 0000000..3e0aa99 --- /dev/null +++ b/src/syntax/parsers/expression/dot_access.rs @@ -0,0 +1,48 @@ +use crate::{ + lexic::token::Token, + syntax::{ + ast::Expression, parsers::expression::utils::try_binary_op, ParsingError, ParsingResult, + }, +}; + +/// Parses a dot access +/// +/// ```ebnf +/// dot_access = unary, (("."), unary)*; +/// ``` +pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { + let (unary, next_pos) = match super::unary::try_parse(tokens, pos) { + Ok((expr, next_pos)) => (expr, next_pos), + _ => 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), + } + }, + ) +} diff --git a/src/syntax/parsers/expression/factor.rs b/src/syntax/parsers/expression/factor.rs index f610248..6699111 100644 --- a/src/syntax/parsers/expression/factor.rs +++ b/src/syntax/parsers/expression/factor.rs @@ -8,10 +8,10 @@ use crate::{ /// Parses a factor expression. /// /// ```ebnf -/// factor = unary, (("/" | "*" | "%"), unary)*; +/// factor = dot_access, (("/" | "*" | "%"), dot_access)*; /// ``` pub fn try_parse(tokens: &Vec, pos: usize) -> ParsingResult { - let (unary, next_pos) = match super::unary::try_parse(tokens, pos) { + let (unary, next_pos) = match super::dot_access::try_parse(tokens, pos) { Ok((expr, next_pos)) => (expr, next_pos), _ => return Err(ParsingError::Unmatched), }; diff --git a/src/syntax/parsers/expression/mod.rs b/src/syntax/parsers/expression/mod.rs index 1e807b5..0667e86 100644 --- a/src/syntax/parsers/expression/mod.rs +++ b/src/syntax/parsers/expression/mod.rs @@ -3,6 +3,7 @@ use crate::{lexic::token::Token, syntax::parseable::Parseable}; mod array; mod comparison; +mod dot_access; mod equality; mod factor; pub mod function_call_expr;