我正在尝试使用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
答案 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)之间没有识别出弹出字。