📅  最后修改于: 2023-12-03 15:06:05.644000             🧑  作者: Mango
%prec
是什么在 Yacc 中,%prec
是一个关键字,用于指定优先级和结合性。通常,它用于更改默认生成的语法树的解析方式,让它更加符合实际需求。
%prec
的语法%prec
关键字被用于规则中的某个终结符号上,以下是它的语法:
term: /* some grammar */ %prec TOKEN_NAME
其中,term
是一个规则的左侧,TOKEN_NAME
是对应的终结符号的名称。
%prec
的作用%prec
关键字可以用于两个方面:
对于第一方面,它的作用类似于 C 语言中的运算符优先级,优先级越高的终结符会在规则中先被处理运算,然后再处理优先级低的终结符。例如,下面的规则表示加法和乘法的运算优先级不同:
expr: expr '+' expr %prec ADD
| expr '*' expr %prec MULTIPLY
| '(' expr ')'
| NUMBER
其中,ADD
和 MULTIPLY
是定义在 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
的使用,可以为语法分析带来更多的灵活性和扩展性。