#[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| { 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| { 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); }