我试图想出一种聪明的方法来解析汇编代码。例如,如果寄存器编号从 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
它可以工作,但错误消息包含解析状态的痕迹,这是不幸的。
最好的方法是什么?是否有一些额外的库来做这种事情?