upd
This commit is contained in:
parent
009b3cb261
commit
ba64e19894
98
src/main.rs
98
src/main.rs
|
@ -8,55 +8,6 @@ enum RegExp {
|
||||||
Kleene(Box<RegExp>),
|
Kleene(Box<RegExp>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Derivatives
|
|
||||||
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RegExp {
|
|
||||||
fn match_string(self : RegExp, s : &String) -> bool {
|
|
||||||
let chrs = s.chars();
|
|
||||||
let mut rs : RegExp = self;
|
|
||||||
for c in chrs {
|
|
||||||
rs = derivative(&rs, c);
|
|
||||||
}
|
|
||||||
is_nullable(&rs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
use std::str::Chars;
|
use std::str::Chars;
|
||||||
|
|
||||||
|
@ -138,6 +89,55 @@ impl RegExp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Derivatives
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RegExp {
|
||||||
|
fn match_string(self : RegExp, s : &String) -> bool {
|
||||||
|
let chrs = s.chars();
|
||||||
|
let mut rs : RegExp = self;
|
||||||
|
for c in chrs {
|
||||||
|
rs = derivative(&rs, c);
|
||||||
|
}
|
||||||
|
is_nullable(&rs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let s1 = RegExp::from(String::from("(ab|c)(ab)*"));
|
let s1 = RegExp::from(String::from("(ab|c)(ab)*"));
|
||||||
let inp = String::from("abab");
|
let inp = String::from("abab");
|
||||||
|
|
Loading…
Reference in New Issue