Add test for parser

This commit is contained in:
Daniel M 2022-01-02 21:28:36 +01:00
parent 541d905551
commit ef4dee98dc
2 changed files with 41 additions and 4 deletions

View File

@ -111,6 +111,6 @@ mod tests {
]; ];
let actual = lex(code); let actual = lex(code);
assert_eq!(&expected, &actual); assert_eq!(expected, actual);
} }
} }

View File

@ -2,7 +2,8 @@ use std::iter::Peekable;
use crate::lexer::Token; use crate::lexer::Token;
#[derive(Debug)] /// Types for binary operators
#[derive(Debug, PartialEq, Eq)]
pub enum BinOpType { pub enum BinOpType {
/// Addition /// Addition
Add, Add,
@ -11,7 +12,7 @@ pub enum BinOpType {
Mul, Mul,
} }
#[derive(Debug)] #[derive(Debug, PartialEq, Eq)]
pub enum Ast { pub enum Ast {
/// Integer literal (64-bit) /// Integer literal (64-bit)
I64(i64), I64(i64),
@ -39,13 +40,14 @@ impl<T: Iterator<Item = Token>> Parser<T> {
self.parse_expr_precedence(lhs, 0) self.parse_expr_precedence(lhs, 0)
} }
/// Parse binary expressions with a precedence equal to or higher than min_prec
fn parse_expr_precedence(&mut self, mut lhs: Ast, min_prec: u8) -> Ast { fn parse_expr_precedence(&mut self, mut lhs: Ast, min_prec: u8) -> Ast {
while let Some(binop) = &self.peek().try_to_binop() { while let Some(binop) = &self.peek().try_to_binop() {
if !(binop.precedence() >= min_prec) { if !(binop.precedence() >= min_prec) {
break; break;
} }
// The while condition already verified that this is some while peeking, so unwrap is // The while condition already verified that this is some while peeking, so unwrap is
// valid // valid
let binop = self.next().try_to_binop().unwrap(); let binop = self.next().try_to_binop().unwrap();
@ -100,3 +102,38 @@ impl BinOpType {
} }
} }
} }
#[cfg(test)]
mod tests {
use super::{parse, Ast, BinOpType};
use crate::lexer::Token;
#[test]
fn test_parser() {
// Expression: 1 + 2 * 3 + 4
// With precedence: (1 + (2 * 3)) + 4
let tokens = [
Token::I64(1),
Token::Add,
Token::I64(2),
Token::Mul,
Token::I64(3),
Token::Add,
Token::I64(4),
];
let expected = Ast::BinOp(
BinOpType::Add,
Ast::BinOp(
BinOpType::Add,
Ast::I64(1).into(),
Ast::BinOp(BinOpType::Mul, Ast::I64(2).into(), Ast::I64(3).into()).into(),
)
.into(),
Ast::I64(4).into(),
);
let actual = parse(tokens);
assert_eq!(expected, actual);
}
}