光年requireFailure不回溯

时间:2018-08-08 06:19:29

标签: idris parser-combinators lightyear

我想解析一系列任意4个字符。但是,这些字符不应形成特定的字符串(在下面的示例中为@Query(value = "select a from TableA a where a.tableB is null and a.id=?1") TableA findTableAValues(Long id); )。因此x"bb"可以,但是"aaaa""abcd"都不应该匹配。

我编写了以下解析器:

"bbcd"

但是,我注意到它“吃”了单个"abbc"个字符。例如

ntimes 4 (requireFailure (string "bb") *> anyChar)

结果为b(但是,按预期结果在parse (ntimes 4 (requireFailure (string "bb") *> anyToken)) "abcde" ['a', 'c', 'd', 'e']上失败)。

作为解决方法,我使用了自己的"bbcd"实现:

"abbc"

所以

requireFailure

按照我的期望提供了requireFailure' : Parser a -> Parser () requireFailure' p = do isP <- p *> pure True <|> pure False if isP then fail "argument parser to fail" else pure ()

显然光年解析器是backtrack-by-default,除非有人调用parse (ntimes 4 (requireFailure' (string "bb") *> anyToken)) "abcde"

所以我的问题是,为什么['a', 'b', 'c', 'd']的库实现在参数失败的情况下不进行回溯,这是预期的行为吗?

1 个答案:

答案 0 :(得分:3)

如果您查看the implementation of requireFailure,您会发现它以状态us调用“成功”延续s,它会在之后运行其参数比以前的ST i pos tw要好。

requireFailure : ParserT str m tok -> ParserT str m ()
requireFailure (PT f) = PT $ \r, us, cs, ue, ce, (ST i pos tw) =>
                               f r
                                 (\t, s => ue [Err pos "argument parser to fail"] s)
                                 (\t, s => ce [Err pos "argument parser to fail"] s)
                                 (\errs, s => us () s)
                                 (\errs, s => cs () s)
                                 (ST i pos tw)

文档声称requireFailure在parsec和that doesn't consume any input中分别称为notFollowedBy,因此您可以说这是LightYear方面的错误。

您可以打开一个错误报告,建议用类似以下内容的代码替换当前代码(我不知道Idris是否支持@模式):

requireFailure : ParserT str m tok -> ParserT str m ()
requireFailure (PT f) = PT $ \r, us, cs, ue, ce, s@(ST i pos tw) =>
                               f r
                                 (\t, s => ue [Err pos "argument parser to fail"] s)
                                 (\t, s => ce [Err pos "argument parser to fail"] s)
                                 (\errs, _ => us () s)
                                 (\errs, _ => cs () s)
                                 s