【发布时间】:2018-09-02 17:10:20
【问题描述】:
我最近又拿起了野牛,但我仍在努力解决优先级的工作方式以及如何解决基本的移位/减少冲突。我对编写语法规则以及递归的工作原理等非常满意,但我仍然无法理解优先规则。
我将非常感谢以下示例中的一些 cmets 以及我对它们的问题和理解。
test1.y
%token ID
%token TYPE_NAME
%token ASTERIX
%nonassoc F_T
%nonassoc P_T
%%
f_type:
ID type %prec F_T
;
type:
TYPE_NAME
| type ASTERIX %prec P_T
| f_type
;
%%
test1.输出
State 5
1 f_type: ID type .
3 type: type . ASTERIX
ASTERIX shift, and go to state 7
ASTERIX [reduce using rule 1 (f_type)]
$default reduce using rule 1 (f_type)
这个例子产生了一个移位减少冲突,因为状态机无法确定它是否应该减少 ID type* -> type* -> type 或 ID type* -> ID type -> 输入。后者是期望的结果。我尝试通过赋予规则类型:type ASTERIX 比 f_type: ID type 更高的优先级来解决此冲突,但这似乎不起作用。我也不想为终端 ASTERIX 分配任何优先级,因为我想在其他上下文中使用它。
test2.y
%token ID
%token DOUBLE_PLUS
%left POSTFIX_OP
%right PREFIX_OP
%%
exp:
ID
| exp DOUBLE_PLUS %prec POSTFIX_OP
| DOUBLE_PLUS exp %prec PREFIX_OP
;
%%
test2.输出
State 4
2 exp: exp . DOUBLE_PLUS
3 | DOUBLE_PLUS exp .
DOUBLE_PLUS shift, and go to state 6
DOUBLE_PLUS [reduce using rule 3 (exp)]
$default reduce using rule 3 (exp)
此示例产生了移位/归约冲突,因为 DOUBLE_PLUS exp DOUBLE_PLUS 的归约存在歧义。所以我尝试为 DOUBLE_PLUS exp 分配比 exp DOUBLE_PLUS 更高的优先级,但这也不起作用。可以通过为终端 DOUBLE_PLUS 分配左侧或右侧优先级来解决此冲突,我猜分配左侧优先级意味着 exp DOUBLE_PLUS 首先和右侧减少意味着 DOUBLE_PLUS exp 首先减少,但我也希望有一些方法可以通过使用 %prec 注释来做到这一点。
我也不确定我是否正确理解了 .output 文件。规则中的 . 表示堆栈中的内容以及前瞻标记是什么,但是为什么在后面的示例中还要提到规则 2?我的意思是 exp: exp 。 DOUBLE_PLUS不应该有任何冲突吗?
【问题讨论】: