|
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 p
Length: 17928 (0x4608) Types: TextFile Names: »parser.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/World/parser.c«
#include "parame.inc" #include "variab.h" #include "arrays.h" #include "vocab.inc" #include "verbtb.inc" /* World C Version 1.00 copyright 1987 J.D.McDonald Use as you like for non-commercial purposes, but please leave this note, and document any changes you make as yours */ /* No apologies for all the goto's. If you can get rid of them, well, I guess some persons are just naturally masochists */ static int typlst[4] = {VRBMIN, ADJMIN, NUNMIN, PRPMIN}; static int index[5], indx; scan() /* * this function scans the input line for gross syntax errors it also expands * special direction commands such as "ne" into their full form. it also * works on adverbs, removes such expressions as "ask frog," etc. finally it * puts the word numbers and types in the wrdnum and wrdtyp arrays the input * is inbuf ,the output is wrdnum,wrdtyp,actor,adverb * */ { int result, offlg, askx, lptr0, wptr, i, lxx, errno; result = 0; offlg = 0; chgact = 0; askx = 0; lab5: adverb = 0; for (i = 0; i < 30; i++) { wrdnum[i] = 0; wrdtyp[i] = 0; } /* * wordtyp is -1 for a period,-2 comma 1 for adverb,2 verb,3 adjective,4 * noun,5 preposition numbers are type 4,and wrdnum=number+10000 */ wptr = 0; lab10: lptr0 = lptr; wscan(); /* * on return from wscan punct contains: 0 for a word 1 for a period 2 for * a comma 3 for a number 4 if an illegal character 5 if a number follows * a letter directly 6 if a letter follows a number directly */ if (punct == 1) return (result); else if (punct == 4) goto lab9000; else if (punct == 2) goto lab9010; else if (punct == 3) goto lab9019; else if (punct == 5) goto lab9020; else if (punct == 6) goto lab9140; else; /* it's a real word, so find out what it is */ find(VOCMAX); /* discard buzzword */ if (indx > 0 && indx <= BUZMAX) goto lab10; if (indx == 0) goto lab9040; if ((indx >= NORTH && indx <= NORTHW) || indx == UP || indx == DOWN) { /* yes,it's a special word */ lptr0 = lptr; wscan(); /* check if it's all that's on the line */ if (punct != 1) goto lab9030; /* expand a direction word into full form */ wrdtyp[1] = 4; wrdnum[1] = indx; wrdnum[0] = GO; wrdtyp[0] = 2; wrdtyp[2] = -1; goto lab9999; } if (index[0] != 0) { if (adverb != 0) goto lab9070; /* adverbs are removed from the wrdtyp list and handled separately */ adverb = index[0]; if (adverb != WHERE && adverb != WHAT) goto lab10; if (actor == 1 || askx != ASK) goto lab9130; goto lab10; } if (index[1] == 0) goto lab9050; wrdtyp[wptr] = 2; wrdnum[wptr] = index[1]; /* * we've found the verb check for legal question */ if ((adverb == WHAT || adverb == WHERE) - (wrdnum[0] == IS)) goto lab9130; if (wrdnum[0] == YELL) { /* the player is told to use "ask" or "tell" */ lab131: wscan(); if (punct != 1) goto lab131; wrdtyp[0] = 2; wrdnum[0] = YELL; result = 1; return (result); } if (wrdnum[0] < SHIT) goto lab200; /* * special handling for words which take no objects or modifiers they * should be alone on a line. they are verbs >= shit */ lptr0 = lptr; wscan(); { if (punct == 1) goto lab9998; else if (punct == 5) goto lab9120; else goto lab9150; } /* inner loop for all words after verb */ lab200: wptr += 1; if (wptr > 27) goto lab9180; lab201: lptr0 = lptr; wscan(); if (punct != 0) goto lab210; find(BUZMAX); /* special code for "noun1 of noun2" construct */ if (indx == 4 && wrdtyp[wptr - 1] == 4) offlg = 1; if (indx != 0) goto lab201; goto lab215; lab210: if (punct == 4) goto lab9000; if (punct == 5) goto lab9020; if (punct == 6) goto lab9140; if (punct != 2) goto lab215; if (wrdtyp[wptr - 1] != 4) goto lab9010; wrdtyp[wptr] = -2; goto lab200; lab215: if (wrdtyp[wptr - 1] != 2 || (wrdnum[wptr - 1] != ASK && wrdnum[wptr - 1] != TELL)) goto lab220; if (punct == 3) goto lab9019; if (punct != 0) goto lab9010; if (actor != 1) goto lab9100; /* * this code is to set up addressing a second "person" the phrases "ask * frog" or "tell frog" etc are discarded and the variable "actor" tells * us who is addressed */ askx = wrdnum[wptr - 1]; find(VOCMAX); if ((index[3] != 0) && (index[3] < ROBOT || index[3] > FERRET)) goto lab9090; if (index[3] == 0) goto lab9160; actor = index[3]; lptr0 = lptr; chgact = 1; wscan(); if (punct != 2) goto lab9110; goto lab5; /* code for numbers inputted in a statement */ lab220: if (punct != 3) goto lab240; wrdtyp[wptr] = 4; wrdnum[wptr] = three[0] + 10000; goto lab200; /* all regular words go here */ lab240: if (punct != 1) goto lab250; wrdtyp[wptr] = -1; goto lab9999; lab250: find(VOCMAX); if (indx == 0) goto lab9040; /* special code for "of" handler */ if (offlg) { offlg = 0; if (index[3] != 0 && wrdtyp[wptr - 2] != 3) { /* exchange two nouns and tell parser the first is an adjective */ wrdtyp[wptr] = wrdtyp[wptr - 1]; wrdnum[wptr] = wrdnum[wptr - 1]; wrdtyp[wptr - 1] = 3; wrdnum[wptr - 1] = index[3]; if (wrdnum[wptr] == PHOTOG && wrdnum[wptr - 1] == FERRET) { wrdnum[wptr - 1] = FAMILY; } goto lab200; } else goto lab9200; } if (indx != AND) goto lab270; if (wrdtyp[wptr - 1] == -2) goto lab201; if (wrdtyp[wptr - 1] != 4) goto lab9120; wrdtyp[wptr] = -2; goto lab200; lab270: if (index[1] != 0 && index[0] == 0 && index[2] == 0 && index[3] == 0 && index[4] == 0) goto lab9080; if (index[0] == 0) goto lab280; if (adverb != 0) goto lab9070; adverb = indx; if (adverb == WHERE || adverb == WHAT) goto lab9130; goto lab201; /* at this point the word must be an adjectine, noun or preposition */ lab280: if (wrdtyp[wptr - 1] == 3 && index[2] != 0) goto lab9170; if (index[2] != 0) { wrdtyp[wptr] = 3; wrdnum[wptr] = index[2]; } else if (index[3] != 0) { wrdtyp[wptr] = 4; wrdnum[wptr] = index[3]; } else { wrdtyp[wptr] = 5; wrdnum[wptr] = index[4]; } if ((wrdtyp[wptr] == 4 && wrdtyp[wptr - 1] == 3) && wrdnum[wptr] < SAPPHI) goto lab9190; goto lab200; /*********** error processing */ lab9000: lxx = lptr; errno = 1; goto lab9900; lab9010: lxx = lptr; errno = 2; goto lab9900; lab9019: lptr -= 1; lab9020: lptr += 1; lxx = lptr; errno = 3; goto lab9900; lab9030: lxx = lptr; errno = 4; goto lab9900; lab9040: lxx = lptr; errno = 5; goto lab9900; lab9050: lxx = lptr; errno = 6; goto lab9900; lab9070: lxx = lptr; errno = 8; goto lab9900; lab9080: lxx = lptr; errno = 9; goto lab9900; lab9090: lxx = 0; errno = 10; goto lab9900; lab9100: lxx = 0; errno = 11; goto lab9900; lab9110: lxx = lptr0 + 1; errno = 12; goto lab9900; lab9120: lxx = lptr; errno = 13; goto lab9900; lab9130: lxx = 0; errno = 14; goto lab9900; lab9140: lxx = lptr; errno = 15; goto lab9900; lab9150: lxx = lptr0; errno = 16; goto lab9900; lab9160: lxx = 0; errno = 17; goto lab9900; lab9170: lxx = lptr; errno = 18; goto lab9900; lab9180: lxx = 0; errno = 25; goto lab9900; lab9190: lxx = lptr; errno = 107; goto lab9900; lab9200: lxx = lptr; errno = 112; lab9900: carerr(lxx, errno); return (result); lab9998: wrdtyp[1] = -1; lab9999: if ((askx == TELL && (adverb == WHERE || adverb == WHAT)) || (askx == ASK && (adverb != WHERE && adverb != WHAT))) goto lab9130; if (adverb == WHERE || adverb == WHAT) dotflg = 1; result = 1; return (result); } wscan() /* * this routine reads the input ascii code and scans for punctuation or * numbers and then converts the first 9 letters of a word to three integer*2 * words of radix 32 form */ { char m; static int pow32[] = {1, 32, 1024, 32768}; int plcpnt, wpnt, kchar; if (dotflg) { actor = 1; dotflg = 0; } plcpnt = 1; punct = 0; wpnt = 1; three[0] = 0; three[1] = 0; three[2] = 0; while (inbuf[lptr] == ' ') lptr++; /* * punct =1 is period, 2 is comma, 3 is number,4 is illegal character and * 5 means a number directly follows a word 6 means letter follows a * number */ if (inbuf[lptr] == '.' || inbuf[lptr] == '?') { dotflg = 1; punct = 1; lptr += 1; return (0); } if (inbuf[lptr] == ',') { punct = 2; lptr += 1; return (0); } while (inbuf[lptr] >= '0' && inbuf[lptr] <= '9') { /* number handling */ punct = 3; if (three[0] < 3200) three[0] = three[0] * 10 + inbuf[lptr] - '0'; lptr += 1; } if (punct == 3 && (inbuf[lptr] != '.' && inbuf[lptr] != ',' && inbuf[lptr] != '?' && inbuf[lptr] != ' ')) punct = 6; if (punct == 3 || punct == 6) return (0); do { if (!((inbuf[lptr] >= 'a' && inbuf[lptr] <= 'z') || (inbuf[lptr] >= 'A' && inbuf[lptr] <= 'Z'))) { lptr += 1; punct = 4; return (0); /* the actual letter packing is done here */ } kchar = inbuf[lptr]; if (kchar >= 'a' && kchar <= 'z') kchar -= ' '; if (wpnt < 4) three[wpnt - 1] = three[wpnt - 1] + (kchar - '@') * pow32[3 - plcpnt]; plcpnt += 1; if (plcpnt >= 4) { wpnt += 1; plcpnt = 1; } lptr += 1; m = inbuf[lptr]; if (m == ' ' || m == ',' || m == '.' || m == '?') { if (three[0] != 20741 || three[1] != 14336 || three[2] != 0) return (0); punct = 1; return (0); } } while (m < '0' || m > '9'); punct = 5; return (0); } find(m) int m; { /* * this routine searches a vocabulary to find a word. index, on output, * gives the position of the word in the list. synonyms do not increment * the counter, so index*3-2 is **not** the actual pointer to the word in * the list */ int i, t, k, type; for (i = 0; i < 5; i++) index[i] = 0; t = 0; indx = 0; for (i = 1; i <= m * 3 - 2; i += 3) { if (vocab[i] > 0) indx += 1; if (abs(vocab[i]) != three[0]) continue; if (vocab[i + 1] != three[1]) continue; if (vocab[i + 2] == three[2]) { t = indx; type = 1; for (k = 1; k <= 4; k++) if (indx >= typlst[k - 1]) type = type + 1; index[type - 1] = indx; } } indx = t; } lbit(arg, pow) int arg, pow; { return ((arg & (1 << pow)) != 0); } parse() { /* * subroutine parse this mess deciphers the various direct and indirect * (i.e. second, usually, but in 'give frog cup' the frog is the i.o.) * objects. it associates them with their respective adjectives (dobjs(i) * and doadjs(i) correspond) butflg is set if the "all but" construct is * encountered allflg is set if the "all" construct is enconntered the * d.o. and i.o prepositions are put in prepdo and prepio */ int result, wptr, thevrb, vrbind, vdo, vio, vobj, i; int frstaj, frstnn, errno, tprp; result = 0; thevrb = wrdnum[0]; vrbind = thevrb - VRBMIN + 1; vdo = 0; vio = 0; vobj = 0; if (thevrb < SHIT) { vdo = vrbpdo[vrbind]; vio = vrbpio[vrbind]; vobj = vrbobj[vrbind]; } butflg = 0; allflg = 0; numdo = 0; prepdo = 0; prepio = 0; iobj = 0; ioadj = 0; for (i = 0; i < 12; i++) { dobjs[i] = 0; doadjs[i] = 0; } /* this block is a test for "sit down" or "get up" or "look up" etc */ if (((lbit(vobj, 1) && wrdnum[1] == DOWN) || (lbit(vobj, 2) && wrdnum[1] == UP)) && wrdtyp[2] == -1) { prepdo = wrdnum[1]; result = 1; goto finalout; } /* yell allows anything after it */ if (thevrb == YELL) goto testout; wptr = 1; frstaj = 0; frstnn = 0; /* a preposition immediately follows verb */ if (wrdtyp[wptr] == 5) { prepdo = wrdnum[wptr]; if (prepdo == BUT) { errno = 21; goto errorout; } if (!lbit(vdo, (prepdo - PRPMIN))) { errno = 21; goto errorout; } wptr += 1; } /* * adjective follows verb *** special case of "terran" and "cygnan" as * nouns */ if (wrdtyp[wptr] == 3) { if ((wrdnum[wptr] == TERRAN || wrdnum[wptr] == CYGNAN) && wrdnum[0] == TRANSL) wrdtyp[wptr] = 4; else { frstaj = wrdnum[wptr]; doadjs[0] = frstaj; wptr += 1; } } /* this takes care of the case of a verb alone on a line */ if (wrdtyp[wptr] != 4) { if (wrdtyp[wptr] != -1) { errno = 28; goto errorout; } else { { if (thevrb >= SHIT) { result = 1; goto finalout; } if (!lbit(vobj, 7)) { result = 1; goto finalout; } } errno = 27; goto errorout; } } frstnn = wrdnum[wptr]; /* look at first set of objects (not always d.o.) */ dobjs[0] = frstnn; numdo += 1; if (numdo == 9) { errno = 25; goto errorout; } wptr += 1; /* the following takes care of multiple objects */ if (frstnn == ALL) { if (!lbit(vobj, 5)) { errno = 22; goto errorout; } if (frstaj != 0) { errno = 26; goto errorout; } allflg = 1; if (wrdnum[wptr] == BUT) { butflg = 1; /* check for adjective before noun */ if (!(wrdtyp[wptr + 1] == 4 || (wrdtyp[wptr + 1] == 3 && wrdtyp[wptr + 2] == 4))) { errno = 23; goto errorout; } wptr += 1; } } if (butflg || (wrdtyp[wptr] == -2)) { if (!lbit(vobj, 5)) { errno = 22; goto errorout; } mulobj(&wptr); if (numdo > 9) { errno = 25; goto errorout; } } /********** end multiple obj processor */ if (wrdtyp[wptr] == -1) goto testout; /* if the verb is "is" we may have a final adjective */ if (thevrb == IS && wrdtyp[wptr] == 3) { doadjs[1] = wrdnum[wptr]; if (wrdtyp[wptr + 1] == -1) goto testout; errno = 20; goto errorout; } /* * if the next word is a noun or adjective, and verb is not "is" we have * a non-prep indirect object such as the frog in "give frog water" */ if (wrdtyp[wptr] == 4 || (wrdtyp[wptr] == 3 && wrdtyp[wptr + 1] == 4)) { if (numdo > 1 || prepdo != 0) { errno = 22; goto errorout; } if (!lbit(vobj, 3)) { errno = 24; goto errorout; } prepio = TO; ioadj = frstaj; iobj = frstnn; doadjs[0] = 0; if (wrdtyp[wptr] == 3) { doadjs[0] = wrdnum[wptr]; wptr += 1; } dobjs[0] = wrdnum[wptr]; numdo = 1; wptr += 1; /****** repeat the multiple obj processor */ if (dobjs[0] == ALL) { if (!lbit(vobj, 5)) { errno = 22; goto errorout; } if (doadjs[0] != 0) { errno = 26; goto errorout; } allflg = 1; if (wrdtyp[wptr] == 5 && wrdnum[wptr] == BUT) { butflg = 1; if (!(wrdtyp[wptr + 1] == 4 || (wrdtyp[wptr + 1] == 3 && wrdtyp[wptr + 2] == 4))) { errno = 23; goto errorout; } } } if (butflg || wrdtyp[wptr] == -2) { if (!lbit(vobj, 5)) { errno = 22; goto errorout; } mulobj(&wptr); if (numdo > 9) { errno = 25; goto errorout; } } /***** end multiple object processor */ if (wrdtyp[wptr] != -1) { errno = 20; goto errorout; } goto testout; } /* the only thing left that is legal is a perpositional construct */ if (wrdtyp[wptr] != 5 || wrdnum[wptr] == BUT || ( wrdtyp[wptr + 1] == 5 && wrdnum[wptr + 1] == BUT)) { errno = 20; goto errorout; } tprp = wrdnum[wptr]; wptr += 1; /* * check for end of line or two preps in a row (e.g. fill the bottle up * with water) */ if (wrdtyp[wptr] == -1 || wrdtyp[wptr] == 5) { if (prepdo != 0 || (!lbit(vdo, (tprp - PRPMIN))) || (!lbit(vobj, 0))) { errno = 20; goto errorout; } prepdo = tprp; if (wrdtyp[wptr] == -1) goto testout; wptr += 1; } if (!lbit(vio, (wrdnum[wptr - 1] - PRPMIN))) { errno = 20; goto errorout; } prepio = wrdnum[wptr - 1]; if (wrdtyp[wptr] == 3) { ioadj = wrdnum[wptr]; wptr += 1; } if (wrdtyp[wptr] != 4) { errno = 20; goto errorout; } iobj = wrdnum[wptr]; wptr += 1; if (wrdtyp[wptr] != -1) { errno = 20; goto errorout; } testout: if ((dobjs[0] == 0 && lbit(vobj, 7)) || (iobj == 0 && lbit(vobj, 6))) { errno = 20; goto errorout; } if (!lbit(vobj, 4) && dobjs[0] != 0 && prepdo == 0) { errno = 19; goto errorout; } result = 1; finalout: if (wrdnum[0] == AGAIN) { for (i = 0; i < 12; i++) { doadjs[i] = zadjs[i]; dobjs[i] = zobjs[i]; } ioadj = ziadj; iobj = ziobj; prepdo = zpdo; prepio = zpio; actor = zactor; adverb = zadvrb; wrdnum[0] = zverb; numdo = znumb; allflg = zall; butflg = zbut; } else { for (i = 0; i < 12; i++) { zadjs[i] = doadjs[i]; zobjs[i] = dobjs[i]; } ziadj = ioadj; ziobj = iobj; zpdo = prepdo; zpio = prepio; zactor = actor; zadvrb = adverb; zverb = wrdnum[0]; zall = allflg; zbut = butflg; } return (result); errorout: carerr(0, errno); return (result); } mulobj(wptr) int *wptr; { /**** multiple opject subroutine from "parse" */ while (1) { if (wrdtyp[*wptr] == 3) { doadjs[numdo] = wrdnum[*wptr]; *wptr += 1; } if (wrdtyp[*wptr] == 4) { numdo += 1; if (numdo > 10) return (1); dobjs[numdo - 1] = wrdnum[*wptr]; *wptr += 1; if (wrdtyp[*wptr] != -2) return (1); } *wptr += 1; } }