2011-07-19 85 views
7

是否有任何解析器組合器庫可提供與Happy/Alex相媲美的性能?解析器組合器選擇庫(haskell)

我知道Attoparsec,但有時工作不順利,就像下面的例子:

isToken c = isLetter c || isDigit c 

symbol :: Parser Expr 
symbol = do 
    c <- skipSpace >> satisfy isLetter 
    rest <- takeWhile isToken 
    let token = C.cons c rest -- oops... O(N) 
    error $ show token 

解決方法是相當難看:

do { skipSpace; bs <- scan go True; when (null bs) (fail "Not a symbol"); return bs} 
    where go True c = if isLetter c then Just False else Nothing 
      go False c = if isToken c then Just Fasle else Nothing 

此外,Attoparsec缺少的錯誤處理。

對於ocamlyacc/ocamllex,Happy/Alex是相當不友好的,BNFC不靈活 並且在我的情況下需要在解析後進行額外的AST遍歷。另外,錯誤處理不是很好。

有三個休息選項:Parsec2,Parsec3和uu-parselib。我發現了一些有爭議的基準,假設Parsec2比Parsec3更快,或者UU更快,或者更慢。

但是要選擇什麼?有沒有人有使用uu-parselib的經驗?我需要針對某種DSL的解析器,需要足夠快的解析才能在將來不改變它。

+1

如果你正在解析「人類大小」的數據(即人們編寫的文件),任何主流的解析器組合庫應該是很好的速度方式,但你可能不得不注意一些控制回溯你寫的解析器。如果你正在解析大量的數據文件,那麼方程式會有所變化,我會在這一點上尋找基準,並考慮你可以交換什麼樣的功能來交換速度(例如源位置跟蹤可能會顯着減慢)。 –

+1

不是答案,但我已經使用uu-parselib了很多。它功能強大,並具有一些不錯的功能,如自動流校正。我唯一的抱怨是,並非所有的功能都立即顯而易見,特別是如果你不熟悉解析器。我從來沒有遇到速度問題,但我的輸入數據大部分都是千字節大小。 –

回答

7
  1. 還有另一種選擇:polyparse。

  2. 去年的編程之夏後,parsec3進行了優化,並且不再明顯比parsec2慢

  3. 幾個語法(中型)年前夫婦我做了測試,發現快樂/亞歷克斯,業績,parsec2/alex,parsec2和polyparse非常接近。 Attoparsec在字節流上速度更快,但我需要多字節。

我的建議:看看替代方法處理內部和用戶定義的狀態和報告錯誤,並選擇這些標準的方式。

+2

你確定Parsec接近Happy/Alex嗎?在這種情況下,根本沒有意義使用Happy或BNFC。可能有我可以自己運行的任何基準嗎? – voidlizard

+3

無論效率如何,使用像Happy這樣的解析器生成器的優點是,您可以獲得有關語法(如歧義)的錯誤和警告。 – augustss

+1

attoparsec-text怎麼樣? – alternative