gpt4 book ai didi

haskell - 使用 Megaparsec 使用开始和结束符号解析 block 注释

转载 作者:行者123 更新时间:2023-12-03 20:33:20 32 4
gpt4 key购买 nike

我想使用 Megaparsec 在 Haskell 中解析与此类似的文本。

# START SKIP
def foo(a,b):
c = 2*a # Foo
return a + b
# END SKIP

,其中 # START SKIP# END SKIP标记要解析的文本块的开始和结束。

skipBlockComment 相比我希望解析器返回开始和结束标记之间的行。

这是我的解析器。
skip :: Parser String
skip = s >> manyTill anyChar e
where s = string "# START SKIP"
e = string "# END SKIP"
skip解析器按预期工作。

允许在开始和结束标记中使用可变数量的空格,例如 # START SKIP我尝试了以下方法:
skip' :: Parser String
skip' = s >> manyTill anyChar e
where s = symbol "#" >> symbol "START" >> symbol "SKIP"
e = symbol "#" >> symbol "END" >> symbol "SKIP"

使用 skip'解析上述文本会出现以下错误。
3:15:
unexpected 'F'
expecting "END", space, or tab

我想了解此错误的原因以及如何修复它。

最佳答案

正如亚历克已经评论过的那样,问题在于 e遭遇'#' ,它算作一个消耗的字符。而 parsec 及其衍生产品的工作方式是,一旦您使用了任何字符,您就会致力于该解析分支——即 manyTill anyChar然后不再考虑替代方案,即使 e最终失败在这里。

不过,您可以通过将结束分隔符包装在 try 中轻松请求回溯。 :

skip' :: Parser String
skip' = s >> manyTill anyChar e
where s = symbol "#" >> symbol "START" >> symbol "SKIP"
e = try $ symbol "#" >> symbol "END" >> symbol "SKIP"

这将在消费之前 '#'设置一个“检查点”,当 e稍后失败(在您的示例中,在 "Foo" 处),它将表现得好像根本没有匹配的字符。

事实上,传统的解析也会为 skip 提供相同的行为。 .只是,因为寻找一个字符串并且只有在它完全匹配时才成功是一项如此常见的任务,megaparsec 的 stringtry . string 一样实现,即如果故障发生在该固定字符串内,则它将始终回溯。

然而,复合解析器在默认情况下仍然不会回溯,就像它们在 attoparsec 中所做的那样。主要原因是,如果任何事情都可以回溯到任何一点,那么您就无法在错误消息中真正得到明确的失败点。

关于haskell - 使用 Megaparsec 使用开始和结束符号解析 block 注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40580164/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com