cfg_classify/
lib.rs

1//! Classification of rules and grammars.
2
3#![deny(unsafe_code)]
4
5use cfg_grammar::Cfg;
6use cfg_symbol::Symbol;
7
8pub mod cyclical;
9pub mod linear;
10#[cfg(feature = "ll")]
11pub mod ll;
12#[cfg(feature = "lr")]
13pub mod lr;
14pub mod recursive;
15pub mod regular;
16pub mod useful;
17
18pub trait CfgClassifyExt {
19    #[cfg(feature = "ll")]
20    fn ll_parse_table(&self) -> ll::LlParseTable<'_>;
21    #[cfg(feature = "lr")]
22    fn lr0_fsm_builder(&mut self) -> lr::Lr0FsmBuilder<'_>;
23    #[cfg(feature = "lr")]
24    fn lr0_closure_builder(&mut self) -> lr::Lr0ClosureBuilder<'_>;
25    fn recursion(&self) -> recursive::Recursion<'_>;
26    fn make_proper(&mut self) -> bool;
27    fn usefulness(&mut self) -> useful::Usefulness;
28    fn usefulness_with_roots(&mut self, roots: &[Symbol]) -> useful::Usefulness;
29}
30
31impl CfgClassifyExt for Cfg {
32    #[cfg(feature = "ll")]
33    fn ll_parse_table(&self) -> ll::LlParseTable<'_> {
34        ll::LlParseTable::new(self)
35    }
36
37    fn recursion(&self) -> recursive::Recursion<'_> {
38        recursive::Recursion::new(self)
39    }
40
41    #[cfg(feature = "lr")]
42    fn lr0_fsm_builder(&mut self) -> lr::Lr0FsmBuilder<'_> {
43        lr::Lr0FsmBuilder::new(self)
44    }
45
46    #[cfg(feature = "lr")]
47    fn lr0_closure_builder(&mut self) -> lr::Lr0ClosureBuilder<'_> {
48        lr::Lr0ClosureBuilder::new(self)
49    }
50
51    fn usefulness(&mut self) -> useful::Usefulness {
52        let mut usefulness = useful::Usefulness::new(self);
53        let roots = self.roots();
54        usefulness.reachable(roots);
55        usefulness
56    }
57
58    fn usefulness_with_roots(&mut self, roots: &[Symbol]) -> useful::Usefulness {
59        let mut usefulness = useful::Usefulness::new(self);
60        usefulness.reachable(roots);
61        usefulness
62    }
63
64    fn make_proper(&mut self) -> bool {
65        let usefulness = self.usefulness();
66        let contains_useless_rules = !usefulness.all_useful();
67        if contains_useless_rules {
68            // for useless in usefulness.useless_rules() {
69            //     let rhs: Vec<_> = useless.rule.rhs().iter().map(|t| tok.get(t.usize())).collect();
70            //     println!("lhs:{:?} rhs:{:?} unreachable:{} unproductive:{}", tok.get(useless.rule.lhs().usize()), rhs, useless.unreachable, useless.unproductive);
71            // }
72            // println!("warning: grammar has useless rules");
73            usefulness.remove_useless_rules(self);
74        }
75        !contains_useless_rules
76    }
77}