|
|
1.1 ! root 1: /* ! 2: * lex3.c ! 3: * output and table generating routines ! 4: */ ! 5: #include "lex.h" ! 6: ! 7: /* VARARGS */ ! 8: output(s) ! 9: char *s; ! 10: { ! 11: fprintf (fileout, "%r", &s); ! 12: } ! 13: ! 14: /* VARARGS 2 */ ! 15: loutput(i, s) ! 16: char *s; ! 17: { ! 18: while (i--) ! 19: putc('\t', fileout); ! 20: fprintf (fileout, "%r\n", &s); ! 21: } ! 22: ! 23: /* ! 24: * estimate the size of the working space ! 25: * the generated automata would require, worst case. ! 26: * this is non-optimum, but fast. ! 27: * optimum could be a thousand times slower to save a few bytes ! 28: */ ! 29: ltable() ! 30: { ! 31: register c, i, l; ! 32: register lookflag; ! 33: ! 34: l = 0; ! 35: i = 0; ! 36: lookflag = 0; ! 37: while (i < nxt) { ! 38: c = 0; ! 39: do { ! 40: switch(nfa[i][0]) { ! 41: case LX_LINK: ! 42: case LX_JUMP: ! 43: c += mark(nfa[i][1]); ! 44: case LX_BLIN: ! 45: case LX_ELIN: ! 46: case LX_SCON: ! 47: if (nfa[i][0] != LX_JUMP) ! 48: c += mark(i+1); ! 49: ++c; ! 50: nfa[i][0] = -nfa[i][0]; ! 51: break; ! 52: case LX_LOOK: ! 53: case -LX_LOOK: ! 54: lookflag = 1; ! 55: if (c > l) ! 56: l = c; ! 57: c = mark(i+1); ! 58: break; ! 59: case LX_STOP: ! 60: if (nfa[i][1]) ! 61: nfa[i][1] = 0; ! 62: else ! 63: ++c; ! 64: } ! 65: } while (nfa[i++][0] != LX_STOP); ! 66: if (c > l) ! 67: l = c; ! 68: } ! 69: ++l; ! 70: for (i=0; i<nxt; ++i) ! 71: if (nfa[i][0] < 0) ! 72: nfa[i][0] = -nfa[i][0]; ! 73: loutput(0, "int *yy_clist[0%o];", l); ! 74: loutput(0, "int *yy_nlist[0%o];", l); ! 75: if (lookflag == 0) ! 76: return; ! 77: loutput(0, "int *yy_llist[0%o];", l); ! 78: } ! 79: ! 80: /* ! 81: * used by ltable, mark a state as counted ! 82: */ ! 83: mark(state) ! 84: { ! 85: switch (nfa[state][0]) { ! 86: case LX_STOP: ! 87: if (nfa[state][1]++) ! 88: break; ! 89: case LX_LOOK: ! 90: case LX_ACPT: ! 91: case LX_CHAR: ! 92: case LX_CLAS: ! 93: case LX_ANYC: ! 94: nfa[state][0] = -nfa[state][0]; ! 95: return (1); ! 96: } ! 97: return (0); ! 98: } ! 99: ! 100: stats() ! 101: { ! 102: fprintf(stderr, "rules: %d\tstates: %d\tclasses: %d\n", ! 103: actn, nxt, clas); ! 104: } ! 105: ! 106: /* ! 107: * put out #defines for start conditions ! 108: */ ! 109: sdefns() ! 110: { ! 111: register struct def *pd; ! 112: ! 113: pd = scnstart; ! 114: while ((pd=pd->d_next) != NULL) ! 115: loutput(0, "#define\t%s\t\t0%o", pd->d_name, pd->d_data); ! 116: } ! 117: ! 118: /* ! 119: * put out #defines for contexts ! 120: */ ! 121: xdefns() ! 122: { ! 123: register struct def *pd; ! 124: register i = 0; ! 125: ! 126: for (pd=ctxstart; pd!=NULL; pd=pd->d_next) ! 127: ++i; ! 128: loutput(0, "#define\tyyswitch(x)\tyyctxt((x),(0%o))", i); ! 129: i = 0; ! 130: pd = ctxstart; ! 131: while ((pd=pd->d_next) != NULL) ! 132: loutput(0, "#define\t%s\t\t0%o", pd->d_name, ++i); ! 133: } ! 134: ! 135: /* ! 136: * table of nfa starting locations for contexts ! 137: */ ! 138: xtable() ! 139: { ! 140: register struct def *pd; ! 141: ! 142: loutput(0, "int yy_ctxtab[] = {"); ! 143: output("00"); ! 144: pd = ctxstart; ! 145: while ((pd=pd->d_next) != NULL) ! 146: output(",0%o", pd->d_data); ! 147: output("\n"); ! 148: loutput(0, "};"); ! 149: } ! 150: ! 151: /* ! 152: * character class tables, here we convert the vertical ! 153: * class storage to horizontal to save space ! 154: */ ! 155: btable() ! 156: { ! 157: register unsigned char *index; ! 158: register bit; ! 159: register b, n, i, t; ! 160: ! 161: if (classptr == NULL) ! 162: return; ! 163: b = 1; ! 164: loutput(0, "int yy_lxctab[] = {"); ! 165: for (n=0; n<clas; ++n) { ! 166: index = classptr + classindex(n); ! 167: bit = classbit(n); ! 168: t = 0; ! 169: i = 0; ! 170: while (i <= MAXUCHAR) { ! 171: if (index[i]&bit) ! 172: t |= b; ! 173: if ((b<<=1) == 0) { ! 174: output("0%o", t); ! 175: if (n+1<clas || i<MAXUCHAR) ! 176: output(","); ! 177: if (++i%(8*NBINT) == 0) ! 178: output("\n"); ! 179: b = 1; ! 180: t = 0; ! 181: } else ! 182: ++i; ! 183: } ! 184: } ! 185: loutput(0, "};"); ! 186: /* ! 187: * output the bit selector table ! 188: */ ! 189: loutput(0, "int yy_lxbtab[] = {"); ! 190: i = 0; ! 191: while (i < NBINT) { ! 192: output("01<<0%02o", i); ! 193: if (++i < NBINT) ! 194: output(","); ! 195: if (i%(NBINT/2) == 0) ! 196: output("\n"); ! 197: } ! 198: loutput(0, "};"); ! 199: } ! 200: ! 201: /* ! 202: * output the actual automata table ! 203: * each state is packed into an int with the low four bits ! 204: * being the opcode, the high twelve being the data ! 205: */ ! 206: ptable() ! 207: { ! 208: register i,s; ! 209: ! 210: loutput(0, "int yy_lextab[] = {"); ! 211: for (s=0,i=0; i<nxt; ++s,++i) { ! 212: if (i) ! 213: output(","); ! 214: if (s && s%8 == 0) ! 215: output("\n"); ! 216: output("0%o", nfa[i][0] | (nfa[i][1]<<LR_SHFT)); ! 217: } ! 218: output("\n"); ! 219: loutput(0, "};"); ! 220: } ! 221: ! 222: /* ! 223: * put a human readable form of the automaton onto stderr ! 224: * undocumented, but useful for debugging and sort of interesting ! 225: */ ! 226: printnfa() ! 227: { ! 228: register i; ! 229: ! 230: for (i=0; i<nxt; ++i) { ! 231: fprintf(stderr, "%d:\t", i); ! 232: switch (nfa[i][0]) { ! 233: case LX_STOP: ! 234: fprintf(stderr, "stop"); ! 235: break; ! 236: case LX_LINK: ! 237: fprintf(stderr, "link "); ! 238: if (nfa[i][1] > 0) ! 239: putc('+', stderr); ! 240: fprintf(stderr, "%d", nfa[i][1]); ! 241: break; ! 242: case LX_JUMP: ! 243: fprintf(stderr, "jump "); ! 244: if (nfa[i][1] > 0) ! 245: putc('+', stderr); ! 246: fprintf(stderr, "%d", nfa[i][1]); ! 247: break; ! 248: case LX_LOOK: ! 249: fprintf(stderr, "look"); ! 250: break; ! 251: case LX_ACPT: ! 252: fprintf(stderr, "acpt %d", nfa[i][1]); ! 253: break; ! 254: case LX_CHAR: ! 255: fprintf(stderr, "char "); ! 256: if (nfa[i][1] == EOF) ! 257: fprintf(stderr, "EOF"); ! 258: else { ! 259: putc('\'', stderr); ! 260: if (iscntrl(nfa[i][1])) switch (nfa[i][1]) { ! 261: case '\b': ! 262: fprintf(stderr, "\\b"); ! 263: break; ! 264: case '\f': ! 265: fprintf(stderr, "\\f"); ! 266: break; ! 267: case '\n': ! 268: fprintf(stderr, "\\n"); ! 269: break; ! 270: case '\r': ! 271: fprintf(stderr, "\\r"); ! 272: break; ! 273: case '\t': ! 274: fprintf(stderr, "\\t"); ! 275: break; ! 276: default: ! 277: fprintf(stderr, "\\%03o", nfa[i][1]); ! 278: } else ! 279: putc(nfa[i][1], stderr); ! 280: putc('\'', stderr); ! 281: } ! 282: break; ! 283: case LX_CLAS: ! 284: fprintf(stderr, "clas %d", nfa[i][1]); ! 285: break; ! 286: case LX_BLIN: ! 287: fprintf(stderr, "blin"); ! 288: break; ! 289: case LX_ELIN: ! 290: fprintf(stderr, "elin"); ! 291: break; ! 292: case LX_ANYC: ! 293: fprintf(stderr, "anyc"); ! 294: break; ! 295: case LX_SCON: ! 296: fprintf(stderr, "scon %d", nfa[i][1]); ! 297: break; ! 298: case LX_TERM: ! 299: fprintf(stderr, "term"); ! 300: break; ! 301: default: ! 302: fprintf(stderr, "undefined"); ! 303: } ! 304: putc('\n', stderr); ! 305: } ! 306: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.