考虑以下玩具语法和解析器:
(* in EBNF:
ap = "a", { "ba" }
bp = ap, "bc"
*)
let ap = sepBy1 (pstring "a") (pstring "b")
let bp = ap .>> (pstring "bc")
let test = run bp "abababc"
我得到以下输出:
Error in Ln: 1 Col: 7
abababc
^
Expecting: 'a'
清楚
sepBy1
看到最后 b
并预计它会导致另一个 a
,当它没有找到时失败。是否有 sepBy1
的变体这将回溯到 b
并使这个解析成功?有什么理由我不应该使用它吗?
最佳答案
这是实现 sepBy1
的这种变体的一种方法。 :
let backtrackingSepBy1 p sep = pipe2 p (many (sep >>? p)) (fun hd tl -> hd::tl)
避免在解析器语法中回溯通常会使解析器更快、更便携且更易于调试。因此,如果您有机会通过重组语法来避免回溯(不会使其过于复杂),我建议您这样做。
关于f# - FParsec:回溯 `sepBy`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45653927/