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

Haskell 使用parsec时避免重复词法分析,haskell,parsec,Haskell,Parsec,Parsec文档中有一个使用makeTokenParser构建lexer的示例: module Main where import Text.Parsec import qualified Text.Parsec.Token as P import Text.Parsec.Language (haskellDef) -- The parser ... expr = parens expr <|> identifier <|&g

Parsec文档中有一个使用
makeTokenParser
构建lexer的示例:

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
 ...
modulemain其中
导入文本.Parsec
将限定的Text.Parsec.Token作为P导入
导入Text.Parsec.Language(haskellDef)
--解析器
...
expr=parens expr
标识符
...
--雷克瑟
lexer=P.makeTokenParser haskellDef
parens=P.parens lexer
大括号=P.大括号lexer
标识符=P.identifier lexer
保留=P.保留lexer
...
在“lexer”块中,每个
p.*
都应用于lexer,这样就可以避免在“parser”块中重复。然而,对每个令牌重复这一点仍然是乏味的。有什么方法可以避免这种重复吗?我本想在“解析器”中的任何地方都隐式地应用lexer,但我不知道该怎么做

Haskell中有一个通用函数(我首先注意到所有的
p.paren
p.brages
,等等都是记录投影函数-您可以通过查看。你可以在这里用

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
Haskell中有一个通用函数(我首先注意到所有的
p.paren
p.brages
,等等都是记录投影函数-您可以通过查看。你可以在这里用

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

如果启用
RecordWildCards
,则可以在顶层使用
P.TokenParser{..}=lexer
来定义所有记录字段。如果启用
RecordWildCards
,则可以在顶层使用
P.TokenParser{..}=lexer
来定义所有记录字段。