diff options
Diffstat (limited to 'chain/src/atom/default.rs')
-rw-r--r-- | chain/src/atom/default.rs | 43 |
1 files changed, 41 insertions, 2 deletions
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<dyn std::error::Error>> { + 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(()) + } +} |