不确定这是否可行(或推荐),但我实际上是在尝试使用Parsec在文件中搜索一系列字符。示例文件:
START (name)
junk
morejunk=junk;
dontcare
foo ()
bar
care_about this (stuff in here i dont care about);
don't care about this
or this
foo = bar;
also_care
about_this
(dont care whats in here);
and_this too(only the names
at the front
do i care about
);
foobar
may hit something = perhaps maybe (like this);
foobar
END
以下是我尝试让它发挥作用:
careAbout :: Parser (String, String)
careAbout = do
name1 <- many1 (noneOf " \n\r")
skipMany space
name2 <- many1 (noneOf " (\r\n")
skipMany space
skipMany1 parens
skipMany space
char ';'
return (name1, name2)
parens :: Parser ()
parens = do
char '('
many (parens <|> skipMany1 (noneOf "()"))
char ')'
return ()
parseFile = do
manyTill (do
try careAbout <|>
anyChar >> return ("", "")) (try $ string "END")
我试图通过查找careAbout
来强制搜索,如果这不起作用,请吃一个字符再试一次。我可以解析中间的所有垃圾(我知道它可能是什么),但我不关心它是什么(所以为什么还要解析它),而且它可能很复杂。
问题是,我的解决方案不太有效。 anyChar
最终消耗了所有内容,搜索END
永远不会有机会。此外,careAbout
中的某个地方我们点击了eof
,而某些Exception
因此被抛出。
这可能是完全错误的做法,我想知道 a 方式,甚至更好的方法,也就是Right Way™。
答案 0 :(得分:1)
如果不是parens
解析器,这将非常适合常规语言解析器,例如regex-applicative。这是因为常规语言解析器对于“回溯”更加“聪明”(实际上根本没有回溯,但是每个可能的分支都被探索过。)
但是,您可能知道,匹配的括号不是常规语言。如果你可以放松你的语法成为常规,试试一下regex-applicative。
答案 1 :(得分:0)
我不能从OP的帖子中真正分辨出我们关心文件的哪个部分,或者 不,所以我不会发布特定的解决方案。但总的来说, 在文件中搜索与递归解析器匹配的模式 可以使用 replace-megaparsec。