избегайте разбора последнего разделителя с помощью `sepBy` - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь разобрать строку, используя megaparsec.

Частично это повторение строк, разделенных разделителем, и я использую sepBy для этого. Рассмотрим, например,

sepBy (char 'a') (char 's')

Это правильно анализирует "", "a", "asa", ... Проблема возникает, если мне нужно продолжить анализ с другим анализатором, который начинается с моего разделителя, как в

(,) <$> sepBy (char 'a') (char 's') <*> string "something"

Если я попытаюсь разобрать строку "asasomething" с этим анализатором, я ожидаю получить ("aa", "something"). Вместо этого я получаю ошибку, потому что у меня нет a после второго s.

Я пробовал также с sepEndBy, но результат тот же

1 Ответ

2 голосов
/ 14 февраля 2020

Я решил это следующим образом.

Реализация sepBy, используемая megapersec,

sepBy :: MonadPlus m => m a -> m sep -> m [a]
sepBy p sep = do
  r <- C.optional p
  case r of
    Nothing -> return []
    Just  x -> (x:) <$> many (sep >> p)

Я изменил его на

sepBy :: Parser a -> Parser sep -> Parser [a]
sepBy p sep = do
  r <- optional p
  case r of
    Nothing -> return []
    Just  x -> (x:) <$> many (try $ sep >> p)

, чтобы специализируйте его на Parsec добавьте try, чтобы избежать разбора

...