diff options
Diffstat (limited to 'grammar/src/lib.rs')
| -rw-r--r-- | grammar/src/lib.rs | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/grammar/src/lib.rs b/grammar/src/lib.rs index 64f4cdb..79c19e0 100644 --- a/grammar/src/lib.rs +++ b/grammar/src/lib.rs @@ -68,6 +68,13 @@ impl Nonterminal { pub fn name(&self) -> &str { &self.0 } + + /// A public constructor for the purposes of easy grammar + /// constructions. + #[inline] + pub fn new(name: String) -> Self { + Self(name) + } } /// The type of a terminal or a non-terminal. @@ -82,6 +89,16 @@ pub enum TNT { Non(usize), } +impl TNT { + /// Retrieve the index of this enum. + pub fn value(&self) -> usize { + match self { + Self::Ter(index) => *index, + Self::Non(index) => *index, + } + } +} + impl Display for TNT { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -881,6 +898,33 @@ impl Grammar { ) .unwrap()) } + + /// Print the names of terminals and non-terminals into a given + /// file. + pub fn print_tnt(&self, file_name: &str) -> Result<(), String> { + let mut fs = std::fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(file_name) + .map_err(|e| format!("{e}"))?; + + use std::io::Write; + + for (n, ter) in (0..(self.ter_num())).map(TNT::Ter).enumerate() { + let name = self.name_of_tnt(ter).unwrap(); + + writeln!(&mut fs, "{n}-th terminal: {name}").map_err(|e| format!("{e}"))?; + } + + for (n, non) in (0..(self.non_num())).map(TNT::Non).enumerate() { + let name = self.name_of_tnt(non).unwrap(); + + writeln!(&mut fs, "{n}-th non-terminal: {name}").map_err(|e| format!("{e}"))?; + } + + Ok(()) + } } pub mod first_set; |
