blob: ce80adea74c278cea03806089c061d331eb3a946 (
plain)
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
|
-- Write a version of globToRegex that uses the type signature earlier.
{-- From examples/examples/ch08/GlobRegex.hs modified according to the assignment --}
import Text.Regex.Posix ((=~))
type GlobError = String
globToRegex :: String -> Either GlobError String
globToRegex cs = propagateError regex
where regex = globToRegex' cs
propagateError (Left e) = Left e
propagateError (Right s) = Right ('^' : s ++ "$")
globToRegex' :: String -> Either GlobError String
globToRegex' "" = Right ""
globToRegex' ('*':cs) = propagateError regex
where regex = globToRegex' cs
propagateError (Left e) = Left e
propagateError (Right s) = Right (".*" ++ s)
globToRegex' ('?':cs) = propagateError regex
where regex = globToRegex' cs
propagateError (Left e) = Left e
propagateError (Right s) = Right ("." ++ s)
globToRegex' ('[':'!':c:cs) = propagateError charCls
where charCls = charClass cs
propagateError (Left e) = Left e
propagateError (Right s) = Right ("[^" ++ c : s)
globToRegex' ('[':c:cs) = propagateError charCls
where charCls = charClass cs
propagateError (Left e) = Left e
propagateError (Right s) = Right ('[' : c : s)
globToRegex' ('[':_) = Left "unterminated character class"
globToRegex' (c:cs) = propagateError regex
where regex = globToRegex' cs
propagateError (Left e) = Left e
propagateError (Right s) = Right ((escape c) ++ s)
escape :: Char -> String
escape c | c `elem` regexChars = '\\' : [c]
| otherwise = [c]
where regexChars = "\\+()^$.{}]|"
charClass :: String -> Either GlobError String
charClass (']':cs) = propagateError regex
where regex = globToRegex' cs
propagateError (Left e) = Left e
propagateError (Right s) = Right (']' : s)
charClass (c:cs) = propagateError charCls
where charCls = charClass cs
propagateError (Left e) = Left e
propagateError (Right s) = Right (c : s)
charClass [] = Left "unterminated character class"
{-- End of code from examples --}
-- ghci> :l 8_c_1.hs
-- [1 of 1] Compiling Main ( 8_c_1.hs, interpreted )
-- Ok, one module loaded.
-- ghci> globToRegex "["
-- Left "unterminated character class"
-- ghci> globToRegex "[]"
-- Left "unterminated character class"
-- ghci> globToRegex "a?b*c[!DE][FG]+"
-- Right "^a.b.*c[^DE][FG]\\+$"
|