自制" Many1"解析器

时间:2017-04-13 05:33:37

标签: parsing haskell

这是在线课程的任务。我已经坐了两天了。请给出一些解释或提示来解决它。

此处的类型

newtype Prs a = Prs { runPrs :: String -> Maybe (a, String) }

我需要实现many1解析器。这是它应该如何工作

> runPrs (many1 $ char 'A') "AAABCDE"
Just ("AAA","BCDE")
> runPrs (many1 $ char 'A') "BCDE"
Nothing

我有像这样实现的解析器many

many p = (:) <$> p <*> many p  <|> pure []

以前示例的输出。

*Main> test9
Just ("AAA","BCDE")
*Main> test10
Just ("","BCDE")

注意上一个结果,它返回空字符串,但many1应该返回Nothing。我不知道如何更改many代码以使其像many1一样工作。我无法理解如何停止第一个不正确的符号。

1 个答案:

答案 0 :(得分:3)

你的many1需要某种方法来失败:正如你所写的那样,它消耗了一段时间的字符,将它们收集到待处理的结果中,直到它最终耗尽了匹配。这不包括解析可能失败的任何情况。

你在这里实现的是many0,一种消耗0次或更多次重复的解析器。你能想到一种在many1方面实施many0的方法吗?它看起来像:

  1. 在失败的情况下,使用p的一个实例,不用替代
  2. 消耗0个或更多p个实例,当失败时返回[]
  3. 或者在Haskell,

    many1 :: Prs a -> Prs [a]
    many1 p = (:) <$> p <*> many0 p