Pica-pau: Um protótipo de ferramenta para visualização e edição de árvores sintáticas

A ferramenta aqui descrita pode ser obtida através do atalho seguinte: floresta.el.
Renato Ribeiro Haber
Processamento Computacional do Português
SINTEF Telecomunicações e Informática
Postboks 124 Blindern
N-0381 Oslo, Noruega

Versão 2.3: [ 6 de Novembro de 2001 ] Texto e implementação de Renato Haber, exemplos de Susana Afonso, edição final de Diana Santos.

Introdução

Este relatório apresenta um protótipo de ferramenta de apoio à revisão de árvores sintáticas dentro do projeto Floresta Sintá(c)tica, que tem como objetivo criar um "treebank" publicamente disponível para a língua portuguesa, ou seja, um conjunto de itens sintaticamente analisados, que permita que todos os interessados na análise do português possam utilizá-lo tendo em conta diferentes objetivos.

O protótipo apresentado é constituído por um conjunto de funções desenvolvidas em Emacs Lisp.

Descrição das funcionalidades da ferramenta

Antes de começar a editar uma árvore, recomenda-se que o usuário execute a macro "highlight-changes-mode", ou simplesmente o seu atalho, definido pela tecla F12. Esta macro faz parte da biblioteca interna do Emacs, e sua funcionalidade consiste em facilitar a indentificação das modificações impostas a um arquivo. Uma vez ativa, todos os pontos do texto que são alterados ficam marcados com uma formatação diferente. No caso do protótipo, as modificações ficam assinaladas em vermelho. Este recurso permite que o usuário indentifique rapidamente os deslocamentos que estão sendo efetuados.

Utilizando-se das macros "highlight-changes-next-change" (ctrl-seta para a direita), o usuário movimenta o cursor para ponto da primeira modificação abaixo da posição em que ele se encontra, se houver, e "highlight-changes-previous-change" (ctrl-seta para a esquerda), o usuário movimenta o cursor para ponto da primeira modificação acima da posição em que ele se encontra, se houver.


Edição de árvores sintáticas

Para deslocar um token, o usuário deve posicionar o cursor na linha correspondente e executar a macro apropriada. Se o token selecionado for um nó não-terminal, todos os seus descendentes também sofrerão as modificações impostas pela macro.

Foram criadas 4 macros de deslocamento:

1. diminui-indentacao

(atalho: ctrl-alt-seta para cima)
Esta macro deve ser utilizada para diminuir a indentação (subir o nível) de nós não-terminais ou de nós-folha (palavra ou sinal-de-pontuação). No caso dos não-terminais, a ferramenta permite a eliminação do nó selecionado.

Exemplo 1: subir nível da vírgula (sinal de pontuação).

====P<:num('1948' M S)		1948
==,
=P:v-fin('declarar' PS 3S IND)	declarou
=ACC:icl
==P:v-inf('estar' V INF)	estar
==SC:ap
===H:adj('pronto' F S)	pronta
===A<:pp
====H:prp('para')	para
====P<:icl
=====P:v-inf('defender' V INF)	defender
=====ACC:np
======>N:art('o' M P)	os
======>N:pron-det('seu' M P)	seus
=======H:n('direito' M P)	direitos
=====ADVL:pp
======H:prp('em')	em
======P<:n('tribunal' M S)	tribunal
===,
CO:conj-c('e')	e
CJT:fcl

Após a execução da macro, a ferramenta indentifica que "===," não é um nó não-terminal, e que "=====P<:n(M S) tribunal" é uma palavra. Logo, não será necessário uma troca de posição entre estes tokens, obtendo-se o seguinte resultado:

====P<:num('1948' M S)		1948
==,
=P:v-fin('declarar' PS 3S IND)	declarou
=ACC:icl
==P:v-inf('estar' V INF)	estar
==SC:ap
===H:adj('pronto' F S)	pronta
===A<:pp
====H:prp('para')	para
====P<:icl
=====P:v-inf('defender' V INF)	defender
=====ACC:np
======>N:art('o' M P)	os
======>N:pron-det('seu' M P)	seus
=======H:n('direito' M P)	direitos
=====ADVL:pp
======H:prp('em')	em
======P<:n('tribunal' M S)	tribunal
==,
CO:conj-c('e')	e
CJT:fcl

