FParsec:回溯`sepBy`

Car*_*lin 5 f# parser-combinators fparsec

考虑以下玩具语法和解析器:

(* 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"
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

Error in Ln: 1 Col: 7
abababc
      ^
Expecting: 'a'
Run Code Online (Sandbox Code Playgroud)

清楚地sepBy1看到最后一个b并期望它导致另一个a,当它找不到时失败.是否有一个变sepBy1体会回溯b并使这个解析成功?我不应该使用它吗?

Ste*_*orf 4

这是实现以下变体的一种方法sepBy1

let backtrackingSepBy1 p sep = pipe2 p (many (sep >>? p)) (fun hd tl -> hd::tl)
Run Code Online (Sandbox Code Playgroud)

避免解析器语法中的回溯通常会使解析器更快、更便携且更易于调试。因此,如果您有机会通过重组语法来避免回溯(而不会使语法变得太复杂),我建议您这样做。