【问题标题】:Implementing try (look-ahead) and untilStop with parser combinators使用解析器组合器实现 try (look-ahead) 和 untilStop
【发布时间】:2017-01-01 13:45:01
【问题描述】:

我正在关注 this tutorial 在 Haskell 中实现 Parser Combinators (a la parsec)。我实现了这篇文章中提到的所有 NanoParsec。

几个小时以来,我一直在努力实施

-- try p. If p fails continue without consuming anything
try :: Parser a -> Parser a
try p = ...

-- Parser for everything, until the character-sequence stop appears. 
-- If stop does not appear at all: fail
untilStop :: String -> Parser String
untilStop stop = ...

我实现untilStop 的最佳尝试看起来有点像这样,但不太有效

untilStop :: String -> Parser String
untilStop (c : cs) = do
  s <- some $ satisfy (/= d)
  string (c : cs) <|> do
    i <- item
    untilStop (d : ds)
  -- maybe use msum from MonadPlus to combine?

我不知道如何结合 si 和递归调用而不会失败,因为 string 没有把所有东西放在一起。

我认为一旦我拥有tryuntilStop 应该是直截了当的。有人可以为我指出正确的方向或实施它 (try) 吗?

现在我还在学习 Monads、Applicative 和相关的东西,所以试图理解 parsec 的源代码对我来说是不可能的。

【问题讨论】:

  • 这个简单的解析器库不需要tryp &lt;|&gt; q 的行为已经类似于 try p &lt;|&gt; q。我说的对吗?
  • 好吧,&lt;|&gt; :: Parser a -&gt; Parser a -&gt; Parser a 需要一个替代我的 tried 选项。我希望能得到一些我可以try 的东西,如果它失败了,什么也不做,然后在我的do 符号中继续下一个语句。
  • &lt;|&gt; 就是这样工作的。

标签: parsing haskell monads alternative-functor


【解决方案1】:

正如我在评论中所说,我认为您不需要像 Parsec 一样的 try

对于untilStop,请检查:

untilStop :: String -> Parser String
untilStop [] = everything
untilStop (c:cs) = item >>= fun
  where fun i = do { s <- untilStop cs;
                     if i == c && s == "" then return "" else failure } <|> do
                     s <- untilStop (c : cs)
                     return (i : s)

首先,如果停止字符串为空,则解析所有内容。其中everything 是:

everything :: Parser String
everything = Parser (\inp -> [(inp,"")])

否则,如果是c:cs的形式,则解析一个字符i,考虑两种情况:

  • 停止字符串正好在解析流的前面(因为c == i 和字符串的其余部分cs 解析得到一个空结果),然后返回“”。或者,

  • 它位于流中的某处,因此您需要进一步寻找它。

请注意,&lt;|&gt; 运算符用于回溯。如果untilStop cs 不是我们想要的,我们需要重新解析,改用untilStop (c:cs)

【讨论】:

  • 感谢您的回答,但这不能正常工作。 parse (untilStop "end") "abcdef end"[("abcd", "ef end")]。它也没有真正使用我认为应该是目标的组合器。
  • 非常感谢很多,理论上可行,但我建议对您的解决方案进行编辑以使其可编译和可复制粘贴。格式化等
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多