2010-03-18 33 views
3

parsec-3.1.0(http://hackage.haskell.org/package/parsec-3.1.0) 適用於任何標記類型。然而,像Text.Parsec.Char.satisfy這樣的組合器只能爲Char數據類型定義。似乎沒有更多的普通對象可用。帶自定義標記數據類型的parsec-3.1.0

我應該定義自己的版本還是錯過了某些東西?

也許還有在Haskell不同的解析器庫,允許:

  • 定製令牌類型
  • 定製解析器的狀態(我需要解析狀態格式 - 波前OBJ)

回答

4

廣義的版本oneOf,noneOfanyChar可以構建出一個廣義的satisfy,很容易:

oneOfT :: (Eq t, Show t, Stream s m t) => [t] -> ParsecT s u m t 
oneOfT ts = satisfyT (`elem` ts) 

noneOfT :: (Eq t, Show t, Stream s m t) => [t] -> ParsecT s u m t 
noneOfT ts = satisfyT (not . (`elem` ts)) 

anyT :: (Show t, Stream s m t) => ParsecT s u m t 
anyT = satisfyT (const True) 

satisfyT :: (Show t, Stream s m t) => (t -> Bool) -> ParsecT s u m t 
satisfyT p = tokenPrim showTok nextPos testTok 
    where 
     showTok t  = show t 
     testTok t  = if p t then Just t else Nothing 
     nextPos p t s = -- however you update position for your token stream 

可能看起來這些泛化似乎失蹤,但你會發現,在這裏這些概括做出t的類型可能不適合別人的令牌類型是真實的某些假設。假設它是ShowEq的一個實例,但我可以想象它們以其他方式顯示的令牌類型,而不是show,並且可以通過==elem以外的某種方法實現一類令牌中的成員資格。

最後,一旦您的令牌類型不再是Char,您選擇表示位置並進行更新的方式高度依賴於您對令牌和流的表示。

因此,我可以看到爲什麼更廣義的形式不存在。

+0

你命名可以通過類型類來解決這些問題: >類令牌,其中 > showTok :: A - >字符串 > nextPosTok ::(適當的類型這裏) > ... 到底你總是可以''newtype'你的令牌類型並提供你自己的定義。 – Tener 2010-03-19 16:55:39

+0

@Tener - 事實上,我就是這麼做的 - 但Parsec 3沒有在Stream類中放入nextPos函數,也沒有定義Token類型類。 – MtnViewMark 2010-03-19 22:55:46