-
Notifications
You must be signed in to change notification settings - Fork 0
/
aoba.hs
265 lines (204 loc) · 6.35 KB
/
aoba.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
{-# LANGUAGE GADTs #-}
import Text.ParserCombinators.Parsec
import RegExpr.Operation
import Data.Either
import Control.Monad
import Data.List(splitAt,elemIndex)
import System.Environment (getArgs)
import Debug.Trace
echars = "\\^*+?|().[]-{}"
--achars = "wWdDsS"
w= cut ws
ws ="[0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz]"
digi = cut digis
digis ="[0123456789]"
s= cut ss
ss = "[\t\n\v\f\r]"
cut:: String -> String
cut str = slice 1 (length str -1) str
slice :: Int -> Int -> [a] -> [a]
slice start stop xs = fst $ splitAt (stop - start) (snd $ splitAt start xs)
flatten :: [[a]] -> [a]
flatten xs = (\z n -> foldr (\x y -> foldr z y x) n xs) (:) []
rng2set:: Char -> Char -> String -> String
rng2set a b str = do
let si = fromJust $ elemIndex a str
let ei = fromJust $ elemIndex b str
slice si (ei+1) str
rparse:: String -> RE
rparse s = do
case parse re "" s of
Left e -> trace ("error" ++ show e ) Phi
Right r -> r
fromJust :: Maybe a -> a
fromJust Nothing = error "Maybe.fromJust: Nothing"
fromJust (Just x) = x
repeatC :: RE -> Int -> RE
repeatC r 0 = Empty
repeatC r 1 = r
repeatC r n = Choice (repeatC r $ n-1 ) (repeatN r n)
repeatN :: RE -> Int -> RE
repeatN r 0 = Empty
repeatN r 1 = r
repeatN r n = Seq (repeatN r $ n-1 ) r
re:: GenParser Char st RE
re = try union <|> sre
union::GenParser Char st RE
union = do
a <- sre
char '|'
b <- re
pure (Choice a b)
sre:: GenParser Char st RE
sre = try concatenation <|> bre
concatenation:: GenParser Char st RE
concatenation = liftM2 Seq (bre) (sre)
bre:: GenParser Char st RE
bre = try estar <|> try eplus <|>try eqm<|>try erange <|> try erange' <|> ere
ere:: GenParser Char st RE
ere = group <|> anyC <|> literal <|>try set <|> try escape <|> alias
group:: GenParser Char st RE
group = between (char '(') (char ')') re
set:: GenParser Char st RE
set = try nset <|> pset
anyC :: GenParser Char st RE
anyC = char '.' >> pure (Any)
literal :: GenParser Char st RE
literal = liftM L (noneOf echars)
escape :: GenParser Char st RE
escape = char '\\' >> liftM L (oneOf echars)
ec :: GenParser Char st Char
ec = char '\\' >> oneOf echars
alias :: GenParser Char st RE
alias = try dgt <|> try ndgt <|> try word <|> try nword <|> try sps <|> nsps
dgt:: GenParser Char st RE
dgt = char '\\' >> char 'd' >> pure(rparse digis)
ndgt:: GenParser Char st RE
ndgt = char '\\' >> char 'D' >> pure(Not digi)
word:: GenParser Char st RE
word = char '\\' >> char 'w' >> pure(rparse ws)
nword:: GenParser Char st RE
nword = char '\\' >> char 'W' >> pure(Not w)
sps:: GenParser Char st RE
sps = char '\\' >> char 's' >> pure(rparse ss)
nsps:: GenParser Char st RE
nsps = char '\\' >> char 'S' >> pure(Not s)
alias' :: GenParser Char st [Char]
alias' = try dgt' <|> try word' <|> try sps'
dgt':: GenParser Char st [Char]
dgt' = char '\\' >> char 'd' >> pure digi
word':: GenParser Char st [Char]
word' = char '\\' >> char 'w' >>pure w
sps':: GenParser Char st [Char]
sps' = char '\\' >> char 's' >>pure s
pset :: GenParser Char st RE
pset = between (char '[') (char ']') setItems
nset :: GenParser Char st RE
nset = do
char '['
char '^'
s <- notItems
char ']'
pure (Not $ flatten s)
notItems :: GenParser Char st [[Char]]
notItems = many1 $ try nrngItems <|> try alias' <|> notItems'
notItems' :: GenParser Char st [Char]
notItems' = many1 $try neitem
rng:: GenParser Char st RE
rng = try rangew <|>try ranges <|> ranged
setItems :: GenParser Char st RE --refactoring to use optionmaybe and manyuntil
setItems = liftM2 Choice (try rng<|>literal<|>try escape <|> try alias) (remainingItems)
remainingItems :: GenParser Char st RE
remainingItems = setItems <|> (return Phi)
neitem::GenParser Char st Char
neitem = do
c <- noneOf echars <|> ec
notFollowedBy $ char '-'
pure c
nrngItems = try nrangew <|> try nranged <|> nranges
nrangew:: GenParser Char st [Char]
nrangew = do
s <- oneOf w
char '-'
e <- oneOf w
pure(rng2set s e w)
nranged:: GenParser Char st [Char]
nranged = do
s <- oneOf digi
char '-'
e <- oneOf digi
pure(rng2set s e digi)
nranges:: GenParser Char st [Char]
nranges = do
st <- oneOf s
char '-'
e <- oneOf s
pure(rng2set st e s)
rangew:: GenParser Char st RE
rangew = do
s <- oneOf w
char '-'
e <- oneOf w
let r = "[" ++ (rng2set s e w)++ "]"
pure (rparse r)
ranged:: GenParser Char st RE
ranged = do
s <- oneOf digi
char '-'
e <- oneOf digi
let r = "[" ++ (rng2set s e digi)++ "]"
pure (rparse r)
ranges:: GenParser Char st RE
ranges = do
st <- oneOf s
char '-'
e <- oneOf s
let r = "[" ++ (rng2set st e s)++ "]"
pure (rparse r)
estar :: GenParser Char st RE
estar =
do e <- ere
char '*'
pure (Star e)
eplus :: GenParser Char st RE
eplus =
do e <- ere
char '+'
pure (Seq e (Star e))
eqm :: GenParser Char st RE
eqm =
do e <- ere
char '?'
pure (Choice e Empty)
erange::GenParser Char st RE
erange = do
e <- ere
char '{'
base <- fmap read $ many1 digit
char ','
high <- fmap read $ many1 digit
char '}'
pure (Seq (repeatN e base) $ Choice Empty (repeatC e (high-base)))
erange'::GenParser Char st RE
erange' = do
e <- ere
char '{'
base <- fmap read $ many1 digit
string ",}"
pure (Seq (repeatN e base) (Star e))
main = do
args <- getArgs
case args of
["-c",r1,r2] -> do
myPrint $ r2 ++ " contains " ++ r1
-- myPrint $ show (rparse r1) ++ " contains " ++ show (rparse r2)
myPrint $ contains (rparse r1) (rparse r2)
["-e",r1,r2] -> do
myPrint $ r2 ++ " equals to " ++ r1
-- myPrint $ show (rparse r1) ++ " equals to " ++ show (rparse r2)
myPrint $ equality (rparse r1) (rparse r2)
["-i",r1,r2] -> do
myPrint $ r2 ++ " intersects with " ++ r1
-- myPrint $ show (rparse r1) ++ " intersects with " ++ show (rparse r2)
myPrint $ intersect (rparse r1) (rparse r2)
_ -> putStrLn "Contains : -c re1 re2 \nEquality: -e re1 re2\nIntersection: -i re1 re2 "