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

Bison中%nonassoc与%token的区别及适用场景咨询

%nonassoc 和 %token 在 Bison 中的核心区别

基础定义

  • %token 仅用于声明终结符,告诉 Bison 某个符号属于语法中的终结符,不涉及任何优先级或结合性规则。
  • %nonassoc 用于给终结符指定无结合性,同时可设置优先级。当相同优先级的该终结符连续出现,或语法规则因无结合性产生歧义时,Bison 会直接判定为语法错误,拒绝该结构。

什么时候用 %token?

当你只需要定义一个终结符,不需要为它设置优先级或结合性时使用。比如单纯的标识符、关键字:

%token IDENTIFIER IF ELSE RETURN

这里仅告知 Bison 这些符号是语法的组成部分,它们之间不存在优先级/结合性的需求,或优先级由其他语法规则间接处理。


什么时候用 %nonassoc?

当你需要禁止某个运算符的连续使用,或明确该运算符不允许左/右结合时使用。最典型的场景是无意义的连续比较——多数语言中,a == b == c 这类写法逻辑模糊,应直接禁止。

示例:禁止连续比较

假设我们要定义一个语法,不允许连续的相等/不等比较:

%nonassoc EQ NEQ  // 给==和!=设置无结合性
%left PLUS MINUS
%left MUL DIV

%%
expr: expr PLUS expr
    | expr MINUS expr
    | expr MUL expr
    | expr DIV expr
    | expr EQ expr    // 允许单个==比较
    | expr NEQ expr
    | NUMBER
    | IDENTIFIER
    ;
%%

当输入1 == 2 == 3时,Bison 会直接报错——因为EQ是%nonassoc,连续两个相同优先级的EQ出现时,没有结合性规则可以消解歧义,因此判定为语法错误。

如果把%nonassoc EQ NEQ换成%token EQ NEQ,Bison 会因歧义报错(无法判断是先算(1==2)==3还是1==(2==3)),而非直接禁止这种写法。若你的语言逻辑就是不允许连续比较,%nonassoc才是正确选择。


总结

  • 用%token:仅声明终结符,不涉及优先级/结合性处理。
  • 用%nonassoc:需要禁止该终结符连续使用,或明确其无结合性,遇到歧义直接报错而非消解。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:10:01