Skip to content

Commit 54b21c2

Browse files
committed
regex derivative matching
1 parent fd7919f commit 54b21c2

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

Regex.hs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
module Regex where
2+
3+
-- TODO: groups
4+
5+
import Prelude hiding (seq)
6+
import Data.Set as S
7+
8+
data Regex a = Null
9+
| Empty
10+
| Seq (Regex a) (Regex a)
11+
| Alt (Regex a) (Regex a)
12+
| Rep (Regex a)
13+
| One a
14+
deriving (Show, Eq)
15+
16+
seq Null _ = Null
17+
seq _ Null = Null
18+
seq Empty pat2 = pat2
19+
seq pat1 Empty = pat1
20+
seq pat1 pat2 = Seq pat1 pat2
21+
22+
alt Null pat2 = pat2
23+
alt pat1 Null = pat1
24+
alt pat1 pat2 = Alt pat1 pat2
25+
26+
rep Null = Empty
27+
rep Empty = Empty
28+
rep pat = Rep pat
29+
30+
toEmpty Null = Null
31+
toEmpty Empty = Empty
32+
toEmpty (Seq pat1 pat2) = seq (toEmpty pat1) (toEmpty pat2)
33+
toEmpty (Alt pat1 pat2) = alt (toEmpty pat1) (toEmpty pat2)
34+
toEmpty (Rep pat) = Empty
35+
toEmpty (One _) = Null
36+
37+
deriv Null _ = Null
38+
deriv Empty _ = Null
39+
deriv (Seq pat1 pat2) atom = alt (seq (deriv pat1 atom) pat2)
40+
(seq (toEmpty pat1) (deriv pat2 atom))
41+
deriv (Alt pat1 pat2) atom = alt (deriv pat1 atom) (deriv pat2 atom)
42+
deriv (Rep pat) atom = seq (deriv pat atom) (rep pat)
43+
deriv (One patom) atom = if patom == atom then Empty else Null
44+
45+
match pat [] = case toEmpty pat of
46+
Empty -> True
47+
_ -> False
48+
match pat (fst:rest) = match (deriv pat fst) rest
49+
50+
tests = [
51+
deriv (One 'b') 'f' == Null,
52+
deriv (seq (One 'f') (One 'b')) 'f' == One 'b',
53+
deriv (alt (seq (One 'f') (One 'b')) (seq (One 'f') (rep (One 'z')))) 'f' == Alt (One 'b') (Rep (One 'z')),
54+
match (seq (One 'f') (rep (One 'b'))) "fbbb" == True,
55+
match (seq (One 'f') (rep (One 'b'))) "fbzbb" == False,
56+
match (seq (One 'f') (rep (alt (One 'b') (One 'z')))) "fbzbb" == True]

0 commit comments

Comments
 (0)