home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume2 / advsys / part03 / advprs.c < prev    next >
C/C++ Source or Header  |  1987-10-23  |  7KB  |  332 lines

  1.  
  2. /* advprs.c - adventure parser */
  3. /*
  4.     Copyright (c) 1986, by David Michael Betz
  5.     All rights reserved
  6. */
  7.  
  8. #include "advint.h"
  9. #include "advdbs.h"
  10.  
  11. /* parser result variables */
  12. int nouns[20];
  13. int *adjectives[20];
  14. static int actor,action,dobject,ndobjects,iobject;
  15. static int flag;
  16.  
  17. /* external routines */
  18. extern char *trm_get();
  19.  
  20. /* external variables */
  21. extern char line[];    /* line buffer */
  22.  
  23. /* local variables */
  24. static char *lptr;    /* line pointer */
  25. static int words[100];    /* word table */
  26. static char *wtext[100];/* word text table */
  27. static int *wptr;    /* word pointer */
  28. static int wcnt;    /* word count */
  29.  
  30. static int verbs[3];     /* words in the verb phrase */
  31. static int nnums[20];    /* noun word numbers */
  32. static int nptr;    /* noun pointer (actually, an index) */
  33. static int adjs[100];     /* adjective lists */
  34. static int anums[100];    /* adjective word numbers */
  35. static int aptr;    /* adjective pointer (actually, an index) */
  36.  
  37. /* parse - read and parse an input line */
  38. int parse()
  39. {
  40.     if (!parse1())
  41.     return (FALSE);
  42.     setvalue(V_ACTOR,actor);
  43.     setvalue(V_ACTION,action);
  44.     setvalue(V_DOBJECT,dobject);
  45.     setvalue(V_NDOBJECTS,ndobjects);
  46.     setvalue(V_IOBJECT,iobject);
  47.     return (TRUE);
  48. }
  49.  
  50. /* next - get the next command (next direct object) */
  51. int next()
  52. {
  53.     if (getvalue(V_NDOBJECTS) > 1) {
  54.     setvalue(V_ACTOR,actor);
  55.     setvalue(V_ACTION,action);
  56.     setvalue(V_DOBJECT,getvalue(V_DOBJECT) + 1);
  57.     setvalue(V_NDOBJECTS,getvalue(V_NDOBJECTS) - 1);
  58.     setvalue(V_IOBJECT,iobject);
  59.     return (TRUE);
  60.     }
  61.     else
  62.     return (FALSE);
  63. }
  64.  
  65. /* parse1 - the main parser */
  66. int parse1()
  67. {
  68.     int noun1,cnt1,noun2,cnt2;
  69.     int preposition,flag;
  70.  
  71.     /* initialize */
  72.     noun1 = noun2 = NIL; cnt1 = cnt2 = 0;
  73.     nptr = aptr = 0;
  74.     preposition = 0;
  75.     flag = 0;
  76.  
  77.     /* initialize the parser result variables */
  78.     actor = action = dobject = iobject = NIL;
  79.     ndobjects = 0;
  80.  
  81.     /* get an input line */
  82.     if (!get_line())
  83.     return (FALSE);
  84.  
  85.     /* check for actor */
  86.     if (wtype(*wptr) == WT_ADJECTIVE || wtype(*wptr) == WT_NOUN) {
  87.     if ((actor = getnoun()) == NIL)
  88.         return (FALSE);
  89.     flag |= A_ACTOR;
  90.     }
  91.  
  92.     /* get verb phrase */
  93.     if (!getverb())
  94.     return (FALSE);
  95.  
  96.     /* direct object, preposition and indirect object */
  97.     if (*wptr) {
  98.  
  99.     /* get the first set of noun phrases (direct objects) */
  100.     noun1 = nptr+1;
  101.     for (;;) {
  102.  
  103.             /* get the next direct object */
  104.             if (getnoun() == NIL)
  105.             return (FALSE);
  106.         ++cnt1;
  107.  
  108.         /* check for more direct objects */
  109.         if (*wptr == NIL || wtype(*wptr) != WT_CONJUNCTION)
  110.         break;
  111.         wptr++;
  112.     }
  113.  
  114.     /* get the preposition and indirect object */
  115.     if (*wptr) {
  116.  
  117.         /* get the preposition */
  118.         if (wtype(*wptr) == WT_PREPOSITION)
  119.         preposition = *wptr++;
  120.  
  121.         /* get the second set of noun phrases (indirect object) */
  122.         noun2 = nptr+1;
  123.         for (;;) {
  124.  
  125.             /* get the next direct object */
  126.             if (getnoun() == NIL)
  127.                 return (FALSE);
  128.         ++cnt2;
  129.  
  130.         /* check for more direct objects */
  131.         if (*wptr == NIL || wtype(*wptr) != WT_CONJUNCTION)
  132.             break;
  133.         wptr++;
  134.         }
  135.     }
  136.  
  137.     /* make sure this is the end of the sentence */
  138.     if (*wptr) {
  139.         parse_error();
  140.         return (FALSE);
  141.     }
  142.     }
  143.  
  144.     /* setup the direct and indirect objects */
  145.     if (preposition) {
  146.     if (cnt2 > 1) {
  147.         parse_error();
  148.         return (FALSE);
  149.     }
  150.     dobject = noun1;
  151.     ndobjects = cnt1;
  152.     iobject = noun2;
  153.     }
  154.     else if (noun2) {
  155.     if (cnt1 > 1) {
  156.         parse_error();
  157.         return (FALSE);
  158.     }
  159.     preposition = findword("to");
  160.     dobject = noun2;
  161.     ndobjects = cnt2;
  162.     iobject = noun1;
  163.     }
  164.     else {
  165.     dobject = noun1;
  166.     ndobjects = cnt1;
  167.     }
  168.  
  169.     /* setup the flags for the action lookup */
  170.     if (dobject) flag |= A_DOBJECT;
  171.     if (iobject) flag |= A_IOBJECT;
  172.  
  173.     /* find the action */
  174.     if ((action = findaction(verbs,preposition,flag)) == NIL) {
  175.     parse_error();
  176.     return (FALSE);
  177.     }
  178.  
  179.     /* return successfully */
  180.     return (TRUE);
  181. }
  182.  
  183. /* getverb - get a verb phrase and return the action it refers to */
  184. int getverb()
  185. {
  186.     /* get the verb */
  187.     if (*wptr == NIL || wtype(*wptr) != WT_VERB) {
  188.     parse_error();
  189.     return (NIL);
  190.     }
  191.     verbs[0] = *wptr++;
  192.     verbs[1] = NIL;
  193.  
  194.     /* check for a word following the verb */
  195.     if (*wptr) {
  196.     verbs[1] = *wptr;
  197.     verbs[2] = NIL;
  198.     if (checkverb(verbs))
  199.         wptr++;
  200.     else {
  201.         verbs[1] = words[wcnt-1];
  202.         if (checkverb(verbs))
  203.         words[--wcnt] = NIL;
  204.         else {
  205.         verbs[1] = NIL;
  206.         if (!checkverb(verbs)) {
  207.             parse_error();
  208.             return (NIL);
  209.         }
  210.         }
  211.     }
  212.     }
  213.     return (T);
  214. }
  215.  
  216. /* getnoun - get a noun phrase and return the object it refers to */
  217. int getnoun()
  218. {
  219.     /* initialize the adjective list pointer */
  220.     adjectives[nptr] = adjs + aptr;
  221.  
  222.     /* get the optional article */
  223.     if (*wptr != NIL && wtype(*wptr) == WT_ARTICLE)
  224.     wptr++;
  225.  
  226.     /* get optional adjectives */
  227.     while (*wptr != NIL && wtype(*wptr) == WT_ADJECTIVE) {
  228.     adjs[aptr] = *wptr++;
  229.     anums[aptr] = wptr - words - 1;
  230.     aptr++;
  231.     }
  232.     adjs[aptr++] = NULL;
  233.  
  234.     /* get the noun itself */
  235.     if (*wptr == NIL || wtype(*wptr) != WT_NOUN) {
  236.     parse_error();
  237.     return (NIL);
  238.     }
  239.  
  240.     /* save the noun */
  241.     nouns[nptr] = *wptr++;
  242.     nnums[nptr] = wptr - words - 1;
  243.     return (++nptr);
  244. }
  245.  
  246. /* get_line - get the input line and lookup each word */
  247. int get_line()
  248. {
  249.     /* read an input line */
  250.     trm_chr(':');
  251.     if ((lptr = trm_get(line)) == NULL) {
  252.     trm_str("Speak up!  I can't hear you!\n");
  253.     return (FALSE);
  254.     }
  255.  
  256.     /* get each word on the line */
  257.     for (wcnt = 0; skip_spaces(); wcnt++)
  258.     if (get_word() == NIL)
  259.         return (FALSE);
  260.     words[wcnt] = NIL;
  261.  
  262.     /* check for a blank line */
  263.     if (wcnt == 0) {
  264.     trm_str("Speak up!  I can't hear you!\n");
  265.     return (FALSE);
  266.     }
  267.  
  268.     /* point to the first word and return successfully */
  269.     wptr = words;
  270.     return (TRUE);
  271. }
  272.  
  273. /* skip_spaces - skip leading spaces */
  274. int skip_spaces()
  275. {
  276.     while (spacep(*lptr))
  277.     lptr++;
  278.     return (*lptr != EOS);
  279. }
  280.  
  281. /* show_noun - show a noun phrase */
  282. show_noun(n)
  283.   int n;
  284. {
  285.     int adj,*p;
  286.  
  287.     /* print the adjectives */
  288.     for (p = adjectives[n-1], adj = FALSE; *p; p++, adj = TRUE) {
  289.     if (adj) trm_chr(' ');
  290.     trm_str(wtext[anums[p-adjs]]);
  291.     }
  292.  
  293.     /* print the noun */
  294.     if (adj) trm_chr(' ');
  295.     trm_str(wtext[nnums[n-1]]);
  296. }
  297.  
  298. /* get_word - get the next word */
  299. int get_word()
  300. {
  301.     int ch;
  302.  
  303.     /* get the next word */
  304.     for (wtext[wcnt] = lptr; (ch = *lptr) != EOS && !spacep(ch); )
  305.     *lptr++ = (isupper(ch) ? tolower(ch) : ch);
  306.     if (*lptr != EOS) *lptr++ = EOS;
  307.  
  308.     /* look up the word */
  309.     if (words[wcnt] = findword(wtext[wcnt]))
  310.     return (words[wcnt]);
  311.     else {
  312.     trm_str("I don't know the word \"");
  313.     trm_str(wtext[wcnt]);
  314.     trm_str("\".\n");
  315.     return (NIL);
  316.     }
  317. }
  318.  
  319. /* spacep - is this character a space? */
  320. int spacep(ch)
  321.   int ch;
  322. {
  323.     return (ch == ' ' || ch == ',' || ch == '.');
  324. }
  325.  
  326. /* parse_error - announce a parsing error */
  327. parse_error()
  328. {
  329.     trm_str("I don't understand.\n");
  330. }
  331.  
  332.