9
votes

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?

1
I recommed looking at "HaRe" it had the same problem solving it with relative positions. Maybe the talk by Matthew Pickering at skillsmatter2015 conference can provide some insightepsilonhalbe

1 Answers

9
votes

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")