【问题标题】:parsec: stopping at empty line秒差距:停在空行
【发布时间】:2020-12-06 11:48:42
【问题描述】:

我想用 parsec 解决以下任务,尽管splitOn "\n\n" 可能是更简单的答案。
我有一个像

这样的输入字符串
testInput = unlines ["ab", "cd", "", "e"] -- "ab\ncd\n\ne"

遇到空行时解析器将停止。

我试过了

import Text.ParserCombinators.Parsec

inputFileP :: GenParser Char st String
inputFileP = many (lower <|> delimP)

delimP :: GenParser Char st Char
delimP = do
  x <- char '\n'
  notFollowedBy (char '\n')
  return x

unexpected '\n' 失败。
为什么?
我的印象是 many x 解析 x 直到它失败然后停止。

【问题讨论】:

    标签: parsing haskell parsec


    【解决方案1】:

    我的印象是许多 x 解析 x 直到它失败然后停止。

    仅当x 失败且未消耗任何输入时才会出现这种情况。如果 x 在使用输入后失败,则整个解析将失败,除非某处有 try (这不仅特定于 many:在这种情况下 x &lt;|&gt; y 也会失败,即使 y 会成功) .在您的情况下,delimP 在已经使用第一个 \n 之后在 notFollowedBy (char '\n') 上失败,因此整个解析失败。

    要更改此行为,您需要使用 try 显式启用回溯,如下所示:

    delimP = try $ do
      x <- char '\n'
      notFollowedBy (char '\n')
      return x
    

    或者,您可以使delimP 在不消耗任何输入的情况下失败(因此无需尝试),方法是使其提前两个字符之前匹配\n

    delimP = do
      notFollowedBy (string "\n\n")
      char '\n'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-20
      • 2017-10-26
      • 2017-09-07
      • 2017-12-09
      • 1970-01-01
      • 2011-09-09
      相关资源
      最近更新 更多