Documentation

Earlgrey is a crate for building parsers that can understand context-free grammars.

How to use it

Parsing stage:

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. - To build this you provide a function that given a terminal produces an AST node. - Then you define semantic actions to evaluate how to interpret each rule in the grammar.

Example

A toy parser that can understand sums.

```rust 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());

} ```

References for Earley's algorithm