Commit 927ebcc797090e26403841646309c762c75c87ce

Authored by Erickson Silva
1 parent 361e9a92
Exists in master and in 1 other branch devel

Define nova versão do tradutor como default

src/AplicaRegras.py 0 → 100644
... ... @@ -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
... ...
src/AplicaSinonimos.py 0 → 100644
... ... @@ -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   -
src/ConverteExtenso.py 0 → 100644
... ... @@ -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
... ...
src/LerDicionarios.py 0 → 100644
... ... @@ -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
... ... @@ -1,14 +0,0 @@
1   -#!/usr/bin/python
2   -# -*- coding: utf-8 -*-
3   -
4   -from Tradutor import *
5   -
6   -tradutor = Tradutor()
7   -
8   -def iniciar(x):
9   - try:
10   - text = x.decode("utf-8")
11   - except:
12   - text = x.decode("iso-8859-1")
13   -
14   - return tradutor.traduzir(text)
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   -
src/PortGlosa.py 0 → 100644
... ... @@ -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] ç: áàãâä! éèêë? íì&#297;îï, óòõôö; úù&#361;ûü.')
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")
src/TraduzSentencas.py 0 → 100644
... ... @@ -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
src/alexp.py 0 → 100644
... ... @@ -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