Exemplo 2: subir o nível de um nó não-terminal "D" sem sua eliminação - todos os seus descendentes também serão modificados, conforme ilustra esquematicamente a Figura 1.

AntesDepois
Figura 1 - Subir nível de um nó não-terminal sem sua eliminação

Após verificar todos os nós a serem deslocados, a ferramenta pergunta se o nó não-terminal selecionado "D" deve ser eliminado. Neste caso, a resposta é negativa. Se a resposta fosse positiva, todos os seus descendentes ficariam dominados imediatamente por "C" (exemplo 3).

Subir o nível de ADVL:pp

STA:fcl
P:v-fin('invocar' PS/MQP 3P IND)	Invocaram-
ACC:pron-pers('se' M/F S/P)	se
SUBJ:np
=>N:art('a' F P)	as
=H:n('evidência' F P)	evidências
=N<:fcl
==ACC:pron-indp('que' F P)	que
==SUBJ:np
===>N:art('o' M S)	o
===H:n('ministério' M S)	ministério
==P:v-fin('apresentar' PS 3S IND)	apresentou
==ADVL:pp
===H:prp('para')	para
===P<:np
====>N:art('a' F S)	a
====H:n('resolução' F S)	resolução
====N<:pp
=====H:prp('de')	de
=====>N:art('o' M S)	o
=====H:n('caso' M S)	caso
.

Após o deslocamento temos:

STA:fcl
P:v-fin('invocar' PS/MQP 3P IND)	Invocaram-
ACC:pron-pers('se' M/F S/P)	se
SUBJ:np
=>N:art('a' F P)	as
=H:n('evidência' F P)	evidências
=N<:fcl
==ACC:pron-indp('que' F P)	que
==SUBJ:np
===>N:art('o' M S)	o
===H:n('ministério' M S)	ministério
==P:v-fin('apresentar' PS 3S IND)	apresentou
ADVL:pp
=H:prp('para')	para
=P<:np
==>N:art('a' F S)	a
==H:n('resolução' F S)	resolução
==N<:pp
===H:prp('de')	de
===>N:art('o' M S)	o
===H:n('caso' M S)	caso
.

Exemplo 3: subir o nível de um nó não-terminal "D" com sua eliminação - serão modificados os níveis de todos os seus descendentes, conforme ilustra esquematicamente a Figura 2.

AntesDepois
Figura 2 - Subir nível de um nó não-terminal com sua eliminação

Neste exemplo, após identificar todos os nós a serem deslocados, a ferramenta pergunta ao usuário se o nó selecionado "D" deve ser eliminado. Neste caso a resposta é positiva - todos os seus descendentes ficarão dominados imediatamente por "C".

Como exemplo, pode-se subir o nível de CJT:fcl, com sua eliminação.

STA:cu
CJT:fcl 
=SUBJ:np 
==>N:art('o' M S)       O
==H:n('Governo'  M S)   Governo
=P:v-fin('inaugurar' PS 3S IND) inaugurou
=ACC:n('ponte' F P)     pontes
=CO:conj-c('e' )        e
=SUBJ:n('estrada' F P)  estradas
=,
CO:conj-c('mas'  )      mas
CJT:fcl 
="«

Após o deslocamento temos:

STA:cu
SUBJ:np 
=>N:art('o' M S)       O
=H:n('Governo'  M S)   Governo
P:v-fin('inaugurar' PS 3S IND) inaugurou
ACC:n('ponte' F P)     pontes
CO:conj-c('e' )        e
SUBJ:n('estrada' F P)  estradas
,
CO:conj-c('mas'  )      mas
CJT:fcl 
="«

Exemplo 4: Subir o nível de uma palavra ("a") sem eliminar o nó não-terminal a que ela pertence ("C"). A palavra "a" deixará de ser dominada imediatamente pelo nó não-terminal "C" para ser dominada imediatamente pelo nó não-terminal "B", conforme ilustra a figura 3.

