【问题标题】:I don't understand how to use the lexeme function我不明白如何使用 lexeme 功能
【发布时间】:2013-05-06 16:01:34
【问题描述】:

来自Text.Parsec.Token

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

似乎 lexeme 采用解析器 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

我做错了什么?

【问题讨论】:

    标签: haskell whitespace lexer parsec parser-combinators


    【解决方案1】:

    你误解了文档,从Text.Parsec.Token导出的lexeme是一个GenTokenParser 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 函数是GenTokenParsermakeTokenParser 生成的解析器记录的访问器,因此您需要将它应用于这样的记录才能获取它。一种常见的方法是使用记录通配符,例如

      {-# LANGUAGE RecordWildCards #-}
      
      import qualified Text.Parsec.Token as Tok
      
      Tok.TokenParser { .. } = Tok.makeTokenParser {- language definition -}
      

      这会将lexeme 和所有其他解析器带入已应用于记录的范围内,因此您可以像尝试那样使用它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-13
        • 1970-01-01
        • 2021-05-17
        • 2021-06-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多