1#![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 usefulness.remove_useless_rules(self);
74 }
75 !contains_useless_rules
76 }
77}