Question

I would like to parse a list of Haskell statements. For instance, suppose I have the following code:

let a = b
    c = e
out <- return 3

I'd like a function, for instance parseStmts, which can return this in some parsed format.

I've looked into haskell-src-exts and saw parseStmt. This works for a single statement. It has type parseStmt :: String -> ParseResult Stmt, and if you try parseStmt "let a = 3", the result is a successful ParseOk. However, if you provide multiple statements, this function complains because there is more than one statement in the string.

How do I parse multiple statements, without wrapping them in a do block? Alternatively, how can I find the places in a string which are separations of Haskell statements, so I can separate them and then use parseStmt from haskell-src-exts?

Thanks!

Was it helpful?

Solution

You're looking for parseExp, although the output is a bit large:

> :m + Language.Haskell.Exts.Parser
> parseExp "do\n  let a = b\n      c = e\n  out <- return 3\n  return $ a + c + out"
ParseOk (Do [LetStmt (BDecls [PatBind (SrcLoc {srcFilename = "<unknown>.hs", srcLine = 2, srcColumn = 7}) (PVar (Ident "a")) Nothing (UnGuardedRhs (Var (UnQual (Ident "b")))) (BDecls []),PatBind (SrcLoc {srcFilename = "<unknown>.hs", srcLine = 3, srcColumn = 7}) (PVar (Ident "c")) Nothing (UnGuardedRhs (Var (UnQual (Ident "e")))) (BDecls [])]),Generator (SrcLoc {srcFilename = "<unknown>.hs", srcLine = 4, srcColumn = 3}) (PVar (Ident "out")) (App (Var (UnQual (Ident "return"))) (Lit (Int 3))),Qualifier (InfixApp (Var (UnQual (Ident "return"))) (QVarOp (UnQual (Symbol "$"))) (InfixApp (InfixApp (Var (UnQual (Ident "a"))) (QVarOp (UnQual (Symbol "+"))) (Var (UnQual (Ident "c")))) (QVarOp (UnQual (Symbol "+"))) (Var (UnQual (Ident "out")))))])

I had to add the return $ a + c + out to the end or else it throws an error, since it wouldn't be considered a valid do block otherwise.

OTHER TIPS

I don't think haskell-src-exts offers a ready-made function doing what you want, so one way or another you're going to have to write some of your own parsing code. That said, not all is lost. You may have to hack on haskell-src-exts itself to expose a few of its internals, but it should not be unduly difficult to throw together -- a few hours of work to get something decent if you're already familiar with whatever parsing technology it uses (alex/happy, I think?), or double it if you have to learn the parsing technology, too.

I'm sure some patches to the package to make this kind of thing easier would be welcomed with open arms, as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top