Hi,
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.
Thanks,
Neil.
mwin...@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@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe