The Parsec documentation has an example of using makeTokenParser
to build a 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
...
In "The lexer" block, every P.*
is applied to lexer so that one can avoid repeating that in "The parser" block. However repeating that for every token is still tedious. Is there some way to avoid the repetition even more? I was thinking to implicitly apply lexer everywhere in "The parser", but am at lost how to.
There is a general 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.) . You can use that here
P.TokenParser { P.parens = parens
, P.braces = braces
, P.identifier = identifier
, P.reserved = reserved
} = P.makeTokenParser haskellDef
As ErikR has pointed out, it you don't just want some of the parsers, but you want all 29 of the GenTokenParser
fields brought into global scope, you can enable the RecordWildCards
extension and just write
P.TokenParser {..} = P.makeTokenParser haskellDef