2013-05-06 18 views
1

Text.Parsec.Token我不明白如何使用語義功能

lexeme p = do { x <- p; whiteSpace; return x } 

看來,語義需要一個解析器P和提供具有相同行爲爲p解析器,但它也跳過所有尾隨的空白。正確?

那爲什麼下面不工作:在下面的錯誤消息

constant :: Parser Int 
constant = do 
    digits <- many1 digit 
    return (read digits) 

lexConst :: Parser Int 
lexConst = lexeme constant 

最後一行的結果:

Couldn't match expected type `ParsecT 
           String() Data.Functor.Identity.Identity Int' 
      with actual type `ParsecT s0 u0 m0 a0 -> ParsecT s0 u0 m0 a0' 
Expected type: Parser Int 
    Actual type: ParsecT s0 u0 m0 a0 -> ParsecT s0 u0 m0 a0 
In the return type of a call of `lexeme' 
In the expression: lexeme constant 

我在做什麼錯?

回答

6

你誤解了這個文件,從Text.Parsec.Token出口的lexemeGenTokenParser s u m的領域,所以類型是

lexeme :: GenTokenParser s u m -> ParsecT s u m a -> ParsecT s u m a 

和你沒有lexeme constant提供的GenTokenParser說法。

您需要先創建GenLanguageDef(通常爲makeTokenParser)的GenTokenParser首先使用其lexeme字段。

2

lexeme函數是由makeTokenParser生成的解析器記錄的一個訪問器,因此您需要將它應用於這樣的記錄才能得到它。一種常見的做法是使用記錄通配符,例如

{-# LANGUAGE RecordWildCards #-} 

import qualified Text.Parsec.Token as Tok 

Tok.TokenParser { .. } = Tok.makeTokenParser {- language definition -} 

這將帶來lexeme和所有其他解析器進入活動範圍已經申請到了創紀錄的,所以你可以使用它就像你試圖做。