0

我有以下最小化语法

Exp : let var '=' Exp in Exp end                     { App (Fn $2 $6) $4 }
    | Exp Exp                                        { App $1 $2 }
    | Exp OpCode Exp                                 { Op $1 Add $3 }
    | '(' Exp ')'                                    { $2 }
    | num                                            { Num $1 }
    | var                                            { Ident $1 }
    | '\\' var '.' Exp                               { Fn $2 $4 }

Exp Exp规则用于在值中应用函数。但是,如果我有类似的东西myFunc 1 2默认为 precendence myFunc (1 2),这不是我想要的。我想要(myFunc 1) 2,用于咖喱。

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

4

1 回答 1

1

除非您有要转换的终端,否则您无法真正应用优先级或关联性,因为优先级和关联性规则用于解决转换/减少冲突。您不一定需要减少终端,因此您可以使用假终端并编写:

Exp: Exp Exp %prec CURRY

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

由于您不能以速记的方式进行操作,因此您需要回退到老式风格,在这种风格中,您可以使用明确的优先规则编写明确的语法:

Curry: Term
     | Curry Term

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

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

Term: Value
    | Term Opcode Value

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

Exp: Curry

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

于 2015-05-19T05:02:57.520 回答