You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bison构建Python解析器时含括号算术表达式语法错误排查

问题分析与修复方案

核心问题

你的语法规则层级设计错误:括号表达式被定义在arith_expr层级,但处理乘除模运算的factor无法引用arith_expr。当解析(a + b) * 2时,(a + b)会被直接归约为arith_expr,此时解析器认为赋值语句的右侧表达式已经完成,后续的*就变成了意外token,触发语法错误。

修复步骤

  1. 调整括号表达式的层级
    把括号表达式移到term层级(最基础的表达式单元),这样它可以作为任何更高优先级运算的操作数:
term: identifier
    | literal_int
    | literal_float
    | TOKEN_PAREN_OPEN arith_expr TOKEN_PAREN_CLOSE { $$ = $2; };
  1. 移除arith_expr中的括号规则
    现在括号由term处理,arith_expr只需专注于加减运算:
arith_expr: factor
    | arith_expr TOKEN_ARITH_ADD factor { $$ = ast_init_arith_op($3, "+", $1); };
    | arith_expr TOKEN_ARITH_SUB factor { $$ = ast_init_arith_op($3, "-", $1); };
;
  1. 正确声明运算符优先级与结合性
    用%left/%right明确运算符的优先级(括号 > 幂 > 乘除模 > 加减)和结合性(幂运算为右结合):
%left TOKEN_ARITH_ADD TOKEN_ARITH_SUB
%left TOKEN_ARITH_MUL TOKEN_ARITH_DIV TOKEN_ARITH_MOD
%right TOKEN_ARITH_POWER
%token TOKEN_ASSIGN
%token TOKEN_PAREN_OPEN TOKEN_PAREN_CLOSE
%token identifier literal_int literal_float
  1. 修复赋值运算符的结合性声明
    之前的错误是因为你给assign这个token错误地编写了语法规则,正确的做法是用%right声明其结合性(赋值为右结合):
%right TOKEN_ASSIGN

确保你的赋值语句规则类似:

statement: identifier TOKEN_ASSIGN arith_expr;

验证

修复后,(a + b) * 2会被正确解析:

  • (a + b) → term → power → factor
  • factor * power(2为term→power)归约为新的factor
  • 最终整个表达式作为arith_expr,满足赋值语句的右侧要求

内容的提问来源于stack exchange,提问作者Havarem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 07:01:57