Parsing 如何使用解析器组合器进行回溯搜索?
我有一个解析器列表,例如,Parsing 如何使用解析器组合器进行回溯搜索?,parsing,haskell,trifecta,Parsing,Haskell,Trifecta,我有一个解析器列表,例如,[string“a”,string“ab”],它们是“重叠的”。我既不能改变解析器本身,也不能改变它们的顺序 使用这些解析器,我想解析一系列令牌,每个令牌都与其中一个解析器完全匹配,例如“aaaab”、“ab”、“abab”,但不是“abb” 如果没有解析器,我只需要实现dept-first搜索,但我想用解析器解决这个问题 我了解到这一点: import Control.Applicative import Text.Trifecta parsers = [strin
[string“a”,string“ab”]
,它们是“重叠的”。我既不能改变解析器本身,也不能改变它们的顺序
使用这些解析器,我想解析一系列令牌,每个令牌都与其中一个解析器完全匹配,例如“aaaab”、“ab”、“abab”
,但不是“abb”
如果没有解析器,我只需要实现dept-first搜索,但我想用解析器解决这个问题
我了解到这一点:
import Control.Applicative
import Text.Trifecta
parsers = [string "a",string "ab"]
parseString (many (choice parsers) <* eof) mempty "aab"
但这并不是:
parseString (try (foldl1 (<|>) $ map (\x -> x <* eof) parsers)) mempty "ab"
parseString(try(foldl1()$map(\x->xtry
级别执行得太高。您应该在各个解析器上执行它。例如:
parseString (foldl1 (<|>) $ map (\x -> try (x <* eof)) parsers) mempty "ab"
因此这里是try
不是左操作数的一部分。因此,如果第一个解析器失败,“游标”将不会返回到它决定尝试第一个操作数的位置
我们可以通过使用以下工具来改进上述内容:
导入数据。可折叠(asum)
parseString(asum)(map(\x->try(x))左折叠在这里似乎不合适。为什么不使用右折叠呢?另外,部分折叠是令人伤心的。foldr()empty
应该可以做到,不是吗?@dfeuer:是的,我在这里只演示了“最小的更改”。但实际上,这是可以改进的。
parseString (foldl1 (<|>) $ map (\x -> try (x <* eof)) parsers) mempty "ab"
parseString ((try (string "a" <* eof)) <|> (string "ab" <*eof)) mempty "ab"
parseString (try ((string "a" <* eof) <|> (string "ab" <*eof))) mempty "ab"
import Data.Foldable(asum)
parseString (asum (map (\x -> try (x <* eof)) parsers)) mempty "ab"