Commit 361e9a92c0e63ceb6a968b59ea25c36fcad2f624

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

Corrige aplicação de regras sintáticas

Showing 1 changed file with 247 additions and 208 deletions   Show diff stats
src/new/AplicaRegras.py
... ... @@ -7,6 +7,7 @@
7 7 #LAViD - Laboratório de Aplicações de Vídeo Digital
8 8  
9 9 import platform
  10 +import re
10 11 import xml.etree.ElementTree as ET
11 12 from os.path import expanduser
12 13 from collections import deque
... ... @@ -19,114 +20,110 @@ from nltk import ParentedTree, Tree, draw
19 20  
20 21 class AplicaRegras(object):
21 22  
22   - # inicializa todos as variaveis
23 23 def __init__(self):
24 24 self.__root = self.get_root()
25 25 self.dicionarios = LerDicionarios()
  26 + # Dicionário de funcões do campo specific do arquivo de regras
26 27 self.__especificos = {"advt":self.verificar_adv_tempo, "v":self.verificar_vb_infinitivo, "x":self.verificar_preposicao,
27 28 "c":self.verificar_subst_genero, "a":self.verificar_artigo, "l":self.verificar_vb_ligacao,
28 29 "i":self.verificar_adv_intensidade, "vbi":"zero", "n":self.verificar_vb_muda_negacao, "abmn":"zero",
29 30 "adji":"zero","adjn":"zero", "advi":"zero"}
30 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
31 35 def get_root(self):
32 36 if platform.system() == 'Windows':
33 37 return ET.parse(expanduser("~")+'\\vlibras-translate\data\\regras.xml').getroot()
34 38 return ET.parse(expanduser("~")+'/vlibras-translate/data/regras.xml').getroot()
35 39  
  40 + # Aplica regras morfológicas apartir do arquivo regras.xml
36 41 def aplicar_regras_morfo(self, lista, sint=False):
37   - self.lista = list(lista)
38   - self.quantidade_iter_pular = 0
39   - self.lista_corrigida = []
  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
40 44  
41 45 it = Iterator()
42 46 it.load(self.lista)
43 47  
44   - while(it.has_next()):
  48 + while(it.has_next()):
45 49 for morpho in self.__root.findall('morphological'):
46   - self.has_rule = False
47   - for rule in morpho.findall('rule'): # procura a tag rule
  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
48 53 if rule.find('active').text == "true" and rule.get('name').split("_")[0] == it.get_ticket():
49 54 count = int(rule.find('count').text)
50   - self.lista_iteracoes = []
51   - if count == 1:
52   - self.lista_iteracoes = [it.get_token()]
53   - else:
54   - try:
55   - self.lista_iteracoes = it.get_interval(count)
56   - it.skip(count-1)
57   - except:
58   - continue
  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
59 64  
  65 + # Gera o nome da regra do intervalo de tuplas e verifica se é igual ao nome da regra em si
60 66 self.nome_regra = self.gerar_nome_regra(self.lista_iteracoes)
61   - if rule.get('name') == self.nome_regra: # verifica se a regra é aplicavel e a mesma esta ativa
  67 + if rule.get('name') == self.nome_regra:
62 68 self.has_rule = True
63   - self.lista_iteracao_regra = count * [None]
64 69 self.count_iteracao_regra = -1
65 70  
66   - print "REGRA MORFOLÓGICA: " + rule.get('name')
  71 + print "REGRA MORFOLÓGICA ENCONTRADA: " + rule.get('name')
67 72  
  73 + self.lista_iteracao_regra = [] # Lista temporária | Insere tokens após a aplicação das regras
  74 +
68 75 for classe in rule.iter('class'): # for nas tags class
69   -
70   - title = classe.find('title')
71   - newpos = classe.find('newpos')
  76 + action = classe.find('action')
72 77 newprop = classe.find('newprop')
73 78 newtoken = classe.find('newtoken')
74 79 newtokenpos = classe.find('newtokenpos')
75   - self.specific = classe.find('specific')
  80 + specific = classe.find('specific')
76 81  
77 82 self.count_iteracao_regra += 1
78 83 tupla = self.lista_iteracoes[self.count_iteracao_regra]
79 84  
80   - if self.specific is not None:
81   - self.specific = self.__especificos[self.specific.text](tupla[0])
82   - if self.specific == False:
  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..."
