1

我目前正在使用Text.Parsec.Expr模块来解析脚本语言的子集。

基本上,这种语言有两种命令:形式的赋值和形式$var = expr的命令$var = $array[$index]——当然还有其他命令,但这足以解释我的问题。

我创建了一个 typeCommand来表示它,以及相应的解析器,其中expr分配由 Parsec 的buildExpressionParser.

现在,问题。首先是解析代码:

main = case parse p "" "$c = $a[$b]" of
          Left err -> putStrLn . show $ err
          Right r  -> putStrLn . show $ r
    where p = (try assignment <|> command) <* eof -- (1)

整个代码(50 行)粘贴在这里:链接(如果你安装了解析器,应该编译)

问题是,解析失败,因为assignment没有成功解析,即使try之前有。颠倒解析顺序 ( try command <|> assignment) 可以解决问题,但在我的情况下是不可能的。

当然,我试图进一步定位问题,在我看来,问题在于表达式解析器(由 构建buildExpressionParser),因为如果我说expr = fail "". 但是,我在 Parsec 来源中找不到任何可以解释这种行为的东西。

4

1 回答 1

3

您的解析器失败了,因为实际上assigment 确实在此处成功使用$c = $a(尝试使用 plain where p = assignment)。然后应该有(或fromeof的其余部分)因此错误。在“assignment”的参数只是一个(like )的情况下,您的“command”的开头似乎与您的“assignment”相同。不知道为什么你不能逆转,但使这个特定示例工作的另一种方法是:exprassigmentvar$c = $acommandassignment

main = case parse p "" "$c = $a[$b]" of
      Left err -> putStrLn . show $ err
      Right r  -> putStrLn . show $ r
   where p = try (assignment <* eof) <|> (command <* eof)
于 2011-09-09T04:19:22.820 回答