1""" 2Grammalecte - Lexicographe 3""" 4 5# License: MPL 2 6 7 8import re 9import traceback 10 11 12_dTAGS = { 13 ':N': (" nom,", "Nom"), 14 ':A': (" adjectif,", "Adjectif"), 15 ':M1': (" prénom,", "Prénom"), 16 ':M2': (" patronyme,", "Patronyme, matronyme, nom de famille…"), 17 ':MP': (" nom propre,", "Nom propre"), 18 ':W': (" adverbe,", "Adverbe"), 19 ':J': (" interjection,", "Interjection"), 20 ':B': (" nombre,", "Nombre"), 21 ':T': (" titre,", "Titre de civilité"), 22 23 ':e': (" épicène", "épicène"), 24 ':m': (" masculin", "masculin"), 25 ':f': (" féminin", "féminin"), 26 ':s': (" singulier", "singulier"), 27 ':p': (" pluriel", "pluriel"), 28 ':i': (" invariable", "invariable"), 29 30 ':V1': (" verbe (1ᵉʳ gr.),", "Verbe du 1ᵉʳ groupe"), 31 ':V2': (" verbe (2ᵉ gr.),", "Verbe du 2ᵉ groupe"), 32 ':V3': (" verbe (3ᵉ gr.),", "Verbe du 3ᵉ groupe"), 33 ':V0e': (" verbe,", "Verbe auxiliaire être"), 34 ':V0a': (" verbe,", "Verbe auxiliaire avoir"), 35 36 ':Y': (" infinitif,", "infinitif"), 37 ':P': (" participe présent,", "participe présent"), 38 ':Q': (" participe passé,", "participe passé"), 39 ':Ip': (" présent,", "indicatif présent"), 40 ':Iq': (" imparfait,", "indicatif imparfait"), 41 ':Is': (" passé simple,", "indicatif passé simple"), 42 ':If': (" futur,", "indicatif futur"), 43 ':K': (" conditionnel présent,", "conditionnel présent"), 44 ':Sp': (" subjonctif présent,", "subjonctif présent"), 45 ':Sq': (" subjonctif imparfait,", "subjonctif imparfait"), 46 ':E': (" impératif,", "impératif"), 47 48 ':1s': (" 1ʳᵉ p. sg.,", "verbe : 1ʳᵉ personne du singulier"), 49 ':1ŝ': (" présent interr. 1ʳᵉ p. sg.,", "verbe : 1ʳᵉ personne du singulier (présent interrogatif)"), 50 ':1ś': (" présent interr. 1ʳᵉ p. sg.,", "verbe : 1ʳᵉ personne du singulier (présent interrogatif)"), 51 ':2s': (" 2ᵉ p. sg.,", "verbe : 2ᵉ personne du singulier"), 52 ':3s': (" 3ᵉ p. sg.,", "verbe : 3ᵉ personne du singulier"), 53 ':1p': (" 1ʳᵉ p. pl.,", "verbe : 1ʳᵉ personne du pluriel"), 54 ':2p': (" 2ᵉ p. pl.,", "verbe : 2ᵉ personne du pluriel"), 55 ':3p': (" 3ᵉ p. pl.,", "verbe : 3ᵉ personne du pluriel"), 56 ':3p!': (" 3ᵉ p. pl.,", "verbe : 3ᵉ personne du pluriel (prononciation distinctive)"), 57 58 ':G': ("", "Mot grammatical"), 59 ':X': (" adverbe de négation,", "Adverbe de négation"), 60 ':U': (" adverbe interrogatif,", "Adverbe interrogatif"), 61 ':R': (" préposition,", "Préposition"), 62 ':Rv': (" préposition verbale,", "Préposition verbale"), 63 ':D': (" déterminant,", "Déterminant"), 64 ':Dd': (" déterminant démonstratif,", "Déterminant démonstratif"), 65 ':De': (" déterminant exclamatif,", "Déterminant exclamatif"), 66 ':Dp': (" déterminant possessif,", "Déterminant possessif"), 67 ':Di': (" déterminant indéfini,", "Déterminant indéfini"), 68 ':Dn': (" déterminant négatif,", "Déterminant négatif"), 69 ':Od': (" pronom démonstratif,", "Pronom démonstratif"), 70 ':Oi': (" pronom indéfini,", "Pronom indéfini"), 71 ':On': (" pronom indéfini négatif,", "Pronom indéfini négatif"), 72 ':Ot': (" pronom interrogatif,", "Pronom interrogatif"), 73 ':Or': (" pronom relatif,", "Pronom relatif"), 74 ':Ow': (" pronom adverbial,", "Pronom adverbial"), 75 ':Os': (" pronom personnel sujet,", "Pronom personnel sujet"), 76 ':Oo': (" pronom personnel objet,", "Pronom personnel objet"), 77 ':Ov': (" préverbe,", "Préverbe (pronom personnel objet, +ne)"), 78 ':O1': (" 1ʳᵉ pers.,", "Pronom : 1ʳᵉ personne"), 79 ':O2': (" 2ᵉ pers.,", "Pronom : 2ᵉ personne"), 80 ':O3': (" 3ᵉ pers.,", "Pronom : 3ᵉ personne"), 81 ':C': (" conjonction,", "Conjonction"), 82 ':Ĉ': (" conjonction (él.),", "Conjonction (élément)"), 83 ':Cc': (" conjonction de coordination,", "Conjonction de coordination"), 84 ':Cs': (" conjonction de subordination,", "Conjonction de subordination"), 85 ':Ĉs': (" conjonction de subordination (él.),", "Conjonction de subordination (élément)"), 86 87 ':ÉN': (" locution nominale (él.),", "Locution nominale (élément)"), 88 ':ÉA': (" locution adjectivale (él.),", "Locution adjectivale (élément)"), 89 ':ÉV': (" locution verbale (él.),", "Locution verbale (élément)"), 90 ':ÉW': (" locution adverbiale (él.),", "Locution adverbiale (élément)"), 91 ':ÉR': (" locution prépositive (él.),", "Locution prépositive (élément)"), 92 ':ÉJ': (" locution interjective (él.),", "Locution interjective (élément)"), 93 94 ':Zp': (" préfixe,", "Préfixe"), 95 ':Zs': (" suffixe,", "Suffixe"), 96 97 ':H': ("", "<Hors-norme, inclassable>"), 98 99 ':@': ("", "<Caractère non alpha-numérique>"), 100 ':@p': ("signe de ponctuation", "Signe de ponctuation"), 101 ':@s': ("signe", "Signe divers"), 102 103 ';S': (" : symbole (unité de mesure)", "Symbole (unité de mesure)"), 104 105 '/*': ("", "Sous-dictionnaire <Commun>"), 106 '/C': (" <classique>", "Sous-dictionnaire <Classique>"), 107 '/M': ("", "Sous-dictionnaire <Moderne>"), 108 '/R': (" <réforme>", "Sous-dictionnaire <Réforme 1990>"), 109 '/A': ("", "Sous-dictionnaire <Annexe>"), 110 '/X': ("", "Sous-dictionnaire <Contributeurs>") 111} 112 113_dPFX = { 114 'd': "(de), déterminant épicène invariable", 115 'l': "(le/la), déterminant masculin/féminin singulier", 116 'j': "(je), pronom personnel sujet, 1ʳᵉ pers., épicène singulier", 117 'm': "(me), pronom personnel objet, 1ʳᵉ pers., épicène singulier", 118 't': "(te), pronom personnel objet, 2ᵉ pers., épicène singulier", 119 's': "(se), pronom personnel objet, 3ᵉ pers., épicène singulier/pluriel", 120 'n': "(ne), adverbe de négation", 121 'c': "(ce), pronom démonstratif, masculin singulier/pluriel", 122 'ç': "(ça), pronom démonstratif, masculin singulier", 123 'qu': "(que), conjonction de subordination", 124 'lorsqu': "(lorsque), conjonction de subordination", 125 'puisqu': "(puisque), conjonction de subordination", 126 'quoiqu': "(quoique), conjonction de subordination", 127 'jusqu': "(jusque), préposition", 128} 129 130_dAD = { 131 'je': " pronom personnel sujet, 1ʳᵉ pers. sing.", 132 'tu': " pronom personnel sujet, 2ᵉ pers. sing.", 133 'il': " pronom personnel sujet, 3ᵉ pers. masc. sing.", 134 'on': " pronom personnel sujet, 3ᵉ pers. sing. ou plur.", 135 'elle': " pronom personnel sujet, 3ᵉ pers. fém. sing.", 136 'nous': " pronom personnel sujet/objet, 1ʳᵉ pers. plur.", 137 'vous': " pronom personnel sujet/objet, 2ᵉ pers. plur.", 138 'ils': " pronom personnel sujet, 3ᵉ pers. masc. plur.", 139 'elles': " pronom personnel sujet, 3ᵉ pers. masc. plur.", 140 141 "là": " particule démonstrative", 142 "ci": " particule démonstrative", 143 144 'le': " COD, masc. sing.", 145 'la': " COD, fém. sing.", 146 'les': " COD, plur.", 147 148 'moi': " COI (à moi), sing.", 149 'toi': " COI (à toi), sing.", 150 'lui': " COI (à lui ou à elle), sing.", 151 'nous2': " COI (à nous), plur.", 152 'vous2': " COI (à vous), plur.", 153 'leur': " COI (à eux ou à elles), plur.", 154 155 'y': " pronom adverbial", 156 "m'y": " (me) pronom personnel objet + (y) pronom adverbial", 157 "t'y": " (te) pronom personnel objet + (y) pronom adverbial", 158 "s'y": " (se) pronom personnel objet + (y) pronom adverbial", 159 160 'en': " pronom adverbial", 161 "m'en": " (me) pronom personnel objet + (en) pronom adverbial", 162 "t'en": " (te) pronom personnel objet + (en) pronom adverbial", 163 "s'en": " (se) pronom personnel objet + (en) pronom adverbial", 164} 165 166 167class Lexicographe: 168 "Lexicographer - word analyzer" 169 170 def __init__ (self, oSpellChecker): 171 self.oSpellChecker = oSpellChecker 172 self._zElidedPrefix = re.compile("(?i)^([dljmtsncç]|quoiqu|lorsqu|jusqu|puisqu|qu)['’](.+)") 173 self._zCompoundWord = re.compile("(?i)(\\w+)-((?:les?|la)-(?:moi|toi|lui|[nv]ous|leur)|t-(?:il|elle|on)|y|en|[mts][’'](?:y|en)|les?|l[aà]|[mt]oi|leur|lui|je|tu|ils?|elles?|on|[nv]ous)$") 174 self._zTag = re.compile("[:;/][\\w*][^:;/]*") 175 176 def analyzeWord (self, sWord): 177 "returns a tuple (a list of morphologies, a set of verb at infinitive form)" 178 try: 179 if not sWord: 180 return (None, None) 181 if sWord.count("-") > 4: 182 return (["élément complexe indéterminé"], None) 183 if sWord.isdigit(): 184 return (["nombre"], None) 185 186 aMorph = [] 187 # préfixes élidés 188 m = self._zElidedPrefix.match(sWord) 189 if m: 190 sWord = m.group(2) 191 aMorph.append( "{}’ : {}".format(m.group(1), _dPFX.get(m.group(1).lower(), "[?]")) ) 192 # mots composés 193 m2 = self._zCompoundWord.match(sWord) 194 if m2: 195 sWord = m2.group(1) 196 # Morphologies 197 lMorph = self.oSpellChecker.getMorph(sWord) 198 if len(lMorph) > 1: 199 # sublist 200 aMorph.append( (sWord, [ self.formatTags(s) for s in lMorph if ":" in s ]) ) 201 elif len(lMorph) == 1: 202 aMorph.append( "{} : {}".format(sWord, self.formatTags(lMorph[0])) ) 203 else: 204 aMorph.append( "{} : inconnu du dictionnaire".format(sWord) ) 205 # suffixe d’un mot composé 206 if m2: 207 aMorph.append( "-{} : {}".format(m2.group(2), self._formatSuffix(m2.group(2).lower())) ) 208 # Verbes 209 aVerb = { s[1:s.find("/")] for s in lMorph if ":V" in s } 210 return (aMorph, aVerb) 211 except (IndexError, TypeError): 212 traceback.print_exc() 213 return (["#erreur"], None) 214 215 def formatTags (self, sTags): 216 "returns string: readable tags" 217 sRes = "" 218 sTags = re.sub("(?<=V[1-3])[itpqnmr_eaxz]+", "", sTags) 219 sTags = re.sub("(?<=V0[ea])[itpqnmr_eaxz]+", "", sTags) 220 for m in self._zTag.finditer(sTags): 221 sRes += _dTAGS.get(m.group(0), " [{}]".format(m.group(0)))[0] 222 if sRes.startswith(" verbe") and not sRes.endswith("infinitif"): 223 sRes += " [{}]".format(sTags[1:sTags.find("/")]) 224 return sRes.rstrip(",") 225 226 def _formatSuffix (self, s): 227 if s.startswith("t-"): 228 return "“t” euphonique +" + _dAD.get(s[2:], "[?]") 229 if not "-" in s: 230 return _dAD.get(s.replace("’", "'"), "[?]") 231 if s.endswith("ous"): 232 s += '2' 233 nPos = s.find("-") 234 return "%s +%s" % (_dAD.get(s[:nPos], "[?]"), _dAD.get(s[nPos+1:], "[?]")) 235