aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/parse/regex/dfa.rs16
-rw-r--r--src/parse/regex/mod.rs4
-rw-r--r--src/run/builtin.rs20
-rw-r--r--test-cases/case2_lookahead/script.sh15
4 files changed, 41 insertions, 14 deletions
diff --git a/src/parse/regex/dfa.rs b/src/parse/regex/dfa.rs
index 243176d..0a5c78d 100644
--- a/src/parse/regex/dfa.rs
+++ b/src/parse/regex/dfa.rs
@@ -34,7 +34,7 @@ impl fmt::Debug for DFA {
write!(f, "{chr:?} to {to}, ")?;
}
- write!(f, "default to {}", s.default_trans)?;
+ write!(f, "dfl to {}", s.default_trans)?;
if s.accept {
write!(f, ", accept")?;
}
@@ -58,14 +58,18 @@ impl DFA {
}
self.states[state].accept
}
+
+ pub fn simplify(&mut self) {
+ for state in self.states.iter_mut() {
+ state.trans.retain(|_, to| *to != state.default_trans);
+ }
+ }
}
impl From<ENFA> for DFA {
fn from(mut nfa: ENFA) -> Self {
nfa.remove_unreachable();
- println!("{nfa:?}");
-
let mut multi_states = nfa.all_multi_states();
multi_states.insert(nfa.void_multi_state());
let mut len = 0;
@@ -97,9 +101,11 @@ impl From<ENFA> for DFA {
}
}
- Self {
+ let mut this = Self {
start: multi_to_dfa[&nfa.start_multi_state()],
states,
- }
+ };
+ this.simplify();
+ this
}
}
diff --git a/src/parse/regex/mod.rs b/src/parse/regex/mod.rs
index 2f7c223..b8dd8ba 100644
--- a/src/parse/regex/mod.rs
+++ b/src/parse/regex/mod.rs
@@ -3,8 +3,8 @@ use crate::parse::OtherHighlights;
use super::{Parse, ParseError, Result};
mod byte_range;
-mod dfa;
-mod enfa;
+pub mod dfa;
+pub mod enfa;
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum LookDirection {
diff --git a/src/run/builtin.rs b/src/run/builtin.rs
index fd4cbed..87a0be0 100644
--- a/src/run/builtin.rs
+++ b/src/run/builtin.rs
@@ -1039,7 +1039,9 @@ impl Builtin for pish_theme {
#[cfg(debug_assertions)]
mod dbg {
- use super::*;
+ use crate::parse::regex::{dfa::DFA, enfa::ENFA};
+
+use super::*;
#[derive(Copy, Clone)]
pub struct debug;
@@ -1121,13 +1123,17 @@ mod dbg {
},
};
- match regex.try_compile() {
- Ok(compiled) => writeln!(stdout, "{compiled:?}")?,
- Err(e) => {
- writeln!(stdout, "compilation error: {e:?}")?;
+ let nfa = match ENFA::try_from(regex) {
+ Ok(nfa) => nfa,
+ Err(err) => {
+ writeln!(stdout, "nfa error: {err:?}")?;
return Err(Error::Exit(2));
- },
- }
+ }
+ };
+ writeln!(stdout, "{nfa:?}")?;
+
+ let dfa = DFA::from(nfa);
+ writeln!(stdout, "{dfa:?}")?;
Ok(())
}
diff --git a/test-cases/case2_lookahead/script.sh b/test-cases/case2_lookahead/script.sh
index a77eb85..891441b 100644
--- a/test-cases/case2_lookahead/script.sh
+++ b/test-cases/case2_lookahead/script.sh
@@ -48,3 +48,18 @@ match x2 xfoobar_some_more_stuff yes
match x2 x___bar no
match x2 xfoo___ no
match x2 xfoo no
+
+fun x3 {
+ case $1 {
+ x(?!(a|b)).* { echo yes }
+ .* { echo no }
+ }
+}
+match x3 x yes
+match x3 xa no
+match x3 xb no
+match x3 xax no
+match x3 xbx no
+match x3 xxa yes
+match x3 xxb yes
+match x3 xfoobar yes