Next: Mais exemplos Up: As DCGs como analisadores Previous: Invocar uma DCG
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