Я использую модуль в 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?