83 89 self.has_rule = False
84   - self.quantidade_iter_pular = 0
85 90 break
86 91  
87   - if newprop is not None and newtoken is not None:
88   - if newtokenpos is not None and newtokenpos.text == "0":
89   - self.lista_iteracao_regra[self.count_iteracao_regra] = (newtoken.text + "_" + self.specific, newprop.text)
90   - else:
91   - self.lista_iteracao_regra[self.count_iteracao_regra] = (self.specific + "_" + newtoken.text, newprop.text)
92   - continue
93   -
94   - elif newprop is not None:
95   - self.lista_iteracao_regra.append([self.specific,newprop.text])
96   -
97   - if newtoken is not None and newpos is not None:
98   - if newtokenpos is not None:
99   - lista_merge = count * [None]
100   - lista_merge[int(newpos.text)] = tupla[0]
101   - lista_merge[int(newtokenpos.text)] = newtoken.text
102   - merge_tokens = "_".join(lista_merge)
103   - self.lista_iteracao_regra.append([merge_tokens, title.text])
104   - else:
105   - self.lista_iteracao_regra.append([tupla[0] + "_" + newtoken.text, title.text])
106   -
107   - elif newpos is not None:
108   - if newpos.text == "-1":
109   - self.lista_corrigida.append(None)
  92 + if action is not None:
  93 + action_text = action.text
  94 + if action_text == "remove":
  95 + self.lista_iteracao_regra.append(None)
110 96 continue
111   - else:
112   - self.lista_iteracao_regra[int(newpos.text)] = tupla
113   -
114   - elif newtoken is not None:
115   - token_anterior = self.lista_iteracao_regra[self.count_iteracao_regra][0]
116   - ticket_anterior = self.lista_iteracao_regra[self.count_iteracao_regra][1]
117   - if newtokenpos is not None and newtokenpos.text == "0":
118   - self.lista_iteracao_regra[self.count_iteracao_regra] = [newtoken.text + "_" + token_anterior, ticket_anterior]
119   - else:
120   - self.lista_iteracao_regra[self.count_iteracao_regra] = [token_anterior + "_" + newtoken.text, ticket_anterior]
121   -
122   - if self.has_rule:
123   - self.lista_corrigida.append(filter(None, self.lista_iteracao_regra)[0])
124   - break
125   -
126   - if (self.has_rule == False):
  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')
127 124 self.lista_corrigida.append(it.get_token()) #se nao achou regra, entao adiciona a tupla original
128 125 if sint:
129   - return self.lista_corrigida
  126 + return self.lista_corrigida
130 127 return filter(None, self.lista_corrigida)
131 128  
132 129  
... ... @@ -135,159 +132,185 @@ class AplicaRegras(object):
135 132 self.adaptar_regras_morfo_arvore(lista, p_arvore)
136 133 for morpho in self.__root.findall('syntactic'):
137 134 for rule in morpho.findall('rule'): # procura a tag rule
138   - nome_regra = self.corrigir_anotacao(rule.get('name'))
  135 + nome_regra = self.corrigir_nome_regra(rule.get('name'))
