Search code examples
haskellparsec

Get current position in parsed source using parsec


Lets assume I have the following Parser and Tokentype:

data Token = TokInt SourcePos Int

parseInt :: Parser Token
parseInt = do
  numStr <- many1 digit
  return $ TokInt (???) (read numStr)

How do I fill in the missing part (???) with the current SourcePos?

I need this information in the next step.

My current flow is to tokenize the complete input on the first run and then build my AST from the resulting list of Tokens. So tokenizing can be successful, but when building the AST there can be errors, and I want to point the user to the actual point in the file where that error occurs, so I need to save the position of the tokens in the source.


Solution

  • This function returns the current source position within ParsecT:

    import Text.Parsec.Prim
    
    sourcePos :: Monad m => ParsecT s u m SourcePos
    sourcePos = statePos `liftM` getParserState
    

    Then you can do for example:

    parseInt :: Parser Token
    parseInt = do
      numStr <- many1 digit
      pos <- sourcePos
      return $ TokInt pos (read numStr)