2010-04-14 21 views
6

Je voudrais utiliser le makeTokenParser de Parsec pour construire mon analyseur, mais je veux utiliser ma propre définition de whiteSpace. Ce qui suit remplace whiteSpace par ma définition, mais tous les parseurs lexeme utilisent toujours l'ancienne définition (par exemple P.identifier lexer utilisera l'ancien whiteSpace).Custom whiteSpace utilisant Haskell Parsec

... 
lexer :: P.TokenParser() 
lexer  = l { P.whiteSpace = myWhiteSpace } 
    where l = P.makeTokenParser myLanguageDef 
... 

En regardant le code pour makeTokenParser Je pense que je comprends pourquoi cela fonctionne de cette façon. Je veux savoir s'il existe des solutions de contournement pour éviter de dupliquer complètement le code pour makeTokenParser?

+0

Connexes: http://stackoverflow.com/questions/5672142/in-parsec-is-there-a-way-to-prevent-lexeme-from-consuming-newlines –

Répondre

7

Malheureusement, je ne pense pas qu'il existe un moyen. Les définitions locales utilisées dans makeTokenParser se réfèrent récursivement à eux-mêmes, et ainsi, comme vous l'avez noté, lexeme utilise whiteSpace comme défini ici, plutôt que le membre d'enregistrement whiteSpace que vous remplacez dans votre objet lexer.

Le code est railleur car il utilise les mêmes noms que les deux fonctions locales dans makeTokenParser et comme membres d'enregistrement du constructeur TokenParser. Ce sont en fait des entités totalement distinctes.

+2

Maintenant, si seulement 'TokenParser' a été écrit avec des classes de type, nous serions prêts à partir. – Steve

+1

.. et s'il pouvait faire des parsers monadiques (en Parsec 3) plutôt que d'être câblé jusqu'à 'Identity'. –