如何解析也是运算符的关键字

时间:2018-12-31 04:53:19

标签: parsing haskell parsec

我正在尝试使用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运算符,如果第一个参数为null,则返回第二个参数:

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

1 个答案:

答案 0 :(得分:0)

非常感谢@talex和@ n.m。指出我必须去的地方。这就是我解决此特定问题的方法:

我为expression解析器(必须启用{-# LANGUAGE FlexibleContexts #-})参数化了一系列“弹出”字词,并在其下均列出了每个相关的解析器,特别是binOperator解析器

 expression :: [String] -> MyParser AST 

 binOperator :: [String] -> MyParser AST

如果在二进制运算符的位置遇到“ eject”字之一,则binOperator解析器将失败(并且使用基于chainl1的解析器读取二进制操作),从而导致向in解析器“弹出”单词(在这种情况下为for)以使用。 if解析器也应该可以正常工作。

我只是不将弹出字传递给paren解析器,因此在()(以及类似的解析器,例如list)之间没有识别出弹出字。