f# - FParsec:回溯 `sepBy`

标签 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"

我得到以下输出:
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/

相关文章:

asynchronous - F#- AsyncSeq - 如何返回列表中的值

c# - 在 F# 中使用 C# 流利库

parsing - Parsec:获取表达式的开始和结束源位置?

regex - 使用 RegexParsers 解析空格

F#、FParsec 和更新 UserState

fparsec - 为什么 FParsec 使用列表?

使用 F# 进行 Azure.Data.Tables 序列化

sql-server - 将引用 FSharp.Data.SqlProvider 的 SQL CLR 程序集注册到 SQL Server 时出现问题

parsing - 在 Scala 中使用解析器组合器创建递归数据结构

使用 OperatorPrecedenceParser 使用 FParsec 解析函数应用程序?