#parser-generator #nom #parser #parser-combinator

nom-peg

基于 nom 构建的 PEG 解析器生成器

2 个版本

使用旧的 Rust 2015

0.1.1 2019 年 4 月 10 日
0.1.0 2019 年 4 月 10 日

#314解析器工具

GPL-3.0 或更新版

19KB
306

Nom 的 PEG 语法

nom-peg 是基于 nom 的 PEG (解析表达式语法) 解析器生成器,其语法深受 LALRPOP 启发。

使用 nom-peg 定义的语法可以与其他 nom 解析器自由混合。

示例

let arithmetic = grammar! {
    // a grammar can have as many non-terminals as you want, and can return any type
    parse: i64 = <expr> "="

    // alternatives are separated by `|`,
    // and the `=> { ... }` syntax is used to manipulate the output of the parser before returning it
    expr: i64 = <l: product> "+" <r: expr> => { l + r }
              | <l: product> "+" <r: expr> => { l - r }
              | product

    // the `<...>` syntax is used to capture the output of a sub-parser,
    // and optionally assign it to a local variable with `<name: ...>`
    product: i64 = <l: value> "*" <r: product> => { l * r }
                 | <l: value> "/" <r: product> => { l / r }
                 | value

    value: i64 = ("0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9")+ => { result.join("").parse::<i64>().unwrap() }
               | "(" <expr> ")"
};

// when the grammar is defined you can use any of the non-terminals as parser functions
assert_eq!(arithmetic.parse("123="), Ok(("", 123 as i64)));
assert_eq!(arithmetic.parse("1+1="), Ok(("", 2 as i64)));
assert_eq!(arithmetic.parse("12+(3*7)="), Ok(("", 33 as i64)));

依赖关系

~3MB
~63K SLoC