14

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.

Rafael S. Calsaverini
  • 13,582
  • 19
  • 75
  • 132
  • 1
    See http://stackoverflow.com/questions/6065951/parsing-haskell-preserving-comments-formatting – Don Stewart Jun 02 '11 at 01:18
  • 2
    There is an obvious point - "don't generate syntactically incorrect programs in the first place". There are many examples of EDSLs in Haskell that follow this dictum. Even for genetic programming you should be able to generate valid code. – stephen tetley Jun 02 '11 at 06:52
  • 1
    @stephen tetley Hi. I have a specific reason to allow for incorrect programs. I'm not interested in using genetic programming to generate programs to solve a specific problem, but I'm interested in the evolution of the code strings. I just want to see if I can write a fitness function that will allow a syntactically correct program to evolve from a population of self-replicating random strings. It's not a CS problem, but maybe a theoretical biology problem. It seems very unlikely, but I wanna try anyway. :) – Rafael S. Calsaverini Jun 02 '11 at 12:38

1 Answers1

15

For parsing Haskell code, you can use either

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.

Mikhail Glushenkov
  • 14,928
  • 3
  • 52
  • 65
  • 1
    See also [hint](http://hackage.haskell.org/package/hint) for an easier way to hook into the GHC API. – luqui Jun 02 '11 at 01:42
  • You mentioned language-c. Do you know of any good source of documentation/example code for this package? – ankh-morpork Apr 03 '16 at 02:59