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>),
|
||||
}
|
||||
|
||||
|
||||
// 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::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() {
|
||||
let s1 = RegExp::from(String::from("(ab|c)(ab)*"));
|
||||
let inp = String::from("abab");
|
||||
|
|
Loading…
Reference in New Issue