2013-10-11 17 views
1

我想解析Haskell的語句列表。舉例來說,假設我有以下代碼:哈斯克爾的Src EXTS解析多個語句

let a = b 
    c = e 
out <- return 3 

我想要的功能,例如parseStmts,這在某些解析格式返回這一點。

我看着haskell-src-exts看到parseStmt。這適用於單個語句。它的類型爲parseStmt :: String -> ParseResult Stmt,如果您嘗試parseStmt "let a = 3",則結果爲成功ParseOk。但是,如果您提供多個語句,則此函數會投訴,因爲字符串中有多個語句。

我如何解析多條語句,而無需在do塊包裹呢?另外,我怎樣才能找到一個字符串中的Haskell語句分離的地方,所以我可以分開它們,然後使用parseStmthaskell-src-exts

謝謝!

回答

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否則阻止。

+0

我認爲這是一個解決方案,但它需要添加一個'do',在年底加入'return',並縮進一切爲了'do'。這是可行的(得到它?''可以嗎?),但有點醜,並希望有一個更好的解決方案。 –

+0

@AndrewGibiansky你想解析_correct_ haskell源代碼,對吧?如果你沒有正確縮進並添加return語句,那麼你不能從它構造一個AST。你是否想簡單地將代碼解析成比AST更不正式的結構? – bheklilr

+0

@AndrewGibiansky我不是太熟悉使用這個庫,但它看起來像你可以使用'lexTokenStream'功能從'Language.Haskell.Exts.Lexer'模塊,它會轉碼成標記,但它仍然可能難以操作。這看起來像一個鏡頭的工作。 – bheklilr

0

我不認爲haskell-src-exts提供了一個現成的函數來做你想做的事情,所以你不得不寫一些你自己的解析代碼。這就是說,並不是所有的都丟失了。你可能不得不破解haskell-src-exts本身來揭露其內部的一些內幕,但它不應該過於困難 - 如果你已經熟悉它使用的任何解析技術,幾個小時的工作就可以得到體面的東西( alex/happy,我認爲?),或者如果你還必須學習解析技術,那麼就加倍吧。

我敢肯定,一些補丁的包,使這種比較容易的事情會張開雙臂歡迎,以及。