I am writing some programs in Haskell which manipulate Haskell source code in certain ways. One of the things I would like to be able to do is to extract all occurrences of a particular type (and possibly their positions as well).
I figured a very crude method using regular expressions would work for simple data types. For example, in the following graphics code:
module Test where
import Picture
r1,r2,r3,r4 :: Region
r1 = Shape(Rectangle 2 2)
r2 = Shape(Ellipse 2 1.5)
r3 = Shape(RtTriangle 3 2)
r4 = Shape(Polygon [(-2.5, 2.5), (-3.0,0), (-1.7,-1.0), (-1.1,0.2),(-1.5,2.0)])
p1,p2,p3,p4 :: Picture
p1 = Region Red r1
p2 = Region Green r2
p3 = Region Blue r3
p4 = Region Yellow r4
pic :: Picture
pic = foldl Over EmptyPic [p1,p2,p3,p4]
I could extract every number by simply creating a regular expression which looks for every instance of numeric characters with no letters surrounding them. Likewise If I wanted to find all colours, I could hard code a regular expression which searches for occurrences of Red or Green or Blue... etc.
The problems as I see it with this method are:
If I ever want to change the type I am searching for, I have to hard code every possible way that type could manifest itself
It doesn't work if the type value is returned as the result of a function call. For example, if p1 instead read:
p1 = Region (getColor 1) r1
where:
getColor :: Int -> Color
getColor n
|n == 1 = Red
|otherwise = Green
Is there a more general way to parse a Haskell file so as to extract all occurrences of a particular type and, if possible, their positions within the text of the source file?
You can use a parser, namely haskell-src-exts, which preserves position information (line and column numbers) in the output AST.
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