2个版本

使用旧的Rust 2015

0.0.2 2018年10月31日
0.0.1 2018年9月27日

#1877 in 进程宏

MIT/Apache

130KB
3.5K SLoC

GLL解析框架

Build Status Latest Version Rust Documentation

用法

开始的最简单方法是使用 gll-macros

[dependencies]
gll = "0.0.2"
gll-macros = "0.0.2"

例如,对于一个类似于JSON的语法,你可以这样写,使用普通标识符而不是字符串字面量作为字段名,并允许使用括号中的Rust表达式作为值

mod json_like {
    gll_macros::proc_macro_parser! {
        Value =
            | Null:"null"
            | False:"false"
            | True:"true"
            | Literal:LITERAL
            | Array:{ "[" elems:Value* % "," "]" }
            | Object:{ "{" fields:Field* % "," "}" }
            | InterpolateRust:{ "(" TOKEN_TREE+ ")" }
            ;
        Field = name:IDENT ":" value:Value;
    }
}

你也可以使用构建脚本来生成解析器(待办事项:文档)。

要使用该语法解析字符串

let tokens = string.parse::<gll::grammer::proc_macro::TokenStream>().unwrap();
json_like::Value::parse(tokens).unwrap().with(|value| {
    // ...
});

语法

所有语法都包含一组命名规则,其语法为 = rule;。 (规则的顺序并不重要)

规则由以下组成

  • 分组,使用 {...}
  • 字符串字面量,与输入字符/标记精确匹配
  • 字符范围'a'..='d' 等价于 "a"|"b"|"c"|"d"
    • 仅在无扫描模式中
  • 内置规则IDENTPUNCTLITERALTOKEN_TREE
    • 仅在进程宏模式中
  • 命名规则,通过其名称引用
  • 连接A B - "A 后跟 B"
  • 选择A | B - "要么 A 要么 B"
  • 可选A? - "要么 A 要么什么也没有"
  • 列表: A* - "零个或多个 A",A+ - "一个或多个 A"
    • 可选分隔符:A* % "," - "逗号分隔的 A"
    • 变体:A* %% "," - "逗号分隔的 A",可选尾随逗号

规则的部分可以用 字段名 标记,以允许以后访问它们

LetDecl = "let" pat:Pat { "=" init:Expr }? ";"; 生成

// Note: generic parameters omitted for brevity.
struct LetDecl {
    pat: Handle<Pat>,
    init: Option<Handle<Expr>>,
}

一个 Rust 特定的约定是,交替字段是枚举变体。

Expr = Lit:LITERAL | Add:{ a:Expr "+" b:Expr }; 生成

enum Expr {
    Lit(Handle<LITERAL>),
    Add {
        a: Handle<Expr>,
        b: Handle<Expr>,
    },
}

许可证

根据您选择以下之一

由您选择。

贡献

除非您明确声明,否则根据 Apache-2.0 许可证定义的任何有意提交以包含在此软件包中的贡献,将根据上述条款双许可,不附加任何额外条款或条件。

依赖项

~555KB
~12K SLoC