如何在Antlr中编写Haskell风格的函数应用

How to write Haskell-style function application in Antlr

我正在尝试在 ANTLR4 中编写一个 Haskell 风格的语言解析器,但我在函数应用方面遇到了一些问题。它解析为右关联而不是左关联

expression :
      unit #UnitExpression
    | IntegerLiteral #IntExpression
    | FloatLiteral #FloatExpression
    | CharLiteral #CharExpression
    | StringLiteral #StringExpression
    | LSquareParen (expression (Comma expression)*)? RSquareParen #ListExpression
    | LParen expression RParen #ParenExpression
    | LParen (expression (Comma expression)+) RParen #TupleExpression
    | expression operatorIdentifier expression #OperatorApplicationExpression
    | expression (expression)+ #FunctionApplicationExpression
    | variableIdentifier # VariableExpression
;

这是语法的相关部分,问题是当我写类似 f a b 的内容时,它被解析为 f (a b) 而不是 (f a) b

我使用的实际示例是 f "a" "b",这似乎更加令人困惑,因为字符串文字的优先级高于函数应用程序。

我还尝试重写为 expression+ expression 但没有成功,因为它显然是相互递归的

我怎样才能完成这项工作?

正如@sepp2k 所指出的,| expression expression 将解决您的问题。

ANTLR 默认为左关联性。,但您在尝试收集所有表达式时用 (expression)+ 覆盖了它。

当然,这会给你一个(expr (expr (expr f) (expr "a")) (expr "b"))

的解析树

但这可能更符合 Haskell 函数应用方法,而不仅仅是表达式列表。

顺便说一句,只有在涉及运算符时,优先级才会发挥作用。在 LSquareParen 之前有 StringLiteral 他对优先级没有影响,因为在确定要派生的正确解析树时没有歧义。您可能会发现您的 OperatorApplicationExpresion 替代方案给出了“令人惊讶”的结果,因为它将从左到右评估所有运算符,因此 a + b * c 将被评估为“(a + b) * c”,这违反了算术范数(也许不过这就是你想要的)。