【问题标题】:yacc associativity of nonterminal symbols?yacc 非终结符号的关联性?
【发布时间】:2026-02-03 13:45:01
【问题描述】:

假设我有这样的语法:

expr : expr '+' expr   { $$ = operation('+', $1, $3); }
     | expr '-' expr   { $$ = operation('-', $1, $3); }
     | expr '*' expr   { $$ = operation('*', $1, $3); }
     | expr '/' expr   { $$ = operation('/', $1, $3); }
     | num
     ;

其中每个运算符都有一个优先级并被标记为左结合。

然后我想重构我的语法,这样:

op   : '+' | '-' | '*' | '/' ;

expr : expr op expr { $$ = operation($2, $1, $3); }
     | num
     ;

在这种情况下,yacc(如果有的话)如何确定op 的关联性和优先级?在评估op 时,它会通过+-*/ 的所有可能的优先级/关联性进行追踪,还是为非终结符号定义关联性没有意义?

AFAIK,具有非终结符的优先顺序,它使用最右边的终结符的优先级,但我找不到任何关于非终结符的关联规则本身的文档。

【问题讨论】:

    标签: yacc


    【解决方案1】:

    执行此操作的“正常”方法(据我所知)是为每个运算符定义不同的 expr 类型,这样您就可以非常明确地控制正在发生的事情。

    Python 的语法就是一个很好的例子:http://docs.python.org/reference/grammar.html

    【讨论】:

    • 谢谢,我知道这并不是构建语法的好方法。我有自己的 LALR(1) 解析器(在 ruby​​ 中),当运算符和操作数之间存在非终结规则时,运算符优先级/关联性不起作用,所以我主要好奇 yacc 是否/如何处理这个问题。我个人试图避免它,但我的一个用户绊倒了它,我们都没有注意到原因;这让我想知道它是否很容易修复。