首页 > 解决方案 > 如何解析也是运算符的关键字

问题描述

我正在尝试使用 parsec 解析以下代码

for x = Int in [1, 2, 3]
    print x + 1

示例中唯一可能难以理解的部分是x = Int这意味着变量x被定义为Int. 从语法上讲Int,这里是一个表达式。它也可以用返回类型的函数调用来代替。

到目前为止,我已经能够解析所有简单的文字和运算符。我现在的问题是,在这种语言in中,关键字和运算符一样,类型 ( Int) 是与任何其他对象一样的对象(可以是in列表)。例如,以下代码完全有效并打印false

print (Int in [1, 2, 3])

所以现在我的解析器for x =正确解析,然后解析Int in [1, 2, 3]为一个表达式。如何让for解析器抓取in而不是将其留给expression解析器?我感觉 parsec 内置了类似的东西,但我不知道如何找到它。

编辑:我更改了示例以使其更有意义...

编辑:我在各个地方都有这个困难,语言很复杂。另一个例子是else如果它的第一个参数为空则返回它的第二个参数的操作符:

print (if true then (null else "hello") else "world")
# >> hello
print (if true then null else "hello" else "world")
# >> world

标签: parsinghaskellparsec

解决方案


非常感谢@talex 和@nm 指出我必须看的地方。这就是我解决这个特定问题的方法:

我用“弹出”单词列表以及它下面的每个相关解析器,特别是解析器,参数化了expression解析器(必须启用){-# LANGUAGE FlexibleContexts #-}binOperator

 expression :: [String] -> MyParser AST 

 binOperator :: [String] -> MyParser AST

如果在二元运算符的位置遇到“弹出”字之一,则binOperator解析器将失败(并且使用chainl1读取二进制操作的基础解析器),从而将“弹出”字(在这种情况下in)留给for解析器以消耗。这应该与if解析器一样好。

而且我根本不将弹出词传递给解析器,因此在和(以及类似的解析器如列表)paren之间没有识别出弹出词。()


推荐阅读