AntesDepois
Figura 3 - Subir nível de um nó não-terminal sem a eliminação
do não-terminal a que ele pertence

Como exemplo, vamos imaginar que o usuário deseja subir o nível de "=ADVL:adv('ainda') ainda", e que o "ADVL:adv" é dependente da oração infinitiva cujo predicado é "fazer". A análise seria:

A1 
STA:fcl 
P:v-fin('conseguir'  PR 1S IND)    Consigo
ACC:icl
=ADVL:adv('ainda')       ainda
=P:v-inf('fazer')       fazer
=ACC:np
==>N:art('o'  M S)	o        
==H:n('pino' M S)       pino
.

A revisão leva a trocar a posição de =ADVL:adv pela de ACC:icl, subindo um nível:

A1
STA:fcl 
P:v-fin('conseguir'  PR 1S IND)    Consigo
ADVL:adv('ainda')       ainda
ACC:icl
=P:v-inf('fazer')       fazer
=ACC:np
==>N:art('o'  M S)	o        
==H:n('pino' M S)       pino
.

2. aumenta-indentacao

(atalho: ctrl-alt-seta para baixo).
Esta macro deve ser utilizada para aumentar a indentação (descer o nível) de nós não-terminais ou de nós-folha (palavra ou sinal de pontuação). Se a macro for executada em nó não-terminal, todos os seus descendentes também serão modificados.

Após identificar o tipo do nó selecionado (terminal ou não-terminal), a ferramenta pergunta ao usuário se o deslocamento deve ser feito para uma ramificação à direita ou para uma ramificação à esquerda. Ou seja, se o nó em questão deverá ficar dependente do nó à sua direita ou do nó à sua esquerda. Além disso, esta macro permite que o usuário aumente a indentação do nó selecionado através da inserção de um novo nó não-terminal (construção de um novo constituinte).

Exemplo 5: Descer o nível de um nó não-terminal ("D") com a inserção de um novo nó não-terminal ("X"). A Figura 4 ilustra este deslocamento.

AntesDepois
Figura 4 - Descer nível de um nó não-terminal com a inserção de um novo nó

Nota-se que a árvore produzida após este deslocamento fica momentaneamente "incorreta", pois as opções lingüísticas das ferramentas do projeto VISL não permitem a existência de um nó não-terminal com um único descendente. Espera-se, então, que o usuário execute um novo deslocamento (exemplo 6). Como exemplo, imaginemos que o usuário quer introduzir um nó antes de H:cu, cuja designação será H:np.

STA:fcl
SUBJ:np
=>N:art('a' F S)	A
=H:n('pianista' F S)	pianista
P:v-fin('interpretar' FUT 3S IND)	interpretará
ACC:np
=H:cu
==CJT:np
===>N:art('o' M S)	o
====H:n('concerto' M S)	concerto
==CO:conj-c('e')	e
==CJT:np
===>N:art('a' F S)	a
===H:n('sinfonia' F S)	sinfonia
=N<:np
==H:n('número' M S)	número
==N<:num('1' M S)	1
=N<:pp
==H:prp('de')	de
==P<:prop('Chopin' M S)	Chopin

Após a execução da macro, obteremos o seguinte resultado:

STA:fcl
SUBJ:np
=>N:art('a' F S)	A
=H:n('pianista' F S)	pianista
P:v-fin('interpretar' FUT 3S IND)	interpretará
ACC:np
=H:np
==H:cu
===CJT:np
====>N:art('o' M S)	o
=====H:n('concerto' M S)	concerto
===CO:conj-c('e')	e
===CJT:np
====>N:art('a' F S)	a
====H:n('sinfonia' F S)	sinfonia
=N<:np
==H:n('número' M S)	número
==N<:num('1' M S)	1
=N<:pp
==H:prp('de')	de
==P<:prop('Chopin' M S)	Chopin

Exemplo 6: Descer nível de um nó não-terminal ("E"), deslocando-o para a esquerda. A Figura 5 ilustra este deslocamento.

AntesDepois
Figura 5 - Descer nível de um nó não-terminal com deslocamento para a esquerda

