aboutsummaryrefslogtreecommitdiff
path: root/grammar/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'grammar/src/lib.rs')
-rw-r--r--grammar/src/lib.rs44
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;