Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell Parsec的非贪婪重复_Haskell_Parsec_Non Greedy - Fatal编程技术网

Haskell Parsec的非贪婪重复

Haskell Parsec的非贪婪重复,haskell,parsec,non-greedy,Haskell,Parsec,Non Greedy,我试着把我的输入分成与特定模式相匹配的部分和其他部分 data Data = A Int | B Char | C String parseDatas :: Parsec [Token] () a [Data] 我已经写了两个或多或少复杂的解析器 parseA :: Parsec [Token] () Data parseB :: Parsec [Token] () Data 这正是我要找的东西。现在显而易见的解决办法是 parseDatas = many (parseA <|>

我试着把我的输入分成与特定模式相匹配的部分和其他部分

data Data = A Int | B Char | C String
parseDatas :: Parsec [Token] () a [Data]
我已经写了两个或多或少复杂的解析器

parseA :: Parsec [Token] () Data
parseB :: Parsec [Token] () Data
这正是我要找的东西。现在显而易见的解决办法是

parseDatas = many (parseA <|> parseB <|> parseC)
但是现在,parseC消耗了以我不寻找的东西开始的整个输入,忽略了应该产生A或B的任何模式

如果我的模式是regexs1,我现在会将+运算符更改为非贪婪+?操作人员如何对多个解析器组合器执行相同的操作

1:我不能使用它,因为我在操作令牌而不是字符

我找到了一个解决办法

parseC = makeC <$> many1 (notFollowedBy (parseA <|> parseB) >> anyToken)
但这看起来确实不太理想。这不是一般的。一定有更好的


我还研究了建议定义递归解析器的位置,但如果我不想删除中间标记并将其收集到列表中,这看起来像是一个骗局。

您可以让parseC一次只使用一个标记:

parseDatas=many$parseA parseB C。显示任意令牌

然后,如果需要,将相邻的Cs分组为一个,以保留语义:

groupCs (C c) (C c':xs) = C (c ++ c') : xs
groupCs x xs = x : xs
parseDatas = foldr groupCs [] <$> many (parseA <|> parseB <|> (C . show <$> anyToken))
来自 可以将字符串拆分为与特定模式匹配的部分和其他部分

试试这个:

sepCap parseA parseB 或者,如果parseA和parseB是不同类型事物的解析器,那么可以使用 比如:

sepCap eitherP parseA parseB
嗯,我的问题是我必须使用makeC,它需要一个令牌列表。马克克。returnanytoken可以工作,但它看起来很难看,而且和我当前的解决方案一样低效。@Bergi,下面是如何腾出空间来应用make。再往这边放透镜库。@Bergi你为什么相信makeC。返回任何令牌是否无效?它当然不会像你的问题中那样效率低下。我不知道,我想我必须进行测试。在Haskell中,性能有点不可预测。只是我使用的库公开的唯一一个转换令牌的函数使用了这个令牌列表,所以我认为应该使用更多的令牌来调用它。它的确切类型是[Token]->Data.Text,如果这有帮助的话。感谢函子方法,我想我可以做到这一点。
parseC = makeC <$> many1 (notFollowedBy (parseA <|> parseB) >> anyToken)
groupCs (C c) (C c':xs) = C (c ++ c') : xs
groupCs x xs = x : xs
parseDatas = foldr groupCs [] <$> many (parseA <|> parseB <|> (C . show <$> anyToken))
data Data c = A Int | B Char | C c deriving Functor

groupCs :: [Data a] -> [Data [a]] -> [Data [a]]
groupCs (C c) (C cs:xs) = C (c:cs) : xs
groupCs (C c) xs = C [c] : xs
groupCs x xs = x : xs

parseDatas = (map.fmap) make . foldr groupCs [] <$> many (parseA <|> parseB <|> (C <$> anyToken))