Implement parenthesis grouping

This commit is contained in:
Daniel M 2022-01-29 20:51:55 +01:00
parent a9ee8eb66c
commit 128b05b8a8
2 changed files with 23 additions and 4 deletions

View File

@ -7,6 +7,12 @@ pub enum Token {
/// Integer literal (64-bit)
I64(i64),
/// Left Parenthesis ('(')
LParen,
/// Right Parenthesis (')')
RParen,
/// Plus (+)
Add,
@ -99,6 +105,8 @@ impl<'a> Lexer<'a> {
'|' => tokens.push(Token::BOr),
'&' => tokens.push(Token::BAnd),
'^' => tokens.push(Token::BXor),
'(' => tokens.push(Token::LParen),
')' => tokens.push(Token::RParen),
//TODO: Don't panic, keep calm
_ => panic!("Lexer encountered unexpected char: '{}'", ch),

View File

@ -47,12 +47,12 @@ pub enum Ast {
/*
## Grammar
### Expressions
expr_primary = LITERAL
expr_primary = LITERAL | "(" expr ")"
expr_mul = expr_primary (("*" | "/" | "%") expr_primary)*
expr_add = expr_mul (("+" | "-") expr_mul)*
expr_shift = expr_add ((">>" | "<<") expr_add)*
expr_band = expr_shift ("&" expr_shift)*
expr_bxor = expr_band ("^") expr_band)*
expr_bxor = expr_band ("^" expr_band)*
expr_bor = expr_bxor ("|" expr_bxor)*
expr = expr_bor
*/
@ -110,6 +110,17 @@ impl<T: Iterator<Item = Token>> Parser<T> {
match self.next() {
Token::I64(val) => Ast::I64(val),
Token::LParen => {
let inner_expr = self.parse_expr();
// Verify that there is a closing parenthesis
if !matches!(self.next(), Token::RParen) {
panic!("Error parsing primary expr: Exepected closing parenthesis ')'");
}
inner_expr
}
tok => panic!("Error parsing primary expr: Unexpected Token '{:?}'", tok),
}
}
@ -133,9 +144,9 @@ pub fn parse<T: Iterator<Item = Token>, A: IntoIterator<IntoIter = T>>(tokens: A
impl BinOpType {
/// Get the precedence for a binary operator. Higher value means the OP is stronger binding.
/// For example Multiplication is stronger than addition, so Mul has higher precedence than Add.
///
///
/// The operator precedences are derived from the C language operator precedences. While not all
/// C operators are included or the exact same, the precedence oder is the same.
/// C operators are included or the exact same, the precedence oder is the same.
/// See: https://en.cppreference.com/w/c/language/operator_precedence
fn precedence(&self) -> u8 {
match self {