Next: Mais exemplos Up: As DCGs como analisadores Previous: Invocar uma DCG

Acrescentar argumentos

Podemos adicionar um qualquer número de argumentos aos símbolos não terminais que estamos a definir numa DCG. Podemos querer acrescentar argumentos, por exemplo, para conseguirmos acordo de número. Caso contrário o analisador sintáctico pode terminar com sucesso com uma frase gramaticalmente incorrecta. Por exemplo todas as frases seguintes estão gramaticalmente incorrectas:

         Os homem vira o disco
         O homem vira os disco
         Os homens vira o disco

No exemplo que se segue vamos adicionar o argumento Numero, que pode estar instanciado quer com singular quer com plural, de modo a sermos capazes de garantir acordo de número. Adicionamos também um outro argumento que nos permitirá distinguir pessoas de coisas. Deste modo, seremos capazes de diferenciar entre o nome homem (pessoa) e o nome disco (coisa) e fazer com que a frase ``o homem vira o disco'' seja aceite enquanto que a frase``o disco vira o homem'' não...

         frase -->
           sintagma_nominal(Numero,pessoa),
           sintagma_verbal(Numero).
         sintagma_nominal(Numero,Tipo) -->
           determinante(Numero),
           nome(Numero,Tipo).
         sintagma_verbal(Numero) -->
           verbo(Numero),
           sintagma_nominal(Numero,coisa).
         determinante(singular) --> [o].
         determinante(plural) --> [os].
         nome(singular,pessoa) --> [homem].
         nome(plural,pessoa) --> [homens].
         nome(singular,coisa) --> [disco].
         verbo(singular) --> [vira].
         verbo(singular) --> [viram].

Também é útil acrescentar argumentos quando pretendemos ver o resultado de um cálculo que ocorre durante o processo de análise sintáctica. Vejamos um exemplo.
Queremos uma gramática que sirva para definir expressões aritméticas simples (envolvendo números de 0 a 9) e que calcule o valor das expressões. Considere-se

         -2+3*5+1

como um exemplo de uma expressão aritmética. No nosso programa lógico Z é o argumento adicional:

         expr(Z) --> termo(X), [+], expr(Y), {Z is X + Y}.
         expr(Z) --> termo(X), [-], expr(Y), {Z is X - Y}.
         expr(Z) --> termo(Z).

         termo(Z) --> numero(X), [*], termo(Y), {Z is X * Y}.
         termo(Z) --> numero(X), [/], termo(Y), {Z is X / Y}.
         termo(Z) --> numero(Z).

         numero(N) --> [+], numero(N).
         numero(N) --> [-], numero(X), {N is 0 - X}.
         numero(N) --> [N], {number(N), 0 =< N, N =< 9}.

Uma possível execução desta gramática será:

         ?- expr(Z,[-,2,+,3,*,5,+,1],[]).
            Z = 14

Vamos agora imaginar que estamos interessados em saber, dada uma frase de entrada, qual a árvore de derivação que representa a estrutura de tal frase. Para isso vamos usar argumentos extra... De maneira a devolvermos a árvore de derivação, vamos adicionar um argumento extra a cada predicado. Este argumento indica que estamos interessados em ver a árvore de derivação construída a partir das árvores das sub frases. Se o interpretador de Prolog poder encontrar um sintagma nominal seguido por um sintagma verbal, as duas árvores de derivação serão combinadas de modo a formar uma árvore de derivação maior, que usa o nome de predicado frase, e que constituirá a árvore da frase completa. Na DCG que se segue Num representa o argumento para o acordo de número; enquanto SN, SV, ... representam os argumentos para a árvore de derivação.

         frase(frase(SN,SV)) -->
           sintagma_nominal(Num,SN),
           sintagma_verbal(Num,SV).


         sintagma_nominal(Num,sintagma_nominal(D,N)) -->
           determinante(Num,D),
           nome(Num,N).
         sintagma_verbal(Num,sintagma_verbal(V,SN)) -->
           verbo(Num,V),
           sintagma_nominal(Num,SN).
         determinante(singular,determinante(o)) --> [o].
         determinante(singular,determinante(a)) --> [a].
         determinante(singular,determinante(um)) --> [um].
         determinante(plural,determinante(os)) --> [os].
         nome(singular,nome(homem)) --> [homem].
         nome(singular,nome(mulher)) --> [mulher].
         nome(plural,nome(homens)) --> [homens].
         nome(singular,nome(disco)) --> [disco].
         nome(singular,nome(livro)) --> [livro].
         verbo(singular,verbo(vira)) --> [vira].
         verbo(singular,verbo(viram)) --> [viram].
         verbo(singular,verbo(escreve)) --> [escreve].

O que se segue é a árvore de derivação (escrita ``toda bonitinha'') para a frase ``a mulher escreve um livro'':

         ?- frase(A,[a,mulher,escreve,um,livro],[]).
            A = frase(
                   sintagma_nominal(
                               determinante(a),
                               nome(mulher)
                   ),
                   sintagma_verbal(
                               verbo(escreve),
                               sintagma_nominal(
                                  determinante(um),
                                  nome(livro)
                               )
                   )
                )

Next: Mais exemplos Up: As DCGs como analisadores Previous: Invocar uma DCG


1999-05-26