使用 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
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