[Haskell-cafe] Parsec - Custom Fail

Neil Brown nccb2 at kent.ac.uk
Tue May 5 11:10:40 EDT 2009


When we needed to do something similar with Parsec, we chose to pack the 
relevant source position into the error string (you can just use 
Show/Read, plus a special sequence of characters to indicate where the 
position ends and the real error starts).  We then unpack it outside 
runParser before issuing the error to the user.  If there's no packed 
position found, we just use the Parsec position.



mwinter at brocku.ca wrote:
> Hi,
> I am using parsec to parse a small programming language. The language is typed and
> I need to do some type checking, too. I have decided to do the parsing and type checking
> simultaneously in the my parsec parser. This approach avoids to keep source code positions
> in the data type in order to produce suitable error messages during type checking. Anyhow,
> because type errors are usually detected after parsing some code I need produce error
> messages with an earlier source position. Unfortunately, there is no function that produces 
> an error taking a position as parameter. 
> I tried the following:
> myFail :: SourcePos -> String -> GenParser tok st a
> myFail pos msg = setPosition pos >> fail msg
> This is already a workaround because I am modifying the position in the parser just to
> produce an error message. But even worse, it does not work. If I use this function as in:
> test :: Either ParseError ()
> test = runParser (char '(' >> myFail (newPos "" 100 100) "Test") () "" "("
> the position of the error is still the original position (line 1, column 2). As far as I can tell
> setPosition does not take effect until another symbol is read. This could be achieved by
> simply using anyToken if we are not at the end of the input (as in the example above). I
> came up with the following:
> myFail :: SourcePos -> String -> GenParser Char st a
> myFail pos msg = do {
>                      State toks _ st <- getParserState;
>                      setParserState $ State ('d':toks) pos st;
>                      anyToken;
>                      fail msg
>                   }
> This code works but it is not nice at all. The function myFail is not longer polymorphic in
> the type of tokens since we need an element of this data type in order to add it temporarily
> to the input ('d' above).
> My guess is that one has to enforce strictness at some point in order to work with the first
> approach, but I was not successful. Any ideas?
> Thanks,
> Michael
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe

More information about the Haskell-Cafe mailing list