Crates.io | earlgrey |
lib.rs | earlgrey |
version | 0.3.2 |
source | src |
created_at | 2016-09-10 18:49:05.333505 |
updated_at | 2022-03-24 20:35:55.131687 |
description | A library for parsing context-free grammars using Earley algorithm |
homepage | |
repository | https://github.com/rodolf0/tox/tree/master/earlgrey |
max_upload_size | |
id | 6320 |
size | 349,443 |
Earlgrey is a crate for building parsers that can understand context-free grammars.
Parsing stage:
GrammarBuilder
to define terminals and rules.EarleyParser
for that grammar and call parse
on some input.Invoking the parser on some input returns an opaque type (list of Earley items) that encodes all possible trees. If the grammar is unambiguous this should represent a single tree.
Evaluating the result:
You need an EarleyForest
that will walk through all resulting parse trees and act on them.
A toy parser that can understand sums.
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());
}