fix(parser): Logic expression (and/or) priority

This commit is contained in:
2026-05-14 19:55:08 +08:00
parent 9a6d11a6a8
commit 5afeeae562
+31 -3
View File
@@ -877,12 +877,11 @@ impl Parser {
}
Ok(left)
}
fn parse_logical(&mut self) -> Result<Expr, ParseProcessError> {
fn parse_logical_and(&mut self) -> Result<Expr, ParseProcessError> {
assert!(self.peek().is_some());
let mut left = self.parse_relational()?;
while let Some(t) = self.peek() {
let op = match t.value {
TokenValue::Or => BinaryOp::Or,
TokenValue::And => BinaryOp::And,
_ => break,
};
@@ -907,6 +906,35 @@ impl Parser {
}
Ok(left)
}
fn parse_logical_or(&mut self) -> Result<Expr, ParseProcessError> {
assert!(self.peek().is_some());
let mut left = self.parse_logical_and()?;
while let Some(t) = self.peek() {
let op = match t.value {
TokenValue::Or => BinaryOp::Or,
_ => break,
};
self.advance(1);
let right = match self.peek() {
Some(_) => self.parse_logical_and()?,
None => {
self.diagnostics
.add_from_frontend_error(ParseError::ExpectButEof("expression"), left.span);
return Err(ParseProcessError::ErrorInMatch);
}
};
let span = Span::from_two(left.span, right.span);
left = Expr {
value: ExprValue::BinaryOp {
lhs: Box::new(left),
op,
rhs: Box::new(right),
},
span,
};
}
Ok(left)
}
fn parse_assign(&mut self) -> Result<Expr, ParseProcessError> {
assert!(self.peek().is_some());
let is_assign = matches!(
@@ -923,7 +951,7 @@ impl Parser {
)
);
if !is_assign {
return self.parse_logical();
return self.parse_logical_or();
}
let lvalue_token = self.next().unwrap().clone();