feat(parser): add parser

added a basic ast parser that is likely riddled with bugs
This commit is contained in:
ozzy committed 2026-09-25 20:29:43 -05:00
1 parent 26e85652af
commit 66da876e2a
4 files changed
+179 -4

No files matched your search

+169
View File
@@ -0,0 +1,169 @@
use crate::math::{
lexer::Token,
types::{Expression, Operator},
};
pub fn from(tokens: Vec<Token>) -> Parser {
Parser::new(tokens)
}
pub struct Parser {
tokens: Vec<Token>,
position: usize,
}
impl Parser {
pub fn new(tokens: Vec<Token>) -> Self {
Self {
tokens,
position: 0,
}
}
pub fn parse(&mut self) -> Expression {
self.parse_additive()
}
fn parse_additive(&mut self) -> Expression {
let mut left = self.parse_multiplicative();
while let Some(token) = self.tokens.get(self.position) {
match token {
Token::Operator(Operator::Add) => {
self.position += 1;
let right = self.parse_multiplicative();
left = Expression::Operation(Operator::Add, Box::new(left), Box::new(right));
}
Token::Operator(Operator::Subtract) => {
self.position += 1;
let right = self.parse_multiplicative();
left =
Expression::Operation(Operator::Subtract, Box::new(left), Box::new(right));
}
_ => break,
}
}
left
}
fn parse_multiplicative(&mut self) -> Expression {
let mut left = self.parse_primary();
while let Some(token) = self.tokens.get(self.position) {
match token {
Token::Operator(Operator::Multiply) => {
self.position += 1;
let right = self.parse_exponential();
left =
Expression::Operation(Operator::Multiply, Box::new(left), Box::new(right));
}
Token::Operator(Operator::Divide) => {
self.position += 1;
let right = self.parse_exponential();
left = Expression::Fraction(Box::new(left), Box::new(right));
}
Token::Operator(Operator::Modulo) => {
self.position += 1;
let right = self.parse_exponential();
left = Expression::Operation(Operator::Modulo, Box::new(left), Box::new(right));
}
Token::OpenParen => {
self.position += 1;
let right = self.parse_group();
left =
Expression::Operation(Operator::Multiply, Box::new(left), Box::new(right));
self.position += 1;
}
Token::Identifier(_) => {
let right = self.parse_primary();
left =
Expression::Operation(Operator::Multiply, Box::new(left), Box::new(right));
}
_ => break,
}
}
left
}
fn parse_exponential(&mut self) -> Expression {
let mut left = self.parse_primary();
while let Some(token) = self.tokens.get(self.position) {
match token {
Token::Operator(Operator::Power) => {
self.position += 1;
let right = self.parse_group();
left =
Expression::Operation(Operator::Multiply, Box::new(left), Box::new(right));
}
_ => break,
}
}
left
}
fn parse_group(&mut self) -> Expression {
match self.tokens.get(self.position).expect("expected token!") {
Token::OpenParen => {
self.position += 1;
self.parse_additive()
}
_ => self.parse_primary(),
}
}
fn parse_primary(&mut self) -> Expression {
let token = self
.tokens
.get(self.position)
.cloned()
.expect("expected token!");
match token {
Token::Number(num) => {
self.position += 1;
Expression::Number(num)
}
Token::Identifier(identifier) => {
let is_function =
matches!(self.tokens.get(self.position + 1), Some(Token::OpenParen));
if is_function {
self.position += 2;
let params = self.parse_function_params();
Expression::Function(identifier, params)
} else {
self.position += 1;
Expression::Variable(identifier)
}
}
_ => {
panic!("unexpected token! {:?}", token);
}
}
}
fn parse_function_params(&mut self) -> Vec<Expression> {
let mut params: Vec<Expression> = Vec::new();
while let Some(token) = self.tokens.get(self.position) {
match token {
Token::Comma => {
self.position += 1;
}
Token::CloseParen => {
self.position += 1;
break;
}
_ => {
let expression = self.parse_additive();
params.push(expression);
}
}
}
params
}
}