No exemplo seguinte, queremos associar o sintagma nominal "número 1" ao sintagma nominal "a sinfonia", ou seja, descer o nível deste último juntando-o à esquerda.
STA:fcl
SUBJ:np
=>N:art('a' F S)	A
=H:n('pianista' F S)	pianista
P:v-fin('interpretar' FUT 3S IND)	interpretará
ACC:np
=H:np
==H:cu
===CJT:np
====>N:art('o' M S)	o
=====H:n('concerto' M S)	concerto
===CO:conj-c('e')	e
===CJT:np
====>N:art('a' F S)	a
====H:n('sinfonia' F S)	sinfonia
=N<:np
==H:n('número' M S)	número
==N<:num('1' M S)	1
=N<:pp
==H:prp('de')	de
==P<:prop('Chopin' M S)	Chopin

Após a execução da macro, obteremos o seguinte resultado:

STA:fcl
SUBJ:np
=>N:art('a' F S)	A
=H:n('pianista' F S)	pianista
P:v-fin('interpretar' FUT 3S IND)	interpretará
ACC:np
=H:np
==H:cu
===CJT:np
====>N:art('o' M S)	o
=====H:n('concerto' M S)	concerto
===CO:conj-c('e')	e
===CJT:np
====>N:art('a' F S)	a
====H:n('sinfonia' F S)	sinfonia
====N<:np
=====H:n('número' M S)	número
=====N<:num('1' M S)	1
=N<:pp
==H:prp('de')	de
==P<:prop('Chopin' M S)	Chopin

Exemplo 7: Descer nível de um nó terminal ("b"), deslocando-o para a direita. A Figura 6 ilustra este deslocamento.

AntesDepois
Figura 6 - Descer nível de um nó terminal com deslocamento para a direita

O exemplo seguinte baixa o nível do advérbio ainda ligando-o à oração infinitiva seguinte (à direita):

