使用 parsec 时避免重复词法分析

Avoid repetition in lexing when using parsec

Parsec 文档有一个使用 makeTokenParser 构建词法分析器的示例:

module Main where

 import Text.Parsec
 import qualified Text.Parsec.Token as P
 import Text.Parsec.Language (haskellDef)

 -- The parser
 ...

 expr  =   parens expr
       <|> identifier
       <|> ...


 -- The lexer
 lexer       = P.makeTokenParser haskellDef    

 parens      = P.parens lexer
 braces      = P.braces lexer
 identifier  = P.identifier lexer
 reserved    = P.reserved lexer
 ...

在 "The lexer" 块中,每个 P.* 都应用于词法分析器,这样就可以避免在 "The parser" 块中重复。然而,为每个标记重复这一点仍然很乏味。有什么方法可以避免重复吗?我正在考虑在 "The parser" 中的任何地方隐式应用词法分析器,但我不知道该怎么做。

有一般syntax for pattern matching on records in Haskell (I started by noticing that all of P.parens, P.braces, etc. are record projection functions - you can see that by looking at the docs.)。你可以在这里使用它

P.TokenParser { P.parens      = parens
              , P.braces      = braces
              , P.identifier  = identifier
              , P.reserved    = reserved
              } = P.makeTokenParser haskellDef 

编辑

正如 ErikR 所指出的,您不只是想要 一些 解析器,而是想要将所有 29 个 GenTokenParser 字段都引入全局范围,您可以启用 RecordWildCards 扩展并只写

 P.TokenParser {..} = P.makeTokenParser haskellDef