我有一个解析器列表,例如[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"