Exemplo 3
/* Exemplo de PLN
recursivo descendente que exibe frases */
#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 e exibe frases*/
parse( )
{
char noun[80]; verb[80];
noun[0]='\0'; verb[0]='\0';
if (!nounphrase( )) return 0;
if (!verbphrase( )) return 0;
if (!terminator( )) return0;
printf ("Frase substantiva: %s\n", noun);
printf ("Frase verbo: %s\n", verb);
return 1;
}
/* le da entrada uma oracao substantiva */
nounphrase( ){
char *s;
char type;
get_token( );
type=find_type(token);
switch(type) {
case DET:
strncat (s,token);
strncat (s," ");
get_token( );
type=find_type(token);
strncat (s,token);
strncat (s," ");
if (type==NOUN) return 1;
else if (type==ADJ){
get_token();
strncat (s,token);
strncat (s," ");
type=find_type(token);
if (type==NOUN) return 1;
}
break;
case PREP:
strncat (s,token);
strncat (s," ");
return nounphrase(s);
}
return 0;
}
/* le uma oracao verbal */
verbphrase( ){
char *s;
char type,*pos,
temp[80];
get_token( );
type=find_type(token);
if (type!=VERB) return 0; /* precisa comecar comum verbo */
strncat (s,token);
strncat (s," ");
strcpy(temp,s);
pos=t_pos; /* salva a posicao corrente */
/* verbo + adverbio
+ NP */
if(verb_adv_np(s)) return 1;
/* verbo + NP
*/
t_pos=pos; /* back up */
strcpy(s,temp);
if (verb_np(s)) return 1;
/* verbo + adverbio - nao NP */
t_pos=pos;
strcpy(s,temp);
if (verb_adv( )) return 1;
/* apenas o verbo
*/
return 1;
}
verb_np( ){
char *s;
/* verbo + NP
*/
return nounphrase(s);
}
verb_adv_np(s){
char *s;
char type, temp[80];
get token ( );
type=find_type (token);
strncat (s,token);
strncat (s," ");
if (type==ADV && nounphrase(temp)) {
strcat (s,temp);
return 1;
}
return 0;
}
verb_adv( ){
char *s;
char type;
get_token ( );
type=find_type(token);
strncat (s,token);
strncat (s," ");
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");
}
}