DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T p

⟦acea9c067⟧ TextFile

    Length: 17928 (0x4608)
    Types: TextFile
    Names: »parser.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/World/parser.c« 

TextFile

#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;
    }
}