From 57134c44207f7129035bbdbca0e4deff398defe3 Mon Sep 17 00:00:00 2001 From: JSDurand Date: Fri, 4 Aug 2023 10:08:49 +0800 Subject: chain/atom/default: Fix nullibility of virtual nodes. * chain/src/atom/default.rs: Previously the nullibility of virtual nodes is determined by the nullibility of all its out-going edges. This is now determined only by the nullibility of out-going edges that are not "left-linearly expanded". This is the correct approach. --- chain/src/atom/default.rs | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'chain') diff --git a/chain/src/atom/default.rs b/chain/src/atom/default.rs index 6ae924f..fa0cc3b 100644 --- a/chain/src/atom/default.rs +++ b/chain/src/atom/default.rs @@ -537,11 +537,15 @@ impl DefaultAtom { .or_insert_with(Default::default) .insert(rule, frag); - accepting = - accepting + // Those left-linearly expanded arrows should + // not affect the nullability of the virtual + // nodes. + if !label.is_left_p() { + accepting = accepting || *accepting_vec.get(child).ok_or( GrammarError::IndexOutOfBounds(child, accepting_vec.len()), )?; + } if let Some((_, old_accepting)) = terminals_map.get_mut(&t) { *old_accepting = *old_accepting || accepting; @@ -736,3 +740,38 @@ impl Atom for DefaultAtom { self.accepting_vec.len() } } + +#[cfg(test)] +mod test_default_atom { + use super::*; + + #[test] + fn test_from_grammar() -> Result<(), Box> { + use grammar::Grammar; + + let grammar_str = std::fs::read_to_string( + "/Users/durand/Desktop/Centre/A propos de programmes/Rust/rep/grammar/abnf grammars/test.abnf", + ) + .unwrap(); + + let grammar: Grammar = grammar_str.parse()?; + + println!("grammar"); + println!("{grammar}"); + + let atom = DefaultAtom::from_grammar(grammar)?; + + atom.print_nullables(); + + atom.print_virtual(); + + for virtual_node in 166..=173 { + assert_eq!( + atom.is_accepting(virtual_node)?, + [169, 170, 172].contains(&virtual_node) + ); + } + + Ok(()) + } +} -- cgit v1.2.3-18-g5258