root / tmp / org.txm.analec.rcp / src / org / txm / macro / urs / edit / Frpos2CattexMacro.groovy @ 1217
History | View | Annotate | Download (10.7 kB)
1 | 671 | mdecorde | // @author Matthieu Quignard
|
---|---|---|---|
2 | 671 | mdecorde | // Date : 04 Mai 2017
|
3 | 671 | mdecorde | |
4 | 671 | mdecorde | /*
|
5 | 671 | mdecorde | Définit la catégorie grammaticale des mentions d'après le champ `frpos'
|
6 | 671 | mdecorde | (tagset de TreeTagger).
|
7 | 671 | mdecorde | |
8 | 671 | mdecorde | La liste des catégories grammaticales est celle de CATTEX2009
|
9 | 671 | mdecorde | -- Groupes nominaux :
|
10 | 671 | mdecorde | GN.NAM (noms propres) : Henri II
|
11 | 671 | mdecorde | GN.DEF (définis) : Le roi, du roi
|
12 | 671 | mdecorde | GN.IND (indéfinis) : Un roi
|
13 | 671 | mdecorde | GN.POS (possessifs) : [Mon roi]
|
14 | 671 | mdecorde | GN.DEM (demonstratif) : Ce roi
|
15 | 671 | mdecorde | GN.NUM (numéraux) : Deux rois
|
16 | 671 | mdecorde | GN.CHECK (GN indéterminés)
|
17 | 671 | mdecorde | -- Déterminants
|
18 | 671 | mdecorde | DET.POS (possessifs) : [mon] roi
|
19 | 671 | mdecorde | -- Pronoms
|
20 | 671 | mdecorde | PRO.PER (personnels) : je, moi, me, on, il, etc.
|
21 | 671 | mdecorde | PRO.ADV (adverbiaux) : y, en
|
22 | 671 | mdecorde | PRO.IND (indéfinis) : tout, tous, certains, plusieurs, etc.
|
23 | 671 | mdecorde | PRO.DEM (demonstratifs) : ceci, cela, ce, ça...
|
24 | 671 | mdecorde | PRO.POS (possessifs) : le mien, les nôtres...
|
25 | 671 | mdecorde | PRO.NUM (cardinaux, ordinaux) : les deux...
|
26 | 671 | mdecorde | PRO.REL (relatifs) : qui, que, quoi, duquel, etc.
|
27 | 671 | mdecorde | PRO.INT (interrogatifs)
|
28 | 671 | mdecorde | PRO.CHECK (pronoms indéterminés)
|
29 | 671 | mdecorde | -- Sujet Zéro : verbes conjugués, éventuellement pronominal
|
30 | 671 | mdecorde | |
31 | 671 | mdecorde | -- ERREUR : erreur (a priori) de mention
|
32 | 671 | mdecorde | |
33 | 671 | mdecorde | |
34 | 671 | mdecorde | */
|
35 | 671 | mdecorde | |
36 | 1217 | mdecorde | package org.txm.macro.urs.edit
|
37 | 671 | mdecorde | |
38 | 671 | mdecorde | import org.apache.commons.lang.* |
39 | 671 | mdecorde | import org.kohsuke.args4j.* |
40 | 671 | mdecorde | import groovy.transform.* |
41 | 671 | mdecorde | import org.txm.* |
42 | 671 | mdecorde | import org.txm.rcp.swt.widget.parameters.* |
43 | 1217 | mdecorde | import org.txm.annotation.urs.* |
44 | 671 | mdecorde | import org.txm.searchengine.cqp.* |
45 | 671 | mdecorde | import org.txm.searchengine.cqp.corpus.* |
46 | 671 | mdecorde | import visuAnalec.Message.* |
47 | 671 | mdecorde | import visuAnalec.donnees.* |
48 | 671 | mdecorde | import visuAnalec.elements.* |
49 | 671 | mdecorde | import visuAnalec.vue.* |
50 | 671 | mdecorde | |
51 | 671 | mdecorde | // Propriété donnant le lemme
|
52 | 671 | mdecorde | def lemmaProperty = "frlemma" |
53 | 671 | mdecorde | |
54 | 671 | mdecorde | /*
|
55 | 671 | mdecorde | TODO : TreeTagger fait un mauvais étiquetage des premiers mots de la phrase.
|
56 | 671 | mdecorde | La majuscule lui fait croire qu'il s'agit d'un nom propre.
|
57 | 671 | mdecorde | Vérifier que ce mot n'est pas en fait un pronom en testant sa présence dans une des listes de formes particulières
|
58 | 671 | mdecorde | */
|
59 | 671 | mdecorde | |
60 | 671 | mdecorde | |
61 | 671 | mdecorde | /**
|
62 | 671 | mdecorde | * Liste de formes utile à la catégorisation des mentions
|
63 | 671 | mdecorde | * TreeTagger n'est pas forcément très performant sur des états plus anciens de la langue
|
64 | 671 | mdecorde | ***/
|
65 | 671 | mdecorde | |
66 | 671 | mdecorde | formesArticlesDéfinis = ["le", "la", "les", "l'", "au", "aux", "du", "des"] |
67 | 671 | mdecorde | formesArticlesIndéfinis = ["un", "une", "des"] |
68 | 671 | mdecorde | formesDéterminantsPossessifs = ["ma", "ta", "sa", "mon", "ton", "son", "mes", "tes", "ses", "notre", "votre", "leur", "nos", "vos", "leurs"] |
69 | 671 | mdecorde | formesAdjectifsDémonstratifs = ["ce", "cet", "cette", "ces"] |
70 | 671 | mdecorde | |
71 | 671 | mdecorde | formesPronomsPersonnels = ["je", "tu", "il", "elle", "on", "nous", "vous", "ils", "elles", "moi", "toi", "eux", "me", "te", "se", "lui", "leur"] |
72 | 671 | mdecorde | formesPronomsAdverbiaux = ["en", "y"] |
73 | 671 | mdecorde | formesPronomsPossessifs = ["mien", "mienne", "miens", "miennes", "tien", "tienne", "tiens", "tiennes", "sien", "sienne", "siens", "siennes", "nôtre", "nôtres", "vôtre", "vôtres", "leur", "leurs"] |
74 | 671 | mdecorde | formesPronomsDémonstratifs = ["ce", "c'", "celui", "celle", "ceux", "celles", "ci", "ça", "ceci", "cela", "tel", "telle", "tels", "telles"] |
75 | 671 | mdecorde | |
76 | 671 | mdecorde | toutesLesFormes = []
|
77 | 671 | mdecorde | toutesLesFormes += formesArticlesDéfinis
|
78 | 671 | mdecorde | toutesLesFormes += formesArticlesIndéfinis
|
79 | 671 | mdecorde | toutesLesFormes += formesDéterminantsPossessifs
|
80 | 671 | mdecorde | toutesLesFormes += formesAdjectifsDémonstratifs
|
81 | 671 | mdecorde | toutesLesFormes += formesPronomsPersonnels |
82 | 671 | mdecorde | toutesLesFormes += formesPronomsAdverbiaux |
83 | 671 | mdecorde | toutesLesFormes += formesPronomsPossessifs |
84 | 671 | mdecorde | toutesLesFormes += formesPronomsDémonstratifs
|
85 | 671 | mdecorde | |
86 | 671 | mdecorde | /** Fin de la déclaration des formes **/
|
87 | 671 | mdecorde | |
88 | 671 | mdecorde | |
89 | 671 | mdecorde | |
90 | 671 | mdecorde | def testRules(def positions, def Mention) { |
91 | 671 | mdecorde | def catégorie = null |
92 | 671 | mdecorde | def forme = CQI.cpos2Str(word.getQualifiedName(), positions)[0].toLowerCase() |
93 | 671 | mdecorde | |
94 | 671 | mdecorde | if (Mention.length == 1) { |
95 | 671 | mdecorde | |
96 | 671 | mdecorde | if (Mention.first() == "NAM" ) catégorie = "GN.NAM" |
97 | 671 | mdecorde | else if (Mention.first() == "DET:POS") catégorie = "DET.POS" |
98 | 671 | mdecorde | else if (Mention.first() == "PRO:PER") { |
99 | 671 | mdecorde | if (formesPronomsAdverbiaux.contains(forme)) catégorie = "PRO.ADV" |
100 | 671 | mdecorde | else catégorie = "PRO.PER" |
101 | 671 | mdecorde | } |
102 | 671 | mdecorde | else if (Mention.first() == "PRO:DEM") catégorie = "PRO.DEM" |
103 | 671 | mdecorde | else if (Mention.first() == "PRO:IND") catégorie = "PRO.IND" |
104 | 671 | mdecorde | else if (Mention.first() == "PRO:REL") catégorie = "PRO.REL" |
105 | 671 | mdecorde | else if (Mention.first().contains("VER:")) catégorie = "SUJ.ZERO" |
106 | 671 | mdecorde | else if (Mention.first() == "PRO") catégorie = "PRO.INT" |
107 | 671 | mdecorde | |
108 | 671 | mdecorde | // GN indéfinis sans articles
|
109 | 671 | mdecorde | else if (Mention.first() == "NOM") catégorie = "GN.IND" |
110 | 671 | mdecorde | else if (Mention.first() == "ADJ") catégorie = "GN.IND" |
111 | 671 | mdecorde | |
112 | 671 | mdecorde | // gestion des erreurs de TreeTagger
|
113 | 671 | mdecorde | else if (Mention.first() == "KON") catégorie = "PRO.REL" // Le 'que' dans une mention simple est un relatif |
114 | 671 | mdecorde | else if (Mention.first() == "DET:ART") catégorie = "PRO.PER" // le, les |
115 | 671 | mdecorde | else if (forme == "en") catégorie = "PRO.ADV" |
116 | 671 | mdecorde | |
117 | 671 | mdecorde | else if (Mention.first() == "ADV") catégorie = "ERREUR" // un adverbe seul n'est jamais référentiel |
118 | 671 | mdecorde | else if (Mention.first() == "PRE") catégorie = "ERREUR" // une preposition seule n'est jamais référentielle |
119 | 671 | mdecorde | else if (Mention.first() == "ADJ") catégorie = "ERREUR" // un adjectif seul n'est jamais référentiel |
120 | 671 | mdecorde | else if (Mention.first() == "INT") catégorie = "ERREUR" // une interjection seule n'est jamais référentielle |
121 | 671 | mdecorde | |
122 | 671 | mdecorde | else catégorie = "PRO.CHECK" |
123 | 671 | mdecorde | } |
124 | 671 | mdecorde | |
125 | 671 | mdecorde | else if (Mention.length == 2) { |
126 | 671 | mdecorde | if (Mention.contains("NAM")) catégorie = "GN.NAM" |
127 | 671 | mdecorde | else if (Mention[1] == "PRO:POS") catégorie = "PRO.POS" // "les miens" |
128 | 671 | mdecorde | else if (Mention[1] == "NUM" ) catégorie = "PRO.NUM" // "les deux" |
129 | 671 | mdecorde | else if (Mention[1] == "PRO:DEM") catégorie = "PRO.DEM" // "Tout cela" |
130 | 671 | mdecorde | else if (Mention[0] == "PRO:IND") catégorie = "GN.IND" // "Quelques trucs" |
131 | 671 | mdecorde | else if (Mention.contains("PRO:REL")) catégorie = "PRO.REL" |
132 | 671 | mdecorde | else if ((Mention[0].contains("DET")) && (Mention[1] == "PROind")) catégorie = "PRO.IND" // des autres |
133 | 671 | mdecorde | else if (Mention[1].contains("VER:")) catégorie = "SUJ.ZERO" |
134 | 671 | mdecorde | else if (!Mention.contains("NOM") && !Mention.contains("ADJ")) { |
135 | 671 | mdecorde | if (Mention[0] == "PRO:DEM") catégorie = "PRO.DEM" |
136 | 671 | mdecorde | else catégorie = "PRO.CHECK" |
137 | 671 | mdecorde | } |
138 | 671 | mdecorde | else catégorie = "GN.CHECK" |
139 | 671 | mdecorde | } |
140 | 671 | mdecorde | |
141 | 671 | mdecorde | if ( (catégorie == null) || (catégorie == "GN.CHECK") ) { |
142 | 671 | mdecorde | // on est dans les GN
|
143 | 671 | mdecorde | if (Mention[0] == "DET:POS" ) catégorie = "GN.POS" |
144 | 671 | mdecorde | else if (Mention[0] == "NUM" ) catégorie = "GN.NUM" |
145 | 671 | mdecorde | else if (Mention[0] == "PRO:DEM" ) catégorie = "GN.DEM" |
146 | 671 | mdecorde | else if (Mention[0] == "PRP:det" ) catégorie = "GN.DEF" |
147 | 671 | mdecorde | else if (formesArticlesIndéfinis.contains(forme) || (forme == "une")) catégorie = "GN.IND" |
148 | 671 | mdecorde | else if (formesArticlesDéfinis.contains(forme)) catégorie = "GN.DEF" |
149 | 671 | mdecorde | else if (Mention[0] == "PRO:IND" ) catégorie = "GN.IND" |
150 | 671 | mdecorde | else if (Mention[0] == "PRP" ) catégorie = "GN.IND" |
151 | 671 | mdecorde | else if (Mention[0] == "ADJ" ) catégorie = "GN.IND" |
152 | 671 | mdecorde | else if (Mention[0] == "NOM" ) catégorie = "GN.IND" |
153 | 671 | mdecorde | else if (Mention.contains("NAM")) catégorie = "GN.NAM" |
154 | 671 | mdecorde | else catégorie = "TEST" |
155 | 671 | mdecorde | } |
156 | 671 | mdecorde | |
157 | 671 | mdecorde | return catégorie |
158 | 671 | mdecorde | } |
159 | 671 | mdecorde | |
160 | 671 | mdecorde | //
|
161 | 671 | mdecorde | // FIN DE LA DÉFINITION DES RÈGLES
|
162 | 671 | mdecorde | //
|
163 | 671 | mdecorde | |
164 | 671 | mdecorde | // CORPS DU SCRIPT
|
165 | 671 | mdecorde | |
166 | 671 | mdecorde | if (!(corpusViewSelection instanceof MainCorpus)) { |
167 | 671 | mdecorde | println "Corpora selection is not a Corpus"
|
168 | 671 | mdecorde | return
|
169 | 671 | mdecorde | } |
170 | 671 | mdecorde | |
171 | 671 | mdecorde | // BEGINNING OF PARAMETERS
|
172 | 671 | mdecorde | @Field @Option(name="unit_type", usage="", widget="String", required=true, def="MENTION") |
173 | 671 | mdecorde | def unit_type
|
174 | 671 | mdecorde | @Field @Option(name="pos_property_name", usage="", widget="String", required=true, def="pos") |
175 | 671 | mdecorde | def pos_property_name
|
176 | 671 | mdecorde | @Field @Option(name="reset", usage="", widget="Boolean", required=true, def="true") |
177 | 671 | mdecorde | def reset
|
178 | 671 | mdecorde | if (!ParametersDialog.open(this)) return |
179 | 671 | mdecorde | |
180 | 671 | mdecorde | corpus = corpusViewSelection |
181 | 786 | sjacqu01 | CQI = CQPSearchEngine.getCqiClient() |
182 | 671 | mdecorde | word = corpus.getWordProperty() |
183 | 671 | mdecorde | posProperty = corpus.getProperty(pos_property_name) |
184 | 671 | mdecorde | if (posProperty == null) { |
185 | 671 | mdecorde | println "Error: CQP corpus does not contains the word property with name=$pos_property_name"
|
186 | 671 | mdecorde | return
|
187 | 671 | mdecorde | } |
188 | 1217 | mdecorde | analecCorpus = URSCorpora.getCorpus(corpus) |
189 | 1217 | mdecorde | vue = URSCorpora.getVue(corpus) |
190 | 671 | mdecorde | structure = analecCorpus.getStructure() |
191 | 671 | mdecorde | if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units |
192 | 671 | mdecorde | println "Error: corpus structure does not contains unit with name=$unit_type"
|
193 | 671 | mdecorde | return
|
194 | 671 | mdecorde | } |
195 | 671 | mdecorde | |
196 | 671 | mdecorde | CATEGORIE = "CATEGORIE"
|
197 | 671 | mdecorde | // Si la structure d'annotation ne contient pas CATEGORIE, on la crée avec ses valeurs
|
198 | 671 | mdecorde | if (!structure.getUniteProperties(unit_type).contains(CATEGORIE)) {
|
199 | 671 | mdecorde | |
200 | 671 | mdecorde | // FIXME: dans le script original (see also
|
201 | 671 | mdecorde | // http://forge.cbp.ens-lyon.fr/redmine/issues/2065), on utilise
|
202 | 671 | mdecorde | // analecCorpus.ajouterProp/Val, mais cela ne marche pas dans ma version de
|
203 | 671 | mdecorde | // TXM-Analec --> je retourne donc à structure.ajouterProp/Val
|
204 | 671 | mdecorde | |
205 | 671 | mdecorde | // la propriété
|
206 | 671 | mdecorde | structure.ajouterProp(Unite.class, unit_type, CATEGORIE) |
207 | 671 | mdecorde | // les valeurs
|
208 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.NAM")
|
209 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.DEF")
|
210 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.IND")
|
211 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.POS")
|
212 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.DEM")
|
213 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.NUM")
|
214 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.CHECK")
|
215 | 671 | mdecorde | |
216 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "DET.POS")
|
217 | 671 | mdecorde | |
218 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.PER")
|
219 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.ADV")
|
220 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.IND")
|
221 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.DEM")
|
222 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.POS")
|
223 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.NUM")
|
224 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.INT")
|
225 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.REL")
|
226 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.CHECK")
|
227 | 671 | mdecorde | |
228 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "SUJ.ZERO")
|
229 | 671 | mdecorde | |
230 | 671 | mdecorde | structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "ERREUR")
|
231 | 671 | mdecorde | } |
232 | 671 | mdecorde | |
233 | 671 | mdecorde | def nModified = 0 |
234 | 671 | mdecorde | def nIgnored = 0 |
235 | 671 | mdecorde | |
236 | 671 | mdecorde | errors = new HashMap() |
237 | 671 | mdecorde | def units = analecCorpus.getUnites(unit_type)
|
238 | 671 | mdecorde | units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() } |
239 | 671 | mdecorde | for (Unite unit : units) { // process all units |
240 | 671 | mdecorde | |
241 | 671 | mdecorde | def prop = unit.getProp(CATEGORIE)
|
242 | 671 | mdecorde | if (!reset && prop != null && prop.length() > 0) continue // l'unité a déjà une CATEGORIE |
243 | 671 | mdecorde | |
244 | 671 | mdecorde | int[] positions = null |
245 | 671 | mdecorde | if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
|
246 | 671 | mdecorde | else positions = (unit.getDeb()..unit.getFin())
|
247 | 671 | mdecorde | |
248 | 671 | mdecorde | def Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
|
249 | 671 | mdecorde | def cat = testRules(positions, Mention)
|
250 | 671 | mdecorde | |
251 | 671 | mdecorde | if (cat != null) { |
252 | 671 | mdecorde | // following line in the original script but doesn't work for me:
|
253 | 671 | mdecorde | // vue.setValeurChamp(unit, CATEGORIE, cat)
|
254 | 671 | mdecorde | unit.getProps().put(CATEGORIE, cat) |
255 | 671 | mdecorde | nModified++ |
256 | 671 | mdecorde | } else {
|
257 | 671 | mdecorde | nIgnored++ |
258 | 671 | mdecorde | } |
259 | 671 | mdecorde | } |
260 | 671 | mdecorde | |
261 | 671 | mdecorde | println "Result:"
|
262 | 671 | mdecorde | println "- $nModified units of type $unit_type have been modified."
|
263 | 671 | mdecorde | println "- $nIgnored units of type $unit_type have not been modified.\n"
|
264 | 671 | mdecorde | |
265 | 671 | mdecorde | if (errors.size() > 0) { |
266 | 671 | mdecorde | println "Some rules should be added to this macro to process the following remaining 'FROPOS / words' values:"
|
267 | 671 | mdecorde | errors.keySet().each { println "fropos="+it+"\twords="+errors[it].join(" | ") } |
268 | 671 | mdecorde | } |
269 | 671 | mdecorde | |
270 | 671 | mdecorde | // udpate the view (also see also
|
271 | 671 | mdecorde | // http://forge.cbp.ens-lyon.fr/redmine/issues/2065)
|
272 | 1217 | mdecorde | URSCorpora.getVue(analecCorpus).retablirVueParDefaut() |