如何在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”,这违反了算术范数(也许不过这就是你想要的)。
我正在尝试在 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”,这违反了算术范数(也许不过这就是你想要的)。