diff options
Diffstat (limited to 'grammar')
| -rw-r--r-- | grammar/src/abnf/mod.rs | 8 | ||||
| -rw-r--r-- | grammar/src/lib.rs | 44 | ||||
| -rw-r--r-- | grammar/src/test_grammar_helper.rs | 2 |
3 files changed, 49 insertions, 5 deletions
diff --git a/grammar/src/abnf/mod.rs b/grammar/src/abnf/mod.rs index b53dcc1..2e2d0f2 100644 --- a/grammar/src/abnf/mod.rs +++ b/grammar/src/abnf/mod.rs @@ -2439,9 +2439,9 @@ impl std::str::FromStr for Grammar { break; } - if appending_p && nonterminals_map.get(&rule_name).is_none() { + if appending_p && !nonterminals_map.contains_key(&rule_name) { return Err(Error::AppendToNothing(current_skipped_index)); - } else if !appending_p && nonterminals_map.get(&rule_name).is_some() { + } else if !appending_p && nonterminals_map.contains_key(&rule_name) { return Err(Error::CreateAgain(current_skipped_index)); } @@ -2473,13 +2473,13 @@ impl std::str::FromStr for Grammar { for data in rule_data { match data { IntermediateConstruct::Terminal(name) => { - if terminals_map.get(&name).is_none() { + if !terminals_map.contains_key(&name) { terminals_map.insert(name.clone(), terminals_vec.len()); terminals_vec.push(name); } } IntermediateConstruct::Nonterminal(name) => { - if nonterminals_map.get(&name).is_none() { + if !nonterminals_map.contains_key(&name) { return Err(Error::UnknownNonterminal(name)); } } 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; diff --git a/grammar/src/test_grammar_helper.rs b/grammar/src/test_grammar_helper.rs index 9d86865..8c9c2ed 100644 --- a/grammar/src/test_grammar_helper.rs +++ b/grammar/src/test_grammar_helper.rs @@ -18,7 +18,7 @@ pub fn new_closure_regex( } /// A function to scan the inputs. -fn scan_tnt( +pub fn scan_tnt( parser: &DefaultRegParser<TNT>, input: &str, ) -> Result<Option<(usize, RegexType<TNT>, ParseDirection)>, ParseError> { |
