From e54e1b1b27158f1411c87b82a345a24a9f04f334 Mon Sep 17 00:00:00 2001 From: Seymur Bagirov Date: Sun, 5 Jan 2025 04:57:56 +0400 Subject: [PATCH] feat: finish challenge #2 from the book Implementing ternary conditional --- src/ast.rs | 7 +++++++ src/parser.rs | 27 +++++++++++++++++++++++++-- src/token.rs | 2 ++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index c2b97f3..bc994bc 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -2,6 +2,13 @@ use crate::token::{LiteralType, Token}; #[derive(Debug, Clone)] pub enum Expr { + Ternary { + first: Box, + first_op: Token, + second: Box, + second_op: Token, + third: Box, + }, Binary { left: Box, op: Token, diff --git a/src/parser.rs b/src/parser.rs index 988aa4a..b65ba4a 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -28,10 +28,32 @@ impl Parser<'_> { } // 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 { 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 { + 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 { @@ -119,6 +141,7 @@ impl Parser<'_> { } // will not be used for the time being (per the book) + // used for error recovery fn synchronize(&mut self) { use TokenType::*; self.advance(); diff --git a/src/token.rs b/src/token.rs index 92d5751..c674f81 100644 --- a/src/token.rs +++ b/src/token.rs @@ -22,6 +22,8 @@ pub enum TokenType { GreaterEqual, Less, LessEqual, + Question, + Colon, Identifier, String,