139 136 regra = self.separar_regra(nome_regra)
140 137 node_pai = tgrep_nodes(p_arvore, regra[0], search_leaves=False)
141   - if node_pai:
142   - node_regra = tgrep_nodes(node_pai[0], regra[1].replace('$', '>'), 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)
143 141 if node_regra:
144   - node_esq = tgrep_nodes(node_pai[0], regra[1], search_leaves=False)
145   - node_esq_pos = tgrep_positions(node_pai[0], regra[1], search_leaves=False)
146   - node_dir = tgrep_nodes(node_pai[0], regra[2], search_leaves=False)
147   - node_dir_pos = tgrep_positions(node_pai[0], regra[2], search_leaves=False)
148   - if node_esq and node_dir:
149   - print "REGRA SINTÁTICA: " + rule.get('name')
150   - subnodes = node_esq + node_dir
151   - for subnode in subnodes:
152   - self.has_rule = True
153   - self.alteracoes_nao_implementadas = [None,None]
154   - self.count_iteracao_regra = -1
155   - self.specific = None
156   -
157   - for classe in rule.findall('class'):
158   - self.specific = classe.find('specific')
159   - if self.specific is not None:
160   - self.specific = self.__especificos[self.specific.text](subnode.leaves()[0])
161   - if self.specific is False:
162   - self.has_rule = False
163   - break
164   -
165   - # modelo: [['node_esq', ['token', 'ticket']],['node_dir', ['token', 'ticket']]]
166   - for classe in rule.iter('class'):
167   - title = classe.find('title')
168   - if subnode.label() == title.text:
169   - newpos = classe.find('newpos')
170   - newprop = classe.find('newprop')
171   - newtoken = classe.find('newtoken')
172   - newtokenpos = classe.find('newtokenpos')
173   -
174   -
175   - self.count_iteracao_regra += 1
176   -
177   - if self.specific is not None:
178   - self.specific = self.__especificos[self.specific.text](subnode.leaves()[0])
179   - if self.specific is False:
180   - self.has_rule = False
181   - break
182   -
183   - if newprop is not None and newtoken is not None:
184   - if newtokenpos is not None and newtokenpos.text == "0":
185   - self.alteracoes_nao_implementadas[self.count_iteracao_regra].append([newtoken.text + "_" + self.specific, newprop.text])
186   - else:
187   - self.alteracoes_nao_implementadas[self.count_iteracao_regra].append([self.specific + "_" + newtoken.text, newprop.text])
188   - continue
189   -
190   - elif newprop is not None:
191   - self.alteracoes_nao_implementadas[self.count_iteracao_regra].append([self.specific,newprop.text])
192   -
193   - if newtoken is not None and newpos is not None:
194   - if newtokenpos is not None:
195   - lista_merge = count * [None]
196   - lista_merge[int(newpos.text)] = subnode.leaves()[0]
197   - lista_merge[int(newtokenpos.text)] = newtoken.text
198   - merge_tokens = "_".join(lista_merge)
199   - self.alteracoes_nao_implementadas[self.count_iteracao_regra].append([merge_tokens, title.text])
200   - else:
201   - self.alteracoes_nao_implementadas[self.count_iteracao_regra].append([subnode.leaves()[0] + "_" + newtoken.text, title.text])
  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
202 164  
203   - elif newpos is not None:
204   - if newpos.text == "-1":
205   - alteracoes_nao_implementadas[self.count_iteracao_regra].append(None)
206   - continue
207   - else:
208   - #TODO
209   - if int(newpos.text) == 0:
210   - self.alteracoes_nao_implementadas[int(newpos.text)] = subnode
211   -
212   - elif newtoken is not None:
213   - token_anterior = self.lista_iteracao_regra[self.count_iteracao_regra][0]
214   - ticket_anterior = self.lista_iteracao_regra[self.count_iteracao_regra][1]
215   - if newtokenpos is not None and newtokenpos.text == "0":
216   - self.lista_iteracao_regra[self.count_iteracao_regra] = [newtoken.text + " " + token_anterior, ticket_anterior]
  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 +
217 221 else:
218   - self.lista_iteracao_regra[self.count_iteracao_regra] = [token_anterior + " " + newtoken.text, ticket_anterior]
  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
