home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource4
/
251_01
/
advprs.c
< prev
next >
Wrap
Text File
|
1987-10-29
|
7KB
|
331 lines
/* advprs.c - adventure parser */
/*
Copyright (c) 1986, by David Michael Betz
All rights reserved
*/
#include "advint.h"
#include "advdbs.h"
/* parser result variables */
int nouns[20];
int *adjectives[20];
static int actor,action,dobject,ndobjects,iobject;
static int flag;
/* external routines */
extern char *trm_get();
/* external variables */
extern char line[]; /* line buffer */
/* local variables */
static char *lptr; /* line pointer */
static int words[100]; /* word table */
static char *wtext[100];/* word text table */
static int *wptr; /* word pointer */
static int wcnt; /* word count */
static int verbs[3]; /* words in the verb phrase */
static int nnums[20]; /* noun word numbers */
static int nptr; /* noun pointer (actually, an index) */
static int adjs[100]; /* adjective lists */
static int anums[100]; /* adjective word numbers */
static int aptr; /* adjective pointer (actually, an index) */
/* parse - read and parse an input line */
int parse()
{
if (!parse1())
return (FALSE);
setvalue(V_ACTOR,actor);
setvalue(V_ACTION,action);
setvalue(V_DOBJECT,dobject);
setvalue(V_NDOBJECTS,ndobjects);
setvalue(V_IOBJECT,iobject);
return (TRUE);
}
/* next - get the next command (next direct object) */
int next()
{
if (getvalue(V_NDOBJECTS) > 1) {
setvalue(V_ACTOR,actor);
setvalue(V_ACTION,action);
setvalue(V_DOBJECT,getvalue(V_DOBJECT) + 1);
setvalue(V_NDOBJECTS,getvalue(V_NDOBJECTS) - 1);
setvalue(V_IOBJECT,iobject);
return (TRUE);
}
else
return (FALSE);
}
/* parse1 - the main parser */
int parse1()
{
int noun1,cnt1,noun2,cnt2;
int preposition,flag;
/* initialize */
noun1 = noun2 = NIL; cnt1 = cnt2 = 0;
nptr = aptr = 0;
preposition = 0;
flag = 0;
/* initialize the parser result variables */
actor = action = dobject = iobject = NIL;
ndobjects = 0;
/* get an input line */
if (!get_line())
return (FALSE);
/* check for actor */
if (wtype(*wptr) == WT_ADJECTIVE || wtype(*wptr) == WT_NOUN) {
if ((actor = getnoun()) == NIL)
return (FALSE);
flag |= A_ACTOR;
}
/* get verb phrase */
if (!getverb())
return (FALSE);
/* direct object, preposition and indirect object */
if (*wptr) {
/* get the first set of noun phrases (direct objects) */
noun1 = nptr+1;
for (;;) {
/* get the next direct object */
if (getnoun() == NIL)
return (FALSE);
++cnt1;
/* check for more direct objects */
if (*wptr == NIL || wtype(*wptr) != WT_CONJUNCTION)
break;
wptr++;
}
/* get the preposition and indirect object */
if (*wptr) {
/* get the preposition */
if (wtype(*wptr) == WT_PREPOSITION)
preposition = *wptr++;
/* get the second set of noun phrases (indirect object) */
noun2 = nptr+1;
for (;;) {
/* get the next direct object */
if (getnoun() == NIL)
return (FALSE);
++cnt2;
/* check for more direct objects */
if (*wptr == NIL || wtype(*wptr) != WT_CONJUNCTION)
break;
wptr++;
}
}
/* make sure this is the end of the sentence */
if (*wptr) {
parse_error();
return (FALSE);
}
}
/* setup the direct and indirect objects */
if (preposition) {
if (cnt2 > 1) {
parse_error();
return (FALSE);
}
dobject = noun1;
ndobjects = cnt1;
iobject = noun2;
}
else if (noun2) {
if (cnt1 > 1) {
parse_error();
return (FALSE);
}
preposition = findword("to");
dobject = noun2;
ndobjects = cnt2;
iobject = noun1;
}
else {
dobject = noun1;
ndobjects = cnt1;
}
/* setup the flags for the action lookup */
if (dobject) flag |= A_DOBJECT;
if (iobject) flag |= A_IOBJECT;
/* find the action */
if ((action = findaction(verbs,preposition,flag)) == NIL) {
parse_error();
return (FALSE);
}
/* return successfully */
return (TRUE);
}
/* getverb - get a verb phrase and return the action it refers to */
int getverb()
{
/* get the verb */
if (*wptr == NIL || wtype(*wptr) != WT_VERB) {
parse_error();
return (NIL);
}
verbs[0] = *wptr++;
verbs[1] = NIL;
/* check for a word following the verb */
if (*wptr) {
verbs[1] = *wptr;
verbs[2] = NIL;
if (checkverb(verbs))
wptr++;
else {
verbs[1] = words[wcnt-1];
if (checkverb(verbs))
words[--wcnt] = NIL;
else {
verbs[1] = NIL;
if (!checkverb(verbs)) {
parse_error();
return (NIL);
}
}
}
}
return (T);
}
/* getnoun - get a noun phrase and return the object it refers to */
int getnoun()
{
/* initialize the adjective list pointer */
adjectives[nptr] = adjs + aptr;
/* get the optional article */
if (*wptr != NIL && wtype(*wptr) == WT_ARTICLE)
wptr++;
/* get optional adjectives */
while (*wptr != NIL && wtype(*wptr) == WT_ADJECTIVE) {
adjs[aptr] = *wptr++;
anums[aptr] = wptr - words - 1;
aptr++;
}
adjs[aptr++] = NULL;
/* get the noun itself */
if (*wptr == NIL || wtype(*wptr) != WT_NOUN) {
parse_error();
return (NIL);
}
/* save the noun */
nouns[nptr] = *wptr++;
nnums[nptr] = wptr - words - 1;
return (++nptr);
}
/* get_line - get the input line and lookup each word */
int get_line()
{
/* read an input line */
trm_chr(':');
if ((lptr = trm_get(line)) == NULL) {
trm_str("Speak up! I can't hear you!\n");
return (FALSE);
}
/* get each word on the line */
for (wcnt = 0; skip_spaces(); wcnt++)
if (get_word() == NIL)
return (FALSE);
words[wcnt] = NIL;
/* check for a blank line */
if (wcnt == 0) {
trm_str("Speak up! I can't hear you!\n");
return (FALSE);
}
/* point to the first word and return successfully */
wptr = words;
return (TRUE);
}
/* skip_spaces - skip leading spaces */
int skip_spaces()
{
while (spacep(*lptr))
lptr++;
return (*lptr != EOS);
}
/* show_noun - show a noun phrase */
show_noun(n)
int n;
{
int adj,*p;
/* print the adjectives */
for (p = adjectives[n-1], adj = FALSE; *p; p++, adj = TRUE) {
if (adj) trm_chr(' ');
trm_str(wtext[anums[p-adjs]]);
}
/* print the noun */
if (adj) trm_chr(' ');
trm_str(wtext[nnums[n-1]]);
}
/* get_word - get the next word */
int get_word()
{
int ch;
/* get the next word */
for (wtext[wcnt] = lptr; (ch = *lptr) != EOS && !spacep(ch); )
*lptr++ = (isupper(ch) ? tolower(ch) : ch);
if (*lptr != EOS) *lptr++ = EOS;
/* look up the word */
if (words[wcnt] = findword(wtext[wcnt]))
return (words[wcnt]);
else {
trm_str("I don't know the word \"");
trm_str(wtext[wcnt]);
trm_str("\".\n");
return (NIL);
}
}
/* spacep - is this character a space? */
int spacep(ch)
int ch;
{
return (ch == ' ' || ch == ',' || ch == '.');
}
/* parse_error - announce a parsing error */
parse_error()
{
trm_str("I don't understand.\n");
}