1

我想解析一个 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 语句的位置,以便将它们分开然后使用parseStmtfrom haskell-src-exts

谢谢!

4

2 回答 2

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块。

于 2013-10-11T20:00:57.030 回答
0

我不认为haskell-src-exts提供了一个现成的函数来做你想做的事,所以你必须以一种或另一种方式编写一些你自己的解析代码。也就是说,并非一切都丢失了。你可能不得不对haskell-src-exts自己进行破解以暴露它的一些内部结构,但它应该不会太难拼凑起来——如果你已经熟悉它使用的任何解析技术(alex /happy,我想?),或者如果您也必须学习解析技术,请加倍。

我敢肯定,为了让这种事情更容易而对包进行一些补丁,也会受到张开双臂的欢迎。

于 2013-10-11T21:41:12.480 回答