2个版本
使用旧的Rust 2015
0.0.2 | 2018年10月31日 |
---|---|
0.0.1 | 2018年9月27日 |
#1877 in 进程宏
130KB
3.5K SLoC
GLL解析框架
用法
开始的最简单方法是使用 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"
- 仅在无扫描模式中
- 内置规则:
IDENT
,PUNCT
,LITERAL
,TOKEN_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 License, Version 2.0 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
由您选择。
贡献
除非您明确声明,否则根据 Apache-2.0 许可证定义的任何有意提交以包含在此软件包中的贡献,将根据上述条款双许可,不附加任何额外条款或条件。
依赖项
~555KB
~12K SLoC