gpt4 book ai didi

haskell - 使用 Parsec 按字符串正确分割

转载 作者:行者123 更新时间:2023-12-02 10:37:13 25 4
gpt4 key购买 nike

下面的代码输出Right ["1<!>2<!>3"] ,但我需要Right ["1", "2", "3"] .

import Text.ParserCombinators.Parsec

response = contents :: CharParser () [String]
where
contents = sepBy content contentDelimiter
contentDelimiter = string "<!>"
content = many anyChar

main = do
putStrLn $ show $ parse response "Response" "1<!>2<!>3"

我想这里的问题是 content解析器消耗 sepBy 之前的所有输入开始测试分隔符。所以,我的问题是:

  1. 我的假设正确吗?如果不是,我犯了什么错误?

  2. 针对此类问题,您会推荐什么解决方案? (使用秒差距)

* content必须匹配任何不包含分隔符的字符串。 1<!>2<!>3这只是一个例子,它可以是 dslkf\n><!>dsf<!>3或其他什么

最佳答案

对于第一个示例,您将替换

content = many anyChar

content = many digit

这样内容的解析器就不会错误地匹配分隔符。

也许您想要匹配的不仅仅是数字,但即便如此,我还是建议您仔细考虑 <!> 之间的有效内容。 s 并编写一个解析器来执行此操作。

为什么?
一旦您拥有了一个非常好的内容解析器,您对响应的定义将是完美的。这样您的内容就可以包括mystring = "hello<!>mum"不被顶级解析器砍断 - 低级 stringLiteral解析器将吃掉整个 "hello<!>mum"并且顶级解析器永远不会看到 <!>正确且无辜地包含在其中。

一般来说,...
在大多数解析情况下,最好真正清楚内容中允许的内容,并仅解析该内容,原因如下:

  • 可重用性(然后您可以在更大的解析器中使用它)
  • 正确性
  • 通常是效率 - 如果避免过多的前瞻,您的解析器运行得更快。

可重用性很重要。目前,如果您使用仅在 <!> 上进行拆分的解析器并吃掉其他所有东西,它保证吃掉整个输入,并且您将无法再进行任何解析。

自下而上
您的解析器应该从头开始工作 - 您在评论中很好地描述了这一点,即“将解析器从特定到一般堆叠”。

为了便于测试,按照这个顺序编写它们是最简单的,所以首先编写一个与 stringChar 匹配的内容。然后stringLiteral之前member之前array之前object之前json之前content然后response 。您可以让他们一路递归地相互调用。然后您可以使用parseTest一边做一边测试每一个 child 子;打字parseTest response "1<!>2<!>3"进入 ghci 比重写 main 和编译更快。

自上而下?
自上而下编写解析器并没有错,只是更难。你可以写

response = many $ content `sepBy` contentSeparator
content = json <|> somethingElse
json = object <|> array
array = ...

但是,除非您编写了最小的解析器,否则没有任何东西是可测试的。

关于haskell - 使用 Parsec 按字符串正确分割,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13431512/

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