diff options
author | JSDurand <mmemmew@gmail.com> | 2023-01-13 14:26:28 +0800 |
---|---|---|
committer | JSDurand <mmemmew@gmail.com> | 2023-01-13 14:26:28 +0800 |
commit | 8f8d3d1a3c276be4be2e5d2e767ada564c47279a (patch) | |
tree | daba317c8d381f7159f9a34d957291472bad2873 /grammar | |
parent | 3c6511f69c7639abff60ac9999a08ce2daa24a7d (diff) |
forest seems to be completed
I seem to have finished the implementation of forests. Now it remains
the implementation of the chain-rule machine, of which I have a rough
plan now.
Diffstat (limited to 'grammar')
-rw-r--r-- | grammar/Cargo.toml | 3 | ||||
-rw-r--r-- | grammar/src/lib.rs | 15 | ||||
-rw-r--r-- | grammar/src/tests/test_grammar_left_closure.rs | 38 |
3 files changed, 42 insertions, 14 deletions
diff --git a/grammar/Cargo.toml b/grammar/Cargo.toml index 20c4b48..793ab5a 100644 --- a/grammar/Cargo.toml +++ b/grammar/Cargo.toml @@ -12,6 +12,9 @@ default = [] # some grammars for testing. test-helper = [] +# This flag controls whether to print GraphViz files during testing. +test-print-viz = [] + [dependencies] nfa = { path = "../nfa" } graph = { path = "../graph" } diff --git a/grammar/src/lib.rs b/grammar/src/lib.rs index 627ae6f..297cb66 100644 --- a/grammar/src/lib.rs +++ b/grammar/src/lib.rs @@ -462,6 +462,19 @@ impl Grammar { // REVIEW: Do we have a better way to record expansion information // than to compute the transitive closure? + // REVIEW: We need a way to eliminate those left-linearly expanded + // edges whose labels had already been considered, and we need to + // preserve the transition of the `left_p` property at the same + // time. + // + // Maybe we could decide to delete those edges in the + // `remove_predicate`? But we cannot access the states of NFA in + // that predicate, in the current design, thus we need to refactor + // some codes, it seems: we need a way to "compactify" an NFA, by + // a key function, in such a way that if two entries have the same + // key (determined by the key function), then only one, determined + // by another function, remains in the NFA. + /// A transformer of labels to be fed into /// [`closure`][nfa::default::nfa::DefaultNFA::closure], with the /// predicate that returns true if and only if the label of the @@ -483,7 +496,7 @@ impl Grammar { } // Compute if this is from left-linear expansion: it is so if - // and only if one if either the edges comes from left-linear + // and only if either one of the edges comes from left-linear // expansion or we are moving across a non-terminal expansion, // that is to say, the source of the second edge is the // starting edge of a non-terminal. diff --git a/grammar/src/tests/test_grammar_left_closure.rs b/grammar/src/tests/test_grammar_left_closure.rs index 003c211..ffc7c0f 100644 --- a/grammar/src/tests/test_grammar_left_closure.rs +++ b/grammar/src/tests/test_grammar_left_closure.rs @@ -33,9 +33,6 @@ fn test_regex() -> Result<(), Box<dyn std::error::Error>> { Ok(()) } -// We ignore this test by default as it is possibly involved with -// printing to a graphviz file. -#[ignore] #[test] fn test_nfa() -> Result<(), Box<dyn std::error::Error>> { let mut grammar = new_notes_grammar()?; @@ -69,19 +66,22 @@ fn test_nfa() -> Result<(), Box<dyn std::error::Error>> { grammar .left_closure_to_nfa(&closure) .map(|_| ()) - .map_err(Into::into) + .map_err(Into::<Box<dyn std::error::Error>>::into)?; // let _nfa = grammar.left_closure_to_nfa(&closure)?; - // writeln!(lock, "Not printing nfa to nfa.gv")?; + #[cfg(features = "test-print-viz")] + { + writeln!(lock, "Not printing nfa to nfa.gv")?; - // nfa.print_viz("nfa.gv").map_err(Into::into) + nfa.print_viz("nfa.gv") + .map_err(Into::<Box<dyn std::error::Error>>::into)?; + } - // Ok(()) + Ok(()) } #[test] -#[ignore] fn test_remove_epsilon() -> Result<(), Box<dyn std::error::Error>> { let mut lock = stdout().lock(); @@ -123,17 +123,18 @@ fn test_remove_epsilon() -> Result<(), Box<dyn std::error::Error>> { 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] -#[ignore] fn test_remove_dead() -> Result<(), Box<dyn std::error::Error>> { let mut grammar = new_paren_grammar()?; let closure = new_closure_regex(&mut grammar)?; @@ -173,9 +174,10 @@ fn test_remove_dead() -> Result<(), Box<dyn std::error::Error>> { 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())?; + // nfa.remove_epsilon(|label| label.get_value().is_none())?; let accumulators: HashSet<usize> = accumulators.into_iter().collect(); @@ -183,15 +185,22 @@ fn test_remove_dead() -> Result<(), Box<dyn std::error::Error>> { let grammar_reserve_node = |node| accumulators.contains(&node); + nfa.closure( + |label| label.get_value().is_none(), + true, + |two_edges| two_edges.second_edge().2, + |label| label.get_value().is_none(), + )?; + nfa.remove_dead(grammar_reserve_node)?; + #[cfg(features = "test-print-viz")] nfa.print_viz("nfa_no_dead.gv")?; Ok(()) } #[test] -#[ignore] fn test_nulling() -> Result<(), Box<dyn std::error::Error>> { // TODO: Test more grammars. let mut grammar = new_right_recursive_grammar()?; @@ -273,9 +282,12 @@ fn test_nulling() -> Result<(), Box<dyn std::error::Error>> { nfa.remove_dead(grammar_reserve_nodes)?; - writeln!(lock, "Printing nfa to nfa.gv")?; + #[cfg(features = "test-print-viz")] + { + writeln!(lock, "Printing nfa to nfa.gv")?; - nfa.print_viz("nfa.gv")?; + nfa.print_viz("nfa.gv")?; + } Ok(()) } |