f# - 简单的 FParsec 列表示例

标签 f# fparsec

我刚刚开始使用 FParsec,无法完全理解一个简单的列表解析器。 给定输入

“{ a;b;c d; }”

我想得到结果 ['a';'b';'c';'d']

如果我这样做

let baseChars = ['0'..'9'] @ ['A'..'Z'] @ ['a'..'z'] @ ['_'; '-']
let chars : Parser<_> = anyOf baseChars
let nameChars : Parser<_> = anyOf (baseChars @ ['.'])                

let semiColonList p : Parser<_> = sepBy p (pstring ";")
let pList p : Parser<_> = between (pstring "{") (pstring "}") (semiColonList p)

do  """{
    a;b;c;
    d;
}"""
    |> run (parse {
        let! data = pList (spaces >>. many1Chars nameChars)
        return data
    })
    |> printfn "%A"

我在最后一个 } 上失败了,因为它试图在关闭 between 解析器之前在 nameChars 解析器上匹配它。 这感觉就像我缺少一个简单的解决方案,特别是因为如果我删除 d 之后的最后一个分号,所有工作都会按预期进行。 任何帮助表示赞赏。

[编辑] 感谢 Fyodor Soikin 的以下工作:

    let semiColonList p = many (p .>> (pstring ";" >>. spaces))
    let pList p : Parser<_> = between (pstring "{") (pstring "}") (semiColonList p)
    """{
    a;b;c;
    d;
}"""
    |> run (parse {
        let! data = pList (spaces >>. many1Chars nameChars)
        return data
    })
    |> printfn "%A" 

最佳答案

sepBy 不允许尾随分隔符。像 sepBy a b 这样的解析器旨在解析像 a b a b a 这样的输入,但是你的输入像 a b a b a b - 有一个额外的分隔符 b 最后。

您要做的是解析多个类似于 a b 的表达式 - 这将为您提供所需的输入形状。

为了解析一个这样的表达式,使用排序运算符 .>>,为了解析多个这样的对,使用 many:

semiColonList p = many (p .>> pstring ";")

关于f# - 简单的 FParsec 列表示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56941072/

相关文章:

casting - 在 F# 中将 DateTime 分配给 Nullable<DateTime>

f# - F# 中的 Haskell 样式到中缀运算符

visual-studio - Visual Studio 2013 Ultimate 调试器未显示整个列表

f# - 检测 FParsec 何时未解析所有输入

f# - 如何处理可选的尾随逗号?

f# - 空格敏感 FParsec

f# - 为什么从 F# 调用我的 C 代码非常慢(与 native 相比)?

.net - F# int.MaxValue 是 "not a valid constant expression,"但 System.Int32.MaxValue 是?

f# - 如何使用 FParsec 解析评论

f# - 使用 FParsec 解析分隔列表