Using Parsec with restrictions on parsed result

I'm trying to come up with a clever way of parsing assembly code. For example, if the registers are numbered from 0 to 31, I want to accept $31 but not $32.

I would like to do these while I parse the source code, because 1) I want to use the position information. 2) I like it simple.

My best idea is to use a special parser to indicate failure.

For example I could write

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

It works, but the error message contains traces of the parsing state, which is unfortunate.

What would be the best way to do it? Is there some additional library for doing this kind of things?

Upvotes: 0

Views: 169

Answers (1)

wit
wit

Reputation: 1622

Try to extract Error messages

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

Upvotes: 1

Related Questions