我不知道如何使用的语义功能(I don't understand how to use th

2019-10-18 03:10发布

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

我究竟做错了什么?

Answer 1:

你误解了文档的lexeme从出口Text.Parsec.Token是的领域GenTokenParser sum ,因此类型

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

和你没有提供的GenTokenParser在参数lexeme constant

您需要创建一个GenTokenParserGenLanguageDef (通常与makeTokenParser )首先使用它的lexeme场。



Answer 2:

lexeme功能是访问到GenTokenParser所产生的解析器的记录makeTokenParser ,所以你需要将它应用到这样的记录得到它。 这样做的一个常用方法是使用记录通配符,如

{-# LANGUAGE RecordWildCards #-}

import qualified Text.Parsec.Token as Tok

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

这将使lexeme和所有其他解析器进入活动范围已经申请到了创纪录的,所以你可以使用它就像你试图做。



文章来源: I don't understand how to use the lexeme function