|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T a
Length: 6939 (0x1b1b) Types: TextFile Names: »advprs.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Advsys/advprs.c«
/* 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"); }