У меня есть список парсеров, например, [string "a",string "ab"]
, которые "перекрываются". Я не могу изменить ни сами парсеры, ни их порядок.
С помощью этих парсеров я хочу проанализировать последовательность токенов, каждый из которых будет точно соответствовать одному из парсеров, например, "aaaab", "ab", "abab"
, но не "abb"
Без парсеров я бы просто реализовалПервый поиск в отделе, но я бы хотел решить эту проблему с помощью синтаксических анализаторов.
Я дошел до этого далеко:
import Control.Applicative
import Text.Trifecta
parsers = [string "a",string "ab"]
parseString (many (choice parsers) <* eof) mempty "aab"
Это не удалось, потому что он будет анализировать "a"
оба раза, а не возвращатьсяпотому что choice
этого не делает. Более того, string "a"
успешно выполнялся оба раза, поэтому потребляемый ввод, вероятно, больше не может быть получен. Как реализовать синтаксический анализатор, который может возвращать и выводить список результатов анализа, например, Success ["a","ab"]
?
Если мне требуется, чтобы вход разделил токены, я все равно не могу заставить его работать:
Это работает:
parseString (try (string "a" <* eof) <|> (string "ab" <*eof)) mempty "ab"
Но это не так:
parseString (try (foldl1 (<|>) $ map (\x -> x <* eof) parsers)) mempty "ab"