#[macro_use]
extern crate log;
extern crate cfg;
extern crate env_logger;
extern crate earley_omnitool;
mod helpers;
use cfg::earley::Grammar;
use cfg::Symbol;
use earley_omnitool::forest::{Bocage, CompactBocage};
use earley_omnitool::grammar::InternalGrammar;
use earley_omnitool::recognizer::Recognizer;
use helpers::{Parse, SimpleCompactEvaluator, SimpleEvaluator};
macro_rules! test_trivial_grammar {
($Bocage:ident, $SimpleEvaluator:ident) => {
let _ = env_logger::try_init();
let mut external = Grammar::new();
let start = external.sym();
external.rule(start).rhs([]);
external.set_start(start);
let cfg = InternalGrammar::from_grammar(&external);
let mut evaluator = $SimpleEvaluator::new(
|_: Symbol| unreachable!(),
|_: u32, _: &[&bool]| unreachable!(),
|sym, builder: &mut Vec<bool>| {
builder.reserve(1);
if sym == start {
builder.push(true);
} else {
builder.push(false);
}
},
);
let bocage = $Bocage::new(&cfg);
let mut rec = Recognizer::new(&cfg, bocage);
assert!(rec.parse(&[]));
let mut traversal = rec.forest.traverse();
let results = evaluator.traverse(&mut traversal, rec.finished_node().unwrap());
assert_eq!(results, &[true]);
};
}
#[test]
fn test_trivial_grammar() {
test_trivial_grammar!(Bocage, SimpleEvaluator);
}
#[test]
fn test_trivial_grammar_compact() {
test_trivial_grammar!(CompactBocage, SimpleCompactEvaluator);
}
macro_rules! test_grammar_with_nulling_intermediate {
($Bocage:ident, $SimpleEvaluator:ident) => {
let _ = env_logger::try_init();
let mut external = Grammar::new();
let (start, a, b, c, d, foo) = external.sym();
external
.rule(start)
.rhs([a, b, c, d, foo])
.rule(a)
.rhs([])
.rule(b)
.rhs([])
.rule(c)
.rhs([])
.rule(d)
.rhs([]);
external.set_start(start);
let cfg = InternalGrammar::from_grammar(&external);
let mut evaluator = $SimpleEvaluator::new(
|sym: Symbol| {
if sym == foo {
3
} else {
unreachable!()
}
},
|rule: u32, arg: &[&i32]| {
if rule == 0 {
arg.iter().cloned().fold(0, |a, e| a + e)
} else {
unreachable!()
}
},
|sym, builder: &mut Vec<i32>| {
builder.reserve(1);
if sym == a {
builder.push(1);
} else {
builder.push(2);
}
},
);
let bocage = $Bocage::new(&cfg);
let mut rec = Recognizer::new(&cfg, bocage);
assert!(rec.parse(&[foo.usize() as u32]));
let mut traversal = rec.forest.traverse();
let results = evaluator.traverse(&mut traversal, rec.finished_node().unwrap());
assert_eq!(results, &[10]);
};
}
#[test]
fn test_grammar_with_nulling_intermediate() {
test_grammar_with_nulling_intermediate!(Bocage, SimpleEvaluator);
}
#[test]
fn test_grammar_with_nulling_intermediate_compact() {
test_grammar_with_nulling_intermediate!(CompactBocage, SimpleCompactEvaluator);
}