From daae12d695d5ae28d34dc608e0e5af39387676e2 Mon Sep 17 00:00:00 2001 From: Hydrostic Date: Fri, 12 Jun 2026 11:38:28 +0800 Subject: [PATCH] fix(ast): SelfInc use wrong way to recognize --- src/ast/parser/expr.rs | 85 +++++++++++++++--------------------------- src/lexer/lexer.rs | 20 +++++++++- src/lexer/types.rs | 3 ++ 3 files changed, 51 insertions(+), 57 deletions(-) diff --git a/src/ast/parser/expr.rs b/src/ast/parser/expr.rs index 326b36f..f7e1c2f 100644 --- a/src/ast/parser/expr.rs +++ b/src/ast/parser/expr.rs @@ -1,14 +1,13 @@ use crate::{ - ast::err::ParseError, - ast::types::{BinaryOp, Expr, ExprValue, IncDecOp, UnaryOp}, + ast::{err::ParseError, types::{BinaryOp, Expr, ExprValue, IncDecOp, UnaryOp}}, diagnostic::span::Span, - lexer::types::TokenValue, + lexer::types::{Token, TokenValue}, }; use super::{ParseProcessError, Parser}; impl Parser { - fn parse_primary_atom(&mut self) -> Result { + fn parse_primary(&mut self) -> Result { let token = self.next().clone(); match token.value { TokenValue::Ident(name) => { @@ -47,13 +46,6 @@ impl Parser { span: Span::from_two(token.span, end_span), }); } - TokenValue::Eof => { - self.diagnostics.add_from_frontend_error( - ParseError::ExpectedBefore(TokenValue::Eof, "`)`"), - token.span, - ); - return Err(ParseProcessError::ErrorInMatch); - } _ => { let token = self.next(); self.diagnostics.add_from_frontend_error( @@ -85,11 +77,6 @@ impl Parser { ..expr }) } - TokenValue::Eof => { - self.diagnostics - .add_from_frontend_error(ParseError::ExpectedBefore(TokenValue::Eof, "`)`"), expr.span); - Err(ParseProcessError::ErrorInMatch) - } _ => { let token = self.next(); self.diagnostics.add_from_frontend_error( @@ -109,8 +96,8 @@ impl Parser { } } } - fn parse_primary(&mut self) -> Result { - let mut expr = self.parse_primary_atom()?; + fn parse_postfix(&mut self) -> Result { + let mut expr = self.parse_primary()?; loop { if self.peek().value == TokenValue::LBracket { let start_span = expr.span; @@ -122,10 +109,6 @@ impl Parser { self.advance(1); span } - TokenValue::Eof => { - self.diagnostics.add_from_frontend_error(ParseError::ExpectedBefore(TokenValue::Eof, "`]`"), index.span); - return Err(ParseProcessError::ErrorInMatch); - } _ => { let token = self.next(); self.diagnostics.add_from_frontend_error( @@ -144,12 +127,12 @@ impl Parser { }; continue; } - let op = match (&self.peek().value, &self.peek_n(1).value) { - (TokenValue::Plus, TokenValue::Plus) => Some(IncDecOp::Inc), - (TokenValue::Minus, TokenValue::Minus) => Some(IncDecOp::Dec), - _ => None, - }; - if let Some(op) = op { + if let TokenValue::PlusPlus | TokenValue::MinusMinus = self.peek().value { + let op = if self.peek().value == TokenValue::PlusPlus { + IncDecOp::Inc + } else { + IncDecOp::Dec + }; let end_span = self.peek_n(1).span; self.advance(2); expr = Expr { @@ -170,19 +153,6 @@ impl Parser { let token = self.peek().clone(); match token.value { TokenValue::Plus => { - if self.peek_n(1).value == TokenValue::Plus { - self.advance(2); - let expr = self.parse_unary()?; - let span = Span::from_two(token.span, expr.span); - return Ok(Expr { - value: ExprValue::IncDec { - op: IncDecOp::Inc, - operand: Box::new(expr), - is_prefix: true, - }, - span, - }); - } self.advance(1); let expr = self.parse_unary()?; let span = Span::from_two(token.span, expr.span); @@ -195,19 +165,6 @@ impl Parser { }) } TokenValue::Minus => { - if self.peek_n(1).value == TokenValue::Minus { - self.advance(2); - let rhs = self.parse_unary()?; - let span = Span::from_two(token.span, rhs.span); - return Ok(Expr { - value: ExprValue::IncDec { - op: IncDecOp::Dec, - operand: Box::new(rhs), - is_prefix: true, - }, - span, - }); - } self.advance(1); let rhs = self.parse_unary()?; let span = Span::from_two(token.span, rhs.span); @@ -231,7 +188,25 @@ impl Parser { span, }) } - _ => self.parse_primary(), + TokenValue::PlusPlus | TokenValue::MinusMinus => { + let op = if token.value == TokenValue::PlusPlus { + IncDecOp::Inc + } else { + IncDecOp::Dec + }; + self.advance(1); + let operand = self.parse_unary()?; + let span = Span::from_two(token.span, operand.span); + Ok(Expr { + value: ExprValue::IncDec { + op, + operand: Box::new(operand), + is_prefix: true, + }, + span, + }) + } + _ => self.parse_postfix(), } } fn parse_multiplicative(&mut self) -> Result { diff --git a/src/lexer/lexer.rs b/src/lexer/lexer.rs index a279a8d..72ce2ad 100644 --- a/src/lexer/lexer.rs +++ b/src/lexer/lexer.rs @@ -269,8 +269,24 @@ fn parse_puncuation( }; let c = str_iter.peek().ok_or(LexParseError::NotMatched)?; let token_value = match c { - '+' => TokenValue::Plus, - '-' => TokenValue::Minus, + '+' => { + str_iter.advance(1); + if let Some('+') = str_iter.peek() { + TokenValue::PlusPlus + } else { + str_iter.back(1); + TokenValue::Plus + } + }, + '-' => { + str_iter.advance(1); + if let Some('-') = str_iter.peek() { + TokenValue::MinusMinus + } else { + str_iter.back(1); + TokenValue::Minus + } + }, '*' => TokenValue::Star, '/' => TokenValue::Slash, '%' => TokenValue::Percent, diff --git a/src/lexer/types.rs b/src/lexer/types.rs index 3e58734..92bf94a 100644 --- a/src/lexer/types.rs +++ b/src/lexer/types.rs @@ -17,6 +17,7 @@ pub enum TokenValue { TypeIdent(TypeIdent), Plus, Minus, Star, Slash, Percent, + PlusPlus, MinusMinus, Equal, DoubleEqual, Not, NotEqual, Less, LessEqual, Greater, GreaterEqual, And, Or, LParen, RParen, @@ -53,6 +54,8 @@ impl std::fmt::Display for TokenValue { TokenValue::TypeIdent(t) => write!(f, "type {}", t.as_ref()), TokenValue::Plus => write!(f, "`+`"), TokenValue::Minus => write!(f, "`-`"), + TokenValue::PlusPlus => write!(f, "`++`"), + TokenValue::MinusMinus => write!(f, "`--`"), TokenValue::Star => write!(f, "`*`"), TokenValue::Slash => write!(f, "`/`"), TokenValue::Percent => write!(f, "`%`"),