Commit ffd8e900adb354632f2184bed1aa52d459a21926

Authored by Erickson Silva
1 parent 78618f34
Exists in master and in 1 other branch devel

Refatora completamente o aplicador de regras

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