219 226  
220   - if self.has_rule:
221   - print self.alteracoes_nao_implementadas[0]
222   - self.lista_corrigida.append(filter(None, self.lista_iteracao_regra)[0])
223   - break
  227 + elif action_text == "concate_neg":
  228 + print "TODO"
  229 + '''
224 230  
  231 + if newprop is not None:
  232 + node_pai[nodes_positions[self.count]].set_label(newprop.text)
  233 +
  234 + break
  235 +
225 236 return self.converter_arv_para_lista(p_arvore)
  237 +
226 238  
  239 + # Aplica regras morfológicas na árvore sintática
227 240 def adaptar_regras_morfo_arvore(self, lista, arvore):
228 241 lista_pos_arv = []
  242 + # Pega as posições das classificações morfológicas dos tokens na arvore sintática
229 243 for tupla in lista:
230   - string_grep = self.corrigir_anotacao(tupla[1]) + " < " + tupla[0].lower()
  244 + string_grep = self.corrigir_nome_regra(tupla[1]) + " < " + tupla[0].lower()
231 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)
232 249 if node[0] in lista_pos_arv:
233 250 node.reverse()
234 251 lista_pos_arv.append(node[0])
  252 +
  253 + # Aplica regras morfológicas na lista
235 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
236 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 +
237 266 arv_ticket = arvore[lista_pos_arv[i]].label()
238 267 arv_token = arvore[lista_pos_arv[i]][0]
  268 +
239 269 if morfo[i] is None:
240   - arvore[lista_pos_arv[i][:-1]] = None
  270 + arvore[lista_pos_arv[i]] = None
  271 +
241 272 elif arv_token != morfo[i][0] and arv_ticket != morfo[i][1]:
242 273 arvore[lista_pos_arv[i]][0] = morfo[i][0]
243   - arvore[lista_pos_arv[i]].set_label(self.corrigir_anotacao(morfo[i][1]))
  274 + arvore[lista_pos_arv[i]].set_label(morfo[i][1])
  275 +
244 276 elif arv_token != morfo[i][0]:
245 277 arvore[lista_pos_arv[i]][0] = morfo[i][0]
  278 +
246 279 elif arv_ticket != morfo[i][1]:
247   - arvore[lista_pos_arv[i]].set_label(self.corrigir_anotacao(morfo[i][1]))
248   - else:
249   - continue
250   -
251   - nodes_none = tgrep_positions(arvore, 'None')
252   - for node in nodes_none:
253   - arvore[node[:-1]].remove(None)
  280 + arvore[lista_pos_arv[i]].set_label(morfo[i][1])
254 281  
  282 + # Converte árvore sintática para uma lista de tuplas (igual a lista morfológica)
255 283 def converter_arv_para_lista(self, arvore):
256   - folhas = arvore.leaves()
  284 + folhas = filter(None, arvore.leaves())
257 285 lista_nodes = []
258 286 for folha in folhas:
259 287 pos = tgrep_positions(arvore, folha)
260 288 node = arvore[pos[0][:-1]]
261 289 #decode node[0]
262   - lista_nodes.append([node[0], self.corrigir_anotacao(node.label())])
  290 + lista_nodes.append([node[0], self.corrigir_nome_regra(node.label())])
263 291 return lista_nodes
264 292  
  293 + def remover_acento(self, texto):
  294 + return normalize('NFKD', texto.encode('utf-8').decode('utf-8')).encode('ascii', 'ignore')
265 295  
266   - def criar_ptree(self, s):
  296 + # Gera um ParentedTree do NLTK apartir da string recebida
  297 + def gerar_no(self, s):
267 298 all_ptrees = []
268   - ptree = ParentedTree.convert(Tree.fromstring(s))
  299 + t_string = '('+s[1] + ' ' + s[0]+')'
  300 + ptree = ParentedTree.convert(Tree.fromstring(t_string))
269 301 all_ptrees.extend(t for t in ptree.subtrees()
270 302 if isinstance(t, Tree))
271 303 return ptree
272 304  
273   - def separar_new_tokens(self, lista):
274   - for index, tupla in enumerate(lista):
275   - if '_' in tupla[0]:
276   - if 'VB' in tupla[1]:
277   - token_split = tupla[0].split('_')
278   - tupla[0] = token_split[0]
279   - lista.append([token_split[1],'NTK'])
280   - else:
281   - token_split = tupla[0].split('_')
282   - tupla[0] = token_split[0]
283   - lista.insert(index+1, [token_split[1],'NTK'])
284   -
285   - def corrigir_anotacao(self, anotacao):
  305 + # Corrige nome da regra descrita no arquivo de regras para como está na árvore sintática
  306 + def corrigir_nome_regra(self, anotacao):
286 307 split = anotacao.split('_')
287 308 for i in range(0, len(split)):
288   - split[i] = split[i].replace('-','_')
  309 + split[i] = re.sub(r"[-+]","_", split[i])
  310 + split[i] = re.sub(r"\$","_S",split[i])
289 311 return "-".join(split).encode('utf-8')
290 312  
  313 + # Separa a regra por nó pai e seus filhos
291 314 def separar_regra(self, regra):
292 315 split = regra.split("(")
293 316 split[1] = split[1].replace(")","").split("-")
... ... @@ -298,22 +321,24 @@ class AplicaRegras(object):
298 321 split[2] = ' $ '.join(split[2])
299 322 return split
300 323  
  324 + # Gera nome de regra apartir de uma lista
301 325 def gerar_nome_regra(self, lista):
302   - self.__nomeRegra = []
  326 + nome_regra = []
303 327 for t in lista:
304   - self.__nomeRegra.append(t[1])
305   - return "_".join(self.__nomeRegra)
  328 + nome_regra.append(t[1])
  329 + return "_".join(nome_regra)
306 330  
307 331 def verificar_adv_tempo(self, token):
308 332 for tupla in self.lista:
309 333 if self.dicionarios.has_adverbio_tempo(tupla[0]):
310   - return self.verificar_vb_infinitivo(token)
  334 + return True
311 335 return False
312 336  
  337 + def verificar_excecao_plural(self, token):
  338 + return self.dicionarios.has_excecao_plural(token)
  339 +
313 340 def verificar_vb_infinitivo(self, token):
314   - if self.dicionarios.has_verbo_infinitivo(token):
315   - return self.dicionarios.get_verbo_infinitivo(token)
316   - return False
  341 + return self.dicionarios.has_verbo_infinitivo(token)
317 342  
318 343 def verificar_preposicao(self, token):
319 344 return self.dicionarios.has_preposicao(token)
... ... @@ -331,29 +356,38 @@ class AplicaRegras(object):
331 356 return self.dicionarios.has_adverbio_intensidade(token)
332 357  
333 358 def verificar_vb_muda_negacao(self, token):
334   - if self.dicionarios.has_verbo_muda_negacao(token):
335   - return self.dicionarios.get_verbo_muda_negacao(token)
336   - return False
  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 +
337 369  
  370 + # Simplifica a sentença para que possa evitar a ditalogia
338 371 def simplificar_sentenca(self, lista):
  372 + lista_simplificada = list(lista)
339 373 it = Iterator()
340   - it.load(lista)
  374 + it.load(lista_simplificada)
341 375 num = False
342   - nova_lista = []
343 376 while(it.has_next()):
344   - token = it.get_word()
345 377 tag = it.get_ticket()
346 378  
347 379 if tag == "NUM":
348 380 num = True
349 381  
350   - if tag[-2:] == "-P":
351   - singular = self.analisar_plural(token)
352   - lista[it.get_count()][0] = singular
  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
353 385  
354   - if num: return self.converter_extenso(nova_lista)
355   - return nova_lista
  386 + if num:
  387 + return self.converter_extenso(lista_simplificada)
  388 + return lista_simplificada
356 389  
  390 + # Alterar uma palavra do plural para o singular
357 391 def analisar_plural(self, token):
358 392 if(token[-3:] == "OES" or token[-2:] == "AES" or token[-2:] == "AOS"):
359 393 return token[0:-3]+"AO"
... ... @@ -376,32 +410,37 @@ class AplicaRegras(object):
376 410 else:
377 411 return token
378 412  
  413 + # Converter número por extenso para numeral
379 414 def converter_extenso(self, lista):
380   - lista_aux = []
381   - index_deleted = []
  415 + lista_extensos = []
  416 + indices_deletar = []
382 417 count = 0
383   - is_running = False
  418 + is_sequence = False
384 419  
385 420 for i in range(0, len(lista)):
386 421 token = lista[i][0]
387 422 tag = lista[i][1]
388 423 if tag == "NUM":
389   - if (is_running is False and len(lista_aux) == count):
390   - lista_aux.append([i,[token]])
391   - is_running = True
  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
392 428 else:
393   - lista_aux[count][1].append(token)
394   - index_deleted.append(i)
395   - elif (is_running):
  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
396 433 if ((lista[i-1][1] == "NUM") and (lista[i+1][1] == "NUM") and (tag == "CONJ")):
397   - index_deleted.append(i)
  434 + indices_deletar.append(i)
398 435 else:
399   - is_running = False
  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
400 439 count += 1
401 440  
402   - for i in lista_aux:
403   - ext = extenso(' '.join(i[1]))
404   - lista[i[0]] = [ext, "NUM"]
  441 + for extenso in lista_extensos:
  442 + ext = convert_extenso(' '.join(extenso[1]))
  443 + lista[extenso[0]] = [ext, "NUM"]
405 444  
406   - deque((list.pop(lista, i) for i in sorted(index_deleted, reverse=True)), maxlen=0)
  445 + deque((list.pop(lista, i) for i in sorted(indices_deletar, reverse=True)), maxlen=0)
407 446 return lista
408 447 \ No newline at end of file
... ...