From fbaa420ed550e9c3e7cdc09d4a8ec22bfbd782a6 Mon Sep 17 00:00:00 2001 From: JSDurand Date: Mon, 27 Feb 2023 12:36:41 +0800 Subject: before a major refactor I decide to adopt a new approach of recording and updating item derivation forests. Since this affects a lot of things, I decide to commit before the refactor, so that I can create a branch for that refactor. --- grammar/src/label.rs | 6 +++ grammar/src/lib.rs | 20 ++++++++++ grammar/src/tests/test_grammar_left_closure.rs | 55 -------------------------- 3 files changed, 26 insertions(+), 55 deletions(-) (limited to 'grammar') diff --git a/grammar/src/label.rs b/grammar/src/label.rs index 058baaf..e3f3422 100644 --- a/grammar/src/label.rs +++ b/grammar/src/label.rs @@ -119,6 +119,12 @@ impl GrammarLabel { self.end } + /// Set the start. + #[inline] + pub fn set_start(&mut self, pos: usize) { + self.start = pos; + } + /// Return the start in the input. #[inline] pub fn start(&self) -> usize { diff --git a/grammar/src/lib.rs b/grammar/src/lib.rs index ab0f693..21ce2b4 100644 --- a/grammar/src/lib.rs +++ b/grammar/src/lib.rs @@ -25,6 +25,12 @@ use std::{ fmt::Display, }; +/// The index of the starting non-terminal. +/// +/// By convention this is the zero-th non-terminal. I define this +/// constant just for the sake of clarity. +pub const START_NONTERMINAL: usize = 0; + /// The type of a terminal. /// /// For the time being this is a wrapper around a string, but in the @@ -478,8 +484,17 @@ impl Grammar { /// Return true if and only if the terminal can appear as the /// first terminal in a string expanded from the non-terminal. + /// + /// # Errors + /// + /// If `non_terminal` or `terminal` is out of bounds, the function + /// returns an error indicating this fact. #[inline] pub fn is_first_of(&self, non_terminal: usize, terminal: usize) -> Result { + if terminal >= self.ter_num() { + return Err(Error::IndexOutOfBounds(terminal, self.ter_num())); + } + Ok(self .firsts .get(non_terminal) @@ -488,6 +503,11 @@ impl Grammar { } /// Return true if and only if the non-terminal is nullable. + /// + /// # Error + /// + /// If `non_terminal` is out of bounds, return the corresponding + /// error. #[inline] pub fn is_nullable(&self, non_terminal: usize) -> Result { Ok(self diff --git a/grammar/src/tests/test_grammar_left_closure.rs b/grammar/src/tests/test_grammar_left_closure.rs index ffc7c0f..be1df9d 100644 --- a/grammar/src/tests/test_grammar_left_closure.rs +++ b/grammar/src/tests/test_grammar_left_closure.rs @@ -81,59 +81,6 @@ fn test_nfa() -> Result<(), Box> { Ok(()) } -#[test] -fn test_remove_epsilon() -> Result<(), Box> { - let mut lock = stdout().lock(); - - let mut grammar = new_paren_grammar()?; - - writeln!(lock, "grammar:")?; - writeln!(lock, "{grammar}")?; - - let closure = new_closure_regex(&mut grammar)?; - - let mut accumulator_value: usize = 0; - - for regex in closure.iter() { - writeln!( - lock, - "regex: {}", - regex.to_string_with(|tnt| { - match tnt { - TNT::Ter(t) => { - format!( - "({})", - grammar.name_of_tnt(grammar.unpack_tnt(t).unwrap()).unwrap() - ) - } - TNT::Non(_) => { - // hyper non-terminal - format!("({})", grammar.name_of_tnt(tnt).unwrap()) - } - } - })? - )?; - writeln!(lock, "regex len = {}", regex.nodes_len())?; - writeln!(lock, "offset = {accumulator_value}")?; - - accumulator_value += regex.nodes_len(); - } - - writeln!(lock, "total = {accumulator_value}")?; - - let mut nfa = grammar.left_closure_to_nfa(&closure)?; - - #[cfg(features = "test-print-viz")] - nfa.print_viz("nfa_orig.gv")?; - - nfa.remove_epsilon(|label| label.get_value().is_none())?; - - #[cfg(features = "test-print-viz")] - nfa.print_viz("nfa_no_epsilon.gv")?; - - Ok(()) -} - #[test] fn test_remove_dead() -> Result<(), Box> { let mut grammar = new_paren_grammar()?; @@ -177,8 +124,6 @@ fn test_remove_dead() -> Result<(), Box> { #[cfg(features = "test-print-viz")] nfa.print_viz("nfa_orig.gv")?; - // nfa.remove_epsilon(|label| label.get_value().is_none())?; - let accumulators: HashSet = accumulators.into_iter().collect(); println!("accumulators = {accumulators:?}"); -- cgit v1.2.3-18-g5258