Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Library to parse and check Haskell code?

Is there any library in hackage that can parse haskell code and check if it is valid code or not?

I'm willing to play a bit with an evolutionary model and I want to check if produced strings of code will compile without having to write them to the disk and run the compiler.

Ideally it would be nice to be able to run the code in the strings too, but only checking the validity of the code is ok.

If you know about parser libraries (in haskell) that check for other languages (lisp, C,...)it would be nice too.

like image 321
Rafael S. Calsaverini Avatar asked Jun 02 '11 00:06

Rafael S. Calsaverini


1 Answers

For parsing Haskell code, you can use either

  • haskell-src
  • or haskell-src-exts

The latter handles all of the GHC extensions (and then some), while the former parses only Haskell 98. Here's an example of usage:

Prelude> import Language.Haskell.Exts.Parser

Prelude Language.Haskell.Exts.Parser> parseModule "main = putStrLn \"Hello\""
ParseOk (Module (SrcLoc {srcFilename = "<unknown>.hs", srcLine = 1, srcColumn = 1}) (ModuleName "Main") [] Nothing (Just [EVar (UnQual (Ident "main"))]) [] [PatBind (SrcLoc {srcFilename = "<unknown>.hs", srcLine = 1, srcColumn = 1}) (PVar (Ident "main")) Nothing (UnGuardedRhs (App (Var (UnQual (Ident "putStrLn"))) (Lit (String "Hello")))) (BDecls [])])

Prelude Language.Haskell.Exts.Parser> parseModule "main == putStrLn \"Hello\""
ParseFailed (SrcLoc {srcFilename = "<unknown>.hs", srcLine = 1, srcColumn = 25}) "TemplateHaskell is not enabled"

Note that even if the code parses correctly, it doesn't mean it will typecheck:

Prelude Language.Haskell.Exts.Parser> parseModule "main = putStrLn2 \"Hello\""
ParseOk (Module (SrcLoc {srcFilename = "<unknown>.hs", srcLine = 1, srcColumn = 1}) (ModuleName "Main") [] Nothing (Just [EVar (UnQual (Ident "main"))]) [] [PatBind (SrcLoc {srcFilename = "<unknown>.hs", srcLine = 1, srcColumn = 1}) (PVar (Ident "main")) Nothing (UnGuardedRhs (App (Var (UnQual (Ident "putStrLn2"))) (Lit (String "Hello")))) (BDecls [])])

So for your specific use case, it is probably better to use GHC API which also lets you typecheck parsed code, or just run ghc -c on your file.

For parsing C code, there is language-c.

If you need to parse some other language, take a look at this category on Hackage. For example, here's a parser for S-expressions.

like image 156
Mikhail Glushenkov Avatar answered Sep 27 '22 18:09

Mikhail Glushenkov