1 个稳定版本
4.6.6 | 2023年2月4日 |
---|
#99 在 解析工具
用于 redis_wasi
515KB
12K SLoC
combine
受 Haskell 库 Parsec 启发的 Rust 解析器组合器实现。与 Parsec 一样,解析器默认为 LL(1),但可以使用 attempt 组合器 选择性地使用任意前瞻。
示例
extern crate combine;
use combine::{many1, Parser, sep_by};
use combine::parser::char::{letter, space};
// Construct a parser that parses *many* (and at least *1) *letter*s
let word = many1(letter());
// Construct a parser that parses many *word*s where each word is *separated by* a (white)*space*
let mut parser = sep_by(word, space())
// Combine can collect into any type implementing `Default + Extend` so we need to assist rustc
// by telling it that `sep_by` should collect into a `Vec` and `many1` should collect to a `String`
.map(|mut words: Vec<String>| words.pop());
let result = parser.parse("Pick up that word!");
// `parse` returns `Result` where `Ok` contains a tuple of the parsers output and any remaining input.
assert_eq!(result, Ok((Some("word".to_string()), "!")));
更多示例可以在 examples、tests 和 benches 文件夹中找到。
教程
教程以及 combine 内部工作原理的解释可以在 维基百科 中找到。
翻译
链接
功能
-
解析任意流 - Combine 可以解析从
&[u8]
和&str
到迭代器和Read
实例的任何内容。如果内置流都不符合您的使用案例,您甚至可以自己实现一些特质来创建自己的自定义 流! -
零拷贝解析 - 当解析内存数据时,combine 可以在不进行拷贝的情况下进行解析。请参阅 range 模块 以获取针对零拷贝解析的专用解析器。
-
部分解析 - Combine 解析器可以在解析过程中的任何位置停止,并在稍后无需丢失任何进度的情况下继续解析。这使得可以开始解析来自诸如套接字之类的 io 设备的局部数据,而无需担心是否有足够的数据来完成解析。如果需要更多数据,解析器将停止,并在更多数据可用时在相同位置恢复。请参阅 异步示例 以及 此文章 以获取介绍。
关于
解析器组合器,广义上讲,是一个函数,它接受多个解析器作为参数,并返回一个新的解析器,该解析器通过组合这些解析器创建。例如,many 解析器接受一个解析器 p
作为输入,并返回一个新的解析器,该解析器将 p
应用零次或多次。得益于解析器组合器提供的模块化,可以在不实现底层管道的同时定义广泛任务的解析器,同时仍然在需要时拥有 Rust 的全部功能。
该库遵循 语义版本控制。
如果您尝试了它,我欢迎您对使用体验的任何反馈。我通常可以通过打开一个问题、发送电子邮件或在 Gitter 上发帖在一天内联系到我。
常见问题解答
为什么我的错误包含难以辨认的位置?
由于 combine
致力于创建几乎没有开销的解析器,因此 &str
和 &[T]
流不携带任何额外的位置信息,而是仅依赖于比较缓冲区的指针来检查哪个 Stream
比另一个 Stream
更靠前。要获取更好的位置,可以调用表示位置的 PointerOffset
上的 translate_position
,或者用 State
包装您的流。
它与 nom 相比如何?
https://github.com/Marwes/combine/issues/73 包含讨论和与 nom 的比较链接。
用 combine 编写的解析器
格式和协议
- GraphQL https://github.com/graphql-rust/graphql-parser(使用自定义分词器作为输入)
- DiffX https://github.com/brennie/diffx-rs
- Redis https://github.com/mitsuhiko/redis-rs/pull/141(使用部分解析)
- Toml https://github.com/ordian/toml_edit
- 制造商交换格式 https://github.com/aidanhs/frametool(将 combine 用作词法分析器)
- JavaScript https://github.com/freemasen/ress
- JPEG 元数据 https://github.com/vadixidav/exifsd
杂项
- 模板语言 https://github.com/tailhook/trimmer
- 代码练习 https://github.com/dgel/adventOfCode2017
- 编程语言
- 查询解析器(+更多) https://github.com/mozilla/mentat
- 查询解析器 https://github.com/tantivy-search/tantivy
额外内容
在 combine-language 中,有一个额外的 crate,它提供了解析编程语言的词法和解析器。
您可以在 这里 找到 combine(解析器组合器)的旧版本。
贡献
当前主分支是 3.0.0 分支。如果您想为 combine 的 2.x 版本提交修复或功能,请将其提交到 2.x 分支,或者将 PR 提交到主分支并要求将其回滚。
最简单的贡献方式就是直接针对使用combine时遇到的问题提交一个issue。如果你有兴趣为这个库添加功能,这里有一份开始工作的一些更容易着手的项目清单。
- 添加额外的解析器 如果你有其他解析器的建议,只需提交一个包含实现方案的issue或PR。
- 添加额外的示例 更多的使用combine的示例总是很有用的!
- 添加和改进文档 虽然这项工作可能不那么吸引人,但良好的文档的重要性不容小觑。
依赖关系
~0.1–13MB
~87K SLoC