|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.