Commit ffd8e900adb354632f2184bed1aa52d459a21926
1 parent
78618f34
Exists in
master
and in
1 other branch
Refatora completamente o aplicador de regras
Showing
2 changed files
with
343 additions
and
1 deletions
Show diff stats
... | ... | @@ -0,0 +1,343 @@ |
1 | +#!/usr/bin/python | |
2 | +# -*- coding: utf-8 -*- | |
3 | + | |
4 | +#Autor: Erickson Silva | |
5 | +#Email: <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | |
6 | + | |
7 | +#LAViD - Laboratório de Aplicações de Vídeo Digital | |
8 | + | |
9 | +import platform | |
10 | +import xml.etree.ElementTree as ET | |
11 | +from os.path import expanduser | |
12 | +from collections import deque | |
13 | +from LerDicionarios import * | |
14 | +from Iterator import * | |
15 | +from StringAux import * | |
16 | +from ConverteExtenso import * | |
17 | +from nltk_tgrep import tgrep_positions, tgrep_nodes | |
18 | +from nltk import ParentedTree, Tree, draw | |
19 | + | |
20 | +class AplicaRegras(object): | |
21 | + | |
22 | + # inicializa todos as variaveis | |
23 | + def __init__(self): | |
24 | + self.__root = self.get_root() | |
25 | + self.dicionarios = LerDicionarios() | |
26 | + self.__especificos = {"advt":self.verificar_adv_tempo, "v":self.verificar_vb_infinitivo, "x":self.verificar_preposicao, | |
27 | + "c":self.verificar_subst_genero, "a":self.verificar_artigo, "l":self.verificar_vb_ligacao, | |
28 | + "i":self.verificar_adv_intensidade, "vbi":"zero", "n":self.verificar_vb_muda_negacao, "abmn":"zero", | |
29 | + "adji":"zero","adjn":"zero", "advi":"zero"} | |
30 | + | |
31 | + def get_root(self): | |
32 | + if platform.system() == 'Windows': | |
33 | + return ET.parse(expanduser("~")+'\\vlibras-translate\data\\regras.xml').getroot() | |
34 | + return ET.parse(expanduser("~")+'/vlibras-translate/data/regras.xml').getroot() | |
35 | + | |
36 | + def aplicar_regras_morfo(self, lista, sint=False): | |
37 | + self.lista = list(lista) | |
38 | + self.quantidade_iter_pular = 0 | |
39 | + self.lista_corrigida = [] | |
40 | + | |
41 | + it = Iterator() | |
42 | + it.load(self.lista) | |
43 | + | |
44 | + while(it.has_next()): | |
45 | + #if self.quantidade_iter_pular > 0: | |
46 | + # self.quantidade_iter_pular-=1 | |
47 | + # continue | |
48 | + | |
49 | + for morpho in self.__root.findall('morphological'): | |
50 | + self.has_rule = False | |
51 | + for rule in morpho.findall('rule'): # procura a tag rule | |
52 | + if rule.find('active').text == "true" and rule.get('name').split("_")[0] == it.get_ticket(): | |
53 | + count = int(rule.find('count').text) | |
54 | + self.lista_iteracoes = [] | |
55 | + if count == 1: | |
56 | + self.lista_iteracoes = [it.get_token()] | |
57 | + else: | |
58 | + try: | |
59 | + self.lista_iteracoes = it.get_interval(count) | |
60 | + it.skip(count-1) | |
61 | + #self.quantidade_iter_pular = count-1 | |
62 | + except: | |
63 | + continue | |
64 | + | |
65 | + self.nome_regra = self.gerar_nome_regra(self.lista_iteracoes) | |
66 | + if rule.get('name') == self.nome_regra: # verifica se a regra é aplicavel e a mesma esta ativa | |
67 | + self.has_rule = True | |
68 | + self.lista_iteracao_regra = count * [None] | |
69 | + self.count_iteracao_regra = -1 | |
70 | + | |
71 | + print "REGRA MORFOLÓGICA: " + rule.get('name') | |
72 | + | |
73 | + for classe in rule.iter('class'): # for nas tags class | |
74 | + | |
75 | + title = classe.find('title') | |
76 | + newpos = classe.find('newpos') | |
77 | + newprop = classe.find('newprop') | |
78 | + newtoken = classe.find('newtoken') | |
79 | + newtokenpos = classe.find('newtokenpos') | |
80 | + self.specific = classe.find('specific') | |
81 | + | |
82 | + self.count_iteracao_regra += 1 | |
83 | + tupla = self.lista_iteracoes[self.count_iteracao_regra] | |
84 | + | |
85 | + if self.specific is not None: | |
86 | + self.specific = self.__especificos[self.specific.text](tupla[0]) | |
87 | + if self.specific == False: | |
88 | + self.has_rule = False | |
89 | + self.quantidade_iter_pular = 0 | |
90 | + break | |
91 | + | |
92 | + if newprop is not None: | |
93 | + self.lista_iteracao_regra.append([self.specific,newprop.text]) | |
94 | + | |
95 | + if newtoken is not None and newpos is not None: | |
96 | + if newtokenpos is not None: | |
97 | + lista_merge = count * [None] | |
98 | + lista_merge[int(newpos.text)] = tupla[0] | |
99 | + lista_merge[int(newtokenpos.text)] = newtoken.text | |
100 | + merge_tokens = " ".join(lista_merge) | |
101 | + self.lista_iteracao_regra.append([merge_tokens, title.text]) | |
102 | + else: | |
103 | + self.lista_iteracao_regra.append([tupla[0] + " " + newtoken.text, title.text]) | |
104 | + | |
105 | + elif newpos is not None: | |
106 | + if newpos.text == "-1": | |
107 | + self.lista_corrigida.append(None) | |
108 | + continue | |
109 | + else: | |
110 | + self.lista_iteracao_regra[int(newpos.text)] = tupla | |
111 | + | |
112 | + elif newtoken is not None: | |
113 | + tokenAnterior = self.lista_iteracao_regra[self.count_iteracao_regra][0] | |
114 | + ticketAnterior = self.lista_iteracao_regra[self.count_iteracao_regra][1] | |
115 | + if newtokenpos is not None and newtokenpos.text == "0": | |
116 | + self.lista_iteracao_regra[self.count_iteracao_regra] = [newtoken.text + " " + tokenAnterior, ticketAnterior] | |
117 | + else: | |
118 | + self.lista_iteracao_regra[self.count_iteracao_regra] = [tokenAnterior + " " + newtoken.text, ticketAnterior] | |
119 | + | |
120 | + #self.lista_corrigida.append(filter(None, self.lista_iteracao_regra)[0]) | |
121 | + #se ele acho uma regra, então quebra o laço e vai para o token seguinte | |
122 | + if self.has_rule: | |
123 | + self.lista_corrigida.append(self.lista_iteracao_regra) | |
124 | + break | |
125 | + | |
126 | + if (self.has_rule == False): | |
127 | + self.lista_corrigida.append(it.get_token()) #se nao achou regra, entao adiciona a tupla original | |
128 | + if sint: | |
129 | + return self.lista_corrigida | |
130 | + return filter(None, self.lista_corrigida) | |
131 | + | |
132 | + | |
133 | + def aplicar_regras_sint(self, lista, arvore): | |
134 | + p_arvore = ParentedTree.convert(arvore) | |
135 | + self.adaptar_regras_morfo_arvore(lista, p_arvore) | |
136 | + for morpho in self.__root.findall('syntactic'): | |
137 | + for rule in morpho.findall('rule'): # procura a tag rule | |
138 | + nome_regra = self.corrigir_anotacao(rule.get('name')) | |
139 | + regra = self.separar_regra(nome_regra) | |
140 | + node = tgrep_nodes(p_arvore, regra[0], search_leaves=False) | |
141 | + if node: | |
142 | + print "REGRA SINTÁTICA: " + rule.get('name') | |
143 | + node_esq = tgrep_nodes(node[0], regra[1], search_leaves=False) | |
144 | + node_esq_pos = tgrep_positions(node[0], regra[1], search_leaves=False) | |
145 | + node_dir = tgrep_nodes(node[0], regra[2], search_leaves=False) | |
146 | + node_dir_pos = tgrep_positions(node[0], regra[2], search_leaves=False) | |
147 | + p_arvore.remove(p_arvore[node_esq_pos]) | |
148 | + if node_esq and node_dir: | |
149 | + subnodes = node_esq + node_dir | |
150 | + for subnode in subnodes: | |
151 | + self.alteracoes_nao_implementadas = [] | |
152 | + # modelo: [['node_esq', ['token', 'ticket']],['node_dir', ['token', 'ticket']]] | |
153 | + for classe in rule.iter('class'): | |
154 | + title = classe.find('title') | |
155 | + if subnode.label() == title.text: | |
156 | + newpos = classe.find('newpos') | |
157 | + newprop = classe.find('newprop') | |
158 | + newtoken = classe.find('newtoken') | |
159 | + newtokenpos = classe.find('newtokenpos') | |
160 | + self.specific = classe.find('specific') | |
161 | + | |
162 | + lista_alter_temp_node = [] | |
163 | + | |
164 | + if self.specific is not None: | |
165 | + self.specific = self.__especificos[self.specific.text](subnode.leaves()[0]) | |
166 | + if self.specific is False: | |
167 | + self.has_rule = False | |
168 | + break | |
169 | + | |
170 | + if newprop is not None: | |
171 | + self.lista_alter_temp_node.append([self.specific,newprop.text]) | |
172 | + ''' | |
173 | + if newtoken is not None and newpos is not None: | |
174 | + if newtokenpos is not None: | |
175 | + lista_merge = count * [None] | |
176 | + lista_merge[int(newpos.text)] = tupla[0] | |
177 | + lista_merge[int(newtokenpos.text)] = newtoken.text | |
178 | + merge_tokens = " ".join(lista_merge) | |
179 | + self.lista_iteracao_regra.append([merge_tokens, title.text]) | |
180 | + else: | |
181 | + self.lista_iteracao_regra.append([tupla[0] + " " + newtoken.text, title.text]) | |
182 | + | |
183 | + elif newpos is not None: | |
184 | + if newpos.text == "-1": | |
185 | + self.lista_corrigida.append(None) | |
186 | + continue | |
187 | + else: | |
188 | + self.lista_iteracao_regra[int(newpos.text)] = tupla | |
189 | + | |
190 | + elif newtoken is not None: | |
191 | + tokenAnterior = self.lista_iteracao_regra[self.count_iteracao_regra][0] | |
192 | + ticketAnterior = self.lista_iteracao_regra[self.count_iteracao_regra][1] | |
193 | + if newtokenpos is not None and newtokenpos.text == "0": | |
194 | + self.lista_iteracao_regra[self.count_iteracao_regra] = [newtoken.text + " " + tokenAnterior, ticketAnterior] | |
195 | + else: | |
196 | + self.lista_iteracao_regra[self.count_iteracao_regra] = [tokenAnterior + " " + newtoken.text, ticketAnterior] | |
197 | + ''' | |
198 | + return p_arvore | |
199 | + | |
200 | + def adaptar_regras_morfo_arvore(self, lista, arvore): | |
201 | + lista_pos_arv = [] | |
202 | + for tupla in lista: | |
203 | + string_grep = self.corrigir_anotacao(tupla[1]) + " < " + tupla[0].lower() | |
204 | + node = tgrep_positions(arvore, string_grep) | |
205 | + if node[0] in lista_pos_arv: | |
206 | + node.reverse() | |
207 | + lista_pos_arv.append(node[0]) | |
208 | + morfo = self.aplicar_regras_morfo(lista, sint=True) | |
209 | + for i in range(0, len(morfo)): | |
210 | + if morfo[i] is None: | |
211 | + arvore[lista_pos_arv[i][:-1]] = None | |
212 | + else: | |
213 | + arvore[lista_pos_arv[i]].set_label(self.corrigir_anotacao(morfo[i][1])) | |
214 | + arvore[lista_pos_arv[i]][0] = morfo[i][0] | |
215 | + nodes_none = tgrep_positions(arvore, 'None') | |
216 | + for node in nodes_none: | |
217 | + arvore[node[:-1]].remove(None) | |
218 | + | |
219 | + def corrigir_anotacao(self, anotacao): | |
220 | + split = anotacao.split('_') | |
221 | + for i in range(0, len(split)): | |
222 | + split[i] = split[i].replace('-','_') | |
223 | + return "-".join(split) | |
224 | + | |
225 | + def separar_regra(self, regra): | |
226 | + split = regra.split("(") | |
227 | + split[1] = split[1].replace(")","").split("-") | |
228 | + rev = list(split[1]) | |
229 | + rev.reverse() | |
230 | + split.append(rev) | |
231 | + split[1] = ' $ '.join(split[1]) | |
232 | + split[2] = ' $ '.join(split[2]) | |
233 | + return split | |
234 | + | |
235 | + def gerar_nome_regra(self, lista): | |
236 | + self.__nomeRegra = [] | |
237 | + for t in lista: | |
238 | + self.__nomeRegra.append(t[1]) | |
239 | + return "_".join(self.__nomeRegra) | |
240 | + | |
241 | + def verificar_adv_tempo(self, token): | |
242 | + for tupla in self.lista: | |
243 | + if self.dicionarios.has_adverbio_tempo(tupla[0]): | |
244 | + return self.verificar_vb_infinitivo(token) | |
245 | + return False | |
246 | + | |
247 | + def verificar_vb_infinitivo(self, token): | |
248 | + if self.dicionarios.has_verbo_infinitivo(token): | |
249 | + return self.dicionarios.get_verbo_infinitivo(token) | |
250 | + return False | |
251 | + | |
252 | + def verificar_preposicao(self, token): | |
253 | + return self.dicionarios.has_preposicao(token) | |
254 | + | |
255 | + def verificar_subst_genero(self, token): | |
256 | + return self.dicionarios.has_subst_2_generos(token) | |
257 | + | |
258 | + def verificar_artigo(self, token): | |
259 | + return self.dicionarios.has_artigo(token) | |
260 | + | |
261 | + def verificar_vb_ligacao(self, token): | |
262 | + return self.dicionarios.has_verbo_ligacao(token) | |
263 | + | |
264 | + def verificar_adv_intensidade(self, token): | |
265 | + return self.dicionarios.has_adverbio_intensidade(token) | |
266 | + | |
267 | + def verificar_vb_muda_negacao(self, token): | |
268 | + if self.dicionarios.has_verbo_muda_negacao(token): | |
269 | + return self.dicionarios.get_verbo_muda_negacao(token) | |
270 | + return False | |
271 | + | |
272 | + def simplificar_sentenca(self, lista): | |
273 | + it = Iterator() | |
274 | + it.load(lista) | |
275 | + num = False | |
276 | + nova_lista = [] | |
277 | + while(it.has_next()): | |
278 | + token = it.get_word() | |
279 | + tag = it.get_ticket() | |
280 | + | |
281 | + if tag == "NUM": | |
282 | + num = True | |
283 | + | |
284 | + if tag[-2:] == "-P": | |
285 | + singular = self.analisar_plural(token) | |
286 | + nova_lista.append([singular,tag]) | |
287 | + else: | |
288 | + nova_lista.append(it.get_token()) | |
289 | + | |
290 | + if num: return self.converter_extenso(nova_lista) | |
291 | + return nova_lista | |
292 | + | |
293 | + def analisar_plural(self, token): | |
294 | + if(token[-3:] == "OES" or token[-2:] == "AES" or token[-2:] == "AOS"): | |
295 | + return token[0:-3]+"AO" | |
296 | + elif(token[-3:] == "RES" or token[-2:] == "ZES" or token[-2:] == "NES"): | |
297 | + return token[0:-2] | |
298 | + elif(token[-3:] == "SES"): | |
299 | + #TODO: Algumas palavras possuem marcações gráficas na raiz singular. Ex: Gás – Gases | |
300 | + return token[0:-2] | |
301 | + elif(token[-2:] == "NS"): | |
302 | + return token[0:-2]+"M" | |
303 | + elif(token[-3:] == "EIS"): | |
304 | + return token[0:-3]+"IL" | |
305 | + elif(token[-2:] == "IS"): | |
306 | + if(token[-3] == "A" or token[-3] == "E" or token[-3] == "O" or token[-3] == "U"): | |
307 | + return token[0:-2]+"L" | |
308 | + return token | |
309 | + elif(token[-1] == "S"): | |
310 | + #TODO: Palavras paroxítonas ou proparoxítonas terminadas em S. Ex: lápis, vírus, tagênis, ônibus, etc | |
311 | + return token[0:-1] | |
312 | + else: | |
313 | + return token | |
314 | + | |
315 | + def converter_extenso(self, lista): | |
316 | + lista_aux = [] | |
317 | + index_deleted = [] | |
318 | + count = 0 | |
319 | + is_running = False | |
320 | + | |
321 | + for i in range(0, len(lista)): | |
322 | + token = lista[i][0] | |
323 | + tag = lista[i][1] | |
324 | + if tag == "NUM": | |
325 | + if (is_running is False and len(lista_aux) == count): | |
326 | + lista_aux.append([i,[token]]) | |
327 | + is_running = True | |
328 | + else: | |
329 | + lista_aux[count][1].append(token) | |
330 | + index_deleted.append(i) | |
331 | + elif (is_running): | |
332 | + if ((lista[i-1][1] == "NUM") and (lista[i+1][1] == "NUM") and (tag == "CONJ")): | |
333 | + index_deleted.append(i) | |
334 | + else: | |
335 | + is_running = False | |
336 | + count += 1 | |
337 | + | |
338 | + for i in lista_aux: | |
339 | + ext = extenso(' '.join(i[1])) | |
340 | + lista[i[0]] = [ext, "NUM"] | |
341 | + | |
342 | + deque((list.pop(lista, i) for i in sorted(index_deleted, reverse=True)), maxlen=0) | |
343 | + return lista | ... | ... |
src/new/TraduzSentencas.py
... | ... | @@ -38,5 +38,4 @@ def gerar_analise(sentenca): |
38 | 38 | analise = aplic_regras.aplicar_regras_morfo(morfologica) |
39 | 39 | else: |
40 | 40 | analise = aplic_regras.aplicar_regras_sint(morfologica, analise) |
41 | - analise = aplic_regras.simplificar_sentenca(analise) | |
42 | 41 | return aplic_sinonimos.aplicar_sinonimos(analise) |
43 | 42 | \ No newline at end of file | ... | ... |