如何在没有标记的规则上定义关联?

How to define association on rule without tokens?

我有以下最小化语法

Exp : let var '=' Exp in Exp end                     { App (Fn  )  }
    | Exp Exp                                        { App   }
    | Exp OpCode Exp                                 { Op  Add  }
    | '(' Exp ')'                                    {  }
    | num                                            { Num  }
    | var                                            { Ident  }
    | '\' var '.' Exp                               { Fn   }

Exp Exp 规则用于在值中应用函数。但是如果我有类似 myFunc 1 2 的东西,它默认优先于 myFunc (1 2),这不是我想要的。我想要 (myFunc 1) 2,用于柯里化。

但是如果我没有非终结符号,我该如何定义关联呢?尝试做 %left Exp 似乎没有帮助。

除非您有要移动的终端,否则您不能真正应用优先级或关联性,因为优先级和关联性规则用于解决 shift/reduce 冲突。您不一定需要还原中的终端,因此您可以使用假终端并写入:

Exp: Exp Exp %prec CURRY

但这对您没有帮助,因为没有可以比较优先级的终端。优先关系是 always 前瞻符号(终结符)的优先级与可能的归约之间的比较(默认情况下,归约的优先级基于规则中最右边的终结符,但是如上所述,您可以明确指定)。

由于您不能使用简写方式,因此您需要回退到使用明确优先规则编写明确语法的老式风格:

Curry: Term
     | Curry Term

(顺便提一下,这是左关联。如果 func 1 2 被解析为 ((func 1) 2),则应用程序关联到左侧。)

假设中缀比应用程序绑定得更紧密,那么您将拥有:

Term: Value
    | Term Opcode Value

Value: '(' Exp ')'
     | num
     | var

Exp: Curry

(您必须弄清楚如何将 lambda 集成到其中。这取决于您期望它们如何分组,但希望上面的模型是清楚的。)