#parser-combinator #parser #combinator #ll #data-stream #arguments-parser

无std combine

在任意流上实现快速解析器组合,支持零拷贝

79 个版本 (稳定)

4.6.7 2024年4月10日
4.6.6 2022年8月9日
4.6.4 2022年4月25日
4.6.3 2022年1月12日
1.0.0-beta2015年7月17日

#3解析工具

Download history 571338/week @ 2024-04-30 582735/week @ 2024-05-07 610359/week @ 2024-05-14 611205/week @ 2024-05-21 667205/week @ 2024-05-28 671029/week @ 2024-06-04 675129/week @ 2024-06-11 616451/week @ 2024-06-18 665738/week @ 2024-06-25 617240/week @ 2024-07-02 654992/week @ 2024-07-09 687513/week @ 2024-07-16 708187/week @ 2024-07-23 699238/week @ 2024-07-30 718126/week @ 2024-08-06 757812/week @ 2024-08-13

3,011,136 每月下载量
用于 4,236 个 crate (100 个直接使用)

MIT 协议

510KB
12K SLoC

combine

Build Status Docs Gitter

受 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()), "!")));

更详细示例可在 示例测试基准测试 文件夹中找到。

教程

教程以及关于 combine 内部运作的解释可以在 Wiki 中找到。

翻译

日语

文档和示例

crates.io

特性

  • 解析任意流 - 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 编写的解析器

格式和协议

杂项

额外内容

combine-language 中有一个额外的crate,它提供了用于词法分析和解析编程语言的解析器。

贡献

最简单的方式是通过打开一个问题来贡献,关于你在使用 combine 时遇到的问题,但如果你有兴趣向库中添加内容,这里有一份易于开始工作的任务清单。

  • 添加额外的解析器 如果你有一个其他解析器的建议,只需打开一个问题或PR并提交实现。
  • 添加额外的示例 使用 combine 的更多示例总是很有用!
  • 添加和改进文档 这不是最花哨的工作,但好的文档的重要性不容小觑。

依赖项

~0.1–2.2MB
~35K SLoC