I am writing a two pass parser where I first scan the text in to tokens (using Alex
) then parse those tokens (using Parsec
). All well and good until I tried to add position information to the tokens so I can write a good error message.
Originally I had:
data Token = TAtom | TString String | TInt Integer | TFloat [...]
It seems like I can either add a Position
element to each Token
constructor or create a new type like data TokenWithPosition = T Token Position
.
I have started down the latter path, but now I have a problem of either having to create a TokenWithPosition
with a fake position when I want to describe a token in Parsec, or I have to unwrap the TokenWithPosition
every time I want to make a comparison. In short my nice clean grammar is being overrun with code needed to ignore the position information.
So my question: Is there a clean way to track position information without having it complicate the parser in the second pass? This seems like something that would have a standard solution.
You need to use functions from Text.Parsec.Prim
(for instance, tokenPrim
) to implement your own "primitive parsers".
Those primitive parsers will update Parsec's internal state with the position information and return a pure Token
without the position.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With