Haskell Parsec, адаптирующий oneOf к [String]

Я прохожу схему "Напиши себе" за 48 часов.

 symbol :: Parser Char
 symbol = oneOf "!#$%&|*+-/:<=>?@^_~"

Это отлично подходит для символов, но что, если у меня есть список ключевых слов? (т.е. struct, int)

можно ли адаптироваться к спискам? Это в идеале то, что я хочу, изображено ниже.

keywords :: Parser String 
keywords = oneOf ["struct","int",..etc]

Или я должен импортировать Text.Parsec.Char и попытаться сопоставить строку по списку ключевых слов?

Я пытаюсь токенизировать и просто хотел узнать, какие лучшие практики были у других, которые пошли по этому пути.

Документы говорят использовать что-то вроде этого:

 divOrMod    =   string "div" 
              <|> string "mod"

http://hackage.haskell.org/packages/archive/parsec/3.0.0/doc/html/Text-Parsec-Char.html

1 ответ

Решение

Общая форма этого choice комбинатор, который имеет следующий тип:

choice :: Stream s m t => [ParsecT s u m a] -> ParsecT s u m a

По сути, вы даете ему список парсеров, и он пробует их по порядку, пока один из них не преуспеет. choice реализуется с использованием (<|>)так что это такой же подход.

В вашем случае, чтобы соответствовать списку ключевых слов, но не других парсеров, вы можете просто сопоставить string по списку Stringс, а затем использовать choice на что.

С другой стороны, mapM string сделал бы что-то совершенно другое - он ожидал бы, что все парсеры преуспеют в порядке.

Другие вопросы по тегам