📜  yacc 中的 %prec 是什么 - Shell-Bash (1)

📅  最后修改于: 2023-12-03 15:06:05.644000             🧑  作者: Mango

Yacc 中的 %prec 是什么

在 Yacc 中,%prec 是一个关键字,用于指定优先级和结合性。通常,它用于更改默认生成的语法树的解析方式,让它更加符合实际需求。

%prec 的语法

%prec 关键字被用于规则中的某个终结符号上,以下是它的语法:

term: /* some grammar */ %prec TOKEN_NAME

其中,term 是一个规则的左侧,TOKEN_NAME 是对应的终结符号的名称。

%prec 的作用

%prec 关键字可以用于两个方面:

  1. 优先级:指定当前终结符的运算优先级,从而影响到其在规则中的运算顺序。
  2. 结合性:指定当前终结符的运算结合性,从而影响到其在规则中的结合方式。

对于第一方面,它的作用类似于 C 语言中的运算符优先级,优先级越高的终结符会在规则中先被处理运算,然后再处理优先级低的终结符。例如,下面的规则表示加法和乘法的运算优先级不同:

expr: expr '+' expr %prec ADD
    | expr '*' expr %prec MULTIPLY
    | '(' expr ')'
    | NUMBER

其中,ADDMULTIPLY 是定义在 Lex 中的终结符号(token)。这个规则的意思是,当解析一个表达式时,会先处理乘法,再处理加法。这样,如果表达式为 2+3*4,就会先计算 3*4,再加上 2,得到的结果为 14

对于第二方面,它的作用是指定当前终结符的结合方式,即相邻的同样优先级的终结符应该如何结合。结合性主要有三种:

  • left:左结合,即从左往右结合。
  • right:右结合,即从右往左结合。
  • nonassoc:不结合,即不能出现相邻的同样优先级的终结符。

例如,如果有以下规则:

expr: expr '*' expr %left MULTIPLY
    | expr '+' expr %left ADD
    | unary_expr

这个规则的意思是,乘法和加法有相同的优先级,且左结合,所以在解析表达式 (1+2)*3+4 时,会先计算 (1+2)*3,再加上 4,得到的结果为 13

总结

%prec 关键字可以用于指定终结符的优先级和结合性,进而影响规则的解析方式。同时,它也可以用于解决规则中终结符和非终结符之间冲突的问题。熟练掌握 %prec 的使用,可以为语法分析带来更多的灵活性和扩展性。