0

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

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

有人可以帮忙吗?

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

4

1 回答 1

2

正如@hammar 指出的那样,你应该使用Text.Parsec.Expr这种东西。然而,既然这是家庭作业,也许你必须努力去做!

问题在于parseArithmetic,您允许anyChar成为运算符,但在 case 语句中,您只允许+, -, *, /, %, 和^. 当parseArithmetic尝试解析i == 0时,它使用第一个=作为运算符,但无法解析intExp2第二个中的一个=,并且在进入 case 语句之前在 monad 和回溯中失败。但是,当您尝试 parse 时i == 0 AND j == 0,它​​得到了i ==部分,但随后它认为有一个算术表达式0 A ND, whereA是一个运算符,并且ND是某个变量的名称,所以它到达了 case 和boom

顺便说一句,您可以让解析器返回一个函数而不是字符串,然后直接应用该函数,而不是使用解析器来匹配一个字符串,然后再使用 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
于 2012-05-30T16:28:29.690 回答