diff options
author | JSDurand <mmemmew@gmail.com> | 2023-02-27 12:36:41 +0800 |
---|---|---|
committer | JSDurand <mmemmew@gmail.com> | 2023-02-27 12:36:41 +0800 |
commit | fbaa420ed550e9c3e7cdc09d4a8ec22bfbd782a6 (patch) | |
tree | fad9722825bb3fa796dd52c3fd4a8bf46b958cf9 /grammar/src | |
parent | afad02bdff111ecccb0077b9c989e869723c231c (diff) |
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.
Diffstat (limited to 'grammar/src')
-rw-r--r-- | grammar/src/label.rs | 6 | ||||
-rw-r--r-- | grammar/src/lib.rs | 20 | ||||
-rw-r--r-- | grammar/src/tests/test_grammar_left_closure.rs | 55 |
3 files changed, 26 insertions, 55 deletions
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<bool, Error> { + 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<bool, Error> { 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 @@ -82,59 +82,6 @@ fn test_nfa() -> Result<(), Box<dyn std::error::Error>> { } #[test] -fn test_remove_epsilon() -> Result<(), Box<dyn std::error::Error>> { - 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<dyn std::error::Error>> { let mut grammar = new_paren_grammar()?; let closure = new_closure_regex(&mut grammar)?; @@ -177,8 +124,6 @@ fn test_remove_dead() -> Result<(), Box<dyn std::error::Error>> { #[cfg(features = "test-print-viz")] nfa.print_viz("nfa_orig.gv")?; - // nfa.remove_epsilon(|label| label.get_value().is_none())?; - let accumulators: HashSet<usize> = accumulators.into_iter().collect(); println!("accumulators = {accumulators:?}"); |