Search code examples
parsinghaskellparsec

Parsec positions as offsets


Can one easily get positions as offsets (as charcters from the starting of input) with Parsec? If so, how? Internally Parsec keeps the position as a data type having the source name, the line and column.

I would like to be able to write a parser like

pWithPos p = do left <- getPosition       -- gets the current position as an offset
                x <- p
                right <- getPosition       -- gets the current position as an offset
                return (x,(left,right))

which parses something using the parser p, and returns its result, as well its left and right position as offsets.

alex (a lexical analyser generator) for instance handles positions keeping the absolute character offset, the line number, and the column number. I am missing the absolute character offset in parsec.


Solution

  • You can use this function to calculate the offset, given the input string and SourcePos:

    offset :: String -> SourcePos -> Maybe Location
    offset source pos = elemIndex pos positions
      where positions = scanl updatePosChar firstPos source
            firstPos = initialPos (sourceName pos)