-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser_and_combinators.hs
More file actions
185 lines (155 loc) · 6.37 KB
/
parser_and_combinators.hs
File metadata and controls
185 lines (155 loc) · 6.37 KB
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
--import Text.Regex.Posix
import qualified Text.Parsec as T
import Text.ParserCombinators.Parsec
import Data.List
type Jour = String
type Mois = String
type Annee = Int
data Date = Date {jour :: Jour, mois :: Mois , annee :: Annee }
type Identifiant = String
data Email = Email {first :: Identifiant , second :: String , end :: String}
type Solde = Int
type Entreprise = String
type ReferenceTransac = String
data Transaction = T {coutTransaction :: Int , referenceTransaction :: ReferenceTransac}
data Facture = F {numeroFacture :: Int, montantFacture :: Int }
data Paiement = P {soldeCourant :: Solde, infoTransaction :: Transaction, infoFacture :: Facture}
instance Show Paiement where
show x = "solde courant : " ++ show (soldeCourant x) ++ "\n" ++
show (infoTransaction x) ++ "\n" ++
show (infoFacture x)
instance Show Facture where
show y = "numero de facture : " ++ show (numeroFacture y) ++ "\n" ++
"montant facture :" ++ show (montantFacture y)
instance Show Transaction where
show t = "cout :" ++ show (coutTransaction t) ++ "\n" ++
"reference :" ++ show (referenceTransaction t)
instance Show Date where
show var = "jour : " ++ show (jour var) ++ "\n" ++ "mois :" ++ show (mois var) ++ "\n" ++ "annee: " ++ show (annee var)
instance Show Email where
show y = if null (first y) then error "identifiant nul"
else first y ++ "@" ++ second y ++ "." ++ end y
-- le code du parser d'une date
parsedate :: Parser Date
parsedate = do
jour <- many digit
char '/'
mois <- many digit
char '/'
annee <- many digit
let anneeInt = read annee :: Int
j = if length jour == 1 then "0" ++ jour else jour
return $ Date j mois anneeInt
-- fonction utile pour faire le parsing de la date
findDate :: String -> Either ParseError Date
findDate = parse parsedate "le format de la date ne correspond pas "
-- -- parser d'un email : elieraoulnet@gmail.com
parserEmail :: Parser Email -- jean94@domain.com
parserEmail = do
x <- parserIdentifiant
let y = parse parserPoint "" x
case y of
Left _ -> unexpected x
Right a -> do
let u = a
char '@'
var <- many (noneOf ".")
let varParser = parse parserDomaine "" var
case varParser of
Left _ -> unexpected var
Right b -> do
let k = b
char '.'
z <- many letter <?> "extension non-valide "
let email = Email {first = u, second = k, end = z} -- u ++ "@" ++ k ++ "." ++ z
return email
-- newline
-- parserEmail
parserIdentifiant :: Parser String
parserIdentifiant = do
lookingFor <- many (noneOf "@")
-- state <- TP.getState
-- TP.putState state
return lookingFor
parserPoint :: Parser String
parserPoint = do
x <- many (noneOf ".") `sepBy` char '.'
if "" `elem` x then unexpected "ne doit pas commencer par '.' | contient au moins deux points consecutifs" else return $ intercalate "." x
parserDomaine :: Parser String
parserDomaine = do
firstChar <- noneOf "-0123456789"
dopo <- many (noneOf "-") `sepBy` char '-'
if "" `elem` dopo then unexpected "ne commence pas par un tiret" else return (firstChar : intercalate "-" dopo)
-- fonction qui appelle la fonction du parsing d'un email
-- parseFromFile permet d'analyser depuis un fichier, il ne retourne pas a la ligne
fonctionEmail :: IO ()
fonctionEmail = do
fileContent <- readFile "emailFile.txt"
let fileLines = lines fileContent
result = map (parse parserEmail "") fileLines
writeFile "email_conformes.txt" (unlines (map f result))
where f :: Either ParseError Email -> String
f (Right x) = show x
f (Left y) = ""
-- test de fonctionnalite avec getInput et setInput
testParser :: Parser String
testParser = do
noneOf "@" >> string "debut"
reste <- getInput -- getInput recupere le reste de la chaine apres un parsing
setInput reste -- setInput continues l'analyse avec le reste de la chaine
string "fin"
fonctionTestParser :: String -> Either ParseError String
fonctionTestParser = parse testParser "erreur survenue : personnalise"
-- parser pour une donne de type ReferenceTransac
parserRefTransac :: Parser ReferenceTransac
parserRefTransac = do
x <- count 2 upper <?> "format de la reference invalide"
-- reste <- getInput
-- setInput reste
first <- many digit
char '.'
second <- many digit
char '.'
y <- upper <?> "format de reference invalide"
end <- many digit
let result = x ++ first ++ "." ++ second ++ "." ++ (y:end)
return result
-- fonction pour analyser un element de type ReferenceTransac
refTest :: String -> Either ParseError ReferenceTransac
refTest = parse parserRefTransac "format de reference invalide"
-- parser d'un message recu apres paiement de la facture
parserMessage :: Parser Paiement
parserMessage = do
string "Vous venez de regler la totalite de votre facture chez" >> spaces
entreprise <- many letter
spaces
string "d'un montant de" >> spaces
montant <- many digit
spaces
many letter >> char '.' >> newline
string "Cette transaction vous a coute:" >> spaces
frais <- many digit
spaces >> many letter >> newline
string "Votre nouveau solde est de:" >> spaces
solde <- many digit
spaces >> many letter >> newline
string "Numero de facture:" >> spaces
numero <- many digit
newline
string "Reference de transaction:" >> spaces
refNum <- parserRefTransac
newline
string "Orange Money vous remercie"
let transac = T {coutTransaction = read frais :: Int , referenceTransaction = refNum}
fact = F {numeroFacture = read numero :: Int , montantFacture = read montant :: Int}
paiement = P {soldeCourant = read solde :: Int, infoTransaction = transac, infoFacture = fact}
return paiement
-- fonction qui fait le parsing d'un message contenu dans un fichier
message :: IO ()
message = do
result <- parseFromFile parserMessage "messages.txt"
writeFile "informations.txt" (f result)
where f :: Either ParseError Paiement -> String
f (Right x) = show x
f (Left y) = show y
-- comment faire pour appeler l'erreur de parserRefTransac dans message fonv