fix(ast): SelfInc use wrong way to recognize

This commit is contained in:
2026-06-12 11:38:28 +08:00
parent ef3dcb41aa
commit daae12d695
3 changed files with 51 additions and 57 deletions
+29 -54
View File
@@ -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<Expr, ParseProcessError> {
fn parse_primary(&mut self) -> Result<Expr, ParseProcessError> {
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<Expr, ParseProcessError> {
let mut expr = self.parse_primary_atom()?;
fn parse_postfix(&mut self) -> Result<Expr, ParseProcessError> {
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 TokenValue::PlusPlus | TokenValue::MinusMinus = self.peek().value {
let op = if self.peek().value == TokenValue::PlusPlus {
IncDecOp::Inc
} else {
IncDecOp::Dec
};
if let Some(op) = op {
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<Expr, ParseProcessError> {
+18 -2
View File
@@ -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,
+3
View File
@@ -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, "`%`"),