我想解析一个Haskell语句列表。例如,假设我有以下代码:
let a = b
c = e
out <- return 3
我想要一个函数,例如parseStmts
,它可以用一些解析的格式返回它。
我调查了haskell-src-exts
并看到了parseStmt
。这适用于单个语句。它的类型为parseStmt :: String -> ParseResult Stmt
,如果您尝试parseStmt "let a = 3"
,则结果为ParseOk
成功。但是,如果您提供多个语句,则此函数会抱怨,因为字符串中有多个语句。
如何解析多个语句,而不将它们包装在do
块中?或者,如何在字符串中找到Haskell语句分隔的位置,以便我可以将它们分开,然后使用parseStmt
中的haskell-src-exts
?
谢谢!
答案 0 :(得分:2)
你正在寻找parseExp
,虽然输出有点大:
> :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")))))])
我必须将return $ a + c + out
添加到最后,否则会引发错误,因为否则它将不会被视为有效的do
块。
答案 1 :(得分:0)
我不认为haskell-src-exts
提供了一个现成的函数来做你想做的事情,所以你不得不写一些你自己的解析代码。也就是说,并非所有人都失去了。你可能不得不攻击haskell-src-exts
本身来暴露它的一些内部结构,但它不应该过于难以组合在一起 - 如果你已经熟悉任何解析,那么需要几个小时的工作来获得一些体面的东西它使用的技术(亚历克斯/快乐,我认为?),或者如果你必须学习解析技术,还要加倍。
我确信包装上的一些补丁可以让这种东西变得更容易,也可以张开双臂欢迎。