Search code examples
parsinghaskellghcparsecparser-combinators

Parsec: Getting start and end source positions of expressions?


I'm writing a programming language which uses Parsec for its parsing. For reporting error messages, I've got each element of my syntax tree labelled with its source location, using the getPosition function from the Pos module of Parsec.

However, it only gives the location of the beginning of each expression I parse, and I'd like the beginning and end, so that I can highlight their entire location within the source code.

Is such a thing possible with parsec? Is there a standard way of getting the end-point of an expression I'm parsing, so that I can include it in my AST?


Solution

  • You can use getPosition after you parse as well.

    import Text.Parsec
    import Text.Parsec.String
    
    spanned :: Parser a -> Parser (SourcePos, SourcePos, a)
    spanned p = do
      pos1 <- getPosition
      a <- p
      pos2 <- getPosition
      pure (pos1, pos2, a)
    

    Testing:

    > parseTest (spanned (many1 (char 'a'))) "aaaaafff"
    ((line 1, column 1),(line 1, column 6),"aaaaa")