使用Parsec对解析结果的限制

时间:2013-08-06 12:53:30

标签: haskell parsec parse-error

我正试图想出一种解析汇编代码的聪明方法。例如,如果寄存器的编号从0到31,我想接受$31但不接受$32

我想在解析源代码时执行这些操作,因为1)我想使用位置信息。 2)我很喜欢它。

我最好的想法是使用特殊的解析器来指示失败。

例如我可以写

import Text.Parsec hiding (label)
import Text.Parsec.Token
import Text.Parsec.Language (emptyDef)
import Text.Parsec.String
import Text.Parsec.Expr
import Text.Parsec.Perm

data Register = Register Integer
  deriving (Eq, Ord, Show)

register :: Parser Register
register = do char '$'
              n <- onlyWhen "Register number must be between 0 and 31" 
                            (\n -> n >= 0 && n <= 31) (decimal p)
              return $ Register n

onlyWhen :: String -> (a -> Bool) -> Parser a -> Parser a
onlyWhen mess pred pars 
  = do r <- pars
       if pred r then return r
                 else fail mess

p = makeTokenParser emptyDef

它可以工作,但错误消息包含解析状态的痕迹,这是不幸的。

最好的方法是什么?是否有一些额外的库来做这种事情?

1 个答案:

答案 0 :(得分:1)

尝试提取错误消息

getErrorMessage (ParseError p xs) = show p ++ concat $ map messageString xs