修复右结合绑定力错误

This commit is contained in:
2026-02-17 14:03:48 +08:00
parent 878157c2fc
commit 6b75e028ff
3 changed files with 26 additions and 22 deletions

View File

@@ -51,7 +51,7 @@ namespace Fig
{TokenType::PercentEqual, BinaryOperator::ModuloAssign}, {TokenType::PercentEqual, BinaryOperator::ModuloAssign},
{TokenType::CaretEqual, BinaryOperator::BitXorAssign}, {TokenType::CaretEqual, BinaryOperator::BitXorAssign},
{TokenType::Pipe, BinaryOperator::BitAnd}, {TokenType::Pipe, BinaryOperator::BitOr},
{TokenType::Ampersand, BinaryOperator::BitAnd}, {TokenType::Ampersand, BinaryOperator::BitAnd},
{TokenType::ShiftLeft, BinaryOperator::ShiftLeft}, {TokenType::ShiftLeft, BinaryOperator::ShiftLeft},
{TokenType::ShiftRight, BinaryOperator::ShiftRight}, {TokenType::ShiftRight, BinaryOperator::ShiftRight},
@@ -137,22 +137,21 @@ namespace Fig
BindingPower GetBinaryOpRBp(BinaryOperator op) BindingPower GetBinaryOpRBp(BinaryOperator op)
{ {
/*
右结合,左绑定力 >= 右
a = b = c
a = (b = c)
a.b.c
*/
switch (op) switch (op)
{ {
case BinaryOperator::Assign: return GetBinaryOpLBp(op); /*
case BinaryOperator::AddAssign: return GetBinaryOpLBp(op); 右结合,左绑定力 >= 右
case BinaryOperator::SubAssign: return GetBinaryOpLBp(op); a = b = c
case BinaryOperator::MultiplyAssign: return GetBinaryOpLBp(op); a = (b = c)
case BinaryOperator::DivideAssign: return GetBinaryOpLBp(op); */
case BinaryOperator::ModuloAssign: return GetBinaryOpLBp(op); case BinaryOperator::Assign:
case BinaryOperator::BitXorAssign: return GetBinaryOpLBp(op); case BinaryOperator::AddAssign:
case BinaryOperator::Power: return GetBinaryOpLBp(op); case BinaryOperator::SubAssign:
case BinaryOperator::MultiplyAssign:
case BinaryOperator::DivideAssign:
case BinaryOperator::ModuloAssign:
case BinaryOperator::BitXorAssign:
case BinaryOperator::Power: return GetBinaryOpLBp(op) - 1;
default: default:
/* /*

View File

@@ -122,12 +122,12 @@ namespace Fig
while (true) while (true)
{ {
token = currentToken();
if (shouldTerminate()) if (shouldTerminate())
{ {
return lhs; return lhs;
} }
token = currentToken();
if (IsTokenOp(token.type /* isBinary = true */)) // 是否为二元运算符 if (IsTokenOp(token.type /* isBinary = true */)) // 是否为二元运算符
{ {
BinaryOperator op = TokenToBinaryOp(token); BinaryOperator op = TokenToBinaryOp(token);
@@ -136,7 +136,7 @@ namespace Fig
{ {
// 前操作数的右绑定力比当前操作数的左绑定力大 // 前操作数的右绑定力比当前操作数的左绑定力大
// lhs被吸走 // lhs被吸走
return lhs; break;
} }
const auto &result = parseInfixExpr(lhs); const auto &result = parseInfixExpr(lhs);
@@ -154,6 +154,7 @@ namespace Fig
return lhs; return lhs;
} }
} }
return lhs;
} }
}; // namespace Fig }; // namespace Fig

View File

@@ -34,7 +34,7 @@ namespace Fig
bool isEOF = false; bool isEOF = false;
const Token &nextToken() Token nextToken()
{ {
assert(!isEOF && "nextToken: eof but called nextToken"); assert(!isEOF && "nextToken: eof but called nextToken");
if (index + 1 < buffer.size()) if (index + 1 < buffer.size())
@@ -57,12 +57,16 @@ namespace Fig
return token; return token;
} }
inline const Token &prevToken() inline Token prevToken()
{ {
if (buffer.size() < 2)
{
return currentToken();
}
return buffer[buffer.size() - 2]; return buffer[buffer.size() - 2];
} }
inline const Token &currentToken() inline Token currentToken()
{ {
if (buffer.empty()) if (buffer.empty())
{ {
@@ -71,7 +75,7 @@ namespace Fig
return buffer.back(); return buffer.back();
} }
const Token &peekToken(size_t lookahead = 1) Token peekToken(size_t lookahead = 1)
{ {
assert(!isEOF && "peekToken: eof but called peekToken"); assert(!isEOF && "peekToken: eof but called peekToken");