2016-12-29 2 views
1

J'utilise le module Parsec dans Haskell pour analyser les fichiers. L'un des composants de ces fichiers sont les couleurs. J'ai créé un type de couleurs comme ceci:Analyse des espaces avant or-else avec Parsec

data Color = Yellow | Red | Blue | Green deriving (Show) 

Ma première tentative de couleurs parsing ressemble à ceci:

symbol :: String -> Parsec String() String 
symbol s = spaces >> string s 

colorP :: Parsec String() Color 
colorP = 
    liftM mkColor $ symbol "Yellow" <|> symbol "Red" <|> symbol "Blue" <|> symbol "Green" 
    where 
    mkColor :: String -> Color 
    mkColor "Yellow" = Yellow 
    mkColor "Red" = Red 
    mkColor "Blue" = Blue 
    mkColor "Green" = Green 

J'ai créé l'analyseur symbol qui se nourrit essentiellement autant des espaces que possible et mange ensuite la chaîne donnée s. Cependant, cela ne semble pas fonctionner. Je teste ce code avec l'appel suivant:

parse colorP "" "  Red" 

Cela m'a donné l'erreur suivante:

unexpected "R" 
expecting space or "Yellow" 

Cependant, je suis à la recherche sur Hoogle pour la documentation qui va avec l'opérateur <|> et là je trouve les éléments suivants:

This combinator implements choice. The parser p <|> q first applies p. If it succeeds, the value of p is returned. If p fails without consuming any input, parser q is tried.

donc, je pense que le problème avec l'exemple ci-dessus est que l'analyseur p (dans ce cas symbol "Yellow") alrea dy a consommé des intrants, à savoir les blancs! Alors, je refactorisé mon colorP comme ceci:

colorP = 
    liftM mkColor $ spaces >> (string "Yellow" <|> string "Red" <|> string "Blue" <|> string "Green") 
where 
    -- mkColor same as before 

qui donne le résultat que je veux.

Maintenant, je me demande s'il n'y a pas d'analyseur comme l'analyseur symbol que j'ai écrit, mais qui remet l'entrée en cas d'échec. Ou est la deuxième mise en œuvre de colorP celle qui est le plus Haskell-ish?

Répondre

2

Vous pouvez utiliser try

symbol s = try (spaces >> string s) 

The parser try p behaves like parser p, except that it pretends that it hasn't consumed any input when an error occurs.