如何强制转移Yacc?

时间:2017-02-10 19:27:16

标签: bison yacc jison

我有以下结构作为yacc语法的一部分(或者说是jison,但两者共享相同的共同基础):

Type
    : IDENT
    | Type "[" "]"
    | Type "*"
    | "func" "(" Types ")" "=>" Type
    ;

Types
    : /* No arguments */
    | Type /* Single argument */
    | Types "," Type /* Multiple arguments */
    ;

这当然是一个简化的例子,但它应该给出一般的想法并显示行动中的问题。我想分别将Foo[]Foo*Foo*[]等结构解析为(Foo)[](Foo)*((Foo)*)[]

然而,Yacc理所当然地抱怨它在遇到以下构造时不知道该怎么做:

func (A, B) => C[]

可以将其解析为func (A, B) => (C[])(func (A, B) => C)[]。我当然希望它成为第一个(因为我有第二个案例的( Type )构造)。如果遇到这种情况,我有什么方法可以告诉yacc(或jison)我想转移吗?

1 个答案:

答案 0 :(得分:1)

使用Type声明和伪终端,或者使用默认值(最后一个终端%prec的优先级),为最后=>个生成提供优先级。然后确保[令牌的优先级更高。 (您还必须使*的优先级高于=>,以解决其他转移 - 减少冲突。)

还有其他解决方案,但其中一个是最简单的。

事实上,野牛/ yacc / jison /等。总是喜欢换班减少冲突,所以你不需要做任何事情来换班。优先规则将取消警告,但您也可以使用expect声明来执行此操作。