hackage中是否有任何库可以解析haskell代码并检查它是否是有效代码?
我愿意使用进化模型,我想检查生成的代码串是否可以编译而无需将它们写入磁盘并运行编译器。
理想情况下,能够在字符串中运行代码也很好,但只检查代码的有效性是可以的。
如果您了解检查其他语言(lisp,C,...)的解析器库(在haskell中),它也会很好。
答案 0 :(得分:15)
对于解析Haskell代码,您可以使用
后者处理所有GHC扩展(然后是一些),而前者仅解析Haskell 98.这是一个使用示例:
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"
请注意,即使代码正确解析,也不意味着它会进行类型检查:
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 [])])
因此,对于您的特定用例,最好使用GHC API,它还允许您对已解析的代码进行类型检查,或者只在您的文件上运行ghc -c
。
对于解析C代码,有language-c。
如果您需要解析其他语言,请查看Hackage上的this类别。例如,这里是a parser for S-expressions。