在MegaParsec中有两种解析器的方法吗?

时间:2016-02-28 00:23:03

标签: parsing haskell

如果我有一个解析器:

notZeroOrOne :: Parser Char
notZeroOrOne = noneOf ['0' , '1'] 

有没有办法可以结合另一个解析器的规则,比如digitChar,这样我就可以得到一个只有两个解析器都能通过才能通过的解析器?

这样的东西
biggerThanOne :: Parser Char
biggerThanOne  = digitChar && notZeroOrOne 

2 个答案:

答案 0 :(得分:6)

正如用户2407038在评论中建议的那样,使用lookAhead功能可以实现。

biggerThanOne :: Parser Char
biggerThanOne =
  lookAhead digitChar *> notZeroOrOne

然而,解析器本质上是顺序的,因此应用顺序逻辑更有效和易于理解。例如,使用Monad的{​​{1}}实例:

Parser

biggerThanOne :: Parser Char biggerThanOne = do c <- digitChar if c /= '0' && c /= '1' then return c else unexpected "Not bigger than one"

MonadPlus

可以重构以使用biggerThanOne :: Parser Char biggerThanOne = mfilter (\c -> c /= '0' && c /= '1') digitChar Ord Char实例,并且非常清楚地表达您的意图:

biggerThanOne :: Parser Char
biggerThanOne =
  mfilter (> '1') digitChar

答案 1 :(得分:1)

在uu-parsinglib中有一个amb组合器,它为您提供所有可能的解析。您可以使用它来查看是否同时获得两个解析。如果只得到一个解析,则可以使用monad失败

p Files.copy(p1.toPath(), p2.toPath(), StandardCopyOption.REPLACE_EXISTING); q = amb(p&lt; |&gt; q)&gt;&gt; = \ r - &gt;如果长度r == 2然后返回...其他pFail