1"""
2Grammalecte - Compiled regular expressions
3"""
4
5import re
6
7#### Lemme
8Lemma = re.compile(r"^>(\w[\w-]*)")
9
10#### Analyses
11Gender = re.compile(":[mfe]")
12Number = re.compile(":[spi]")
13
14#### Nom et adjectif
15NA = re.compile(":[NA]")
16
17## nombre
18NAs = re.compile(":[NA].*:s")
19NAp = re.compile(":[NA].*:p")
20NAi = re.compile(":[NA].*:i")
21NAsi = re.compile(":[NA].*:[si]")
22NApi = re.compile(":[NA].*:[pi]")
23
24## genre
25NAm = re.compile(":[NA].*:m")
26NAf = re.compile(":[NA].*:f")
27NAe = re.compile(":[NA].*:e")
28NAme = re.compile(":[NA].*:[me]")
29NAfe = re.compile(":[NA].*:[fe]")
30
31## nombre et genre
32# singuilier
33NAms = re.compile(":[NA].*:m.*:s")
34NAfs = re.compile(":[NA].*:f.*:s")
35NAes = re.compile(":[NA].*:e.*:s")
36NAmes = re.compile(":[NA].*:[me].*:s")
37NAfes = re.compile(":[NA].*:[fe].*:s")
38
39# singulier et invariable
40NAmsi = re.compile(":[NA].*:m.*:[si]")
41NAfsi = re.compile(":[NA].*:f.*:[si]")
42NAesi = re.compile(":[NA].*:e.*:[si]")
43NAmesi = re.compile(":[NA].*:[me].*:[si]")
44NAfesi = re.compile(":[NA].*:[fe].*:[si]")
45
46# pluriel
47NAmp = re.compile(":[NA].*:m.*:p")
48NAfp = re.compile(":[NA].*:f.*:p")
49NAep = re.compile(":[NA].*:e.*:p")
50NAmep = re.compile(":[NA].*:[me].*:p")
51NAfep = re.compile(":[NA].*:[me].*:p")
52
53# pluriel et invariable
54NAmpi = re.compile(":[NA].*:m.*:[pi]")
55NAfpi = re.compile(":[NA].*:f.*:[pi]")
56NAepi = re.compile(":[NA].*:e.*:[pi]")
57NAmepi = re.compile(":[NA].*:[me].*:[pi]")
58NAfepi = re.compile(":[NA].*:[fe].*:[pi]")
59
60# divers
61AD = re.compile(":[AB]")
62
63#### Verbe
64Vconj = re.compile(":[123][sp]")
65Vconj123 = re.compile(":V[123].*:[123][sp]")
66
67#### Nom | Adjectif | Verbe
68NVconj = re.compile(":(?:N|[123][sp])")
69NAVconj = re.compile(":(?:N|A|[123][sp])")
70
71#### Spécifique
72NnotA = re.compile(":N(?!:A)")
73PNnotA = re.compile(":(?:N(?!:A)|Q)")
74
75#### Noms propres
76NP = re.compile(":(?:M[12P]|T)")
77NPm = re.compile(":(?:M[12P]|T):m")
78NPf = re.compile(":(?:M[12P]|T):f")
79NPe = re.compile(":(?:M[12P]|T):e")
80
81
82#### FONCTIONS
83
84def getLemmaOfMorph (s):
85    "return lemma in morphology <s>"
86    return Lemma.search(s).group(1)
87
88def checkAgreement (l1, l2):
89    "returns True if agreement in gender and number is possible between morphologies <l1> and <l2>"
90    # check number agreement
91    if not mbInv(l1) and not mbInv(l2):
92        if mbSg(l1) and not mbSg(l2):
93            return False
94        if mbPl(l1) and not mbPl(l2):
95            return False
96    # check gender agreement
97    if mbEpi(l1) or mbEpi(l2):
98        return True
99    if mbMas(l1) and not mbMas(l2):
100        return False
101    if mbFem(l1) and not mbFem(l2):
102        return False
103    return True
104
105def checkConjVerb (lMorph, sReqConj):
106    "returns True if <sReqConj> in <lMorph>"
107    return any(sReqConj in s  for s in lMorph)
108
109def getGender (lMorph):
110    "returns gender of word (':m', ':f', ':e' or empty string)."
111    sGender = ""
112    for sMorph in lMorph:
113        m = Gender.search(sMorph)
114        if m:
115            if not sGender:
116                sGender = m.group(0)
117            elif sGender != m.group(0):
118                return ":e"
119    return sGender
120
121def getNumber (lMorph):
122    "returns number of word (':s', ':p', ':i' or empty string)."
123    sNumber = ""
124    for sMorph in lMorph:
125        m = Number.search(sMorph)
126        if m:
127            if not sNumber:
128                sNumber = m.group(0)
129            elif sNumber != m.group(0):
130                return ":i"
131    return sNumber
132
133# NOTE :  isWhat (lMorph)    returns True   if lMorph contains nothing else than What
134#         mbWhat (lMorph)    returns True   if lMorph contains What at least once
135
136## isXXX = it’s certain
137
138def isNom (lMorph):
139    "returns True if all morphologies are “nom”"
140    return all(":N" in s  for s in lMorph)
141
142def isNomNotAdj (lMorph):
143    "returns True if all morphologies are “nom”, but not “adjectif”"
144    return all(NnotA.search(s)  for s in lMorph)
145
146def isAdj (lMorph):
147    "returns True if all morphologies are “adjectif”"
148    return all(":A" in s  for s in lMorph)
149
150def isNomAdj (lMorph):
151    "returns True if all morphologies are “nom” or “adjectif”"
152    return all(NA.search(s)  for s in lMorph)
153
154def isNomVconj (lMorph):
155    "returns True if all morphologies are “nom” or “verbe conjugué”"
156    return all(NVconj.search(s)  for s in lMorph)
157
158def isInv (lMorph):
159    "returns True if all morphologies are “invariable”"
160    return all(":i" in s  for s in lMorph)
161
162def isSg (lMorph):
163    "returns True if all morphologies are “singulier”"
164    return all(":s" in s  for s in lMorph)
165
166def isPl (lMorph):
167    "returns True if all morphologies are “pluriel”"
168    return all(":p" in s  for s in lMorph)
169
170def isEpi (lMorph):
171    "returns True if all morphologies are “épicène”"
172    return all(":e" in s  for s in lMorph)
173
174def isMas (lMorph):
175    "returns True if all morphologies are “masculin”"
176    return all(":m" in s  for s in lMorph)
177
178def isFem (lMorph):
179    "returns True if all morphologies are “féminin”"
180    return all(":f" in s  for s in lMorph)
181
182
183## mbXXX = MAYBE XXX
184
185def mbNom (lMorph):
186    "returns True if one morphology is “nom”"
187    return any(":N" in s  for s in lMorph)
188
189def mbAdj (lMorph):
190    "returns True if one morphology is “adjectif”"
191    return any(":A" in s  for s in lMorph)
192
193def mbAdjNb (lMorph):
194    "returns True if one morphology is “adjectif” or “nombre”"
195    return any(AD.search(s)  for s in lMorph)
196
197def mbNomAdj (lMorph):
198    "returns True if one morphology is “nom” or “adjectif”"
199    return any(NA.search(s)  for s in lMorph)
200
201def mbNomNotAdj (lMorph):
202    "returns True if one morphology is “nom”, but not “adjectif”"
203    bResult = False
204    for s in lMorph:
205        if ":A" in s:
206            return False
207        if ":N" in s:
208            bResult = True
209    return bResult
210
211def mbPpasNomNotAdj (lMorph):
212    "returns True if one morphology is “nom” or “participe passé”, but not “adjectif”"
213    return any(PNnotA.search(s)  for s in lMorph)
214
215def mbVconj (lMorph):
216    "returns True if one morphology is “nom” or “verbe conjugué”"
217    return any(Vconj.search(s)  for s in lMorph)
218
219def mbVconj123 (lMorph):
220    "returns True if one morphology is “nom” or “verbe conjugué” (but not “avoir” or “être”)"
221    return any(Vconj123.search(s)  for s in lMorph)
222
223def mbMG (lMorph):
224    "returns True if one morphology is “mot grammatical”"
225    return any(":G" in s  for s in lMorph)
226
227def mbInv (lMorph):
228    "returns True if one morphology is “invariable”"
229    return any(":i" in s  for s in lMorph)
230
231def mbSg (lMorph):
232    "returns True if one morphology is “singulier”"
233    return any(":s" in s  for s in lMorph)
234
235def mbPl (lMorph):
236    "returns True if one morphology is “pluriel”"
237    return any(":p" in s  for s in lMorph)
238
239def mbEpi (lMorph):
240    "returns True if one morphology is “épicène”"
241    return any(":e" in s  for s in lMorph)
242
243def mbMas (lMorph):
244    "returns True if one morphology is “masculin”"
245    return any(":m" in s  for s in lMorph)
246
247def mbFem (lMorph):
248    "returns True if one morphology is “féminin”"
249    return any(":f" in s  for s in lMorph)
250
251def mbNpr (lMorph):
252    "returns True if one morphology is “nom propre” or “titre de civilité”"
253    return any(NP.search(s)  for s in lMorph)
254
255def mbNprMasNotFem (lMorph):
256    "returns True if one morphology is “nom propre masculin” but not “féminin”"
257    if any(NPf.search(s)  for s in lMorph):
258        return False
259    return any(NPm.search(s)  for s in lMorph)
260