1#![deny(unsafe_code)]
4#![deny(missing_docs)]
5
6use cfg_grammar::Cfg;
7use cfg_symbol::Symbol;
8
9pub mod cyclical;
10#[cfg(feature = "ll")]
12pub mod ll;
13#[cfg(feature = "lr")]
14pub mod lr;
15pub mod recursive;
16pub mod useful;
18
19pub trait CfgClassifyExt {
22 #[cfg(feature = "ll")]
24 fn ll_parse_table(&self) -> ll::LlParseTable<'_>;
25 #[cfg(feature = "lr")]
27 fn lr0_fsm_builder(&mut self) -> lr::Lr0FsmBuilder<'_>;
28 #[cfg(feature = "lr")]
30 fn lr0_closure_builder(&mut self) -> lr::Lr0ClosureBuilder<'_>;
31 fn recursion(&self) -> recursive::Recursion<'_>;
33 fn make_proper(&mut self) -> bool;
36 fn usefulness(&mut self) -> useful::Usefulness;
41 fn usefulness_with_roots(&mut self, roots: &[Symbol]) -> useful::Usefulness;
46}
47
48impl CfgClassifyExt for Cfg {
49 #[cfg(feature = "ll")]
50 fn ll_parse_table(&self) -> ll::LlParseTable<'_> {
51 ll::LlParseTable::new(self)
52 }
53
54 fn recursion(&self) -> recursive::Recursion<'_> {
55 recursive::Recursion::new(self)
56 }
57
58 #[cfg(feature = "lr")]
59 fn lr0_fsm_builder(&mut self) -> lr::Lr0FsmBuilder<'_> {
60 lr::Lr0FsmBuilder::new(self)
61 }
62
63 #[cfg(feature = "lr")]
64 fn lr0_closure_builder(&mut self) -> lr::Lr0ClosureBuilder<'_> {
65 lr::Lr0ClosureBuilder::new(self)
66 }
67
68 fn usefulness(&mut self) -> useful::Usefulness {
69 let mut usefulness = useful::Usefulness::new(self);
70 let roots = self.roots();
71 usefulness.reachable(roots);
72 usefulness
73 }
74
75 fn usefulness_with_roots(&mut self, roots: &[Symbol]) -> useful::Usefulness {
76 let mut usefulness = useful::Usefulness::new(self);
77 usefulness.reachable(roots);
78 usefulness
79 }
80
81 fn make_proper(&mut self) -> bool {
82 let usefulness = self.usefulness();
83 let contains_useless_rules = !usefulness.all_useful();
84 if contains_useless_rules {
85 usefulness.remove_useless_rules(self);
91 }
92 !contains_useless_rules
93 }
94}