From e6c9c27b334cf09188609711ff65df8edd39ec25 Mon Sep 17 00:00:00 2001 From: Dan Frumin Date: Sat, 8 Jun 2024 18:35:37 +0200 Subject: [PATCH] test --- .gitignore | 1 + Cargo.toml | 8 +++++++ src/main.rs | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..51bc171 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "aut" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..5542ad9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,64 @@ +#[derive(Debug,Clone)] +enum RegExp { + Char(char), + Empt, + Epsilon, + Union(Box, Box), + Concat(Box, Box), + Kleene(Box), +} + +fn is_nullable (r : &RegExp) -> bool { + match r { + RegExp::Epsilon => true, + RegExp::Kleene(_) => true, + RegExp::Union(r1, r2) => is_nullable(&*r1) | is_nullable(&*r2), + RegExp::Concat(r1, r2) => is_nullable(&*r1) & is_nullable(&*r2), + _ => false, + } +} + +fn derivative(r : &RegExp, a : char) -> RegExp { + match r { + RegExp::Empt => RegExp::Empt, + RegExp::Epsilon => RegExp::Empt, + RegExp::Char(c) => if *c == a { + RegExp::Epsilon + } else { RegExp::Empt }, + RegExp::Union(r1, r2) => + RegExp::Union(Box::new(derivative(&*r1, a)), Box::new(derivative(&*r2, a))), + RegExp::Kleene(r) => + RegExp::Concat(Box::new(derivative(&*r, a)), + Box::new(RegExp::Kleene(Box::new(*r.clone())))), + RegExp::Concat(r1, r2) => { + let r : RegExp = RegExp::Concat(Box::new(derivative(&*r1, a)), + Box::new(*r2.clone())); + if is_nullable(&*r1) { + RegExp::Union(Box::new(derivative(&*r2, a)), Box::new(r)) + } else { + r + } + } + _ => RegExp::Empt, + } +} + +fn regexp_match(r : RegExp, s : &String) -> bool { + let chrs = s.chars(); + let mut rs : RegExp = r; + for c in chrs { + println!("Computing der({:?}, {:?}) ...", rs, c); + rs = derivative(&rs, c); + } + println!("Result: {:?}", rs); + is_nullable(&rs) +} + +fn main() { + let r1 = RegExp::Concat(Box::new( RegExp::Char('a')), Box::new( RegExp::Char('b'))); + let r2 = RegExp::Kleene(Box::new(r1.clone())); + let r3 = RegExp::Concat(Box::new(RegExp::Union(Box::new(r1.clone()), Box::new(RegExp::Char('c')))), Box::new(r2.clone())); + let inp = String::from("c"); + let res = regexp_match(r3.clone(), &inp); + println!("match {:?}, {:?} = {:?}", r3, inp, res); +}