From 5ce263b586c5047d16ee93cc53bc3bce6f7ff12c Mon Sep 17 00:00:00 2001 From: Jonas Maier Date: Tue, 2 Jun 2026 23:52:23 +0200 Subject: fix lookahead --- src/parse/regex/enfa.rs | 28 +++++++++++++++++--------- test-cases/case2_positive_lookahead/script.sh | 14 +++++++++++++ test-cases/case2_positive_lookahead/stdout.txt | 2 ++ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/parse/regex/enfa.rs b/src/parse/regex/enfa.rs index a407e9e..272c709 100644 --- a/src/parse/regex/enfa.rs +++ b/src/parse/regex/enfa.rs @@ -116,7 +116,7 @@ mod product_tests { } } -#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] struct Thread { state: StateId, positives: Vec, @@ -200,19 +200,28 @@ impl Thread { let Self { state, - mut positives, - mut negatives, + positives, + negatives, } = self; + let mut p = Vec::new(); + let mut n = Vec::new(); for assertion in new_assertions { - let mut threads = Self::new_simple(assertion.to).step_epsilon(enfa); + let threads = Self::new_simple(assertion.to).step_epsilon(enfa); let vec = match assertion.polarity { - LookPolarity::Positive => &mut positives, - LookPolarity::Negative => &mut negatives, + LookPolarity::Positive => &mut p, + LookPolarity::Negative => &mut n, }; - vec.append(&mut threads); + vec.push(threads); } - if let Some(thread) = Self::new(enfa, state, positives, negatives) { - ret(thread); + let p = cartesian_product(p); + for mut p in p { + let mut positives = positives.clone(); + let mut negatives = negatives.clone(); + positives.append(&mut p); + negatives.append(&mut n.iter().cloned().flatten().collect()); + if let Some(thread) = Self::new(enfa, state, positives, negatives) { + ret(thread); + } } } @@ -230,6 +239,7 @@ impl Thread { fn step0(self, enfa: &ENFA, input: ByteRange, ret: &mut impl FnMut(Thread)) { let positives = self .positives + .clone() .into_iter() .map(|t| t.step(enfa, input)) .collect(); diff --git a/test-cases/case2_positive_lookahead/script.sh b/test-cases/case2_positive_lookahead/script.sh index f19441a..053461d 100644 --- a/test-cases/case2_positive_lookahead/script.sh +++ b/test-cases/case2_positive_lookahead/script.sh @@ -88,4 +88,18 @@ match x4 aaaaaaaaaaae no match x4 aaaaaaaaaaaae yes echo x4 +fun x5 { + case $1 { + (?=(a.)*e)(?=(a..)*e)(?=(a....)*e).*e { echo yes } + .* { echo no } + } +} +match x5 e yes +match x5 aaaaaaaaaaaaaaaaaaaaaaaaaaaaae no +match x5 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaae yes +match x5 a.aaaaaaaaaaaaaaaaaaaaaaaaaaa.e yes +match x5 .aaaaaaaaaaaaaaaaaaaaaaaaaaaaae no +match x5 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaae no +echo x5 + echo done diff --git a/test-cases/case2_positive_lookahead/stdout.txt b/test-cases/case2_positive_lookahead/stdout.txt index ffa387f..fa2c182 100644 --- a/test-cases/case2_positive_lookahead/stdout.txt +++ b/test-cases/case2_positive_lookahead/stdout.txt @@ -1,6 +1,8 @@ begin +x0 x1 x2 x3 x4 +x5 done -- cgit v1.2.3