#parser-combinator #nom #combinator #parser #parse

combinedfun

这是一个类似nom的解析器组合库,它避免了宏的使用,同时试图实现至少部分nom的表达能力。

4个版本

0.1.3 2019年8月17日
0.1.2 2019年8月13日
0.1.1 2019年5月13日
0.1.0 2019年5月13日

解析器工具 中排名 252

MIT 许可证

62KB
1K SLoC

combinedfun

这是一个类似nom的解析器组合库,它避免了宏的使用,同时试图实现至少部分nom的表达能力。

欢迎来到这个小巧的库,唯一限制是天空。还有深度递归。还有编译时间。还有类型推理出问题。有时,如果你“幸运”:在生命周期推理上出现重大错误,留你只能使用方法而不是操作符,因为,虽然方法实际上使用了操作符,实际上在那里工作。不要问我为什么。这是一个谜。


lib.rs:

这是一个旨在提供简短且简洁,但易于阅读的解析器组合库。

如果你不知道解析器组合器是如何工作的,我建议先看看 nom

这个库不使用宏,所以对于某些应用来说有点受限(特别是可以使用 map_parser 的地方相当有限)。

它还使用操作符重载来编写易于阅读和编写的解析器。

以下是一个示例(我不知道为什么几乎每个闭包都需要指定其参数)

use std::iter;
use combinedfun as cf;

enum End {
    Repeat(String),
    Add(usize),
}

let parser = (
    cf::record_while(|c: &char| c.is_digit(10), 1..)
    >> (|s: &str| s.parse::<usize>().unwrap())
    >> (
        -cf::tag(" ")
        >> cf::take(..)
        >> (|s: &str| End::Repeat(s.to_owned()))
        |
        -cf::tag("+")
        >> cf::record_while(|c: &char| c.is_digit(10), 1..)
        >> (|s: &str| End::Add(s.parse::<usize>().unwrap()))
    )
    >> (|(i, end)| match end {
        End::Repeat(s) => (0..i).fold("".to_owned(), |acc, _| acc + &s),
        End::Add(j) => (i + j).to_string()
    })
);

assert_eq!(parser.parse("3 abc"), Ok("abcabcabc".to_owned()));
assert_eq!(parser.parse("10 x"), Ok("xxxxxxxxxx".to_owned()));
assert_eq!(parser.parse("42+123"), Ok("165".to_owned()));
assert_eq!(parser.parse("42+abc"), Err(()));
assert_eq!(parser.parse("+123"), Err(()));

无运行时依赖