0
votes

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.

1

1 Answers

3
votes

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 

EDIT

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