STA:fcl
SUBJ:np
=>N:art('a' F S)	A
=H:np('Câmara_Municipal' F S)	Câmara_Municipal
=N<:pp
==H:prp('de')	de
==P<:prop('Lisboa' F S)	Lisboa
P:v-fin('afirmar' P 3S IND)	afirma
ADVL:adv('ainda')	ainda
ACC:cu
=CJT:icl
==ADVL:adv('não)	não
==P:vp
===AUX:v-inf('ter')	ter
===AUX:v-pcp('ser')      sido
===MV:v-pcp('levantar' M S)      levantado
==ACC:pron-det('nenhum' M S)	nenhum
=CO:conj-c('mas')	mas
=CJT:fcl
==SUB:conj-s('que')	que
==SUBJ:adv('tal')	tal
==P:vp
===AUX:v-fin('vir' FUT 3S IND)     virá
===PRT-AUX<:prp('a')     a
===MV:v-inf('acontecer') acontecer
==ADVL:pp('a_breve_trecho')      a_breve_trecho
.

Após a execução (duas vezes) da macro, obteremos o seguinte resultado:

STA:fcl
SUBJ:np
=>N:art('a' F S)	A
=H:np('Câmara_Municipal' F S)	Câmara_Municipal
=N<:pp
==H:prp('de')	de
==P<:prop('Lisboa' F S)	Lisboa
P:v-fin('afirmar' P 3S IND)	afirma
ACC:cu
=CJT:icl
==ADVL:adv('ainda')	ainda
==ADVL:adv('não)	não
==P:vp
===AUX:v-inf('ter')	ter
===AUX:v-pcp('ser')      sido
===MV:v-pcp('levantar' M S)      levantado
==ACC:pron-det('nenhum' M S)	nenhum
=CO:conj-c('mas')	mas
=CJT:fcl
==SUB:conj-s('que')	que
==SUBJ:adv('tal')	tal
==P:vp
===AUX:v-fin('vir' FUT 3S IND)     virá
===PRT-AUX<:prp('a')     a
===MV:v-inf('acontecer') acontecer
==ADVL:pp('a_breve_trecho')      a_breve_trecho
.

3. diminui-indentacao-selecionado

(atalho: ctrl-alt-seta para esquerda).
Diminui a indentação (sobe o nível), se possível, de todos os tokens selecionados pelo usuário - todos os tokens a serem deslocados devem ser selecionados com o auxílio do mouse ou do teclado, ou ainda com as funções de seleção de texto do Emacs.

Esta macro não se preocupa em verificar se estão sendo deslocados nós terminais ou não-terminais. Apenas, retira do início de cada linha selecionada um sinal-de-igual, se houver.

Exemplo 8: subir o nível de todos os tokens selecionados.

STA:fcl
SUBJ:np
=>N:art('o' M S)	O
=H:n('procurador' M S)	procurador
P:vp
=AUX:v-fin('ser' PS 3S IND)     foi
=MV:v-pcp('nomear' M S) nomeado
PIV:pp
=H:prp('para')	para
=P<:icl
==P:v-inf('acompanhar')	acompanhar
==ACC:np
===>N:art('a' F S)	a
===H:n('investigação' F S)	investigação
===N<:pp
====H:prp('em')	em
====P<:np
=====>N:art('o' M S)	o
=====H:n('sentido' M S)	sentido
=====N<:pp
======H:prp('de')	de
======P<:icl
=======P:v-inf('promover')	promover
=======ACC:np
========>N:art('um' F S)		uma
========H:n('acareação' F S)	acareação
========N<:pp
=========H:prp('entre')		entre
=========P<:np
==========>N:art('o' M P)	os
==========>N:num('7' M P)	7
==========H:n('indivíduo' M P)	indivíduos 
.

Após a execução da macro, temos:

STA:fcl
SUBJ:np
=>N:art('o' M S)	O
=H:n('procurador' M S)	procurador
P:vp
=AUX:v-fin('ser' PS 3S IND)     foi
=MV:v-pcp('nomear' M S) nomeado
PIV:pp
=H:prp('para')	para
=P<:icl
==P:v-inf('acompanhar')	acompanhar
==ACC:np
===>N:art('a' F S)	a
===H:n('investigação' F S)	investigação
ADVL:pp
=H:prp('em')	em
=P<:np
==>N:art('o' M S)	o
==H:n('sentido' M S)	sentido
==N<:pp
===H:prp('de')	de
===P<:icl
====P:v-inf('promover')	promover
====ACC:np
=====>N:art('um' F S)		uma
=====H:n('acareação' F S)	acareação
=====N<:pp
======H:prp('entre')		entre
======P<:np
=======>N:art('o' M P)	os
=======>N:num('7' M P)	7
=======H:n('indivíduo' M P)	indivíduos 
.

4. aumenta-indentacao-selecionado

(atalho: ctrl-alt-seta para direita).
Aumenta a indentação (desce o nível) de todos os tokens selecionados pelo usuário - todos os tokens a serem deslocados devem ser selecionados com o auxílio do mouse ou do teclado, ou ainda com as funções de seleção de texto do Emacs.

Esta macro também não se preocupa em verificar o "tipo" dos nós que estão sendo deslocados. Apenas, acrescenta ao início de cada linha selecionada um sinal-de-igual.

Exemplo 9: descer duas vezes o nível de todos os tokens selecionados.


=P<:np 
==>N:art('o' <-sam> M S)	o
==H:n('contrato' M S)	contrato 
==N<:pp 
===H:prp('com')	com
===P<:prop('Teerão' M S)	Teerão
,
N<:fcl 
=SUBJ:np 
==>N:pron-det('cujo'  M S)	cujo
==H:n('montante' M S)	montante
=ADVL:adv('não')	não
=P:vp
==AUX:v-fin('ser' PS 3S IND)	foi
==P:v-pcp('especificar' M S)	especificado  
=,

Após a execução da macro, temos:

=P<:np 
==>N:art('o' <-sam> M S)	o
==H:n('contrato' M S)	contrato
===N<:pp 
====H:prp('com')	com
====P<:prop('Teerão' M S)	Teerão
==,
==N<:fcl 
===SUBJ:np 
====>N:pron-det('cujo'  M S)	cujo
====H:n('montante' M S)	montante
===ADVL:adv('não')	não
===P:vp
====AUX:v-fin('ser' PS 3S IND)	foi
====P:v-pcp('especificar' M S)	especificado  
=,

Durante a fase de testes do protótipo, verificou-se que algumas tarefas eram constantemente executadas, e para se chegar ao resultado desejado com as macros apresentadas acima, o usuário tem que responder 2 ou 3 perguntas. Então, foram criadas 3 especializações.

  1. baixa-nivel-com-insercao (atalho: ctrl-shift-seta para baixo). Esta macro tem a mesma funcionalidade da macro aumenta-indentacao, mas adiciona automaticamente um novo token (apenas o nome do novo nó é perguntado ao usuário).

  2. subir-nivel-com-eliminacao (atalho: ctrl-shift-seta para cima). Esta macro tem a mesma funcionalidade da macro diminui-indentacao, mas elimina automaticamente o token selecionado. Logo, funciona apenas com nós não-terminais. Se o usuário tentar executar esta macro em uma palavra ou sinal-de-pontuação, uma mensagem de operação ilegal é exibida.

  3. subir-nivel-sem-eliminacao (atalho: ctrl-shift-seta para esquerda). Esta macro tem a mesma funcionalidade da macro diminui-indentacao, mas não executa a eliminação do token selecionado.


Exemplo de utilização

Para exemplificar a utilização do protótipo, utilizaremos um exemplo preparado por Susana Afonso, em Maio de 2001. (Desde essa altura, convém indicar, já se sistematizou X:cu para ?:cu e CJT:fcl para CJT:?, assim como as aspas foram regularizadas, optando-se pela sua colocação imediatamente antes do nó terminal.)

Observe a seguinte frase, retirada do corpus CETEMPúblico:

SOURCE: CETEMPúblico n=65 sec=pol sem=95b
C65-3 O Governo inaugurou pontes e estradas, mas «não foi capaz de
inaugurar» uma Lei de Bases do Ordenamento do Território.

STA:cu 
CJT:fcl 
=SUBJ:np 
==>N:art('o' M S)	O
==H:n('Governo'  M S)	Governo
=P:v-fin('inaugurar' PS 3S IND)	inaugurou
=ACC:n('ponte' F P)	pontes
=CO:conj-c('e' )	e
=SUBJ:n('estrada' F P)	estradas
=,
CO:conj-c('mas'  )	mas
CJT:fcl 
="«
=ADVL:adv('não')	não
=P:v-fin('ser' PS 3S IND)	foi
=SC:ap 
==H:adj('capaz' F S)	capaz
==A<:pp 
===H:prp('de')	de
===P<:icl 
====P:v-inf('inaugurar')	inaugurar
===="»
====ACC:np 
=====>N:art('um'  F S)	uma
=====H:prop('Lei_de_Bases_do_Ordenamento_do_Território' F S)	Lei_de_Bases_do_Ordenamento_do_Território.

A Figura 7 ilustra a mesma frase, porém sendo editada em uma janela do Emacs já com as macros do protótipo ativas em sua memória.


Figura 7 - Edição de árvore sintática com o auxílio do protótipo

Vamos imaginar que o usuário queira alterar o nome do nó não-terminal STA:cu para STA:fcl (manualmente) e eliminar o nó não-terminal CJT:fcl. Para isto, após alterar o nome, o usuário deve posicionar o cursor em CJT:fcl e executar a macro diminui-indentação, que verifica que o nó selecionado é do tipo não-terminal, e pergunta ao usuário se ele deseja a sua eliminação. Neste caso, a resposta será positiva, obtendo-se a estrutura apresentada pela Figura 8.


Figura 8 - Edição de árvore sintática com o auxílio do protótipo

Em seguinda, o usuário deseja introduzir um novo nó não-terminal antes de P:v-fin, cuja designação será X:cu e outro nó não-terminal (CJT:fcl) imediatamente a seguir. Para este deslocamento, ele deve executar 2 vezes a macro aumenta-indentação ou executar, também duas vezes, a macro baixa-nível-com-inserção. Vale lembrar que na segunda opção, o usuário apenas terá que informar o nome do novo nó, não sendo necessário responder a pergunta de inserção ou não-inserção do mesmo. A árvore resultante encontra-se ilustrada pela Figura 9.


Figura 9 - Edição de árvore sintática com o auxílio do protótipo

Neste momento, ele verifica que precisa introduzir nó antes de ACC:n (ACC:cu) e substituir ACC:n, por CJT:n (manualmente) e aumentar nível de CO:conj-c e de SUBJ:n (cujo nome será alterado manualmente para CJT), conforme ilustra a Figura 10. Para este deslocamento, ele terá que primeiramente executar a macro aumenta-indentação, reponder positivamente pela inserção de um novo nó e informar o nome do mesmo. Em seguinda, manualmente, modificar o nome de ACC:n. E, então, executar a macro aumenta-indentação, respondendo negativamente quanto à inserção de um novo nó, para cada nó terminal que se deseja deslocar. Melhor ainda, se ao invés de executar tantos passos, o usuário selecionar estes dois nós e executar a macro aumenta-indentação-selecionado. Em qualquer caso, o resultado será o mesmo (Figura 10)


Figura 10 - Edição de árvore sintática com o auxílio do protótipo

E, em seguida, repara que o nível do nó ACC:cu tem de ser aumentado (Figura 11 - aumenta-indentação).


Figura 11 - Edição de árvore sintática com o auxílio do protótipo

Finalmente, aumentar o nível da vírgula, CO:conj-c e CJT:fcl (Figura 12 - aumenta-indentação-selecionado.


Figura 12 - Edição de árvore sintática com o auxílio do protótipo

Terminada a análise, basta guardar o arquivo, ou mesmo editar outras árvores que estejam contidas neles. Uma recomendação é que o usuário sempre faça cópias de segurança dos arquivos manipulados pela ferramenta, pois deste modo, ele pode comparar uma determinada árvore sintática original com as manipulalas por ele.

Preparação do ambiente de trabalho

Para instalar o protótipo, o usuário deve seguir os seguintes passos:

  1. Copiar o arquivo floresta.el para um diretório local.

  2. Inserir em seu arquivo .emacs (Linux/Unix) ou _emacs (Windows) a linha de comando: (load-library "~/floresta.el") - neste caso, o arquivo está armazenado em seu diretório raiz (/ ou C:\, na maioria dos casos).

Trabalhos futuros

Algumas das funcionalidades que podem ser incorporadas ao protótipo apresentado são:

  1. Visualização. Uma frase pode conter muitos tokens, o que dificulta a visualização estrutural da árvore sintática correspondente, e consequentemente, a sua análise. Para reduzir este problema, seria interessante a implementação de macros que possibilitem ao usuário expandir e contrair as ramificações das árvores. Essa funcionalidade foi prevista no levantamento inicial de requisitos inicial, mas não foi implementada.

  2. Histórico de edição. Uma mesma frase pode sofrer várias modificações, e estas serem feitas por usuários diferentes. Na versão atual, não se sabe quen efetuou as modificações e nem quantos ou quais deslocamentos foram necessários para se chegar ao estado final de uma determinada árvore. Seria interessante a incorporação de novas macros que guardem o histórico de todas as modificações realizadas em uma determinada árvore, bem como que faça uma assinatura "digital" do autor das modificações.

  3. Generalização. Na versão atual, o protótipo apresentado apenas consegue manipular árvores produzidas pelas ferramentas do projeto VISL, ou árvores que obedeçam a mesma formalismo sintático. Uma modificação muito interessante, seria a generalização do protótipo, de modo que outras árvores pudessem ser manipuladas/editadas.


Considerações finais

Além dos recursos de deslocamento apresentados, foram criadas macros que modificam o ambiente de edição do Emacs para que ele fique semelhante a editores baseados em Windows - funções de teclado (início e fim de linha, seleção de texto, deleção de caracteres e palavras) e funções de mouse. Isto permite que usuários não acostumados com este editor, possam trabalhar com mais facilidade.

A ferramenta foi testada e utilizada por Susana Afonso, Eckhard Bick e Raquel Marchi, que ajudaram na indentificação dos problemas, bem como fizeram muitas propostas construtivas quanto a funcionalidades ausentes e redundantes nas versões preliminares do protótipo.