pub fn nt_reachability(cfg: &Cfg) -> BTreeMap<String, BTreeSet<String>>
Expand description

Calculates the reachable non-terminals for each non-terminal of the given Cfg.

Calculates for a given non-terminal all reachable non-terminals. Used for special derivation calculations (i.e. FOLLOW k relations)

use parol::{Cfg, Pr, Symbol};
use parol::analysis::nt_reachability;
use std::collections::{BTreeMap, BTreeSet};
use std::convert::From;

let g = Cfg::with_start_symbol("S")
    .add_pr(Pr::new("S", vec![Symbol::n("A")]))
    .add_pr(Pr::new("A", vec![Symbol::t_n("x", vec![0]), Symbol::n("B"), Symbol::n("AA")]))
    .add_pr(Pr::new("AA", vec![Symbol::t_n("d", vec![0]), Symbol::n("AA")]))
    .add_pr(Pr::new("AA", vec![]))
    .add_pr(Pr::new("B", vec![Symbol::t_n("y", vec![0])]))
    .add_pr(Pr::new("C", vec![Symbol::t_n("b", vec![0])]));
let reachability = nt_reachability(&g);
assert_eq!(
    [
        ("A".to_owned(), [
            "AA".to_owned(),
            "B".to_owned()].iter().cloned().collect::<BTreeSet<String>>()),
        ("AA".to_owned(), [
            "AA".to_owned()].iter().cloned().collect::<BTreeSet<String>>()),
        ("B".to_owned(), [].iter().cloned().collect::<BTreeSet<String>>()),
        ("C".to_owned(), [].iter().cloned().collect::<BTreeSet<String>>()),
        ("S".to_owned(), [
            "A".to_owned(),
            "AA".to_owned(),
            "B".to_owned()].iter().cloned().collect::<BTreeSet<String>>()),
    ].iter().cloned().collect::<BTreeMap<String, BTreeSet<String>>>(),
    reachability);