12个版本
0.3.2 | 2022年3月24日 |
---|---|
0.3.0 | 2020年1月20日 |
0.2.4 | 2019年5月1日 |
0.2.3 | 2019年2月21日 |
0.0.4 | 2016年9月10日 |
#69 in 解析工具
在 2 个crate中使用
155KB
1K SLoC
文档
Earlgrey是一个crate,用于构建能够理解上下文无关语法的解析器。
如何使用
解析阶段
- 首先,您需要使用
GrammarBuilder
定义终端和规则来定义语法。 - 然后为该语法构建一个
EarleyParser
并在某个输入上调用parse
。
在某个输入上调用解析器返回一个不透明的类型(Earley项的列表),它编码了所有可能的树。如果语法是无歧义的,这应该表示一棵树。
评估结果
您需要一个 EarleyForest
,它将遍历所有结果解析树并对它们进行操作。
- 为此,您提供一个函数,该函数给定一个终端产生一个AST节点。
- 然后您定义语义操作来评估如何解释语法中的每个规则。
示例
一个玩具解析器,可以理解求和。
fn main() {
// Gramar: S -> S + N | N; N -> [0-9];
let g = earlgrey::GrammarBuilder::default()
.nonterm("S")
.nonterm("N")
.terminal("[+]", |c| c == "+")
.terminal("[0-9]", |n| "1234567890".contains(n))
.rule("S", &["S", "[+]", "N"])
.rule("S", &["N"])
.rule("N", &["[0-9]"])
.into_grammar("S")
.unwrap();
// Parse some sum
let input = "1 + 2 + 3".split_whitespace();
let trees = earlgrey::EarleyParser::new(g)
.parse(input)
.unwrap();
// Evaluate the results
// Describe what to do when we find a Terminal
let mut ev = earlgrey::EarleyForest::new(
|symbol, token| match symbol {
"[0-9]" => token.parse().unwrap(),
_ => 0.0,
});
// Describe how to execute grammar rules
ev.action("S -> S [+] N", |n| n[0] + n[2]);
ev.action("S -> N", |n| n[0]);
ev.action("N -> [0-9]", |n| n[0]);
println!("{}", ev.eval(&trees).unwrap());
}