2016-12-29 2 views
1

Я использую модуль в Haskell для анализа файлов. Одним из компонентов этих файлов являются цвета. Я создал тип для цветов, как это:Разбор пропусков перед или-else с Parsec

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

Моя первая попытка синтаксического анализа цвета выглядит следующим образом:

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 

Я создал symbol анализатор, который в основном съедает столько пробелов, насколько это возможно, а затем ест данная строка s. Однако это не работает. Я проверить этот код следующего вызова:

parse colorP "" "  Red" 

Это дало мне следующую ошибку:

unexpected "R" 
expecting space or "Yellow" 

Однако, я пошел искать на Hoogle для документации, которая идет с оператором <|> и там я нашел следующий:

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.

Так что, я думаю, что проблема с приведенным выше примером является то, что синтаксический анализатором p (в данном случае symbol "Yellow") alrea dy действительно потреблял некоторый вклад, а именно пробелы! Итак, я переработан моей colorP так:

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

, который дает результат я хочу.

Теперь, мне интересно, нет ли парсера, как анализатор symbol, который я написал, но это возвращает данные в случае сбоя. Или это вторая реализация colorP той, которая является наиболее Haskell-ish?

ответ

2

Вы можете использовать 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.

Смежные вопросы