【问题标题】:Haskell Stuck at parsing boolean logicHaskell 卡在解析布尔逻辑
【发布时间】:2012-05-30 13:24:09
【问题描述】:

我目前正在为一种简单的编程语言编写解析器。它到了那里但是我无法解析布尔逻辑语句,例如“i == 0 AND j == 0”。我得到的只是“以防万一”

当我自己解析一个布尔表达式时,它可以正常工作,例如“我 == 0”。注意“i == 0 a”也将返回一个布尔语句,但“i == 0 AND”不返回任何内容。

有人可以帮忙吗?

虽然上面的输入可以正常工作,例如运行 parseBoolean "i == 0"

【问题讨论】:

  • 请不要链接到外部代码。也请不要在这里转储所有代码。缩小问题范围,然后写一个具体的问题以及相关代码、预期输出和实际输出。
  • 嗯...你检查过相关的案例陈述吗?
  • 您是否尝试过添加默认情况?
  • 程序的哪一行给出了错误信息?
  • 考虑使用Text.Parsec.Expr。它比从头开始编写表达式解析器更不容易出错。

标签: haskell parsec


【解决方案1】:

正如@hammar 指出的那样,您应该使用Text.Parsec.Expr 来处理这种事情。不过,既然这是功课,也许你必须努力去做!

问题出在parseArithmetic,你允许anyChar是一个运算符,但是在case语句中,你只允许+-*/,@987654328 @ 和 ^。当parseArithmetic 尝试解析i == 0 时,它使用第一个= 作为运算符,但无法从第二个= 解析intExp2,并且在monad 和回溯中失败,然后才到达案例陈述。然而,当你尝试解析i == 0 AND j == 0时,它得到了i ==部分,但随后它认为有一个0 A ND的算术表达式,其中A是一个运算符,ND是一些名字变量,所以它得到了案例,繁荣

顺便说一句,您可以让您的解析器返回一个函数而不是字符串,然后直接应用该函数,而不是使用解析器匹配一个字符串,然后再使用 case 语句进行第二次匹配:

 parseOp :: String -> a -> Parser a
 parseOp op a = string op >> spaces >> return a

 parseLogic :: Parser BoolExp 
 parseLogic = do 
    boolExp1 <- parseBoolExp 
    spaces 
    operator <- choice [ try $ parseOp "AND" And
                       , parseOp "OR" Or
                       , parseOp "XOR" XOr
                       ]
    boolExp2 <- parseBoolExp
    return $ operator boolExp1 boolExp2


parseBoolean :: Parser BoolExp 
parseBoolean = do       
   intExp1 <- parseIntExp 
   spaces 
   operator <- choice [ try $ parseOp "==" Main.EQ
                      , parseOp "=>" GTorEQ
                      , parseOp "<=" LTorEQ 
                      ]
   intExp2 <- parseIntExp
   return $ operator intExp1 intExp2

【讨论】:

  • 谢谢帕特。我在考虑 parseArithmetic 中的错误。如果我像上面那样使用选择,你认为它应该起作用吗?还是有更好的方法来做到这一点?现在我已经开始这样做了,下次我将使用 Text.Parsec.Expr。我这样做是因为这就是我们在类中进行解析的方式。
  • 我没有调试你的整个解析器,但只允许你想要的而不是使用anyChar 是一件好事。
  • 另外,您可能希望所有终端解析器都以spaces 结尾,这样您就不需要在非终端上到处使用spaces。这就是 lexeme 组合器的用途。
  • 谢谢。我已经使用您使用的方法更改了解析算法的代码,并且一切正常。这是我在 Haskell 中的第一个大型程序,所以请原谅任何错误。完成此操作后,我将尝试使用 Text.Parsec.Expr
猜你喜欢
  • 2011-10-18
  • 1970-01-01
  • 1970-01-01
  • 2011-02-15
  • 2022-08-19
  • 1970-01-01
  • 2021-09-04
  • 2020-07-11
  • 1970-01-01
相关资源
最近更新 更多