feat: finish challenge #2 from the book

Implementing ternary conditional
This commit is contained in:
Seymur Bagirov 2025-01-05 04:57:56 +04:00
parent 8338c360e0
commit e54e1b1b27
3 changed files with 34 additions and 2 deletions

View File

@ -2,6 +2,13 @@ use crate::token::{LiteralType, Token};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Expr { pub enum Expr {
Ternary {
first: Box<Expr>,
first_op: Token,
second: Box<Expr>,
second_op: Token,
third: Box<Expr>,
},
Binary { Binary {
left: Box<Expr>, left: Box<Expr>,
op: Token, op: Token,

View File

@ -28,10 +28,32 @@ impl Parser<'_> {
} }
// Challenge #1. We're writing comma before equality, because it has the lowest precedence // Challenge #1. We're writing comma before equality, because it has the lowest precedence
// comma -> equality ((,) equality)* ; // expression grammar // comma -> equality ("," equality)* ; // expression grammar
fn comma(&mut self) -> Result<Expr, ParseError> { fn comma(&mut self) -> Result<Expr, ParseError> {
use TokenType::*; use TokenType::*;
self.left_association_binary(&[Comma], Parser::equality) self.left_association_binary(&[Comma], Self::ternary)
}
// ternary -> equality ("?" expression : ternary)? // expression grammar
fn ternary(&mut self) -> Result<Expr, ParseError> {
use TokenType::*;
let expr = self.equality()?;
if self.match_token(&[Question]) {
let first_op = self.previous().clone();
let second = self.expression()?;
let second_op = self.consume(Colon, "Expected : after ternary operator ?")?;
let third = self.ternary()?;
return Ok(Expr::Ternary {
first: Box::new(expr),
first_op,
second: Box::new(second),
second_op,
third: Box::new(third),
});
}
Ok(expr)
} }
fn equality(&mut self) -> Result<Expr, ParseError> { fn equality(&mut self) -> Result<Expr, ParseError> {
@ -119,6 +141,7 @@ impl Parser<'_> {
} }
// will not be used for the time being (per the book) // will not be used for the time being (per the book)
// used for error recovery
fn synchronize(&mut self) { fn synchronize(&mut self) {
use TokenType::*; use TokenType::*;
self.advance(); self.advance();

View File

@ -22,6 +22,8 @@ pub enum TokenType {
GreaterEqual, GreaterEqual,
Less, Less,
LessEqual, LessEqual,
Question,
Colon,
Identifier, Identifier,
String, String,