Exemplo 2
/* Exemplo de PLN
recursivo descendente */
#include <stdio.h>
#define MAX 100
#define NOUN 1
#define VERB 2
#define ADJ 3
#define ADV 4
#define DET 5
#define PREP 6
#define TERM 7
/* estrutura do
banco de dados das palavras (wdb) */
struct word {
char word [20];
char type;
};
struct word wdb[MAX]; /* matriz da estrutura do db */
int db_pos=0; /* numero de entradas no wdb */
char s[80]; /* contem a sentenca */
char *t_pos=0; /* pontos na sentenca */
char token[80]; /* contem a palavra */
/* coloca os fatos
no banco de dados */
assert_wdb(word,type){
char *word;
int type;
if(db_pos<MAX)
{
strcpy(wdb[db_pos].word,word);
wdb[db_pos].type=type;
db_pos++;
}
else printf ("O banco de dados esta cheio.\n");
}
setup( )
{
assert_wdb("door",NOUN);
assert_wdb("window",NOUN);
assert_wdb("house",NOUN);
assert_wdb("child",NOUN);
assert_wdb("has",VERB);
assert_wdb("runs",VERB);
assert_wdb("plays",VERB);
assert_wdb("large",ADJ);
assert_wdb("quickly",ADV);
assert_wdb("the",DET);
assert_wdb("a",DET);
assert_wdb("to",PREP);
assert_wdb(".",TERM);
}
/* analisador PLN recursivo descendente livre de contexto */
parse( )
{
if (!nounphrase( )) return 0;
if (!verbphrase( )) return 0;
if (!terminator( )) return0;
return 1;
}
/* le da entrada uma oracao substantiva */
nounphrase( )
{
char type;
get_token( );
type=find_type(token);
switch(type) {
case DET:
get_token( );
type=find_type(token);
if (type==NOUN) return 1;
else if (type==ADJ){
get_token();
type=find_type(token);
if (type==NOUN) return 1;
}
break;
case PREP:
return nounphrase();
}
return 0;
}
/* le uma oracao verbal */
verbphrase( )
{
char type,*pos;
get_token( );
type=find_type(token);
if (type!=VERB) return 0; /* precisa comecar comum verbo */
pos=t_pos; /* salva a posicao corrente */
/* verbo + adverbio
+ NP */
if(verb_adv_np()) return 1;
/* verbo + NP */
t_pos=pos;
if (verb_np( )) return 1;
/* verbo + adverbio
- nao NP */
t_pos=pos;
if (verb_adv( )) return 1;
/* apenas o verbo
*/
return 1;
}
verb_np( )
{
/* verbo + NP */
return nounphrase ( );
}
verb_adv_np( )
{
char type;
get token ( );
type=find_type (token);
if (type==ADV && nounphrase ( )) return 1;
return 0;
}
verb_adv( )
{
char type;
get_token ( );
type=find_type(token);
return (type == ADV);
}
terminator( )
{
get_token( );
return (find_type(token)==TERM);
}
/* acha o tipo
dando a palavra */
find_type(word){
char *word;
int t;
for (t=0; t<db_pos; t++)
if (!strcmp(word,wdb[t].word))
return wdb[t].type;
return 0;
}
/* retorna um "token" atraves da entrada */
get_token ( )
{
char *p;
p=token;
/* pula espacos */
while (*t_pos == ' ') t_pos++;
if (*t_pos== '.') {
*p++='.';
*p='\0';
return;
}
/* le uma palavra ate um espaco ou ponto */
while(*t_pos!=' ' && *t_pos!='.') {
*p=*t_pos++;
p++;
}
*p='\0'
}
main ()
{
setup();
printf("Entre com a sentenca:");
gets(s);
t_pos=s;
if(parse()) printf("Sentenca OK\n");
else printf ("Erro na sentenca\n");
}