Search code examples
haskellparsec

Printing an AST to show indentation


I would like to print an Abstract Syntax Tree in Haskell. Currently I can print the tree out line by line but what I would prefer is to indent it out for each block the parsed code is within.

E.g.

Code to parse:

module test
foo(x,y):
    foo x y
    x + y 

Here are my functions to create and print the AST.

Returns the tree.

parse :: String -> Either ParseError [Expr]
parse = runParser (many expr <* eof) () "[input]" . indentConfig

Prints the tree.

printTree :: String -> IO ()
printTree line = do
    let res = parse line
    case res of
        Left err -> print err
        Right ex -> mapM_ print ex

Current output:

Function "foo" ["x","y"] (FunctionCall "foo" [Variable "x",Variable "y"])
BinOp Plus (FunctionCall "x" []) (FunctionCall "y" [])

Desired output:

Function "foo" ["x","y"] 
    (FunctionCall "foo" [Variable "x",Variable "y"])
    BinOp Plus (FunctionCall "x" []) (FunctionCall "y" [])

What is the best method of achieving this?


Solution

  • There are several packages on Hackage that lets you show such tree structures in an "indented" way. Previously, I used Iavor Diatchki's pretty-show package, and it does a really good job. You might want to give that a try: https://hackage.haskell.org/package/pretty-show