Annotation of coherent/d/bin/lex/lex1.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * lex1.c
                      3:  * main and parsing routines
                      4:  */
                      5: #include "lex.h"
                      6: 
                      7: main(argc, argv)
                      8: char **argv;
                      9: {
                     10:        register i, s;
                     11:        int pflag = 0, tflag = 0, vflag = 0;
                     12: 
                     13:        while (argc>1 && **++argv=='-') {
                     14:                while (*++*argv) switch (**argv) {
                     15:                case 'p':
                     16:                        ++pflag;
                     17:                        break;
                     18:                case 't':
                     19:                        ++tflag;
                     20:                        break;
                     21:                case 'v':
                     22:                        ++vflag;
                     23:                        break;
                     24:                default:
                     25:                        usage();
                     26:                }
                     27:                --argc;
                     28:        }
                     29:        if (argc > 2)
                     30:                usage();
                     31:        if (!tflag) {
                     32:                if ((fileout=fopen(OUTFILE, "w")) == NULL)
                     33:                        error(opnerr, OUTFILE);
                     34:        }
                     35:        if (argc > 1) {
                     36:                if ((filein=fopen(*argv, "r")) == NULL)
                     37:                        error(opnerr, *argv);
                     38:                loutput(0, "#line 1 %s", *argv);
                     39:        }
                     40:        /*
                     41:         * write header section of output
                     42:         */
                     43:        loutput(0, "#include <stdio.h>");
                     44:        loutput(0, "extern\tchar\t\tyytext[];");
                     45:        loutput(0, "extern\tint\t\tyyleng;");
                     46:        loutput(0, "extern\tint\t\tyyscon;");
                     47:        loutput(0, "extern\tint\t\tyyline;");
                     48:        loutput(0, "#define\tinput()\t\tgetchar()");
                     49:        loutput(0, "#define\toutput(c)\tputchar(c)");
                     50:        loutput(0, "#define\tunput(c)\tyyback(c)");
                     51:        loutput(0, "#define\tECHO\t\t%s",
                     52:                "{register n=0; while (n<yyleng) output(yytext[n++]);}");
                     53:        loutput(0, "#define\tREJECT\t\tyyrjct()");
                     54:        loutput(0, "#define\tBEGIN\t\tyyscon = ");
                     55:        /*
                     56:         * set up context and start condition lists
                     57:         */
                     58:        ctxstart = alloc(sizeof(struct def));
                     59:        ctxstart->d_next = NULL;
                     60:        ctxstart->d_name = "0";
                     61:        scnstart = alloc(sizeof(struct def));
                     62:        scnstart->d_next = NULL;
                     63:        scnstart->d_name = "0";
                     64:        scnstart->d_data = 0;
                     65:        /*
                     66:         * parse definitions section
                     67:         * definitions are nfa segments that get copied wherever
                     68:         * they are used, classes used in definitions are stored once.
                     69:         * definition nfa's start at 0, each ends with LX_TERM
                     70:         */
                     71:        setltype();
                     72:        indefs = 1;
                     73:        yyparse();
                     74:        indefs = 0;
                     75:        /*
                     76:         * set beginning of context 0 to where definitions end
                     77:         */
                     78:        ctxstart->d_data = nxt;
                     79:        /*
                     80:         * write #defines for start conditions and contexts
                     81:         */
                     82:        sdefns();
                     83:        xdefns();
                     84:        /*
                     85:         * these two routines are used by the generated atuomata
                     86:         * to access the user-provided i/o routines
                     87:         */
                     88:        loutput(0, "_llic()");
                     89:        loutput(0, "{");
                     90:        loutput(1, "return (input());");
                     91:        loutput(0, "}");
                     92:        loutput(0, "_lloc(c)");
                     93:        loutput(0, "{");
                     94:        loutput(1, "output(c);");
                     95:        loutput(0, "}");
                     96:        /*
                     97:         * parse rules section, each rule gets a case in yylex()
                     98:         */
                     99:        loutput(0, "yylex()");
                    100:        loutput(0, "{");
                    101:        outlnum(1);
                    102:        while (ltype == LN_LSPC)
                    103:                lcopy();
                    104:        loutput(0, "yyloop:");
                    105:        loutput(1, "switch (_lltk()) {");
                    106:        loutput(1, "case 0:");
                    107:        loutput(2, "if (yywrap())");
                    108:        loutput(3, "return (EOF);");
                    109:        loutput(2, "break;");
                    110:        yyparse();
                    111:        loutput(1, "}");
                    112:        loutput(1, "goto yyloop;\n");
                    113:        loutput(0, "}");
                    114:        nfa[nxt++][0] = LX_STOP;
                    115:        /*
                    116:         * don't need definitions anymore, copy nfa down to 0
                    117:         */
                    118:        s = ctxstart->d_data;
                    119:        i = 0;
                    120:        while (s < nxt) {
                    121:                nfa[i][0] = nfa[s][0];
                    122:                nfa[i++][1] = nfa[s++][1];
                    123:        }
                    124:        nxt = i;
                    125:        freedef(defstart);
                    126:        outlnum(1);
                    127:        /*
                    128:         * copy the rest of the input spec through
                    129:         */
                    130:        while (ltype != LN_EOFL)
                    131:                lcopy();
                    132:        /*
                    133:         * class tables
                    134:         * context table
                    135:         * nfa
                    136:         * workspace
                    137:         */
                    138:        btable();
                    139:        xtable();
                    140:        ptable();
                    141:        ltable();
                    142:        if (pflag) {
                    143:                printnfa();
                    144:        }
                    145:        if (vflag)
                    146:                stats();
                    147:        fclose(fileout);
                    148: }
                    149: 
                    150: /*
                    151:  * interpret input according to type of line
                    152:  */
                    153: yyparse()
                    154: {
                    155:        register s = nxt;
                    156:        register struct def *nd, *pd = NULL;
                    157:        register char *pc;
                    158: 
                    159:        for (;;) switch (ltype) {
                    160:        case LN_DFLT:
                    161:                if (indefs) {
                    162:                        s = nxt;
                    163:                        pc = getident();
                    164:                        rexparse(0);
                    165:                        nfa[nxt++][0] = LX_TERM;
                    166:                        nd = alloc(sizeof(struct def));
                    167:                        if (pd != NULL)
                    168:                                pd->d_next = nd;
                    169:                        else
                    170:                                defstart = nd;
                    171:                        pd = nd;
                    172:                        pd->d_name = pc;
                    173:                        pd->d_data = s;
                    174:                        pd->d_next = NULL;
                    175:                        if (yylval != '\n')
                    176:                                dnl();
                    177:                        else
                    178:                                setltype();
                    179:                } else {
                    180:                        if (look(0) == '<') {
                    181:                                next();
                    182:                                inscons();
                    183:                                if (next() != '>')
                    184:                                        error("%s in start list", illchr);
                    185:                        }
                    186:                        if (look(0) == '^') {
                    187:                                next();
                    188:                                nfa[nxt++][0] = LX_BLIN;
                    189:                        }
                    190:                        rexparse(0);
                    191:                        if (yylval == '/') {
                    192:                                nfa[nxt++][0] = LX_LOOK;
                    193:                                rexparse(0);
                    194:                        }
                    195:                        switch (yylval) {
                    196:                        case '$':
                    197:                                nfa[nxt++][0] = LX_ELIN;
                    198:                                break;
                    199:                        case ' ':
                    200:                        case '\t':
                    201:                                break;
                    202:                        case '\n':
                    203:                                error(noactn);
                    204:                        default:
                    205:                                error(rulsyn);
                    206:                        }
                    207:                        nfa[nxt][0] = LX_ACPT;
                    208:                        nfa[nxt++][1] = ++actn;
                    209:                        loutput(1, "case 0%o:", actn);
                    210:                        outlnum(0);
                    211:                        eatspc();
                    212:                        if (look(0) == '\n')
                    213:                                error(noactn);
                    214:                        if (look(0) == '|')
                    215:                                dnl();
                    216:                        else {
                    217:                                output("\t\t");
                    218:                                getactn();
                    219:                                loutput(2, "break;");
                    220:                        }
                    221:                        nfalink(s);
                    222:                        s = nxt;
                    223:                        while (ltype == LN_LSPC)
                    224:                                lcopy();
                    225:                }
                    226:                break;
                    227:        case LN_LSPC:
                    228:                outlnum(1);
                    229:                while (lcopy(), ltype==LN_LSPC);
                    230:                break;
                    231:        case LN_CTXT:
                    232:                if (indefs)
                    233:                        addcontext();
                    234:                else {
                    235:                        nfa[nxt++][0] = LX_STOP;
                    236:                        markcontext(nxt - ctxstart->d_data);
                    237:                        s = nxt;
                    238:                }
                    239:                dnl();
                    240:                break;
                    241:        case LN_SCON:
                    242:                if (!indefs)
                    243:                        error(illstc);
                    244:                addstart();
                    245:                dnl();
                    246:                break;
                    247:        case LN_LCOM:
                    248:                dnl();
                    249:                outlnum(1);
                    250:                while (ltype != LN_RCOM)
                    251:                        lcopy();
                    252:                dnl();
                    253:                break;
                    254:        case LN_OPTN:
                    255:                dnl();
                    256:                break;
                    257:        case LN_DLIM:
                    258:                dnl();
                    259:                return;
                    260:        case LN_EOFL:
                    261:                if (indefs)
                    262:                        error(eoferr);
                    263:                return;
                    264:        }
                    265: }
                    266: 
                    267: /*
                    268:  * parse regular expressions into nfa segments
                    269:  */
                    270: rexparse(p)
                    271: {
                    272:        register c, t, s;
                    273: 
                    274:        s = nxt;
                    275:        for (c=yylex(); c!=LX_TERM; c=nfaclose(t)) {
                    276:                t = nxt;
                    277:                if (c != LX_OPER) {
                    278:                        nfa[nxt][0] = c;
                    279:                        nfa[nxt++][1] = yylval;
                    280:                } else switch (c=yylval) {
                    281:                case '|':
                    282:                        nfa[t=nxt++][0] = LX_JUMP;
                    283:                        nfalink(s);
                    284:                        c = rexparse(p);
                    285:                        ++t;
                    286:                        nfa[t][1] = nxt - t;
                    287:                        return (c);
                    288:                case '"':
                    289:                        if (!inquotes)
                    290:                                return (p);
                    291:                case '(':
                    292:                        if (rexparse(c) == c)
                    293:                                break;
                    294:                        error(unmopr, c);
                    295:                case ')':
                    296:                        if (p)
                    297:                                return (p);
                    298:                        error(unmopr, c);
                    299:                case '{':
                    300:                        for (c=getdefn(); nfa[c][0]!=LX_TERM; ++c) {
                    301:                                nfa[nxt][0] = nfa[c][0];
                    302:                                nfa[nxt][1] = nfa[c][1];
                    303:                                ++nxt;
                    304:                        }
                    305:                        break;
                    306:                default:
                    307:                        error(regsyn);
                    308:                }
                    309:        }
                    310:        return (c);
                    311: }
                    312: 
                    313: /*
                    314:  * look for and apply a closure operator to the
                    315:  * nfa segement starting at t, ending at nxt
                    316:  */
                    317: nfaclose(t)
                    318: register t;
                    319: {
                    320:        register c;
                    321:        int v0, v1;
                    322: 
                    323:        if ((c=yylex()) == LX_OPER) switch (yylval) {
                    324:        case '*':
                    325:        case '+':
                    326:                nfa[nxt][0] = LX_LINK;
                    327:                nfa[nxt][1] = t - nxt;
                    328:                ++nxt;
                    329:        case '?':
                    330:                if (yylval != '+')
                    331:                        nfalink(t);
                    332:                c = yylex();
                    333:                break;
                    334:        case '{':
                    335:                if (!isdigit(look(0)))
                    336:                        break;
                    337:                v0 = v1 = 0;
                    338:                do {
                    339:                        v0 *= 10;
                    340:                        v0 += next()-'0';
                    341:                } while (isdigit(look(0)));
                    342:                if (look(0) == ',') {
                    343:                        next();
                    344:                        while (isdigit(look(0))) {
                    345:                                v1 *= 10;
                    346:                                v1 += next()-'0';
                    347:                        }
                    348:                        v1 -= v0;
                    349:                } else
                    350:                        v1 = 0;
                    351:                if (next()!='}' || v0<0 || v1<0)
                    352:                        error(reperr);
                    353:                if (v0) {
                    354:                        while (--v0)
                    355:                                t = nfacopy(t);
                    356:                        if (v1)
                    357:                                t = nfacopy(t);
                    358:                } else if (v1 == 0)
                    359:                        while (--nxt > t)
                    360:                                nfa[nxt][0] = nfa[nxt][1] = 0;
                    361:                if (v1) {
                    362:                        nfalink(t);
                    363:                        c = (nxt - t) * v1 + t;
                    364:                        nfa[t][1] = c - t;
                    365:                        while (--v1) {
                    366:                                t = nfacopy(t);
                    367:                                nfa[t][1] = c - t;
                    368:                        }
                    369:                }
                    370:                c = yylex();
                    371:        }
                    372:        return (c);
                    373: }
                    374: 
                    375: /*
                    376:  * create an epsilon transition at nfa state s to nxt
                    377:  */
                    378: nfalink(s)
                    379: register s;
                    380: {
                    381:        register i, j;
                    382: 
                    383:        j = nxt++;
                    384:        while ((i=j--) > s) {
                    385:                nfa[i][0] = nfa[j][0];
                    386:                nfa[i][1] = nfa[j][1];
                    387:        }
                    388:        nfa[s][0] = LX_LINK;
                    389:        nfa[s][1] = nxt - s;
                    390: }
                    391: 
                    392: /*
                    393:  * replicate the nfa segment starting at t ending at nxt
                    394:  */
                    395: nfacopy(t)
                    396: register t;
                    397: {
                    398:        register s;
                    399: 
                    400:        for (s=nxt; t<s; ++t,++nxt) {
                    401:                nfa[nxt][0] = nfa[t][0];
                    402:                nfa[nxt][1] = nfa[t][1];
                    403:        }
                    404:        return (t);
                    405: }
                    406: 
                    407: /*
                    408:  * insert conditional epsilon transitions for
                    409:  * each applicable start condition
                    410:  */
                    411: inscons()
                    412: {
                    413:        register t;
                    414: 
                    415:        nfa[nxt][0] = LX_SCON;
                    416:        nfa[t=nxt++][1] = getstart();
                    417:        if (look(0) == ',') {
                    418:                next();
                    419:                nfa[nxt++][0] = LX_JUMP;
                    420:                nfalink(t++);
                    421:                inscons();
                    422:                ++t;
                    423:                nfa[t][1] = nxt - t;
                    424:        }
                    425: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.