Annotation of coherent/f/f0/lex/lex1.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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