Function parol::analysis::reachability::reachable_from_production

source ยท
pub fn reachable_from_production(cfg: &Cfg, prod_num: usize) -> BTreeSet<String>
Expand description

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

use parol::{Cfg, Pr, Symbol, SymbolAttribute, Terminal, TerminalKind};
use parol::analysis::reachable_from_production;
use std::collections::BTreeSet;
use std::convert::From;

macro_rules! terminal {
    ($term:literal) => {Symbol::T(Terminal::Trm($term.to_string(), TerminalKind::Legacy,
        vec![0], SymbolAttribute::None, None))};
}

let g = Cfg::with_start_symbol("S")
    .add_pr(Pr::new("S", vec![Symbol::n("Y")]))
    .add_pr(Pr::new("Y", vec![Symbol::n("Y"), Symbol::n("Z")]))
    .add_pr(Pr::new("Y", vec![Symbol::n("Y"), terminal!("a")]))
    .add_pr(Pr::new("Y", vec![terminal!("b")]))
    .add_pr(Pr::new("U", vec![Symbol::n("V")]))
    .add_pr(Pr::new("X", vec![terminal!("c")]))
    .add_pr(Pr::new("V", vec![Symbol::n("V"), terminal!("d")]))
    .add_pr(Pr::new("V", vec![terminal!("d")]))
    .add_pr(Pr::new("Z", vec![Symbol::n("Z"), Symbol::n("X")]));
let productive = reachable_from_production(&g, 0);
assert_eq!(
    [
        "X".to_owned(),
        "Y".to_owned(),
        "Z".to_owned()
    ].iter().cloned().collect::<BTreeSet<String>>(),
    productive);

let productive = reachable_from_production(&g, 1);
assert_eq!(
    [
        "X".to_owned(),
        "Y".to_owned(),
        "Z".to_owned()
    ].iter().cloned().collect::<BTreeSet<String>>(),
    productive);

let productive = reachable_from_production(&g, 2);
assert_eq!(
    [
        "X".to_owned(),
        "Y".to_owned(),
        "Z".to_owned()
    ].iter().cloned().collect::<BTreeSet<String>>(),
    productive);

let productive = reachable_from_production(&g, 3);
assert_eq!(
    [
    ].iter().cloned().collect::<BTreeSet<String>>(),
    productive);

let productive = reachable_from_production(&g, 4);
assert_eq!(
    [
        "V".to_owned(),
    ].iter().cloned().collect::<BTreeSet<String>>(),
    productive);

let productive = reachable_from_production(&g, 5);
assert_eq!(
    [
    ].iter().cloned().collect::<BTreeSet<String>>(),
    productive);

let productive = reachable_from_production(&g, 6);
assert_eq!(
    [
        "V".to_owned(),
    ].iter().cloned().collect::<BTreeSet<String>>(),
    productive);

let productive = reachable_from_production(&g, 7);
assert_eq!(
    [
    ].iter().cloned().collect::<BTreeSet<String>>(),
    productive);

let productive = reachable_from_production(&g, 8);
assert_eq!(
    [
        "X".to_owned(),
        "Z".to_owned()
    ].iter().cloned().collect::<BTreeSet<String>>(),
    productive);