2013-08-06 106 views
0

我试图想出一个解析汇编代码的聪明方式。例如,如果寄存器编号从0到31,我想接受$31,但不是$32使用Parsec解析结果的限制

我想这样做,而我解析源代码,因为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 

它的工作原理,但错误信息中包含的分析状态,这是不幸的痕迹。

什么是最好的方法来做到这一点?有没有额外的图书馆做这种事情?

+0

该错误消息似乎体面,你会喜欢它的样子? –

+0

如果错误信息只是我的信息,错误位置会更好。 –

+0

这种知识应该是解析器的一部分吗?它不是语法的......如果我的编译器决定为一个未绑定的变量或其他东西发出语法错误,我会大吃一惊 – jozefg

回答

1

尝试提取错误消息

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