我有以下结构作为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)我想转移吗?
答案 0 :(得分:1)
使用Type
声明和伪终端,或者使用默认值(最后一个终端%prec
的优先级),为最后=>
个生成提供优先级。然后确保[
令牌的优先级更高。 (您还必须使*
的优先级高于=>
,以解决其他转移 - 减少冲突。)
还有其他解决方案,但其中一个是最简单的。
事实上,野牛/ yacc / jison /等。总是喜欢换班减少冲突,所以你不需要做任何事情来换班。优先规则将取消警告,但您也可以使用expect
声明来执行此操作。