Commit 927ebcc797090e26403841646309c762c75c87ce
1 parent
361e9a92
Exists in
master
and in
1 other branch
Define nova versão do tradutor como default
Showing
24 changed files
with
1114 additions
and
1721 deletions
Show diff stats
... | ... | @@ -0,0 +1,446 @@ |
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 re | |
11 | +import xml.etree.ElementTree as ET | |
12 | +from os.path import expanduser | |
13 | +from collections import deque | |
14 | +from LerDicionarios import * | |
15 | +from Iterator import * | |
16 | +from StringAux import * | |
17 | +from ConverteExtenso import * | |
18 | +from nltk_tgrep import tgrep_positions, tgrep_nodes | |
19 | +from nltk import ParentedTree, Tree, draw | |
20 | + | |
21 | +class AplicaRegras(object): | |
22 | + | |
23 | + def __init__(self): | |
24 | + self.__root = self.get_root() | |
25 | + self.dicionarios = LerDicionarios() | |
26 | + # Dicionário de funcões do campo specific do arquivo de regras | |
27 | + self.__especificos = {"advt":self.verificar_adv_tempo, "v":self.verificar_vb_infinitivo, "x":self.verificar_preposicao, | |
28 | + "c":self.verificar_subst_genero, "a":self.verificar_artigo, "l":self.verificar_vb_ligacao, | |
29 | + "i":self.verificar_adv_intensidade, "vbi":"zero", "n":self.verificar_vb_muda_negacao, "abmn":"zero", | |
30 | + "adji":"zero","adjn":"zero", "advi":"zero"} | |
31 | + | |
32 | + self.__acoes = {"change_vb":self.get_vb_infinitivo, "concate_intens":self.get_token_intensidade} | |
33 | + | |
34 | + # Gera arvore a partir do arquivos regras.xml | |
35 | + def get_root(self): | |
36 | + if platform.system() == 'Windows': | |
37 | + return ET.parse(expanduser("~")+'\\vlibras-translate\data\\regras.xml').getroot() | |
38 | + return ET.parse(expanduser("~")+'/vlibras-translate/data/regras.xml').getroot() | |
39 | + | |
40 | + # Aplica regras morfológicas apartir do arquivo regras.xml | |
41 | + def aplicar_regras_morfo(self, lista, sint=False): | |
42 | + self.lista = list(lista) # Nova cópia da lista morfológica | |
43 | + self.lista_corrigida =[] # Lista morfológica após a aplicação das regras | |
44 | + | |
45 | + it = Iterator() | |
46 | + it.load(self.lista) | |
47 | + | |
48 | + while(it.has_next()): | |
49 | + for morpho in self.__root.findall('morphological'): | |
50 | + self.has_rule = False # Boolean caso encontre encontre regra compativel | |
51 | + for rule in morpho.findall('rule'): | |
52 | + # Verifica se a regra está ativa e se o nome da regra, ou o ínicio, é igual a tag de classificação do token atual | |
53 | + if rule.find('active').text == "true" and rule.get('name').split("_")[0] == it.get_ticket(): | |
54 | + count = int(rule.find('count').text) | |
55 | + self.lista_iteracoes = [] # Lista que conterá todas tuplas referentes a quantidade de classes da regra | |
56 | + | |
57 | + # Obtém o intervalo de tuplas de acordo com o número de classes da regra | |
58 | + try: | |
59 | + self.lista_iteracoes = it.get_interval(count) | |
60 | + print '# LISTA DA ITERAÇÂO: ' | |
61 | + print self.lista_iteracoes | |
62 | + except: | |
63 | + continue | |
64 | + | |
65 | + # Gera o nome da regra do intervalo de tuplas e verifica se é igual ao nome da regra em si | |
66 | + self.nome_regra = self.gerar_nome_regra(self.lista_iteracoes) | |
67 | + if rule.get('name') == self.nome_regra: | |
68 | + self.has_rule = True | |
69 | + self.count_iteracao_regra = -1 | |
70 | + | |
71 | + print "REGRA MORFOLÓGICA ENCONTRADA: " + rule.get('name') | |
72 | + | |
73 | + self.lista_iteracao_regra = [] # Lista temporária | Insere tokens após a aplicação das regras | |
74 | + | |
75 | + for classe in rule.iter('class'): # for nas tags class | |
76 | + action = classe.find('action') | |
77 | + newprop = classe.find('newprop') | |
78 | + newtoken = classe.find('newtoken') | |
79 | + newtokenpos = classe.find('newtokenpos') | |
80 | + specific = classe.find('specific') | |
81 | + | |
82 | + self.count_iteracao_regra += 1 | |
83 | + tupla = self.lista_iteracoes[self.count_iteracao_regra] | |
84 | + | |
85 | + if specific is not None: | |
86 | + result_specific = self.__especificos[specific.text](tupla[0]) | |
87 | + if result_specific is False: | |
88 | + print "REGRA MORFOLÓGICA " + rule.get('name') + " INVÁLIDA. PROCURANDO OUTRA..." | |
89 | + self.has_rule = False | |
90 | + break | |
91 | + | |
92 | + if action is not None: | |
93 | + action_text = action.text | |
94 | + if action_text == "remove": | |
95 | + self.lista_iteracao_regra.append(None) | |
96 | + continue | |
97 | + elif action_text == "invert": | |
98 | + self.lista_iteracao_regra.reverse() | |
99 | + elif self.__acoes.has_key(action_text): | |
100 | + result_action = self.__acoes[action_text](tupla[0]).lower() | |
101 | + self.lista_iteracao_regra.append([result_action, tupla[1]]) | |
102 | + else: | |
103 | + self.lista_iteracao_regra.append(tupla) | |
104 | + | |
105 | + if newprop is not None: | |
106 | + self.lista_iteracao_regra[self.count_iteracao_regra][1] = newprop.text | |
107 | + | |
108 | + if newtoken is not None: | |
109 | + if newtokenpos.text == "next": | |
110 | + self.lista_iteracao_regra.append([newtoken.text.lower(), "NTK"]) | |
111 | + elif newtokenpos.text == "previous": | |
112 | + self.lista_iteracao_regra.append(self.lista_iteracao_regra[-1]) | |
113 | + self.lista_iteracao_regra[-2] = [newtoken.text.lower(), "NTK"] | |
114 | + elif newtokenpos.text == "end": | |
115 | + print "TODO" | |
116 | + | |
117 | + if self.has_rule: | |
118 | + it.skip(count-1) | |
119 | + self.lista_corrigida.extend(self.lista_iteracao_regra) | |
120 | + break | |
121 | + | |
122 | + if self.has_rule is False: | |
123 | + print 'NÃO ACHOU REGRA - ' + it.get_word().encode('utf-8') | |
124 | + self.lista_corrigida.append(it.get_token()) #se nao achou regra, entao adiciona a tupla original | |
125 | + if sint: | |
126 | + return self.lista_corrigida | |
127 | + return filter(None, self.lista_corrigida) | |
128 | + | |
129 | + | |
130 | + def aplicar_regras_sint(self, lista, arvore): | |
131 | + p_arvore = ParentedTree.convert(arvore) | |
132 | + self.adaptar_regras_morfo_arvore(lista, p_arvore) | |
133 | + for morpho in self.__root.findall('syntactic'): | |
134 | + for rule in morpho.findall('rule'): # procura a tag rule | |
135 | + nome_regra = self.corrigir_nome_regra(rule.get('name')) | |
136 | + regra = self.separar_regra(nome_regra) | |
137 | + node_pai = tgrep_nodes(p_arvore, regra[0], search_leaves=False) | |
138 | + if node_pai and rule.find('active').text == "true": | |
139 | + node_pai = node_pai[0] | |
140 | + node_regra = tgrep_nodes(node_pai, regra[1].replace('$', '..'), search_leaves=False) | |
141 | + if node_regra: | |
142 | + node_esq_pos = tgrep_positions(node_pai, regra[1], search_leaves=False) | |
143 | + node_dir_pos = tgrep_positions(node_pai, regra[2], search_leaves=False) | |
144 | + if node_esq_pos and node_dir_pos: | |
145 | + print "REGRA SINTÁTICA ENCONTRADA: " + rule.get('name') | |
146 | + nodes_positions = node_esq_pos + node_dir_pos | |
147 | + self.count = -1 | |
148 | + self.has_rule = True | |
149 | + | |
150 | + count_temp = -1 | |
151 | + for classe in rule.findall('class'): | |
152 | + count_temp += 1 | |
153 | + leaves = node_pai[nodes_positions[count_temp]].leaves() | |
154 | + token = filter(None, leaves)[0] | |
155 | + specific = classe.find('specific') | |
156 | + if specific is not None: | |
157 | + result_specific = self.__especificos[specific.text](token) | |
158 | + if result_specific is False: | |
159 | + self.has_rule = False | |
160 | + | |
161 | + if self.has_rule is False: | |
162 | + print "REGRA SINTÁTICA " + rule.get('name') + " INVÁLIDA. PROCURANDO OUTRA..." | |
163 | + break | |
164 | + | |
165 | + nodes_deleted = [] | |
166 | + | |
167 | + for classe in rule.iter('class'): | |
168 | + action = classe.find('action') | |
169 | + newprop = classe.find('newprop') | |
170 | + | |
171 | + self.count += 1 | |
172 | + | |
173 | + if action is not None: | |
174 | + action_text = action.text | |
175 | + | |
176 | + if action_text == "remove": | |
177 | + pos_del = nodes_positions[self.count] | |
178 | + nodes_deleted.append(node_pai[pos_del]) | |
179 | + node_pai[pos_del] = None | |
180 | + continue | |
181 | + | |
182 | + elif action_text == "invert": | |
183 | + aux1 = node_pai[nodes_positions[self.count]] | |
184 | + aux2 = node_pai[nodes_positions[self.count+1]] | |
185 | + node_pai[nodes_positions[self.count]] = None | |
186 | + node_pai[nodes_positions[self.count+1]] = None | |
187 | + node_pai[nodes_positions[self.count]] = aux2 | |
188 | + node_pai[nodes_positions[self.count+1]] = aux1 | |
189 | + | |
190 | + ''' | |
191 | + elif self.__acoes.has_key(action_text): | |
192 | + leaves = node_pai[nodes_positions[self.count]].leaves() | |
193 | + token = filter(None, leaves)[0] | |
194 | + result_action = self.__acoes[action_text](token) | |
195 | + | |
196 | + #self.lista_iteracao_regra.append([result_action, tupla[1]]) | |
197 | + nodes_positions[self.count] = 'TODO' | |
198 | + | |
199 | + if action_text == "concate_intens": | |
200 | + leaves_prev = node_pai[nodes_positions[self.count-1]].leaves() | |
201 | + token_prev = filter(None, leaves_prev)[0] | |
202 | + title_text = classe.find('title').text | |
203 | + if title_text == "ADV-R": | |
204 | + node_prev = nodes_deleted.pop() | |
205 | + label_prev = node_prev[0][0].label() | |
206 | + token_prev = filter(None, node_pai[nodes_positions[count_temp-1]].leaves())[0] | |
207 | + token = filter(None, node_pai[nodes_positions[count_temp]].leaves())[0] | |
208 | + token_concate = token_prev + "_" + token | |
209 | + node_pai[nodes_positions[count_temp-1]][0][0][0] = token_concate | |
210 | + newprop = "" | |
211 | + if label_prev[:-2] == "VB": | |
212 | + newprop = "VBi" | |
213 | + elif label_prev[:-3] == "ADJ": | |
214 | + newprop = "ADJi" | |
215 | + | |
216 | + # TODO: Verifica qual newprop adicionada e remove o nó corrente | |
217 | + node_pai[nodes_positions[count_temp-1]][0][0].set_label(newprop) | |
218 | + pos_del = nodes_positions[self.count] | |
219 | + node_pai[pos_del] = None | |
220 | + | |
221 | + else: | |
222 | + token_prev = filter(None, nodes_deleted.pop().leaves())[0] | |
223 | + token = filter(None, node_pai[nodes_positions[count_temp]].leaves())[0] | |
224 | + token_concate = token + "_" + token_prev | |
225 | + node_pai[nodes_positions[count_temp]][0][0][0] = token_concate | |
226 | + | |
227 | + elif action_text == "concate_neg": | |
228 | + print "TODO" | |
229 | + ''' | |
230 | + | |
231 | + if newprop is not None: | |
232 | + node_pai[nodes_positions[self.count]].set_label(newprop.text) | |
233 | + | |
234 | + break | |
235 | + | |
236 | + return self.converter_arv_para_lista(p_arvore) | |
237 | + | |
238 | + | |
239 | + # Aplica regras morfológicas na árvore sintática | |
240 | + def adaptar_regras_morfo_arvore(self, lista, arvore): | |
241 | + lista_pos_arv = [] | |
242 | + # Pega as posições das classificações morfológicas dos tokens na arvore sintática | |
243 | + for tupla in lista: | |
244 | + string_grep = self.corrigir_nome_regra(tupla[1]) + " < " + tupla[0].lower() | |
245 | + node = tgrep_positions(arvore, string_grep) | |
246 | + if not node: | |
247 | + string_grep = self.corrigir_nome_regra(tupla[1]) + " < " + self.remover_acento(tupla[0].lower()) | |
248 | + node = tgrep_positions(arvore, string_grep) | |
249 | + if node[0] in lista_pos_arv: | |
250 | + node.reverse() | |
251 | + lista_pos_arv.append(node[0]) | |
252 | + | |
253 | + # Aplica regras morfológicas na lista | |
254 | + morfo = self.aplicar_regras_morfo(lista, sint=True) | |
255 | + | |
256 | + # Corrige arvore de acordo com a lista após aplicar as regras morfológicas | |
257 | + for i in range(0, len(morfo)): | |
258 | + if morfo[i] is not None and morfo[i][1] == "NTK": | |
259 | + new_node = self.gerar_no(morfo[i]) | |
260 | + arvore[lista_pos_arv[i-1][:-2]].insert(2, new_node) | |
261 | + try: | |
262 | + lista_pos_arv.insert(i,lista_pos_arv[i]) | |
263 | + except: | |
264 | + continue | |
265 | + | |
266 | + arv_ticket = arvore[lista_pos_arv[i]].label() | |
267 | + arv_token = arvore[lista_pos_arv[i]][0] | |
268 | + | |
269 | + if morfo[i] is None: | |
270 | + arvore[lista_pos_arv[i]] = None | |
271 | + | |
272 | + elif arv_token != morfo[i][0] and arv_ticket != morfo[i][1]: | |
273 | + arvore[lista_pos_arv[i]][0] = morfo[i][0] | |
274 | + arvore[lista_pos_arv[i]].set_label(morfo[i][1]) | |
275 | + | |
276 | + elif arv_token != morfo[i][0]: | |
277 | + arvore[lista_pos_arv[i]][0] = morfo[i][0] | |
278 | + | |
279 | + elif arv_ticket != morfo[i][1]: | |
280 | + arvore[lista_pos_arv[i]].set_label(morfo[i][1]) | |
281 | + | |
282 | + # Converte árvore sintática para uma lista de tuplas (igual a lista morfológica) | |
283 | + def converter_arv_para_lista(self, arvore): | |
284 | + folhas = filter(None, arvore.leaves()) | |
285 | + lista_nodes = [] | |
286 | + for folha in folhas: | |
287 | + pos = tgrep_positions(arvore, folha) | |
288 | + node = arvore[pos[0][:-1]] | |
289 | + #decode node[0] | |
290 | + lista_nodes.append([node[0], self.corrigir_nome_regra(node.label())]) | |
291 | + return lista_nodes | |
292 | + | |
293 | + def remover_acento(self, texto): | |
294 | + return normalize('NFKD', texto.encode('utf-8').decode('utf-8')).encode('ascii', 'ignore') | |
295 | + | |
296 | + # Gera um ParentedTree do NLTK apartir da string recebida | |
297 | + def gerar_no(self, s): | |
298 | + all_ptrees = [] | |
299 | + t_string = '('+s[1] + ' ' + s[0]+')' | |
300 | + ptree = ParentedTree.convert(Tree.fromstring(t_string)) | |
301 | + all_ptrees.extend(t for t in ptree.subtrees() | |
302 | + if isinstance(t, Tree)) | |
303 | + return ptree | |
304 | + | |
305 | + # Corrige nome da regra descrita no arquivo de regras para como está na árvore sintática | |
306 | + def corrigir_nome_regra(self, anotacao): | |
307 | + split = anotacao.split('_') | |
308 | + for i in range(0, len(split)): | |
309 | + split[i] = re.sub(r"[-+]","_", split[i]) | |
310 | + split[i] = re.sub(r"\$","_S",split[i]) | |
311 | + return "-".join(split).encode('utf-8') | |
312 | + | |
313 | + # Separa a regra por nó pai e seus filhos | |
314 | + def separar_regra(self, regra): | |
315 | + split = regra.split("(") | |
316 | + split[1] = split[1].replace(")","").split("-") | |
317 | + rev = list(split[1]) | |
318 | + rev.reverse() | |
319 | + split.append(rev) | |
320 | + split[1] = ' $ '.join(split[1]) | |
321 | + split[2] = ' $ '.join(split[2]) | |
322 | + return split | |
323 | + | |
324 | + # Gera nome de regra apartir de uma lista | |
325 | + def gerar_nome_regra(self, lista): | |
326 | + nome_regra = [] | |
327 | + for t in lista: | |
328 | + nome_regra.append(t[1]) | |
329 | + return "_".join(nome_regra) | |
330 | + | |
331 | + def verificar_adv_tempo(self, token): | |
332 | + for tupla in self.lista: | |
333 | + if self.dicionarios.has_adverbio_tempo(tupla[0]): | |
334 | + return True | |
335 | + return False | |
336 | + | |
337 | + def verificar_excecao_plural(self, token): | |
338 | + return self.dicionarios.has_excecao_plural(token) | |
339 | + | |
340 | + def verificar_vb_infinitivo(self, token): | |
341 | + return self.dicionarios.has_verbo_infinitivo(token) | |
342 | + | |
343 | + def verificar_preposicao(self, token): | |
344 | + return self.dicionarios.has_preposicao(token) | |
345 | + | |
346 | + def verificar_subst_genero(self, token): | |
347 | + return self.dicionarios.has_subst_2_generos(token) | |
348 | + | |
349 | + def verificar_artigo(self, token): | |
350 | + return self.dicionarios.has_artigo(token) | |
351 | + | |
352 | + def verificar_vb_ligacao(self, token): | |
353 | + return self.dicionarios.has_verbo_ligacao(token) | |
354 | + | |
355 | + def verificar_adv_intensidade(self, token): | |
356 | + return self.dicionarios.has_adverbio_intensidade(token) | |
357 | + | |
358 | + def verificar_vb_muda_negacao(self, token): | |
359 | + return self.dicionarios.has_verbo_muda_negacao(token) | |
360 | + | |
361 | + def get_vb_infinitivo(self, token): | |
362 | + if self.dicionarios.has_verbo_infinitivo(token): | |
363 | + return self.dicionarios.get_verbo_infinitivo(token) | |
364 | + return token | |
365 | + | |
366 | + def get_token_intensidade(self, token): | |
367 | + print 'TODO' | |
368 | + | |
369 | + | |
370 | + # Simplifica a sentença para que possa evitar a ditalogia | |
371 | + def simplificar_sentenca(self, lista): | |
372 | + lista_simplificada = list(lista) | |
373 | + it = Iterator() | |
374 | + it.load(lista_simplificada) | |
375 | + num = False | |
376 | + while(it.has_next()): | |
377 | + tag = it.get_ticket() | |
378 | + | |
379 | + if tag == "NUM": | |
380 | + num = True | |
381 | + | |
382 | + if tag[-2:] == "-P" and self.verificar_excecao_plural(it.get_word()): | |
383 | + singular = self.analisar_plural(it.get_word()) | |
384 | + lista_simplificada[it.get_count()][0] = singular | |
385 | + | |
386 | + if num: | |
387 | + return self.converter_extenso(lista_simplificada) | |
388 | + return lista_simplificada | |
389 | + | |
390 | + # Alterar uma palavra do plural para o singular | |
391 | + def analisar_plural(self, token): | |
392 | + if(token[-3:] == "OES" or token[-2:] == "AES" or token[-2:] == "AOS"): | |
393 | + return token[0:-3]+"AO" | |
394 | + elif(token[-3:] == "RES" or token[-2:] == "ZES" or token[-2:] == "NES"): | |
395 | + return token[0:-2] | |
396 | + elif(token[-3:] == "SES"): | |
397 | + #TODO: Algumas palavras possuem marcações gráficas na raiz singular. Ex: Gás – Gases | |
398 | + return token[0:-2] | |
399 | + elif(token[-2:] == "NS"): | |
400 | + return token[0:-2]+"M" | |
401 | + elif(token[-3:] == "EIS"): | |
402 | + return token[0:-3]+"IL" | |
403 | + elif(token[-2:] == "IS"): | |
404 | + if(token[-3] == "A" or token[-3] == "E" or token[-3] == "O" or token[-3] == "U"): | |
405 | + return token[0:-2]+"L" | |
406 | + return token | |
407 | + elif(token[-1] == "S"): | |
408 | + #TODO: Palavras paroxítonas ou proparoxítonas terminadas em S. Ex: lápis, vírus, tagênis, ônibus, etc | |
409 | + return token[0:-1] | |
410 | + else: | |
411 | + return token | |
412 | + | |
413 | + # Converter número por extenso para numeral | |
414 | + def converter_extenso(self, lista): | |
415 | + lista_extensos = [] | |
416 | + indices_deletar = [] | |
417 | + count = 0 | |
418 | + is_sequence = False | |
419 | + | |
420 | + for i in range(0, len(lista)): | |
421 | + token = lista[i][0] | |
422 | + tag = lista[i][1] | |
423 | + if tag == "NUM": | |
424 | + # Verifico se não há sequência de obtenção de extenso em andamento para começar a obter um nova sequência | |
425 | + if (is_sequence is False): # and len(lista_extensos) == count (???) | |
426 | + lista_extensos.append([i,[token]]) # i = Posição do primeiro extenso encontrado, token = número por extenso | |
427 | + is_sequence = True | |
428 | + else: | |
429 | + lista_extensos[count][1].append(token) # Pego número por extenso que está na sequência e adiciona na lista | |
430 | + indices_deletar.append(i) # Insiro indice na lista para ser removido depois | |
431 | + elif (is_sequence): | |
432 | + # Se o token anterior e o próximo foram classificados como número, e o token atual como conjunção, significa que podemos remove-lo | |
433 | + if ((lista[i-1][1] == "NUM") and (lista[i+1][1] == "NUM") and (tag == "CONJ")): | |
434 | + indices_deletar.append(i) | |
435 | + else: | |
436 | + # A sequência foi quebrada, o que significa que selecionamos o extenso do número por completo | |
437 | + # Podemos agora procurar por outra sequencia de número por extenso na lista | |
438 | + is_sequence = False | |
439 | + count += 1 | |
440 | + | |
441 | + for extenso in lista_extensos: | |
442 | + ext = convert_extenso(' '.join(extenso[1])) | |
443 | + lista[extenso[0]] = [ext, "NUM"] | |
444 | + | |
445 | + deque((list.pop(lista, i) for i in sorted(indices_deletar, reverse=True)), maxlen=0) | |
446 | + return lista | |
0 | 447 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,33 @@ |
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 os | |
10 | +import csv | |
11 | +import sys | |
12 | +from nltk.tree import Tree | |
13 | +from LerDicionarios import * | |
14 | + | |
15 | +class AplicaSinonimos(object): | |
16 | + """Classe para aplicar sinonimos após a aplicação de regras morfológicas/sintáticas""" | |
17 | + | |
18 | + def __init__(self): | |
19 | + self.dicionarios = LerDicionarios() | |
20 | + | |
21 | + # Itera sobre os tokens obtendo os sinonimos | |
22 | + def aplicar_sinonimos(self, lista_anotada): | |
23 | + lista_corrigida = [] | |
24 | + for tupla in lista_anotada: | |
25 | + sinonimo = self.verificar_sinonimo(tupla[0]) | |
26 | + lista_corrigida.append(sinonimo) | |
27 | + return " ".join(lista_corrigida) | |
28 | + | |
29 | + # Verifica se há sinonimo do token | |
30 | + def verificar_sinonimo(self, token): | |
31 | + if self.dicionarios.has_sinonimo(token): | |
32 | + return self.dicionarios.get_sinonimo(token) | |
33 | + return token | |
0 | 34 | \ No newline at end of file | ... | ... |
src/AplicadorRegras.py
... | ... | @@ -1,67 +0,0 @@ |
1 | -#!/usr/bin/python | |
2 | -# -*- coding: utf-8 -*- | |
3 | - | |
4 | -#Autor: Erickson Silva <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | |
5 | - | |
6 | -import xml.etree.ElementTree as ET | |
7 | -from os.path import expanduser | |
8 | -import platform | |
9 | - | |
10 | -class AplicadorRegras(object): | |
11 | - | |
12 | - # inicializacao das variaves | |
13 | - def __init__(self): | |
14 | - | |
15 | - so = platform.system() | |
16 | - if so == 'Windows': | |
17 | - self.__tree = ET.parse(expanduser("~")+'\\vlibras-translate\data\\regras.xml') | |
18 | - else: | |
19 | - self.__tree = ET.parse(expanduser("~")+'/vlibras-translate/data/regras.xml') | |
20 | - | |
21 | - self.__root = self.__tree.getroot() | |
22 | - self.__tAux = [] | |
23 | - self.__dAux = {} | |
24 | - | |
25 | - # aplica as regras | |
26 | - def aplicarRegras(self, ts): | |
27 | - self.__n = len(ts) # quantidade de tokens | |
28 | - for i in range(0,self.__n): | |
29 | - self.__tAux.append(self.__n) | |
30 | - self.__name = self.getNameRule(ts) # todos os etiquetadores numa so string (ver linha 35) | |
31 | - for morpho in self.__root: | |
32 | - for rule in morpho.findall('rule'): # procura a tag rule | |
33 | - if rule.get('name') == self.__name: # procura o atributo name na tag rule (ver linha 17) | |
34 | - if rule.find('active').text == "true": # verifica se a regra esta ativa | |
35 | - self.__c = 0 | |
36 | - for classe in rule.iter('class'): # for nas tags class | |
37 | - self.__dAux[self.__c] = int(classe.find('newpos').text) # preenche dicionario com a ordem atual e futura das palavras | |
38 | - self.__c += 1 | |
39 | - self.__c = 0 | |
40 | - for w,t in ts: | |
41 | - i = self.__dAux.get(self.__c) # pega o indice de onde ficara a palavra | |
42 | - self.__tAux[i] = ([w,t]) # preenche a lista com a palavra+etiqueta na posicao correta (segundo o arquivo regras.xml) | |
43 | - self.__c += 1 | |
44 | - return self.__tAux # retorna nova lista (ordenada) | |
45 | - return ts # retorna a lista sem alteracoes (nao existe regra) | |
46 | - | |
47 | - def getNameRule(self, ts): | |
48 | - self.__name = "" | |
49 | - for w,t in ts: | |
50 | - if t[:2] != "VB": | |
51 | - self.__name += t | |
52 | - else: | |
53 | - self.__name += t[:2] | |
54 | - return self.__name | |
55 | - | |
56 | - | |
57 | - | |
58 | - | |
59 | - | |
60 | - | |
61 | - | |
62 | - | |
63 | - | |
64 | - | |
65 | - | |
66 | - | |
67 | - |
src/Classificador.py
... | ... | @@ -1,44 +0,0 @@ |
1 | -#!/usr/bin/python | |
2 | -# -*- coding: utf-8 -*- | |
3 | - | |
4 | -#Autor: Erickson Silva <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | |
5 | - | |
6 | -from Aelius import AnotaCorpus, Toqueniza, Extras | |
7 | - | |
8 | -class Classificador(object): | |
9 | - | |
10 | - # inicializacao das variaveis | |
11 | - def __init__(self): | |
12 | - self.__h = Extras.carrega("AeliusHunPos") # carrega o modelo de idioma (passado por parametro ao instanciar) | |
13 | - | |
14 | - def anotaSentencas(self, str): | |
15 | - self.__t = "" | |
16 | - self.__tokens = "" | |
17 | - #try: | |
18 | - # tokenizae | |
19 | - self.__tokens = Toqueniza.TOK_PORT.tokenize(str) | |
20 | - | |
21 | - # realiza a classificacao morfologica | |
22 | - self.__t = AnotaCorpus.anota_sentencas([self.__tokens],self.__h,'hunpos') | |
23 | - | |
24 | - return self.listClean(self.__t) | |
25 | - #except: | |
26 | - # print "Erro ao efetuar a classificação morfologica." | |
27 | - | |
28 | - | |
29 | - def listClean(self, l): | |
30 | - lClean = [] | |
31 | - for w,t in l[0]: | |
32 | - lClean.append([w,t]) | |
33 | - return lClean | |
34 | - | |
35 | - # faz a impressao (usado apenas pra testes) | |
36 | - def imprimeSentencas(self): | |
37 | - for w,t in self.t[0]: | |
38 | - print "%s_%s " % (w,t), | |
39 | - | |
40 | - | |
41 | - | |
42 | - | |
43 | - | |
44 | - |
... | ... | @@ -0,0 +1,154 @@ |
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 sys | |
10 | +from unicodedata import normalize | |
11 | +from Iterator import * | |
12 | + | |
13 | +num = {"zero":0, "um":1, "dois":2, "tres":3, "quatro":4, "cinco":5, "seis":6, | |
14 | +"sete":7, "oito":8, "nove":9} | |
15 | + | |
16 | +ext = [{"um":"1", "dois":"2", "tres":"3", "quatro":"4", "cinco":"5", "seis":"6", | |
17 | +"sete":"7", "oito":"8", "nove":"9", "dez":"10", "onze":"11", "doze":"12", | |
18 | +"treze":"13", "quatorze":"14", "quinze":"15", "dezesseis":"16", | |
19 | +"dezessete":"17", "dezoito":"18", "dezenove":"19"}, {"vinte":"2", "trinta":"3", | |
20 | +"quarenta":"4", "cinquenta":"5", "sessenta":"6", "setenta":"7", "oitenta":"8", | |
21 | +"noventa":"9"}, {"cento":"1", "cem":"1", "duzentos":"2", "trezentos":"3", | |
22 | +"quatrocentos":"4", "quinhentos":"5", "seissentos":"6", "setessentos":"7", | |
23 | +"oitocentos":"8", "novecentos":"9"}] | |
24 | + | |
25 | +und = {"mil":1000, "milhao":1000000, "bilhao":1000000000, "trilhao":1000000000000} | |
26 | +unds = {"mil":"000", "milhao":"000000","milhoes":"000000", "bilhao":"000000000","bilhoes":"000000000", "trilhao":"000000000000", "trilhoes":"000000000000"} | |
27 | + | |
28 | + | |
29 | + | |
30 | +def oneDigit(x): | |
31 | + return ext[0][x] | |
32 | + | |
33 | +def twoDigit(x): | |
34 | + try: | |
35 | + return ext[1][x[0]]+ext[0][x[1]] | |
36 | + except: | |
37 | + return ext[1][x[0]]+"0" | |
38 | + | |
39 | +def threeDigit(x): | |
40 | + return ext[2][x[0]]+ext[1][x[1]]+ext[0][x[2]] | |
41 | + | |
42 | +# Não faço mais a minima idéia de como fiz isso, só sei que funciona! | |
43 | +def extensoUnit(n): | |
44 | + sn = n.split(",") | |
45 | + size = len(sn) | |
46 | + firstWord = sn[0] | |
47 | + endWord = "" | |
48 | + numExt = "" | |
49 | + | |
50 | + if(unds.has_key(sn[size-1])): | |
51 | + size -= 1 | |
52 | + endWord = sn[size] | |
53 | + del sn[size] | |
54 | + | |
55 | + if(ext[0].has_key(firstWord)): | |
56 | + numExt = oneDigit(firstWord) | |
57 | + | |
58 | + elif (ext[1].has_key(firstWord)): | |
59 | + numExt = twoDigit(sn) | |
60 | + | |
61 | + elif (ext[2].has_key(firstWord)): | |
62 | + if(size == 1): | |
63 | + numExt = ext[2][firstWord]+"00" | |
64 | + elif (size == 2): | |
65 | + if(sn[1] == "dez"): | |
66 | + numExt = ext[2][firstWord]+oneDigit(sn[1]) | |
67 | + try: | |
68 | + numExt = ext[2][firstWord]+"0"+oneDigit(sn[1]) | |
69 | + except: | |
70 | + numExt = ext[2][firstWord]+twoDigit([sn[1]]) | |
71 | + else: | |
72 | + numExt = threeDigit(sn) | |
73 | + | |
74 | + if(endWord != ""): | |
75 | + numExt = numExt+unds[endWord] | |
76 | + | |
77 | + return numExt | |
78 | + | |
79 | + | |
80 | +''' | |
81 | +Comece com uma lista vazia. Itere pelas palavras da string da esquerda | |
82 | +para direita. Ao encontrar um numeral, adicione o número à lista se a | |
83 | +última palavra foi uma escala, ou some ao último numero da lista se a | |
84 | +última palavra foi um numeral. Ao encontrar uma escala, multiplique o | |
85 | +último número da lista de acordo. Quando terminar, some tudo e retorne | |
86 | +o resultado. | |
87 | +''' | |
88 | + | |
89 | +# TODO: Refatorar para nao usar mais o extensoUnit | |
90 | +def convert_extenso(extenso): | |
91 | + global newToken, auxToken | |
92 | + extensoQuebrado = extenso.lower().split(" ") | |
93 | + nums = [] | |
94 | + it = Iterator() | |
95 | + it.load(extensoQuebrado) | |
96 | + while(it.has_next()): | |
97 | + token = simplifica(it.get_token()) | |
98 | + tokenAnterior = simplifica(it.get_token(-1)) | |
99 | + if (und.has_key(token)): | |
100 | + if(it.get_count() == 0): | |
101 | + nums.append(und[token]) | |
102 | + else: | |
103 | + newToken = und[token] * int(nums[-1]) | |
104 | + nums[-1] = newToken | |
105 | + else: | |
106 | + if (num.has_key(token)): | |
107 | + auxToken = num[token] | |
108 | + elif (not und.has_key(token)): | |
109 | + auxToken = extensoUnit(token) | |
110 | + | |
111 | + if((not und.has_key(tokenAnterior)) and it.get_count() > 0): | |
112 | + newToken = int(auxToken) + int(nums[-1]) | |
113 | + nums[-1] = newToken | |
114 | + else: | |
115 | + nums.append(auxToken) | |
116 | + return soma(nums) | |
117 | + | |
118 | +def soma(lista): | |
119 | + soma = 0 | |
120 | + for i in lista: | |
121 | + soma += int(i) | |
122 | + return soma | |
123 | + | |
124 | +def simplifica(txt): | |
125 | + newToken = "" | |
126 | + try: | |
127 | + newToken = normalize('NFKD', txt.decode('utf-8')).encode('ASCII','ignore') | |
128 | + except: | |
129 | + newToken = normalize('NFKD', txt.decode('iso-8859-1')).encode('ASCII','ignore') | |
130 | + | |
131 | + if(newToken[-3:] == "oes"): | |
132 | + return newToken[:-3] + "ao" | |
133 | + | |
134 | + return newToken | |
135 | + | |
136 | +# Test | |
137 | +''' | |
138 | +if __name__ == '__main__': | |
139 | + n = sys.argv[1] | |
140 | + return extenso(n) | |
141 | + arquivoExts = open('exts', 'r') | |
142 | + listaExts = arquivoExts.readlines() | |
143 | + arquivoNums = open('nums', 'r') | |
144 | + listaNums = arquivoNums.readlines() | |
145 | + for i in range(0,500): | |
146 | + n = listaNums[i].replace("\n","") | |
147 | + e = listaExts[i].replace("\n","") | |
148 | + numNew = extenso(e) | |
149 | + if (str(numNew) != n): | |
150 | + print n + " != " + str(numNew) | |
151 | + #else: | |
152 | + # print "OK: " + n + " == " + str(numNew) | |
153 | +''' | |
154 | + | ... | ... |
src/Iterator.py
1 | 1 | #!/usr/bin/python |
2 | 2 | # -*- coding: utf-8 -*- |
3 | 3 | |
4 | -#Autor: Erickson Silva <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | |
4 | +#Autor: Erickson Silva | |
5 | +#Email: <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | |
5 | 6 | |
6 | -from StringAux import * | |
7 | +#LAViD - Laboratório de Aplicações de Vídeo Digital | |
7 | 8 | |
8 | 9 | class Iterator(object): |
10 | + """Classe para iterar sobre as tuplas (palavra,etiqueta) após análise morfologica""" | |
9 | 11 | |
10 | - # inicializacao das variaveis | |
11 | - def __init__(self): | |
12 | + def init(self): | |
12 | 13 | self.count = -1 |
13 | 14 | |
14 | 15 | def load(self, lista): |
15 | - self.__list = list(lista); | |
16 | + self.reset() | |
17 | + self.list = list(lista); | |
16 | 18 | self.size = len(lista) |
17 | 19 | |
18 | 20 | def reset(self): |
19 | 21 | self.count = -1 |
20 | 22 | |
21 | - def getSize(self): | |
23 | + def get_size(self): | |
22 | 24 | return self.size |
23 | 25 | |
24 | - def getCount(self): | |
26 | + def get_count(self): | |
25 | 27 | return self.count |
26 | 28 | |
27 | - def getToken(self, i=None): | |
28 | - if(i == "+"): | |
29 | - return self.__list[self.count+1] | |
29 | + def get_token(self, i=None): | |
30 | + if(i != None): | |
31 | + return self.list[self.count+(i)] | |
32 | + return self.list[self.count] | |
30 | 33 | |
31 | - elif(i == "-"): | |
32 | - return self.__list[self.count-1] | |
34 | + def get_word(self): | |
35 | + return self.get_token()[0] | |
33 | 36 | |
34 | - return self.__list[self.count] | |
37 | + def get_ticket(self): | |
38 | + return self.get_token()[1] | |
35 | 39 | |
36 | - def getAtualW(self): | |
37 | - return remover_acentos(self.getToken(0)[0].upper().encode('utf-8')) | |
40 | + def get_next_word(self): | |
41 | + return self.get_token(1)[0] | |
38 | 42 | |
39 | - def getAtualT(self): | |
40 | - return self.getToken(0)[1].upper().encode('utf-8') | |
43 | + def get_next_ticket(self): | |
44 | + return self.get_token(1)[1] | |
41 | 45 | |
42 | - def getProxW(self): | |
43 | - return remover_acentos(self.getToken("+")[0].upper().encode('utf-8')) | |
46 | + def get_prev_word(self): | |
47 | + return self.get_token(-1)[0] | |
44 | 48 | |
45 | - def getProxT(self): | |
46 | - return self.getToken("+")[1].upper().encode('utf-8') | |
49 | + def get_prev_ticket(self): | |
50 | + return self.get_token(-1)[1] | |
47 | 51 | |
48 | - def getAntW(self): | |
49 | - return remover_acentos(self.getToken("-")[0].upper().encode('utf-8')) | |
52 | + def get_interval(self, n): | |
53 | + if self.count+n > self.size: | |
54 | + raise IndexError | |
55 | + return self.list[self.count:self.count+n] | |
50 | 56 | |
51 | - def getAntT(self): | |
52 | - return self.getToken("-")[1].upper().encode('utf-8') | |
57 | + def skip(self, n): | |
58 | + self.count += n | |
53 | 59 | |
54 | - def hasNext(self): | |
60 | + def has_next(self): | |
55 | 61 | if(self.count < self.size-1): |
56 | 62 | self.count += 1 |
57 | 63 | return True | ... | ... |
... | ... | @@ -0,0 +1,212 @@ |
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 | +from os.path import expanduser | |
10 | +from os import environ | |
11 | +import csv | |
12 | +import platform | |
13 | + | |
14 | +class LerDicionarios(object): | |
15 | + | |
16 | + def __init__(self): | |
17 | + self.path = self.get_path() | |
18 | + self.set_exc_plural = [] | |
19 | + self.dic_adv_intensidade = {} | |
20 | + self.set_adv_tempo = [] | |
21 | + self.set_art = [] | |
22 | + self.set_prep = [] | |
23 | + self.dic_sin = {} | |
24 | + self.set_sb_2_gen = [] | |
25 | + self.dic_vb_infinitivo = {} | |
26 | + self.set_vb_ligacao = [] | |
27 | + self.dic_vb_muda_negacao = [] | |
28 | + self.file = '' | |
29 | + self.carregar_dicionarios() | |
30 | + | |
31 | + def get_path(self): | |
32 | + if platform.system() == 'Windows': | |
33 | + return os.environ.get("HOMEDRIVE") + "\\vlibras-libs\\vlibras-translate\data\\" | |
34 | + return expanduser("~") + "/vlibras-translate/data/" | |
35 | + | |
36 | + def carregar_dicionarios(self): | |
37 | + self.carregar_excecoes_plural() | |
38 | + self.carregar_adverbios_intensidade() | |
39 | + self.carregar_adverbios_tempo() | |
40 | + self.carregar_artigos() | |
41 | + self.carregar_preposicoes() | |
42 | + self.carregar_sinonimos() | |
43 | + self.carregar_subs_2_generos() | |
44 | + self.carregar_verbos_infinitivo() | |
45 | + self.carregar_verbos_ligacao() | |
46 | + self.carregar_verbos_muda_negacao | |
47 | + | |
48 | + | |
49 | + def carregar_excecoes_plural(self): | |
50 | + try: | |
51 | + self.file = csv.reader(open(self.path+"excecoesPlural.csv")) | |
52 | + except IOError, (errno, strerror): | |
53 | + print "I/O error(%s): %s" % (errno, strerror) | |
54 | + print "carregar_excecoes_plural" | |
55 | + | |
56 | + rows = [] | |
57 | + for row in self.file: | |
58 | + rows.append(row[0].decode("utf-8")) | |
59 | + self.set_exc_plural = set(rows) | |
60 | + | |
61 | + def carregar_adverbios_intensidade(self): | |
62 | + try: | |
63 | + self.file = csv.reader(open(self.path+"adverbiosIntensidade.csv"), delimiter=";") | |
64 | + except IOError, (errno, strerror): | |
65 | + print "I/O error(%s): %s" % (errno, strerror) | |
66 | + print "carregar_adverbios_intensidade" | |
67 | + | |
68 | + for row in self.file: | |
69 | + if row[1] != "": | |
70 | + self.dic_adv_intensidade[row[0].decode("utf-8")] = row[1].decode("utf-8") | |
71 | + | |
72 | + def carregar_adverbios_tempo(self): | |
73 | + try: | |
74 | + self.file = csv.reader(open(self.path+"adverbiosTempo.csv")) | |
75 | + except IOError, (errno, strerror): | |
76 | + print "I/O error(%s): %s" % (errno, strerror) | |
77 | + print "carregar_adverbios_tempo" | |
78 | + | |
79 | + rows = [] | |
80 | + for row in self.file: | |
81 | + rows.append(row[0].decode("utf-8")) | |
82 | + self.set_adv_tempo = set(rows) | |
83 | + | |
84 | + def carregar_artigos(self): | |
85 | + try: | |
86 | + self.file = csv.reader(open(self.path+"artigos.csv")) | |
87 | + except IOError, (errno, strerror): | |
88 | + print "I/O error(%s): %s" % (errno, strerror) | |
89 | + print "carregar_artigos" | |
90 | + | |
91 | + rows = [] | |
92 | + for row in self.file: | |
93 | + rows.append(row[0].decode("utf-8")) | |
94 | + self.set_art = set(rows) | |
95 | + | |
96 | + def carregar_preposicoes(self): | |
97 | + try: | |
98 | + self.file = csv.reader(open(self.path+"preposicoes.csv")) | |
99 | + except IOError, (errno, strerror): | |
100 | + print "I/O error(%s): %s" % (errno, strerror) | |
101 | + print "carregar_preposicoes" | |
102 | + | |
103 | + rows = [] | |
104 | + for row in self.file: | |
105 | + rows.append(row[0].decode("utf-8")) | |
106 | + self.set_prep = set(rows) | |
107 | + | |
108 | + def carregar_sinonimos(self): | |
109 | + try: | |
110 | + self.file = csv.reader(open(self.path+"sinonimos.csv"), delimiter=";") | |
111 | + except IOError, (errno, strerror): | |
112 | + print "I/O error(%s): %s" % (errno, strerror) | |
113 | + print "carregar_sinonimos" | |
114 | + | |
115 | + for row in self.file: | |
116 | + if row[1] != "": | |
117 | + try: | |
118 | + self.dic_sin[row[0].decode("utf-8")] = row[1].decode("utf-8") | |
119 | + except UnicodeDecodeError: | |
120 | + self.dic_sin[row[0].decode('iso8859-1').encode('utf-8').decode('utf-8')] = row[1].decode('iso8859-1').encode('utf-8').decode('utf-8') | |
121 | + | |
122 | + def carregar_subs_2_generos(self): | |
123 | + try: | |
124 | + self.file = csv.reader(open(self.path+"subs2Generos.csv")) | |
125 | + except IOError, (errno, strerror): | |
126 | + print "I/O error(%s): %s" % (errno, strerror) | |
127 | + print "carregar_subs_2_generos" | |
128 | + | |
129 | + rows = [] | |
130 | + for row in self.file: | |
131 | + rows.append(row[0].decode('iso8859-1').encode('utf-8').decode('utf-8')) | |
132 | + self.set_sb_2_gen = set(rows) | |
133 | + | |
134 | + def carregar_verbos_infinitivo(self): | |
135 | + try: | |
136 | + self.file = csv.reader(open(self.path+"verbosInfinitivo.csv"), delimiter=";") | |
137 | + except IOError, (errno, strerror): | |
138 | + print "I/O error(%s): %s" % (errno, strerror) | |
139 | + print "carregar_verbos_infinitivo" | |
140 | + | |
141 | + for row in self.file: | |
142 | + if row[1] != "": | |
143 | + try: | |
144 | + self.dic_vb_infinitivo[row[0].decode("utf-8")] = row[1].decode("utf-8") | |
145 | + except UnicodeDecodeError: | |
146 | + self.dic_vb_infinitivo[row[0].decode('iso8859-1').encode('utf-8').decode('utf-8')] = row[1].decode('iso8859-1').encode('utf-8').decode('utf-8') | |
147 | + | |
148 | + def carregar_verbos_ligacao(self): | |
149 | + try: | |
150 | + self.file = csv.reader(open(self.path+"verbosLigacao.csv")) | |
151 | + except IOError, (errno, strerror): | |
152 | + print "I/O error(%s): %s" % (errno, strerror) | |
153 | + print "carregar_verbos_ligacao" | |
154 | + | |
155 | + rows = [] | |
156 | + for row in self.file: | |
157 | + rows.append(row[0].decode("utf-8")) | |
158 | + self.set_vb_ligacao = set(rows) | |
159 | + | |
160 | + | |
161 | + def carregar_verbos_muda_negacao(self): | |
162 | + try: | |
163 | + self.file = csv.reader(open(self.path+"verbosMudaNegacao.csv"), delimiter=";") | |
164 | + except IOError, (errno, strerror): | |
165 | + print "I/O error(%s): %s" % (errno, strerror) | |
166 | + print "carregar_verbos_muda_negacao" | |
167 | + | |
168 | + for row in self.file: | |
169 | + if row[1] != "": | |
170 | + self.dic_vb_muda_negacao[row[0].decode("utf-8")] = row[1].decode("utf-8") | |
171 | + | |
172 | + def has_excecao_plural(self, token): | |
173 | + return token not in self.set_exc_plural | |
174 | + | |
175 | + def has_adverbio_intensidade(self, token): | |
176 | + return self.dic_adv_intensidade.has_key(token) | |
177 | + | |
178 | + def has_adverbio_tempo(self, token): | |
179 | + return token in self.set_adv_tempo | |
180 | + | |
181 | + def has_artigo(self, token): | |
182 | + return token in self.set_art | |
183 | + | |
184 | + def has_preposicao(self, token): | |
185 | + return token in self.set_prep | |
186 | + | |
187 | + def has_sinonimo(self, token): | |
188 | + return self.dic_sin.has_key(token) | |
189 | + | |
190 | + def has_subst_2_generos (self, token): | |
191 | + return token in self.set_sb_2_gen | |
192 | + | |
193 | + def has_verbo_infinitivo(self, token): | |
194 | + return self.dic_vb_infinitivo.has_key(token) | |
195 | + | |
196 | + def has_verbo_ligacao(self, token): | |
197 | + return token in self.set_vb_ligacao | |
198 | + | |
199 | + def has_verbo_muda_negacao(self, token): | |
200 | + return self.dic_vb_muda_negacao.has_key(token) | |
201 | + | |
202 | + def get_adverbio_intensidade(self, token): | |
203 | + return self.dic_adv_intensidade[token] | |
204 | + | |
205 | + def get_sinonimo(self, token): | |
206 | + return self.dic_sin[token] | |
207 | + | |
208 | + def get_verbo_infinitivo(self, token): | |
209 | + return self.dic_vb_infinitivo[token] | |
210 | + | |
211 | + def get_verbo_muda_negacao(self, token): | |
212 | + return self.dic_vb_muda_negacao[token] | |
0 | 213 | \ No newline at end of file | ... | ... |
src/ModuleTranslate.py
src/Output.py
... | ... | @@ -1,24 +0,0 @@ |
1 | -#!/usr/bin/python | |
2 | -# -*- coding: utf-8 -*- | |
3 | - | |
4 | -#Autor: Erickson Silva <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | |
5 | - | |
6 | -import sys | |
7 | -from Iterator import * | |
8 | -from StringAux import * | |
9 | - | |
10 | -class Output(object): | |
11 | - | |
12 | - # inicializa a variavel com o valor passado por paramentro ao instanciar | |
13 | - def __init__(self): | |
14 | - self.it = Iterator() | |
15 | - | |
16 | - # executa a saida | |
17 | - def executeOut(self, ts): | |
18 | - self.__glosa = [] | |
19 | - self.it.load(ts) | |
20 | - while(self.it.hasNext()): | |
21 | - self.__glosa.append(self.it.getAtualW()) | |
22 | - self.it.reset() | |
23 | - return ' '.join(self.__glosa) | |
24 | - |
... | ... | @@ -0,0 +1,50 @@ |
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 | +from TraduzSentencas import * | |
10 | + | |
11 | +def traduzir(texto): | |
12 | + glosa = iniciar_traducao(texto) | |
13 | + if glosa: | |
14 | + return glosa | |
15 | + return "selecione_texto" | |
16 | + | |
17 | +def iniciar_traducao(texto): | |
18 | + texto_quebrado = quebrar_texto(texto) | |
19 | + num_threads = len(texto_quebrado) | |
20 | + texto_traduzido = [] | |
21 | + threads = [] | |
22 | + | |
23 | + for i in range(num_threads): | |
24 | + if texto_quebrado[i] > 0 and texto_quebrado[i] != " ": | |
25 | + threads.insert(i, TraduzSentencas(texto_quebrado[i])) | |
26 | + threads[i].start() | |
27 | + for i in range(num_threads): | |
28 | + threads[i].join() | |
29 | + texto_traduzido.append(threads[i].obter_glosa()) | |
30 | + | |
31 | + try: | |
32 | + return " ".join(texto_traduzido) | |
33 | + except: | |
34 | + return None | |
35 | + | |
36 | +def quebrar_texto(texto): | |
37 | + quantidade_pontos = texto.count('. ') | |
38 | + sentencas = [] | |
39 | + for i in range(quantidade_pontos): | |
40 | + posicao_ponto = texto.find('.') | |
41 | + if texto[posicao_ponto+2].isupper(): | |
42 | + sentencas.append(texto[:posicao_ponto]) | |
43 | + texto = texto[posicao_ponto+2:] | |
44 | + if len(texto) > 0: | |
45 | + sentencas.append(texto) | |
46 | + return sentencas | |
47 | + | |
48 | +def ajuda(): | |
49 | + #TODO: Adicionar um pequeno tuto aqui | |
50 | + print "Help" | |
0 | 51 | \ No newline at end of file | ... | ... |
src/Simplificador.py
... | ... | @@ -1,164 +0,0 @@ |
1 | -#!/usr/bin/python | |
2 | -# -*- coding: utf-8 -*- | |
3 | - | |
4 | -#Autor: Erickson Silva <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | |
5 | - | |
6 | -from WorkCSV import * | |
7 | -from Iterator import * | |
8 | -from StringAux import * | |
9 | - | |
10 | -class Simplificador(object): | |
11 | - | |
12 | - # inicializa todos as variaveis | |
13 | - def __init__(self): | |
14 | - self.it = Iterator() | |
15 | - self.__csv = WorkCSV() | |
16 | - self.__dicInf = {} | |
17 | - self.__dicSin = {} | |
18 | - self.__dicWords = {} | |
19 | - self.__dic2Gen = {} | |
20 | - self.__dicTemVerbs = {} | |
21 | - self.executeWorkCSV() | |
22 | - | |
23 | - # retira artigos e preposicoes; passa verbos para infinitivo e verificar se há sinonimos | |
24 | - def simplificar(self, texto): | |
25 | - self.__ts = [] | |
26 | - self.it.load(texto) | |
27 | - self.__verb = False | |
28 | - self.__adv = False; | |
29 | - self.__countVerb = 0 | |
30 | - self.__countAdv = 0 | |
31 | - countWords = 0 | |
32 | - while(self.it.hasNext()): | |
33 | - w = self.auxConvert(self.it.getAtualW()) | |
34 | - t = self.it.getAtualT() | |
35 | - self.__b = False | |
36 | - if self.__dicWords.has_key(t) == False: # verifica se nao eh artigo/preposicao | |
37 | - wu = str(w).upper() # deixa o token maiusculo | |
38 | - #if t[:2] == "VB": | |
39 | - if t[-2:] == "-P": | |
40 | - wu = self.pluralAnalysis(w) | |
41 | - if t == "VB-P" or t == "VB-D" or t == "VB-R": | |
42 | - self.__verb = True | |
43 | - self.__countVerb += 1 | |
44 | - if t[:3] == "ADV": | |
45 | - self.__adv = True | |
46 | - self.__countAdv += 1 | |
47 | - if self.__dicInf.has_key(wu): # verifica se ha um verbo infinitivo desse token | |
48 | - sAux = self.__dicInf[wu] # se sim, adiciona numa string aux | |
49 | - if self.__dicSin.has_key(sAux): # verifica se ha um sinonimo para esse verbo infinitivo | |
50 | - self.__ts.append([self.__dicSin[sAux],t]) # se sim, entao adiciona na lista | |
51 | - self.__b = True | |
52 | - else: | |
53 | - self.__ts.append([sAux,t]) # caso contrario, adiciona so o verbo infinitivo msm | |
54 | - self.__b = True | |
55 | - if self.__b == False and self.__dicSin.has_key(wu): # verifica se nao foi encontrado verbo infinitivo e se ha sinonimo | |
56 | - self.__ts.append([self.__dicSin[wu],t]) # adiciona na o sinonimo lista | |
57 | - self.__b = True | |
58 | - | |
59 | - if self.__dic2Gen.has_key(wu): | |
60 | - del self.__ts[-1] | |
61 | - lenTicket = len(self.it.getAntT()) | |
62 | - if ((self.__dicWords.has_key(self.it.getAntT())) and (self.it.getAntT()[lenTicket-1:] == "F") or (self.it.getAntT()[lenTicket-3:] == "F-P")): | |
63 | - self.__ts.append(["MULHER " + wu,t]) | |
64 | - else: | |
65 | - self.__ts.append(["HOMEM " + wu,t]) | |
66 | - self.__b = True | |
67 | - if self.__b == False: # verifica se nao encontrou nem verbo infinito ou sinonimo | |
68 | - self.__ts.append([wu,t]) | |
69 | - countWords += 1 | |
70 | - self.it.reset() | |
71 | - if self.__verb == True: | |
72 | - return self.verbalAnalysis(self.__ts) | |
73 | - return self.__ts | |
74 | - | |
75 | - # cria e recupera todos os dicionarios (verbos inf., sinonimos e artigos/preposicoes) | |
76 | - def executeWorkCSV(self): | |
77 | - self.__dicInf = self.__csv.getDicInf() | |
78 | - self.__dicSin = self.__csv.getDicSin() | |
79 | - self.__dicWords = self.__csv.getDicWords() | |
80 | - self.__dic2Gen = self.__csv.getDic2Gen() | |
81 | - self.__dicTemVerbs = self.__csv.getDicTemVerbs() | |
82 | - | |
83 | - # converte romano para numero | |
84 | - def auxConvert(self, t): | |
85 | - try: | |
86 | - return roman_to_int(t) | |
87 | - except: | |
88 | - return t | |
89 | - | |
90 | - | |
91 | - def verbalAnalysis(self, lista): | |
92 | - lv = [] | |
93 | - self.it.load(lista) | |
94 | - hasFut = False | |
95 | - hasPas = False | |
96 | - count = 0 | |
97 | - while(self.it.hasNext()): | |
98 | - w = self.it.getAtualW().upper() | |
99 | - t = self.it.getAtualT() | |
100 | - | |
101 | - if(t[:3] == "ADV"): | |
102 | - if (self.__dicTemVerbs.has_key(w)): | |
103 | - self.it.reset() | |
104 | - #print "ADV: retornou lista original" | |
105 | - return lista | |
106 | - | |
107 | - if(t == "VB-P"): | |
108 | - if (self.__countVerb > 1): | |
109 | - count += 1 | |
110 | - #print "VB-P: Incrementou" | |
111 | - if(count == self.__countVerb): | |
112 | - #print "VB-P Adicionou " + w | |
113 | - lv.append([w,t]) | |
114 | - else: | |
115 | - #print "VB-P: retornou lista original" | |
116 | - self.it.reset() | |
117 | - return lista | |
118 | - elif(t == "VB-D"): | |
119 | - count += 1 | |
120 | - hasPas = True | |
121 | - #print "VB-D: Incrementou" | |
122 | - if(count == self.__countVerb): | |
123 | - #print "VB-D Adicionou " + w | |
124 | - lv.append([w,t]) | |
125 | - elif(t == "VB-R"): | |
126 | - count += 1 | |
127 | - hasFut = True | |
128 | - #print "VB-R: Incrementou" | |
129 | - if(count == self.__countVerb): | |
130 | - #print "VB-R Adicionou " + w | |
131 | - lv.append([w,t]) | |
132 | - else: | |
133 | - lv.append([w,t]) | |
134 | - if (hasFut): | |
135 | - lv.append(["FUTURO", "TVB"]) | |
136 | - elif (hasPas): | |
137 | - lv.append(["PASSADO", "TVB"]) | |
138 | - self.it.reset() | |
139 | - return lv | |
140 | - | |
141 | - | |
142 | - def pluralAnalysis(self, word): | |
143 | - | |
144 | - if(word[-3:] == "OES" or word[-2:] == "AES" or word[-2:] == "AOS"): | |
145 | - return word[0:-3]+"AO" | |
146 | - elif(word[-3:] == "RES" or word[-2:] == "ZES" or word[-2:] == "NES"): | |
147 | - return word[0:-2] | |
148 | - elif(word[-3:] == "SES"): | |
149 | - #TODO: Algumas palavras possuem marcações gráficas na raiz singular. Ex: Gás – Gases | |
150 | - return word[0:-2] | |
151 | - elif(word[-2:] == "NS"): | |
152 | - return word[0:-2]+"M" | |
153 | - elif(word[-3:] == "EIS"): | |
154 | - return word[0:-3]+"IL" | |
155 | - elif(word[-2:] == "IS"): | |
156 | - if(word[-3] == "A" or word[-3] == "E" or word[-3] == "O" or word[-3] == "U"): | |
157 | - return word[0:-2]+"L" | |
158 | - else: | |
159 | - return word | |
160 | - elif(word[-1] == "S"): | |
161 | - #TODO: Palavras paroxítonas ou proparoxítonas terminadas em S. Ex: lápis, vírus, tênis, ônibus, etc | |
162 | - return word[0:-1] | |
163 | - else: | |
164 | - return word | |
165 | 0 | \ No newline at end of file |
src/StringAux.py
... | ... | @@ -1,83 +0,0 @@ |
1 | -#!/usr/bin/python | |
2 | -# -*- coding: utf-8 -*- | |
3 | - | |
4 | -from unicodedata import normalize | |
5 | - | |
6 | -ext = {1:"um", 2:"dois", 3:"três", 4:"quatro", 5:"cinco", 6:"seis", 7:"sete", 8:"oito", 9:"nove", 0:"zero"} | |
7 | - | |
8 | -def extenso(n): | |
9 | - strn = str(n) | |
10 | - sizen = len(strn) | |
11 | - tokens = [] | |
12 | - for i in range (0, sizen): | |
13 | - x = int(strn[i]) | |
14 | - tokens.append(ext[x]) | |
15 | - return ' '.join(tokens) | |
16 | - | |
17 | -""" | |
18 | -def extenso(n): | |
19 | - strn = str(n) | |
20 | - sizen = len(strn) | |
21 | - tokens = [] | |
22 | - for i in range (0, sizen): | |
23 | - tokens.append(strn[i]) | |
24 | - return ' '.join(tokens) | |
25 | -""" | |
26 | - | |
27 | -def remover_acentos(txt): | |
28 | - | |
29 | - """ Devolve cópia de uma str substituindo os caracteres | |
30 | - acentuados pelos seus equivalentes não acentuados. | |
31 | - | |
32 | - ATENÇÃO: carateres gráficos não ASCII e não alfa-numéricos, | |
33 | - tais como bullets, travessões, aspas assimétricas, etc. | |
34 | - são simplesmente removidos! | |
35 | - | |
36 | - >>> remover_acentos('[ACENTUAÇÃO] ç: áàãâä! éèêë? íìĩîï, óòõôö; úùũûü.') | |
37 | - '[ACENTUACAO] c: aaaaa! eeee? iiiii, ooooo; uuuuu.' | |
38 | - | |
39 | - """ | |
40 | - try: | |
41 | - return normalize('NFKD', txt.decode('utf-8')).encode('ASCII','ignore') | |
42 | - except: | |
43 | - return normalize('NFKD', txt.decode('iso-8859-1')).encode('ASCII','ignore') | |
44 | - | |
45 | - | |
46 | -def roman_to_int(input): | |
47 | - if not isinstance(input, type("")): | |
48 | - raise TypeError, "expected string, got %s" % type(input) | |
49 | - input = input.upper( ) | |
50 | - nums = {'M':1000, | |
51 | - 'D':500, | |
52 | - 'C':100, | |
53 | - 'L':50, | |
54 | - 'X':10, | |
55 | - 'V':5, | |
56 | - 'I':1} | |
57 | - sum = 0 | |
58 | - for i in range(len(input)): | |
59 | - try: | |
60 | - value = nums[input[i]] | |
61 | - if i+1 < len(input) and nums[input[i+1]] > value: | |
62 | - sum -= value | |
63 | - else: sum += value | |
64 | - except KeyError: | |
65 | - raise ValueError, 'input is not a valid Roman numeral: %s' % input | |
66 | - | |
67 | - if int_to_roman(sum) == input: return sum | |
68 | - else: raise ValueError, 'input is not a valid Roman numeral: %s' % input | |
69 | - | |
70 | -def int_to_roman(input): | |
71 | - if not isinstance(input, type(1)): | |
72 | - raise TypeError, "expected integer, got %s" % type(input) | |
73 | - if not 0 < input < 4000: | |
74 | - raise ValueError, "Argument must be between 1 and 3999" | |
75 | - ints = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1) | |
76 | - nums = ('M', 'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I') | |
77 | - result = [] | |
78 | - | |
79 | - for i in range(len(ints)): | |
80 | - count = int(input / ints[i]) | |
81 | - result.append(nums[i] * count) | |
82 | - input -= ints[i] * count | |
83 | - return ''.join(result) | |
84 | 0 | \ No newline at end of file |
src/Tradutor.py
... | ... | @@ -1,38 +0,0 @@ |
1 | -#!/usr/bin/python | |
2 | -# -*- coding: utf-8 -*- | |
3 | - | |
4 | -#Autor: Erickson Silva <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | |
5 | - | |
6 | -from Classificador import * | |
7 | -from Simplificador import * | |
8 | -#from AplicadorRegras import * | |
9 | -from Output import * | |
10 | -from StringAux import * | |
11 | - | |
12 | - | |
13 | -class Tradutor(object): | |
14 | - | |
15 | - def __init__(self): | |
16 | - #instanciando os objetos | |
17 | - self.__classificador = Classificador() | |
18 | - self.__simplificador = Simplificador() | |
19 | - #self.__regras = AplicadorRegras() | |
20 | - self.__out = Output() | |
21 | - | |
22 | - | |
23 | - def traduzir(self, txt): | |
24 | - self.__tr = None | |
25 | - | |
26 | - #faz a tokenizacao e a classificacao | |
27 | - self.__t = self.__classificador.anotaSentencas(txt) | |
28 | - | |
29 | - #retira artigos e preposicoes | |
30 | - self.__ts = self.__simplificador.simplificar(self.__t) | |
31 | - self.__t = None | |
32 | - | |
33 | - #aplica as regras | |
34 | - #self.__tr = self.__regras.aplicarRegras(self.__ts) | |
35 | - #self.__ts = None | |
36 | - | |
37 | - #executa a saida | |
38 | - return self.__out.executeOut(self.__ts).encode("utf-8") |
... | ... | @@ -0,0 +1,52 @@ |
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 | +from threading import Thread | |
10 | +import alexp | |
11 | +from AplicaSinonimos import * | |
12 | +from AplicaRegras import * | |
13 | +import logging | |
14 | + | |
15 | +class TraduzSentencas(Thread): | |
16 | + | |
17 | + def __init__(self, sentenca): | |
18 | + Thread.__init__(self) | |
19 | + self.sentenca = sentenca | |
20 | + self.glosa = "" | |
21 | + self.aplic_sinonimos = AplicaSinonimos() | |
22 | + self.aplic_regras = AplicaRegras() | |
23 | + logging.basicConfig(filename='translate.log', | |
24 | + format='%(asctime)s - %(levelname)s:\n%(message)s\n\n\n##############################################\n\n', | |
25 | + level=logging.ERROR) | |
26 | + | |
27 | + | |
28 | + def run(self): | |
29 | + try: | |
30 | + analise_sintatica = alexp.run(self.sentenca) | |
31 | + except Exception as ex: | |
32 | + self.salvar_log(str(ex)) | |
33 | + analise_sintatica = None | |
34 | + | |
35 | + analise_morfologica = alexp.getAnaliseMorfologica() | |
36 | + | |
37 | + if (isinstance(analise_sintatica,type(None))): | |
38 | + print "# ANÁLISE MORFOLÓGICA" | |
39 | + regras_aplicadas = self.aplic_regras.aplicar_regras_morfo(analise_morfologica) | |
40 | + else: | |
41 | + print "# ANÁLISE SINTÁTICA" | |
42 | + regras_aplicadas = self.aplic_regras.aplicar_regras_sint(analise_morfologica, analise_sintatica) | |
43 | + | |
44 | + sentenca_corrigida = self.aplic_regras.simplificar_sentenca(regras_aplicadas) | |
45 | + sinonimos_aplicados = self.aplic_sinonimos.aplicar_sinonimos(sentenca_corrigida) | |
46 | + self.glosa = sinonimos_aplicados.upper().encode('utf-8') | |
47 | + | |
48 | + def obter_glosa(self): | |
49 | + return self.glosa | |
50 | + | |
51 | + def salvar_log(self, erro): | |
52 | + logging.error(erro) | |
0 | 53 | \ No newline at end of file | ... | ... |
src/WorkCSV.py
... | ... | @@ -1,115 +0,0 @@ |
1 | -#!/usr/bin/python | |
2 | -# -*- coding: utf-8 -*- | |
3 | - | |
4 | -#Autor: Erickson Silva <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | |
5 | - | |
6 | -import csv, platform | |
7 | -from os.path import expanduser | |
8 | - | |
9 | -class WorkCSV(object): | |
10 | - | |
11 | - # Define e inicializa os atributos | |
12 | - def __init__(self): | |
13 | - | |
14 | - so = platform.system() | |
15 | - if so == 'Windows': | |
16 | - self.__path = expanduser("~") + "\\vlibras-translate\data\\" | |
17 | - else: | |
18 | - self.__path = expanduser("~") + "/vlibras-translate/data/" | |
19 | - | |
20 | - self.__fileInf = '' | |
21 | - self.__dicInf = {} | |
22 | - self.__fileSin = '' | |
23 | - self.__dicSin = {} | |
24 | - self.__fileWords = '' | |
25 | - self.__dicWords = {} | |
26 | - self.__file2Gen = '' | |
27 | - self.__dic2Gen = {} | |
28 | - self.__fileTemVerbs = '' | |
29 | - self.__dicTemVerbs = {} | |
30 | - self.createDicInf() | |
31 | - self.createDicSin() | |
32 | - self.createDicWords() | |
33 | - self.createDic2Gen() | |
34 | - self.createDicTemVerbs() | |
35 | - | |
36 | - # Abre o arquivo que contem os verbos no infinitivo e preenche o dicionario com os mesmos | |
37 | - def createDicInf(self): | |
38 | - try: | |
39 | - self.__fileInf = csv.reader(open(self.__path+"dicPortGlosa.csv"), delimiter=";") | |
40 | - except IOError, (errno, strerror): | |
41 | - print "I/O error(%s): %s" % (errno, strerror) | |
42 | - print "createDicInf" | |
43 | - | |
44 | - for row in self.__fileInf: | |
45 | - if row[1] != "": | |
46 | - try: | |
47 | - self.__dicInf[row[0].decode("utf-8")] = row[1].decode("utf-8") | |
48 | - except UnicodeDecodeError: | |
49 | - self.__dicInf[row[0].decode('iso8859-1').encode('utf-8')] = row[1].decode('iso8859-1').encode('utf-8') | |
50 | - | |
51 | - # Abre o arquivo que contem os sinonimos e preenche o dicionario com os mesmos | |
52 | - def createDicSin(self): | |
53 | - try: | |
54 | - self.__fileSin = csv.reader(open(self.__path+"portuguesGlosa.csv"), delimiter=";") | |
55 | - except IOError, (errno, strerror): | |
56 | - print "I/O error(%s): %s" % (errno, strerror) | |
57 | - print "createDicSin" | |
58 | - | |
59 | - for row in self.__fileSin: | |
60 | - if row[1] != "": | |
61 | - self.__dicSin[row[0].decode("utf-8")] = row[1].decode("utf-8") | |
62 | - | |
63 | - | |
64 | - # Abre o arquivo que contem os tempos verbais | |
65 | - def createDicTemVerbs(self): | |
66 | - try: | |
67 | - self.__fileTemVerbs = csv.reader(open(self.__path+"temposVerbais.csv"), delimiter=";") | |
68 | - except IOError, (errno, strerror): | |
69 | - print "I/O error(%s): %s" % (errno, strerror) | |
70 | - print "createDicTemVerbs" | |
71 | - | |
72 | - for row in self.__fileTemVerbs: | |
73 | - self.__dicTemVerbs[row[0].decode("utf-8")] = row[0].decode("utf-8") | |
74 | - | |
75 | - # Abre o arquivo que contem os artigos e preposicoes de acordo com o modelo de idioma passado na chamada e preenche o dicionario com os mesmos | |
76 | - def createDicWords(self): | |
77 | - try: | |
78 | - self.__fileWords = csv.reader(open(self.__path+"hWordsRemove.csv"), delimiter=";") | |
79 | - except IOError, (errno, strerror): | |
80 | - print "I/O error(%s): %s" % (errno, strerror) | |
81 | - print "createDicWords" | |
82 | - | |
83 | - for row in self.__fileWords: | |
84 | - self.__dicWords[row[0].decode("utf-8")] = row[0].decode("utf-8") | |
85 | - | |
86 | - # Abre o arquivo que contem os substantivos que sao comuns dos 2 generos e preenche o dicionario com os mesmos | |
87 | - def createDic2Gen(self): | |
88 | - try: | |
89 | - self.__file2Gen = csv.reader(open(self.__path+"subs2Generos.csv"), delimiter=";") | |
90 | - except IOError, (errno, strerror): | |
91 | - print "I/O error(%s): %s" % (errno, strerror) | |
92 | - print "createDic2Gen" | |
93 | - | |
94 | - for row in self.__file2Gen: | |
95 | - self.__dic2Gen[row[0].decode("utf-8")] = row[0].decode("utf-8") | |
96 | - | |
97 | - # Retorna o dicionario dos verbos no infinitivo | |
98 | - def getDicInf(self): | |
99 | - return self.__dicInf | |
100 | - | |
101 | - # Retorna o dicionario dos sinonimos | |
102 | - def getDicSin(self): | |
103 | - return self.__dicSin | |
104 | - | |
105 | - # Retorna o dicionario dos artigos e preposicoes a serem removidos pelo simplificador | |
106 | - def getDicWords(self): | |
107 | - return self.__dicWords | |
108 | - | |
109 | - # Retorna o dicionario dos substantivos a serem analisados pelo simplificador | |
110 | - def getDic2Gen(self): | |
111 | - return self.__dic2Gen | |
112 | - | |
113 | - # Retorna o dicionario dos tempos verbais | |
114 | - def getDicTemVerbs(self): | |
115 | - return self.__dicTemVerbs | |
116 | 0 | \ No newline at end of file |
... | ... | @@ -0,0 +1,135 @@ |
1 | +#! /usr/bin/env python2.6 | |
2 | +# -*- coding: utf-8 -*- | |
3 | + | |
4 | +#--------------------------------- | |
5 | + | |
6 | +# Editado: | |
7 | + | |
8 | +#Autor: Erickson Silva | |
9 | +#Email: <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | |
10 | + | |
11 | +#LAViD - Laboratório de Aplicações de Vídeo Digital | |
12 | + | |
13 | +#--------------------------------- | |
14 | + | |
15 | + | |
16 | +# Donatus Brazilian Portuguese Parser | |
17 | +# | |
18 | +# Copyright (C) 2010-2013 Leonel F. de Alencar | |
19 | +# | |
20 | +# Author: Leonel F. de Alencar <leonel.de.alencar@ufc.br> | |
21 | +# Homepage: <http://www.leonel.profusehost.net/> | |
22 | +# | |
23 | +# Project's URL: <http://sourceforge.net/projects/donatus/> | |
24 | +# For license information, see LICENSE.TXT | |
25 | +# | |
26 | +# $Id: alexp.py $ | |
27 | + | |
28 | +"""Este módulo contém funções que permitem utilizar o Aelius para etiquetar uma sentença, construindo entradas lexicais com base nas etiquetas atribuídas às palavras da sentença. Essas entradas lexicais são integradas em uma gramática CFG dada, que é transformada em um parser, utilizado para gerar uma árvore de estrutura sintagmática da sentença. | |
29 | +""" | |
30 | +import re,nltk,platform, time, random | |
31 | +from os.path import expanduser | |
32 | +from os import environ | |
33 | +from Aelius.Extras import carrega | |
34 | +from Aelius import AnotaCorpus | |
35 | +from unicodedata import normalize | |
36 | + | |
37 | + | |
38 | +sentenca_anotada="" | |
39 | +sleep_times=[0.1,0.2] | |
40 | + | |
41 | +def toqueniza(s): | |
42 | + """Decodifica string utilizando utf-8, retornando uma lista de tokens em unicode. | |
43 | + """ | |
44 | + decodificada=s.decode("utf-8") | |
45 | + return AnotaCorpus.TOK_PORT.tokenize(decodificada) | |
46 | + | |
47 | +def getAnaliseMorfologica(): | |
48 | + return sentenca_anotada | |
49 | + #return [list(x) for x in sentenca_anotada] | |
50 | + | |
51 | +def etiquetaSentenca(s): | |
52 | + """Aplica um dos etiquetadores do Aelius na etiquetagem da sentença dada como lista de tokens. | |
53 | + """ | |
54 | + etiquetador = carrega("AeliusHunPos") | |
55 | + anotada = AnotaCorpus.anota_sentencas([s],etiquetador,"hunpos")[0] | |
56 | + while (anotada[0][1] is None): | |
57 | + time.sleep(random.choice(sleep_times)) | |
58 | + anotada = AnotaCorpus.anota_sentencas([s],etiquetador,"hunpos")[0] | |
59 | + #anotada[0] = (anotada[0][0].lower(), anotada[0][1]) | |
60 | + #return anotada | |
61 | + return [[x[0].lower(),x[1]] for x in anotada] | |
62 | + | |
63 | +def geraEntradasLexicais(lista): | |
64 | + """Gera entradas lexicais no formato CFG do NLTK a partir de lista de pares constituídos de tokens e suas etiquetas. | |
65 | + """ | |
66 | + entradas=[] | |
67 | + for e in lista: | |
68 | + # é necessário substituir símbolos como "-" e "+" do CHPTB | |
69 | + # que não são aceitos pelo NLTK como símbolos não terminais | |
70 | + c=re.sub(r"[-+]","_",e[1]) | |
71 | + c=re.sub(r"\$","_S",c) | |
72 | + entradas.append("%s -> '%s'" % (c, removeAcento(e[0]))) | |
73 | + return entradas | |
74 | + | |
75 | +def corrigeAnotacao(lista): | |
76 | + """Esta função deverá corrigir alguns dos erros de anotação mais comuns do Aelius. No momento, apenas é corrigida VB-AN depois de TR. | |
77 | + """ | |
78 | + i=1 | |
79 | + while i < len(lista): | |
80 | + if lista[i][1] == "VB-AN" and lista[i-1][1].startswith("TR"): | |
81 | + lista[i]=(lista[i][0],"VB-PP") | |
82 | + i+=1 | |
83 | + | |
84 | +def encontraArquivo(): | |
85 | + """Encontra arquivo na pasta vlibras-translate. | |
86 | + """ | |
87 | + so = platform.system() | |
88 | + if so == 'Windows': | |
89 | + return os.environ.get("HOMEDRIVE") + "\\vlibras-libs\\vlibras-translate\data\cfg.syn.nltk" | |
90 | + else: | |
91 | + return expanduser("~") + "/vlibras-translate/data/cfg.syn.nltk" | |
92 | + | |
93 | +def extraiSintaxe(): | |
94 | + """Extrai gramática armazenada em arquivo cujo caminho é definido relativamente ao diretório nltk_data. | |
95 | + """ | |
96 | + arquivo=encontraArquivo() | |
97 | + if arquivo: | |
98 | + f=open(arquivo,"rU") | |
99 | + sintaxe=f.read() | |
100 | + f.close() | |
101 | + return sintaxe | |
102 | + else: | |
103 | + print "Arquivo %s não encontrado em nenhum dos diretórios de dados do NLTK:\n%s" % (caminho,"\n".join(nltk.data.path)) | |
104 | + | |
105 | +def analisaSentenca(sentenca): | |
106 | + """Retorna lista de árvores de estrutura sintagmática para a sentença dada sob a forma de uma lista de tokens, com base na gramática CFG cujo caminho é especificado como segundo argumento da função. Esse caminho é relativo à pasta nltk_data da instalação local do NLTK. A partir da etiquetagem morfossintática da sentença são geradas entradas lexicais que passam a integrar a gramática CFG. O caminho da gramática e o parser gerado são armazenados como tupla na variável ANALISADORES. | |
107 | + """ | |
108 | + parser=constroiAnalisador(sentenca) | |
109 | + codificada=[removeAcento(w).encode("utf-8") for w in sentenca] | |
110 | + trees=parser.parse_one(codificada) | |
111 | + return trees | |
112 | + | |
113 | +def constroiAnalisador(s): | |
114 | + """Constrói analisador a partir de uma única sentença não anotada, dada como lista de tokens, e uma lista de regras sintáticas no formato CFG, armazenadas em arquivo. Esta função tem um bug, causado pela maneira como o Aelius etiqueta sentenças usando o módulo ProcessaNomesProprios: quando a sentença se inicia por paravra com inicial minúscula, essa palavra não é incorporada ao léxico, mas a versão com inicial maiúscula. | |
115 | + """ | |
116 | + global sentenca_anotada | |
117 | + sentenca_anotada=etiquetaSentenca(s) | |
118 | + corrigeAnotacao(sentenca_anotada) | |
119 | + entradas=geraEntradasLexicais(sentenca_anotada) | |
120 | + lexico="\n".join(entradas) | |
121 | + gramatica="%s\n%s" % (extraiSintaxe().strip(),lexico) | |
122 | + cfg=nltk.CFG.fromstring(gramatica) | |
123 | + return nltk.ChartParser(cfg) | |
124 | + | |
125 | +def removeAcento(texto): | |
126 | + return normalize('NFKD', texto.encode('utf-8').decode('utf-8')).encode('ascii', 'ignore') | |
127 | + | |
128 | +def exibeArvores(arvores): | |
129 | + """Função 'wrapper' para a função de exibição de árvores do NLTK""" | |
130 | + nltk.draw.draw_trees(*arvores) | |
131 | + | |
132 | +def run(sentenca): | |
133 | + tokens=toqueniza(sentenca) | |
134 | + tree=analisaSentenca(tokens) | |
135 | + return tree | |
0 | 136 | \ No newline at end of file | ... | ... |
src/new/AplicaRegras.py
... | ... | @@ -1,446 +0,0 @@ |
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 re | |
11 | -import xml.etree.ElementTree as ET | |
12 | -from os.path import expanduser | |
13 | -from collections import deque | |
14 | -from LerDicionarios import * | |
15 | -from Iterator import * | |
16 | -from StringAux import * | |
17 | -from ConverteExtenso import * | |
18 | -from nltk_tgrep import tgrep_positions, tgrep_nodes | |
19 | -from nltk import ParentedTree, Tree, draw | |
20 | - | |
21 | -class AplicaRegras(object): | |
22 | - | |
23 | - def __init__(self): | |
24 | - self.__root = self.get_root() | |
25 | - self.dicionarios = LerDicionarios() | |
26 | - # Dicionário de funcões do campo specific do arquivo de regras | |
27 | - self.__especificos = {"advt":self.verificar_adv_tempo, "v":self.verificar_vb_infinitivo, "x":self.verificar_preposicao, | |
28 | - "c":self.verificar_subst_genero, "a":self.verificar_artigo, "l":self.verificar_vb_ligacao, | |
29 | - "i":self.verificar_adv_intensidade, "vbi":"zero", "n":self.verificar_vb_muda_negacao, "abmn":"zero", | |
30 | - "adji":"zero","adjn":"zero", "advi":"zero"} | |
31 | - | |
32 | - self.__acoes = {"change_vb":self.get_vb_infinitivo, "concate_intens":self.get_token_intensidade} | |
33 | - | |
34 | - # Gera arvore a partir do arquivos regras.xml | |
35 | - def get_root(self): | |
36 | - if platform.system() == 'Windows': | |
37 | - return ET.parse(expanduser("~")+'\\vlibras-translate\data\\regras.xml').getroot() | |
38 | - return ET.parse(expanduser("~")+'/vlibras-translate/data/regras.xml').getroot() | |
39 | - | |
40 | - # Aplica regras morfológicas apartir do arquivo regras.xml | |
41 | - def aplicar_regras_morfo(self, lista, sint=False): | |
42 | - self.lista = list(lista) # Nova cópia da lista morfológica | |
43 | - self.lista_corrigida =[] # Lista morfológica após a aplicação das regras | |
44 | - | |
45 | - it = Iterator() | |
46 | - it.load(self.lista) | |
47 | - | |
48 | - while(it.has_next()): | |
49 | - for morpho in self.__root.findall('morphological'): | |
50 | - self.has_rule = False # Boolean caso encontre encontre regra compativel | |
51 | - for rule in morpho.findall('rule'): | |
52 | - # Verifica se a regra está ativa e se o nome da regra, ou o ínicio, é igual a tag de classificação do token atual | |
53 | - if rule.find('active').text == "true" and rule.get('name').split("_")[0] == it.get_ticket(): | |
54 | - count = int(rule.find('count').text) | |
55 | - self.lista_iteracoes = [] # Lista que conterá todas tuplas referentes a quantidade de classes da regra | |
56 | - | |
57 | - # Obtém o intervalo de tuplas de acordo com o número de classes da regra | |
58 | - try: | |
59 | - self.lista_iteracoes = it.get_interval(count) | |
60 | - print '# LISTA DA ITERAÇÂO: ' | |
61 | - print self.lista_iteracoes | |
62 | - except: | |
63 | - continue | |
64 | - | |
65 | - # Gera o nome da regra do intervalo de tuplas e verifica se é igual ao nome da regra em si | |
66 | - self.nome_regra = self.gerar_nome_regra(self.lista_iteracoes) | |
67 | - if rule.get('name') == self.nome_regra: | |
68 | - self.has_rule = True | |
69 | - self.count_iteracao_regra = -1 | |
70 | - | |
71 | - print "REGRA MORFOLÓGICA ENCONTRADA: " + rule.get('name') | |
72 | - | |
73 | - self.lista_iteracao_regra = [] # Lista temporária | Insere tokens após a aplicação das regras | |
74 | - | |
75 | - for classe in rule.iter('class'): # for nas tags class | |
76 | - action = classe.find('action') | |
77 | - newprop = classe.find('newprop') | |
78 | - newtoken = classe.find('newtoken') | |
79 | - newtokenpos = classe.find('newtokenpos') | |
80 | - specific = classe.find('specific') | |
81 | - | |
82 | - self.count_iteracao_regra += 1 | |
83 | - tupla = self.lista_iteracoes[self.count_iteracao_regra] | |
84 | - | |
85 | - if specific is not None: | |
86 | - result_specific = self.__especificos[specific.text](tupla[0]) | |
87 | - if result_specific is False: | |
88 | - print "REGRA MORFOLÓGICA " + rule.get('name') + " INVÁLIDA. PROCURANDO OUTRA..." | |
89 | - self.has_rule = False | |
90 | - break | |
91 | - | |
92 | - if action is not None: | |
93 | - action_text = action.text | |
94 | - if action_text == "remove": | |
95 | - self.lista_iteracao_regra.append(None) | |
96 | - continue | |
97 | - elif action_text == "invert": | |
98 | - self.lista_iteracao_regra.reverse() | |
99 | - elif self.__acoes.has_key(action_text): | |
100 | - result_action = self.__acoes[action_text](tupla[0]).lower() | |
101 | - self.lista_iteracao_regra.append([result_action, tupla[1]]) | |
102 | - else: | |
103 | - self.lista_iteracao_regra.append(tupla) | |
104 | - | |
105 | - if newprop is not None: | |
106 | - self.lista_iteracao_regra[self.count_iteracao_regra][1] = newprop.text | |
107 | - | |
108 | - if newtoken is not None: | |
109 | - if newtokenpos.text == "next": | |
110 | - self.lista_iteracao_regra.append([newtoken.text.lower(), "NTK"]) | |
111 | - elif newtokenpos.text == "previous": | |
112 | - self.lista_iteracao_regra.append(self.lista_iteracao_regra[-1]) | |
113 | - self.lista_iteracao_regra[-2] = [newtoken.text.lower(), "NTK"] | |
114 | - elif newtokenpos.text == "end": | |
115 | - print "TODO" | |
116 | - | |
117 | - if self.has_rule: | |
118 | - it.skip(count-1) | |
119 | - self.lista_corrigida.extend(self.lista_iteracao_regra) | |
120 | - break | |
121 | - | |
122 | - if self.has_rule is False: | |
123 | - print 'NÃO ACHOU REGRA - ' + it.get_word().encode('utf-8') | |
124 | - self.lista_corrigida.append(it.get_token()) #se nao achou regra, entao adiciona a tupla original | |
125 | - if sint: | |
126 | - return self.lista_corrigida | |
127 | - return filter(None, self.lista_corrigida) | |
128 | - | |
129 | - | |
130 | - def aplicar_regras_sint(self, lista, arvore): | |
131 | - p_arvore = ParentedTree.convert(arvore) | |
132 | - self.adaptar_regras_morfo_arvore(lista, p_arvore) | |
133 | - for morpho in self.__root.findall('syntactic'): | |
134 | - for rule in morpho.findall('rule'): # procura a tag rule | |
135 | - nome_regra = self.corrigir_nome_regra(rule.get('name')) | |
136 | - regra = self.separar_regra(nome_regra) | |
137 | - node_pai = tgrep_nodes(p_arvore, regra[0], search_leaves=False) | |
138 | - if node_pai and rule.find('active').text == "true": | |
139 | - node_pai = node_pai[0] | |
140 | - node_regra = tgrep_nodes(node_pai, regra[1].replace('$', '..'), search_leaves=False) | |
141 | - if node_regra: | |
142 | - node_esq_pos = tgrep_positions(node_pai, regra[1], search_leaves=False) | |
143 | - node_dir_pos = tgrep_positions(node_pai, regra[2], search_leaves=False) | |
144 | - if node_esq_pos and node_dir_pos: | |
145 | - print "REGRA SINTÁTICA ENCONTRADA: " + rule.get('name') | |
146 | - nodes_positions = node_esq_pos + node_dir_pos | |
147 | - self.count = -1 | |
148 | - self.has_rule = True | |
149 | - | |
150 | - count_temp = -1 | |
151 | - for classe in rule.findall('class'): | |
152 | - count_temp += 1 | |
153 | - leaves = node_pai[nodes_positions[count_temp]].leaves() | |
154 | - token = filter(None, leaves)[0] | |
155 | - specific = classe.find('specific') | |
156 | - if specific is not None: | |
157 | - result_specific = self.__especificos[specific.text](token) | |
158 | - if result_specific is False: | |
159 | - self.has_rule = False | |
160 | - | |
161 | - if self.has_rule is False: | |
162 | - print "REGRA SINTÁTICA " + rule.get('name') + " INVÁLIDA. PROCURANDO OUTRA..." | |
163 | - break | |
164 | - | |
165 | - nodes_deleted = [] | |
166 | - | |
167 | - for classe in rule.iter('class'): | |
168 | - action = classe.find('action') | |
169 | - newprop = classe.find('newprop') | |
170 | - | |
171 | - self.count += 1 | |
172 | - | |
173 | - if action is not None: | |
174 | - action_text = action.text | |
175 | - | |
176 | - if action_text == "remove": | |
177 | - pos_del = nodes_positions[self.count] | |
178 | - nodes_deleted.append(node_pai[pos_del]) | |
179 | - node_pai[pos_del] = None | |
180 | - continue | |
181 | - | |
182 | - elif action_text == "invert": | |
183 | - aux1 = node_pai[nodes_positions[self.count]] | |
184 | - aux2 = node_pai[nodes_positions[self.count+1]] | |
185 | - node_pai[nodes_positions[self.count]] = None | |
186 | - node_pai[nodes_positions[self.count+1]] = None | |
187 | - node_pai[nodes_positions[self.count]] = aux2 | |
188 | - node_pai[nodes_positions[self.count+1]] = aux1 | |
189 | - | |
190 | - ''' | |
191 | - elif self.__acoes.has_key(action_text): | |
192 | - leaves = node_pai[nodes_positions[self.count]].leaves() | |
193 | - token = filter(None, leaves)[0] | |
194 | - result_action = self.__acoes[action_text](token) | |
195 | - | |
196 | - #self.lista_iteracao_regra.append([result_action, tupla[1]]) | |
197 | - nodes_positions[self.count] = 'TODO' | |
198 | - | |
199 | - if action_text == "concate_intens": | |
200 | - leaves_prev = node_pai[nodes_positions[self.count-1]].leaves() | |
201 | - token_prev = filter(None, leaves_prev)[0] | |
202 | - title_text = classe.find('title').text | |
203 | - if title_text == "ADV-R": | |
204 | - node_prev = nodes_deleted.pop() | |
205 | - label_prev = node_prev[0][0].label() | |
206 | - token_prev = filter(None, node_pai[nodes_positions[count_temp-1]].leaves())[0] | |
207 | - token = filter(None, node_pai[nodes_positions[count_temp]].leaves())[0] | |
208 | - token_concate = token_prev + "_" + token | |
209 | - node_pai[nodes_positions[count_temp-1]][0][0][0] = token_concate | |
210 | - newprop = "" | |
211 | - if label_prev[:-2] == "VB": | |
212 | - newprop = "VBi" | |
213 | - elif label_prev[:-3] == "ADJ": | |
214 | - newprop = "ADJi" | |
215 | - | |
216 | - # TODO: Verifica qual newprop adicionada e remove o nó corrente | |
217 | - node_pai[nodes_positions[count_temp-1]][0][0].set_label(newprop) | |
218 | - pos_del = nodes_positions[self.count] | |
219 | - node_pai[pos_del] = None | |
220 | - | |
221 | - else: | |
222 | - token_prev = filter(None, nodes_deleted.pop().leaves())[0] | |
223 | - token = filter(None, node_pai[nodes_positions[count_temp]].leaves())[0] | |
224 | - token_concate = token + "_" + token_prev | |
225 | - node_pai[nodes_positions[count_temp]][0][0][0] = token_concate | |
226 | - | |
227 | - elif action_text == "concate_neg": | |
228 | - print "TODO" | |
229 | - ''' | |
230 | - | |
231 | - if newprop is not None: | |
232 | - node_pai[nodes_positions[self.count]].set_label(newprop.text) | |
233 | - | |
234 | - break | |
235 | - | |
236 | - return self.converter_arv_para_lista(p_arvore) | |
237 | - | |
238 | - | |
239 | - # Aplica regras morfológicas na árvore sintática | |
240 | - def adaptar_regras_morfo_arvore(self, lista, arvore): | |
241 | - lista_pos_arv = [] | |
242 | - # Pega as posições das classificações morfológicas dos tokens na arvore sintática | |
243 | - for tupla in lista: | |
244 | - string_grep = self.corrigir_nome_regra(tupla[1]) + " < " + tupla[0].lower() | |
245 | - node = tgrep_positions(arvore, string_grep) | |
246 | - if not node: | |
247 | - string_grep = self.corrigir_nome_regra(tupla[1]) + " < " + self.remover_acento(tupla[0].lower()) | |
248 | - node = tgrep_positions(arvore, string_grep) | |
249 | - if node[0] in lista_pos_arv: | |
250 | - node.reverse() | |
251 | - lista_pos_arv.append(node[0]) | |
252 | - | |
253 | - # Aplica regras morfológicas na lista | |
254 | - morfo = self.aplicar_regras_morfo(lista, sint=True) | |
255 | - | |
256 | - # Corrige arvore de acordo com a lista após aplicar as regras morfológicas | |
257 | - for i in range(0, len(morfo)): | |
258 | - if morfo[i] is not None and morfo[i][1] == "NTK": | |
259 | - new_node = self.gerar_no(morfo[i]) | |
260 | - arvore[lista_pos_arv[i-1][:-2]].insert(2, new_node) | |
261 | - try: | |
262 | - lista_pos_arv.insert(i,lista_pos_arv[i]) | |
263 | - except: | |
264 | - continue | |
265 | - | |
266 | - arv_ticket = arvore[lista_pos_arv[i]].label() | |
267 | - arv_token = arvore[lista_pos_arv[i]][0] | |
268 | - | |
269 | - if morfo[i] is None: | |
270 | - arvore[lista_pos_arv[i]] = None | |
271 | - | |
272 | - elif arv_token != morfo[i][0] and arv_ticket != morfo[i][1]: | |
273 | - arvore[lista_pos_arv[i]][0] = morfo[i][0] | |
274 | - arvore[lista_pos_arv[i]].set_label(morfo[i][1]) | |
275 | - | |
276 | - elif arv_token != morfo[i][0]: | |
277 | - arvore[lista_pos_arv[i]][0] = morfo[i][0] | |
278 | - | |
279 | - elif arv_ticket != morfo[i][1]: | |
280 | - arvore[lista_pos_arv[i]].set_label(morfo[i][1]) | |
281 | - | |
282 | - # Converte árvore sintática para uma lista de tuplas (igual a lista morfológica) | |
283 | - def converter_arv_para_lista(self, arvore): | |
284 | - folhas = filter(None, arvore.leaves()) | |
285 | - lista_nodes = [] | |
286 | - for folha in folhas: | |
287 | - pos = tgrep_positions(arvore, folha) | |
288 | - node = arvore[pos[0][:-1]] | |
289 | - #decode node[0] | |
290 | - lista_nodes.append([node[0], self.corrigir_nome_regra(node.label())]) | |
291 | - return lista_nodes | |
292 | - | |
293 | - def remover_acento(self, texto): | |
294 | - return normalize('NFKD', texto.encode('utf-8').decode('utf-8')).encode('ascii', 'ignore') | |
295 | - | |
296 | - # Gera um ParentedTree do NLTK apartir da string recebida | |
297 | - def gerar_no(self, s): | |
298 | - all_ptrees = [] | |
299 | - t_string = '('+s[1] + ' ' + s[0]+')' | |
300 | - ptree = ParentedTree.convert(Tree.fromstring(t_string)) | |
301 | - all_ptrees.extend(t for t in ptree.subtrees() | |
302 | - if isinstance(t, Tree)) | |
303 | - return ptree | |
304 | - | |
305 | - # Corrige nome da regra descrita no arquivo de regras para como está na árvore sintática | |
306 | - def corrigir_nome_regra(self, anotacao): | |
307 | - split = anotacao.split('_') | |
308 | - for i in range(0, len(split)): | |
309 | - split[i] = re.sub(r"[-+]","_", split[i]) | |
310 | - split[i] = re.sub(r"\$","_S",split[i]) | |
311 | - return "-".join(split).encode('utf-8') | |
312 | - | |
313 | - # Separa a regra por nó pai e seus filhos | |
314 | - def separar_regra(self, regra): | |
315 | - split = regra.split("(") | |
316 | - split[1] = split[1].replace(")","").split("-") | |
317 | - rev = list(split[1]) | |
318 | - rev.reverse() | |
319 | - split.append(rev) | |
320 | - split[1] = ' $ '.join(split[1]) | |
321 | - split[2] = ' $ '.join(split[2]) | |
322 | - return split | |
323 | - | |
324 | - # Gera nome de regra apartir de uma lista | |
325 | - def gerar_nome_regra(self, lista): | |
326 | - nome_regra = [] | |
327 | - for t in lista: | |
328 | - nome_regra.append(t[1]) | |
329 | - return "_".join(nome_regra) | |
330 | - | |
331 | - def verificar_adv_tempo(self, token): | |
332 | - for tupla in self.lista: | |
333 | - if self.dicionarios.has_adverbio_tempo(tupla[0]): | |
334 | - return True | |
335 | - return False | |
336 | - | |
337 | - def verificar_excecao_plural(self, token): | |
338 | - return self.dicionarios.has_excecao_plural(token) | |
339 | - | |
340 | - def verificar_vb_infinitivo(self, token): | |
341 | - return self.dicionarios.has_verbo_infinitivo(token) | |
342 | - | |
343 | - def verificar_preposicao(self, token): | |
344 | - return self.dicionarios.has_preposicao(token) | |
345 | - | |
346 | - def verificar_subst_genero(self, token): | |
347 | - return self.dicionarios.has_subst_2_generos(token) | |
348 | - | |
349 | - def verificar_artigo(self, token): | |
350 | - return self.dicionarios.has_artigo(token) | |
351 | - | |
352 | - def verificar_vb_ligacao(self, token): | |
353 | - return self.dicionarios.has_verbo_ligacao(token) | |
354 | - | |
355 | - def verificar_adv_intensidade(self, token): | |
356 | - return self.dicionarios.has_adverbio_intensidade(token) | |
357 | - | |
358 | - def verificar_vb_muda_negacao(self, token): | |
359 | - return self.dicionarios.has_verbo_muda_negacao(token) | |
360 | - | |
361 | - def get_vb_infinitivo(self, token): | |
362 | - if self.dicionarios.has_verbo_infinitivo(token): | |
363 | - return self.dicionarios.get_verbo_infinitivo(token) | |
364 | - return token | |
365 | - | |
366 | - def get_token_intensidade(self, token): | |
367 | - print 'TODO' | |
368 | - | |
369 | - | |
370 | - # Simplifica a sentença para que possa evitar a ditalogia | |
371 | - def simplificar_sentenca(self, lista): | |
372 | - lista_simplificada = list(lista) | |
373 | - it = Iterator() | |
374 | - it.load(lista_simplificada) | |
375 | - num = False | |
376 | - while(it.has_next()): | |
377 | - tag = it.get_ticket() | |
378 | - | |
379 | - if tag == "NUM": | |
380 | - num = True | |
381 | - | |
382 | - if tag[-2:] == "-P" and self.verificar_excecao_plural(it.get_word()): | |
383 | - singular = self.analisar_plural(it.get_word()) | |
384 | - lista_simplificada[it.get_count()][0] = singular | |
385 | - | |
386 | - if num: | |
387 | - return self.converter_extenso(lista_simplificada) | |
388 | - return lista_simplificada | |
389 | - | |
390 | - # Alterar uma palavra do plural para o singular | |
391 | - def analisar_plural(self, token): | |
392 | - if(token[-3:] == "OES" or token[-2:] == "AES" or token[-2:] == "AOS"): | |
393 | - return token[0:-3]+"AO" | |
394 | - elif(token[-3:] == "RES" or token[-2:] == "ZES" or token[-2:] == "NES"): | |
395 | - return token[0:-2] | |
396 | - elif(token[-3:] == "SES"): | |
397 | - #TODO: Algumas palavras possuem marcações gráficas na raiz singular. Ex: Gás – Gases | |
398 | - return token[0:-2] | |
399 | - elif(token[-2:] == "NS"): | |
400 | - return token[0:-2]+"M" | |
401 | - elif(token[-3:] == "EIS"): | |
402 | - return token[0:-3]+"IL" | |
403 | - elif(token[-2:] == "IS"): | |
404 | - if(token[-3] == "A" or token[-3] == "E" or token[-3] == "O" or token[-3] == "U"): | |
405 | - return token[0:-2]+"L" | |
406 | - return token | |
407 | - elif(token[-1] == "S"): | |
408 | - #TODO: Palavras paroxítonas ou proparoxítonas terminadas em S. Ex: lápis, vírus, tagênis, ônibus, etc | |
409 | - return token[0:-1] | |
410 | - else: | |
411 | - return token | |
412 | - | |
413 | - # Converter número por extenso para numeral | |
414 | - def converter_extenso(self, lista): | |
415 | - lista_extensos = [] | |
416 | - indices_deletar = [] | |
417 | - count = 0 | |
418 | - is_sequence = False | |
419 | - | |
420 | - for i in range(0, len(lista)): | |
421 | - token = lista[i][0] | |
422 | - tag = lista[i][1] | |
423 | - if tag == "NUM": | |
424 | - # Verifico se não há sequência de obtenção de extenso em andamento para começar a obter um nova sequência | |
425 | - if (is_sequence is False): # and len(lista_extensos) == count (???) | |
426 | - lista_extensos.append([i,[token]]) # i = Posição do primeiro extenso encontrado, token = número por extenso | |
427 | - is_sequence = True | |
428 | - else: | |
429 | - lista_extensos[count][1].append(token) # Pego número por extenso que está na sequência e adiciona na lista | |
430 | - indices_deletar.append(i) # Insiro indice na lista para ser removido depois | |
431 | - elif (is_sequence): | |
432 | - # Se o token anterior e o próximo foram classificados como número, e o token atual como conjunção, significa que podemos remove-lo | |
433 | - if ((lista[i-1][1] == "NUM") and (lista[i+1][1] == "NUM") and (tag == "CONJ")): | |
434 | - indices_deletar.append(i) | |
435 | - else: | |
436 | - # A sequência foi quebrada, o que significa que selecionamos o extenso do número por completo | |
437 | - # Podemos agora procurar por outra sequencia de número por extenso na lista | |
438 | - is_sequence = False | |
439 | - count += 1 | |
440 | - | |
441 | - for extenso in lista_extensos: | |
442 | - ext = convert_extenso(' '.join(extenso[1])) | |
443 | - lista[extenso[0]] = [ext, "NUM"] | |
444 | - | |
445 | - deque((list.pop(lista, i) for i in sorted(indices_deletar, reverse=True)), maxlen=0) | |
446 | - return lista | |
447 | 0 | \ No newline at end of file |
src/new/AplicaSinonimos.py
... | ... | @@ -1,33 +0,0 @@ |
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 os | |
10 | -import csv | |
11 | -import sys | |
12 | -from nltk.tree import Tree | |
13 | -from LerDicionarios import * | |
14 | - | |
15 | -class AplicaSinonimos(object): | |
16 | - """Classe para aplicar sinonimos após a aplicação de regras morfológicas/sintáticas""" | |
17 | - | |
18 | - def __init__(self): | |
19 | - self.dicionarios = LerDicionarios() | |
20 | - | |
21 | - # Itera sobre os tokens obtendo os sinonimos | |
22 | - def aplicar_sinonimos(self, lista_anotada): | |
23 | - lista_corrigida = [] | |
24 | - for tupla in lista_anotada: | |
25 | - sinonimo = self.verificar_sinonimo(tupla[0]) | |
26 | - lista_corrigida.append(sinonimo) | |
27 | - return " ".join(lista_corrigida) | |
28 | - | |
29 | - # Verifica se há sinonimo do token | |
30 | - def verificar_sinonimo(self, token): | |
31 | - if self.dicionarios.has_sinonimo(token): | |
32 | - return self.dicionarios.get_sinonimo(token) | |
33 | - return token | |
34 | 0 | \ No newline at end of file |
src/new/ConverteExtenso.py
... | ... | @@ -1,154 +0,0 @@ |
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 sys | |
10 | -from unicodedata import normalize | |
11 | -from Iterator import * | |
12 | - | |
13 | -num = {"zero":0, "um":1, "dois":2, "tres":3, "quatro":4, "cinco":5, "seis":6, | |
14 | -"sete":7, "oito":8, "nove":9} | |
15 | - | |
16 | -ext = [{"um":"1", "dois":"2", "tres":"3", "quatro":"4", "cinco":"5", "seis":"6", | |
17 | -"sete":"7", "oito":"8", "nove":"9", "dez":"10", "onze":"11", "doze":"12", | |
18 | -"treze":"13", "quatorze":"14", "quinze":"15", "dezesseis":"16", | |
19 | -"dezessete":"17", "dezoito":"18", "dezenove":"19"}, {"vinte":"2", "trinta":"3", | |
20 | -"quarenta":"4", "cinquenta":"5", "sessenta":"6", "setenta":"7", "oitenta":"8", | |
21 | -"noventa":"9"}, {"cento":"1", "cem":"1", "duzentos":"2", "trezentos":"3", | |
22 | -"quatrocentos":"4", "quinhentos":"5", "seissentos":"6", "setessentos":"7", | |
23 | -"oitocentos":"8", "novecentos":"9"}] | |
24 | - | |
25 | -und = {"mil":1000, "milhao":1000000, "bilhao":1000000000, "trilhao":1000000000000} | |
26 | -unds = {"mil":"000", "milhao":"000000","milhoes":"000000", "bilhao":"000000000","bilhoes":"000000000", "trilhao":"000000000000", "trilhoes":"000000000000"} | |
27 | - | |
28 | - | |
29 | - | |
30 | -def oneDigit(x): | |
31 | - return ext[0][x] | |
32 | - | |
33 | -def twoDigit(x): | |
34 | - try: | |
35 | - return ext[1][x[0]]+ext[0][x[1]] | |
36 | - except: | |
37 | - return ext[1][x[0]]+"0" | |
38 | - | |
39 | -def threeDigit(x): | |
40 | - return ext[2][x[0]]+ext[1][x[1]]+ext[0][x[2]] | |
41 | - | |
42 | -# Não faço mais a minima idéia de como fiz isso, só sei que funciona! | |
43 | -def extensoUnit(n): | |
44 | - sn = n.split(",") | |
45 | - size = len(sn) | |
46 | - firstWord = sn[0] | |
47 | - endWord = "" | |
48 | - numExt = "" | |
49 | - | |
50 | - if(unds.has_key(sn[size-1])): | |
51 | - size -= 1 | |
52 | - endWord = sn[size] | |
53 | - del sn[size] | |
54 | - | |
55 | - if(ext[0].has_key(firstWord)): | |
56 | - numExt = oneDigit(firstWord) | |
57 | - | |
58 | - elif (ext[1].has_key(firstWord)): | |
59 | - numExt = twoDigit(sn) | |
60 | - | |
61 | - elif (ext[2].has_key(firstWord)): | |
62 | - if(size == 1): | |
63 | - numExt = ext[2][firstWord]+"00" | |
64 | - elif (size == 2): | |
65 | - if(sn[1] == "dez"): | |
66 | - numExt = ext[2][firstWord]+oneDigit(sn[1]) | |
67 | - try: | |
68 | - numExt = ext[2][firstWord]+"0"+oneDigit(sn[1]) | |
69 | - except: | |
70 | - numExt = ext[2][firstWord]+twoDigit([sn[1]]) | |
71 | - else: | |
72 | - numExt = threeDigit(sn) | |
73 | - | |
74 | - if(endWord != ""): | |
75 | - numExt = numExt+unds[endWord] | |
76 | - | |
77 | - return numExt | |
78 | - | |
79 | - | |
80 | -''' | |
81 | -Comece com uma lista vazia. Itere pelas palavras da string da esquerda | |
82 | -para direita. Ao encontrar um numeral, adicione o número à lista se a | |
83 | -última palavra foi uma escala, ou some ao último numero da lista se a | |
84 | -última palavra foi um numeral. Ao encontrar uma escala, multiplique o | |
85 | -último número da lista de acordo. Quando terminar, some tudo e retorne | |
86 | -o resultado. | |
87 | -''' | |
88 | - | |
89 | -# TODO: Refatorar para nao usar mais o extensoUnit | |
90 | -def convert_extenso(extenso): | |
91 | - global newToken, auxToken | |
92 | - extensoQuebrado = extenso.lower().split(" ") | |
93 | - nums = [] | |
94 | - it = Iterator() | |
95 | - it.load(extensoQuebrado) | |
96 | - while(it.has_next()): | |
97 | - token = simplifica(it.get_token()) | |
98 | - tokenAnterior = simplifica(it.get_token(-1)) | |
99 | - if (und.has_key(token)): | |
100 | - if(it.get_count() == 0): | |
101 | - nums.append(und[token]) | |
102 | - else: | |
103 | - newToken = und[token] * int(nums[-1]) | |
104 | - nums[-1] = newToken | |
105 | - else: | |
106 | - if (num.has_key(token)): | |
107 | - auxToken = num[token] | |
108 | - elif (not und.has_key(token)): | |
109 | - auxToken = extensoUnit(token) | |
110 | - | |
111 | - if((not und.has_key(tokenAnterior)) and it.get_count() > 0): | |
112 | - newToken = int(auxToken) + int(nums[-1]) | |
113 | - nums[-1] = newToken | |
114 | - else: | |
115 | - nums.append(auxToken) | |
116 | - return soma(nums) | |
117 | - | |
118 | -def soma(lista): | |
119 | - soma = 0 | |
120 | - for i in lista: | |
121 | - soma += int(i) | |
122 | - return soma | |
123 | - | |
124 | -def simplifica(txt): | |
125 | - newToken = "" | |
126 | - try: | |
127 | - newToken = normalize('NFKD', txt.decode('utf-8')).encode('ASCII','ignore') | |
128 | - except: | |
129 | - newToken = normalize('NFKD', txt.decode('iso-8859-1')).encode('ASCII','ignore') | |
130 | - | |
131 | - if(newToken[-3:] == "oes"): | |
132 | - return newToken[:-3] + "ao" | |
133 | - | |
134 | - return newToken | |
135 | - | |
136 | -# Test | |
137 | -''' | |
138 | -if __name__ == '__main__': | |
139 | - n = sys.argv[1] | |
140 | - return extenso(n) | |
141 | - arquivoExts = open('exts', 'r') | |
142 | - listaExts = arquivoExts.readlines() | |
143 | - arquivoNums = open('nums', 'r') | |
144 | - listaNums = arquivoNums.readlines() | |
145 | - for i in range(0,500): | |
146 | - n = listaNums[i].replace("\n","") | |
147 | - e = listaExts[i].replace("\n","") | |
148 | - numNew = extenso(e) | |
149 | - if (str(numNew) != n): | |
150 | - print n + " != " + str(numNew) | |
151 | - #else: | |
152 | - # print "OK: " + n + " == " + str(numNew) | |
153 | -''' | |
154 | - |
src/new/Iterator.py
... | ... | @@ -1,64 +0,0 @@ |
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 | -class Iterator(object): | |
10 | - """Classe para iterar sobre as tuplas (palavra,etiqueta) após análise morfologica""" | |
11 | - | |
12 | - def init(self): | |
13 | - self.count = -1 | |
14 | - | |
15 | - def load(self, lista): | |
16 | - self.reset() | |
17 | - self.list = list(lista); | |
18 | - self.size = len(lista) | |
19 | - | |
20 | - def reset(self): | |
21 | - self.count = -1 | |
22 | - | |
23 | - def get_size(self): | |
24 | - return self.size | |
25 | - | |
26 | - def get_count(self): | |
27 | - return self.count | |
28 | - | |
29 | - def get_token(self, i=None): | |
30 | - if(i != None): | |
31 | - return self.list[self.count+(i)] | |
32 | - return self.list[self.count] | |
33 | - | |
34 | - def get_word(self): | |
35 | - return self.get_token()[0] | |
36 | - | |
37 | - def get_ticket(self): | |
38 | - return self.get_token()[1] | |
39 | - | |
40 | - def get_next_word(self): | |
41 | - return self.get_token(1)[0] | |
42 | - | |
43 | - def get_next_ticket(self): | |
44 | - return self.get_token(1)[1] | |
45 | - | |
46 | - def get_prev_word(self): | |
47 | - return self.get_token(-1)[0] | |
48 | - | |
49 | - def get_prev_ticket(self): | |
50 | - return self.get_token(-1)[1] | |
51 | - | |
52 | - def get_interval(self, n): | |
53 | - if self.count+n > self.size: | |
54 | - raise IndexError | |
55 | - return self.list[self.count:self.count+n] | |
56 | - | |
57 | - def skip(self, n): | |
58 | - self.count += n | |
59 | - | |
60 | - def has_next(self): | |
61 | - if(self.count < self.size-1): | |
62 | - self.count += 1 | |
63 | - return True | |
64 | - return False | |
65 | 0 | \ No newline at end of file |
src/new/LerDicionarios.py
... | ... | @@ -1,212 +0,0 @@ |
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 | -from os.path import expanduser | |
10 | -from os import environ | |
11 | -import csv | |
12 | -import platform | |
13 | - | |
14 | -class LerDicionarios(object): | |
15 | - | |
16 | - def __init__(self): | |
17 | - self.path = self.get_path() | |
18 | - self.set_exc_plural = [] | |
19 | - self.dic_adv_intensidade = {} | |
20 | - self.set_adv_tempo = [] | |
21 | - self.set_art = [] | |
22 | - self.set_prep = [] | |
23 | - self.dic_sin = {} | |
24 | - self.set_sb_2_gen = [] | |
25 | - self.dic_vb_infinitivo = {} | |
26 | - self.set_vb_ligacao = [] | |
27 | - self.dic_vb_muda_negacao = [] | |
28 | - self.file = '' | |
29 | - self.carregar_dicionarios() | |
30 | - | |
31 | - def get_path(self): | |
32 | - if platform.system() == 'Windows': | |
33 | - return os.environ.get("HOMEDRIVE") + "\\vlibras-libs\\vlibras-translate\data\\" | |
34 | - return expanduser("~") + "/vlibras-translate/data/" | |
35 | - | |
36 | - def carregar_dicionarios(self): | |
37 | - self.carregar_excecoes_plural() | |
38 | - self.carregar_adverbios_intensidade() | |
39 | - self.carregar_adverbios_tempo() | |
40 | - self.carregar_artigos() | |
41 | - self.carregar_preposicoes() | |
42 | - self.carregar_sinonimos() | |
43 | - self.carregar_subs_2_generos() | |
44 | - self.carregar_verbos_infinitivo() | |
45 | - self.carregar_verbos_ligacao() | |
46 | - self.carregar_verbos_muda_negacao | |
47 | - | |
48 | - | |
49 | - def carregar_excecoes_plural(self): | |
50 | - try: | |
51 | - self.file = csv.reader(open(self.path+"excecoesPlural.csv")) | |
52 | - except IOError, (errno, strerror): | |
53 | - print "I/O error(%s): %s" % (errno, strerror) | |
54 | - print "carregar_excecoes_plural" | |
55 | - | |
56 | - rows = [] | |
57 | - for row in self.file: | |
58 | - rows.append(row[0].decode("utf-8")) | |
59 | - self.set_exc_plural = set(rows) | |
60 | - | |
61 | - def carregar_adverbios_intensidade(self): | |
62 | - try: | |
63 | - self.file = csv.reader(open(self.path+"adverbiosIntensidade.csv"), delimiter=";") | |
64 | - except IOError, (errno, strerror): | |
65 | - print "I/O error(%s): %s" % (errno, strerror) | |
66 | - print "carregar_adverbios_intensidade" | |
67 | - | |
68 | - for row in self.file: | |
69 | - if row[1] != "": | |
70 | - self.dic_adv_intensidade[row[0].decode("utf-8")] = row[1].decode("utf-8") | |
71 | - | |
72 | - def carregar_adverbios_tempo(self): | |
73 | - try: | |
74 | - self.file = csv.reader(open(self.path+"adverbiosTempo.csv")) | |
75 | - except IOError, (errno, strerror): | |
76 | - print "I/O error(%s): %s" % (errno, strerror) | |
77 | - print "carregar_adverbios_tempo" | |
78 | - | |
79 | - rows = [] | |
80 | - for row in self.file: | |
81 | - rows.append(row[0].decode("utf-8")) | |
82 | - self.set_adv_tempo = set(rows) | |
83 | - | |
84 | - def carregar_artigos(self): | |
85 | - try: | |
86 | - self.file = csv.reader(open(self.path+"artigos.csv")) | |
87 | - except IOError, (errno, strerror): | |
88 | - print "I/O error(%s): %s" % (errno, strerror) | |
89 | - print "carregar_artigos" | |
90 | - | |
91 | - rows = [] | |
92 | - for row in self.file: | |
93 | - rows.append(row[0].decode("utf-8")) | |
94 | - self.set_art = set(rows) | |
95 | - | |
96 | - def carregar_preposicoes(self): | |
97 | - try: | |
98 | - self.file = csv.reader(open(self.path+"preposicoes.csv")) | |
99 | - except IOError, (errno, strerror): | |
100 | - print "I/O error(%s): %s" % (errno, strerror) | |
101 | - print "carregar_preposicoes" | |
102 | - | |
103 | - rows = [] | |
104 | - for row in self.file: | |
105 | - rows.append(row[0].decode("utf-8")) | |
106 | - self.set_prep = set(rows) | |
107 | - | |
108 | - def carregar_sinonimos(self): | |
109 | - try: | |
110 | - self.file = csv.reader(open(self.path+"sinonimos.csv"), delimiter=";") | |
111 | - except IOError, (errno, strerror): | |
112 | - print "I/O error(%s): %s" % (errno, strerror) | |
113 | - print "carregar_sinonimos" | |
114 | - | |
115 | - for row in self.file: | |
116 | - if row[1] != "": | |
117 | - try: | |
118 | - self.dic_sin[row[0].decode("utf-8")] = row[1].decode("utf-8") | |
119 | - except UnicodeDecodeError: | |
120 | - self.dic_sin[row[0].decode('iso8859-1').encode('utf-8').decode('utf-8')] = row[1].decode('iso8859-1').encode('utf-8').decode('utf-8') | |
121 | - | |
122 | - def carregar_subs_2_generos(self): | |
123 | - try: | |
124 | - self.file = csv.reader(open(self.path+"subs2Generos.csv")) | |
125 | - except IOError, (errno, strerror): | |
126 | - print "I/O error(%s): %s" % (errno, strerror) | |
127 | - print "carregar_subs_2_generos" | |
128 | - | |
129 | - rows = [] | |
130 | - for row in self.file: | |
131 | - rows.append(row[0].decode('iso8859-1').encode('utf-8').decode('utf-8')) | |
132 | - self.set_sb_2_gen = set(rows) | |
133 | - | |
134 | - def carregar_verbos_infinitivo(self): | |
135 | - try: | |
136 | - self.file = csv.reader(open(self.path+"verbosInfinitivo.csv"), delimiter=";") | |
137 | - except IOError, (errno, strerror): | |
138 | - print "I/O error(%s): %s" % (errno, strerror) | |
139 | - print "carregar_verbos_infinitivo" | |
140 | - | |
141 | - for row in self.file: | |
142 | - if row[1] != "": | |
143 | - try: | |
144 | - self.dic_vb_infinitivo[row[0].decode("utf-8")] = row[1].decode("utf-8") | |
145 | - except UnicodeDecodeError: | |
146 | - self.dic_vb_infinitivo[row[0].decode('iso8859-1').encode('utf-8').decode('utf-8')] = row[1].decode('iso8859-1').encode('utf-8').decode('utf-8') | |
147 | - | |
148 | - def carregar_verbos_ligacao(self): | |
149 | - try: | |
150 | - self.file = csv.reader(open(self.path+"verbosLigacao.csv")) | |
151 | - except IOError, (errno, strerror): | |
152 | - print "I/O error(%s): %s" % (errno, strerror) | |
153 | - print "carregar_verbos_ligacao" | |
154 | - | |
155 | - rows = [] | |
156 | - for row in self.file: | |
157 | - rows.append(row[0].decode("utf-8")) | |
158 | - self.set_vb_ligacao = set(rows) | |
159 | - | |
160 | - | |
161 | - def carregar_verbos_muda_negacao(self): | |
162 | - try: | |
163 | - self.file = csv.reader(open(self.path+"verbosMudaNegacao.csv"), delimiter=";") | |
164 | - except IOError, (errno, strerror): | |
165 | - print "I/O error(%s): %s" % (errno, strerror) | |
166 | - print "carregar_verbos_muda_negacao" | |
167 | - | |
168 | - for row in self.file: | |
169 | - if row[1] != "": | |
170 | - self.dic_vb_muda_negacao[row[0].decode("utf-8")] = row[1].decode("utf-8") | |
171 | - | |
172 | - def has_excecao_plural(self, token): | |
173 | - return token not in self.set_exc_plural | |
174 | - | |
175 | - def has_adverbio_intensidade(self, token): | |
176 | - return self.dic_adv_intensidade.has_key(token) | |
177 | - | |
178 | - def has_adverbio_tempo(self, token): | |
179 | - return token in self.set_adv_tempo | |
180 | - | |
181 | - def has_artigo(self, token): | |
182 | - return token in self.set_art | |
183 | - | |
184 | - def has_preposicao(self, token): | |
185 | - return token in self.set_prep | |
186 | - | |
187 | - def has_sinonimo(self, token): | |
188 | - return self.dic_sin.has_key(token) | |
189 | - | |
190 | - def has_subst_2_generos (self, token): | |
191 | - return token in self.set_sb_2_gen | |
192 | - | |
193 | - def has_verbo_infinitivo(self, token): | |
194 | - return self.dic_vb_infinitivo.has_key(token) | |
195 | - | |
196 | - def has_verbo_ligacao(self, token): | |
197 | - return token in self.set_vb_ligacao | |
198 | - | |
199 | - def has_verbo_muda_negacao(self, token): | |
200 | - return self.dic_vb_muda_negacao.has_key(token) | |
201 | - | |
202 | - def get_adverbio_intensidade(self, token): | |
203 | - return self.dic_adv_intensidade[token] | |
204 | - | |
205 | - def get_sinonimo(self, token): | |
206 | - return self.dic_sin[token] | |
207 | - | |
208 | - def get_verbo_infinitivo(self, token): | |
209 | - return self.dic_vb_infinitivo[token] | |
210 | - | |
211 | - def get_verbo_muda_negacao(self, token): | |
212 | - return self.dic_vb_muda_negacao[token] | |
213 | 0 | \ No newline at end of file |
src/new/PortGlosa.py
... | ... | @@ -1,50 +0,0 @@ |
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 | -from TraduzSentencas import * | |
10 | - | |
11 | -def traduzir(texto): | |
12 | - glosa = iniciar_traducao(texto) | |
13 | - if glosa: | |
14 | - return glosa | |
15 | - return "selecione_texto" | |
16 | - | |
17 | -def iniciar_traducao(texto): | |
18 | - texto_quebrado = quebrar_texto(texto) | |
19 | - num_threads = len(texto_quebrado) | |
20 | - texto_traduzido = [] | |
21 | - threads = [] | |
22 | - | |
23 | - for i in range(num_threads): | |
24 | - if texto_quebrado[i] > 0 and texto_quebrado[i] != " ": | |
25 | - threads.insert(i, TraduzSentencas(texto_quebrado[i])) | |
26 | - threads[i].start() | |
27 | - for i in range(num_threads): | |
28 | - threads[i].join() | |
29 | - texto_traduzido.append(threads[i].obter_glosa()) | |
30 | - | |
31 | - try: | |
32 | - return " ".join(texto_traduzido) | |
33 | - except: | |
34 | - return None | |
35 | - | |
36 | -def quebrar_texto(texto): | |
37 | - quantidade_pontos = texto.count('. ') | |
38 | - sentencas = [] | |
39 | - for i in range(quantidade_pontos): | |
40 | - posicao_ponto = texto.find('.') | |
41 | - if texto[posicao_ponto+2].isupper(): | |
42 | - sentencas.append(texto[:posicao_ponto]) | |
43 | - texto = texto[posicao_ponto+2:] | |
44 | - if len(texto) > 0: | |
45 | - sentencas.append(texto) | |
46 | - return sentencas | |
47 | - | |
48 | -def ajuda(): | |
49 | - #TODO: Adicionar um pequeno tuto aqui | |
50 | - print "Help" | |
51 | 0 | \ No newline at end of file |
src/new/TraduzSentencas.py
... | ... | @@ -1,52 +0,0 @@ |
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 | -from threading import Thread | |
10 | -import alexp | |
11 | -from AplicaSinonimos import * | |
12 | -from AplicaRegras import * | |
13 | -import logging | |
14 | - | |
15 | -class TraduzSentencas(Thread): | |
16 | - | |
17 | - def __init__(self, sentenca): | |
18 | - Thread.__init__(self) | |
19 | - self.sentenca = sentenca | |
20 | - self.glosa = "" | |
21 | - self.aplic_sinonimos = AplicaSinonimos() | |
22 | - self.aplic_regras = AplicaRegras() | |
23 | - logging.basicConfig(filename='translate.log', | |
24 | - format='%(asctime)s - %(levelname)s:\n%(message)s\n\n\n##############################################\n\n', | |
25 | - level=logging.ERROR) | |
26 | - | |
27 | - | |
28 | - def run(self): | |
29 | - try: | |
30 | - analise_sintatica = alexp.run(self.sentenca) | |
31 | - except Exception as ex: | |
32 | - self.salvar_log(str(ex)) | |
33 | - analise_sintatica = None | |
34 | - | |
35 | - analise_morfologica = alexp.getAnaliseMorfologica() | |
36 | - | |
37 | - if (isinstance(analise_sintatica,type(None))): | |
38 | - print "# ANÁLISE MORFOLÓGICA" | |
39 | - regras_aplicadas = self.aplic_regras.aplicar_regras_morfo(analise_morfologica) | |
40 | - else: | |
41 | - print "# ANÁLISE SINTÁTICA" | |
42 | - regras_aplicadas = self.aplic_regras.aplicar_regras_sint(analise_morfologica, analise_sintatica) | |
43 | - | |
44 | - sentenca_corrigida = self.aplic_regras.simplificar_sentenca(regras_aplicadas) | |
45 | - sinonimos_aplicados = self.aplic_sinonimos.aplicar_sinonimos(sentenca_corrigida) | |
46 | - self.glosa = sinonimos_aplicados.upper().encode('utf-8') | |
47 | - | |
48 | - def obter_glosa(self): | |
49 | - return self.glosa | |
50 | - | |
51 | - def salvar_log(self, erro): | |
52 | - logging.error(erro) | |
53 | 0 | \ No newline at end of file |
src/new/alexp.py
... | ... | @@ -1,135 +0,0 @@ |
1 | -#! /usr/bin/env python2.6 | |
2 | -# -*- coding: utf-8 -*- | |
3 | - | |
4 | -#--------------------------------- | |
5 | - | |
6 | -# Editado: | |
7 | - | |
8 | -#Autor: Erickson Silva | |
9 | -#Email: <erickson.silva@lavid.ufpb.br> <ericksonsilva@live.com> | |
10 | - | |
11 | -#LAViD - Laboratório de Aplicações de Vídeo Digital | |
12 | - | |
13 | -#--------------------------------- | |
14 | - | |
15 | - | |
16 | -# Donatus Brazilian Portuguese Parser | |
17 | -# | |
18 | -# Copyright (C) 2010-2013 Leonel F. de Alencar | |
19 | -# | |
20 | -# Author: Leonel F. de Alencar <leonel.de.alencar@ufc.br> | |
21 | -# Homepage: <http://www.leonel.profusehost.net/> | |
22 | -# | |
23 | -# Project's URL: <http://sourceforge.net/projects/donatus/> | |
24 | -# For license information, see LICENSE.TXT | |
25 | -# | |
26 | -# $Id: alexp.py $ | |
27 | - | |
28 | -"""Este módulo contém funções que permitem utilizar o Aelius para etiquetar uma sentença, construindo entradas lexicais com base nas etiquetas atribuídas às palavras da sentença. Essas entradas lexicais são integradas em uma gramática CFG dada, que é transformada em um parser, utilizado para gerar uma árvore de estrutura sintagmática da sentença. | |
29 | -""" | |
30 | -import re,nltk,platform, time, random | |
31 | -from os.path import expanduser | |
32 | -from os import environ | |
33 | -from Aelius.Extras import carrega | |
34 | -from Aelius import AnotaCorpus | |
35 | -from unicodedata import normalize | |
36 | - | |
37 | - | |
38 | -sentenca_anotada="" | |
39 | -sleep_times=[0.1,0.2] | |
40 | - | |
41 | -def toqueniza(s): | |
42 | - """Decodifica string utilizando utf-8, retornando uma lista de tokens em unicode. | |
43 | - """ | |
44 | - decodificada=s.decode("utf-8") | |
45 | - return AnotaCorpus.TOK_PORT.tokenize(decodificada) | |
46 | - | |
47 | -def getAnaliseMorfologica(): | |
48 | - return sentenca_anotada | |
49 | - #return [list(x) for x in sentenca_anotada] | |
50 | - | |
51 | -def etiquetaSentenca(s): | |
52 | - """Aplica um dos etiquetadores do Aelius na etiquetagem da sentença dada como lista de tokens. | |
53 | - """ | |
54 | - etiquetador = carrega("AeliusHunPos") | |
55 | - anotada = AnotaCorpus.anota_sentencas([s],etiquetador,"hunpos")[0] | |
56 | - while (anotada[0][1] is None): | |
57 | - time.sleep(random.choice(sleep_times)) | |
58 | - anotada = AnotaCorpus.anota_sentencas([s],etiquetador,"hunpos")[0] | |
59 | - #anotada[0] = (anotada[0][0].lower(), anotada[0][1]) | |
60 | - #return anotada | |
61 | - return [[x[0].lower(),x[1]] for x in anotada] | |
62 | - | |
63 | -def geraEntradasLexicais(lista): | |
64 | - """Gera entradas lexicais no formato CFG do NLTK a partir de lista de pares constituídos de tokens e suas etiquetas. | |
65 | - """ | |
66 | - entradas=[] | |
67 | - for e in lista: | |
68 | - # é necessário substituir símbolos como "-" e "+" do CHPTB | |
69 | - # que não são aceitos pelo NLTK como símbolos não terminais | |
70 | - c=re.sub(r"[-+]","_",e[1]) | |
71 | - c=re.sub(r"\$","_S",c) | |
72 | - entradas.append("%s -> '%s'" % (c, removeAcento(e[0]))) | |
73 | - return entradas | |
74 | - | |
75 | -def corrigeAnotacao(lista): | |
76 | - """Esta função deverá corrigir alguns dos erros de anotação mais comuns do Aelius. No momento, apenas é corrigida VB-AN depois de TR. | |
77 | - """ | |
78 | - i=1 | |
79 | - while i < len(lista): | |
80 | - if lista[i][1] == "VB-AN" and lista[i-1][1].startswith("TR"): | |
81 | - lista[i]=(lista[i][0],"VB-PP") | |
82 | - i+=1 | |
83 | - | |
84 | -def encontraArquivo(): | |
85 | - """Encontra arquivo na pasta vlibras-translate. | |
86 | - """ | |
87 | - so = platform.system() | |
88 | - if so == 'Windows': | |
89 | - return os.environ.get("HOMEDRIVE") + "\\vlibras-libs\\vlibras-translate\data\cfg.syn.nltk" | |
90 | - else: | |
91 | - return expanduser("~") + "/vlibras-translate/data/cfg.syn.nltk" | |
92 | - | |
93 | -def extraiSintaxe(): | |
94 | - """Extrai gramática armazenada em arquivo cujo caminho é definido relativamente ao diretório nltk_data. | |
95 | - """ | |
96 | - arquivo=encontraArquivo() | |
97 | - if arquivo: | |
98 | - f=open(arquivo,"rU") | |
99 | - sintaxe=f.read() | |
100 | - f.close() | |
101 | - return sintaxe | |
102 | - else: | |
103 | - print "Arquivo %s não encontrado em nenhum dos diretórios de dados do NLTK:\n%s" % (caminho,"\n".join(nltk.data.path)) | |
104 | - | |
105 | -def analisaSentenca(sentenca): | |
106 | - """Retorna lista de árvores de estrutura sintagmática para a sentença dada sob a forma de uma lista de tokens, com base na gramática CFG cujo caminho é especificado como segundo argumento da função. Esse caminho é relativo à pasta nltk_data da instalação local do NLTK. A partir da etiquetagem morfossintática da sentença são geradas entradas lexicais que passam a integrar a gramática CFG. O caminho da gramática e o parser gerado são armazenados como tupla na variável ANALISADORES. | |
107 | - """ | |
108 | - parser=constroiAnalisador(sentenca) | |
109 | - codificada=[removeAcento(w).encode("utf-8") for w in sentenca] | |
110 | - trees=parser.parse_one(codificada) | |
111 | - return trees | |
112 | - | |
113 | -def constroiAnalisador(s): | |
114 | - """Constrói analisador a partir de uma única sentença não anotada, dada como lista de tokens, e uma lista de regras sintáticas no formato CFG, armazenadas em arquivo. Esta função tem um bug, causado pela maneira como o Aelius etiqueta sentenças usando o módulo ProcessaNomesProprios: quando a sentença se inicia por paravra com inicial minúscula, essa palavra não é incorporada ao léxico, mas a versão com inicial maiúscula. | |
115 | - """ | |
116 | - global sentenca_anotada | |
117 | - sentenca_anotada=etiquetaSentenca(s) | |
118 | - corrigeAnotacao(sentenca_anotada) | |
119 | - entradas=geraEntradasLexicais(sentenca_anotada) | |
120 | - lexico="\n".join(entradas) | |
121 | - gramatica="%s\n%s" % (extraiSintaxe().strip(),lexico) | |
122 | - cfg=nltk.CFG.fromstring(gramatica) | |
123 | - return nltk.ChartParser(cfg) | |
124 | - | |
125 | -def removeAcento(texto): | |
126 | - return normalize('NFKD', texto.encode('utf-8').decode('utf-8')).encode('ascii', 'ignore') | |
127 | - | |
128 | -def exibeArvores(arvores): | |
129 | - """Função 'wrapper' para a função de exibição de árvores do NLTK""" | |
130 | - nltk.draw.draw_trees(*arvores) | |
131 | - | |
132 | -def run(sentenca): | |
133 | - tokens=toqueniza(sentenca) | |
134 | - tree=analisaSentenca(tokens) | |
135 | - return tree | |
136 | 0 | \ No newline at end of file |