L% rm -f *.gcda L% gcc -fprofile-arcs -ftest-coverage y.tab.c pop2lex.c -ly L% cat *.pop libm.d/*.pop | a.out -kforall 2>COVLOG L% gcov -f pop2lex.c Function 'yylex' Lines executed:100.00% of 10 Function 'prelex' Lines executed:84.71% of 340 Function 'set_source' Lines executed:100.00% of 3 Function 'enable_keyword' Lines executed:50.00% of 10 Function 'unary_wanted' Lines executed:100.00% of 4 Function 'bracket_error' Lines executed:0.00% of 18 File 'pop2lex.c' Lines executed:80.52% of 385 Creating 'pop2lex.c.gcov' L% gcov pop2lex.c File 'pop2lex.c' Lines executed:80.52% of 385 Creating 'pop2lex.c.gcov' L% cat pop2lex.c.gcov -: 0:Source:pop2lex.c -: 0:Graph:pop2lex.gcno -: 0:Data:pop2lex.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:/* File : pop2lex.c -: 2: Author : Richard A. O'Keefe -: 3: Updated: "@(#)2017/03/28 pop2lex.c 1.36" -: 4: Purpose: Pop-2 lexical analysis. -: 5:*/ -: 6:#include -: 7:#include -: 8:#include -: 9:#include -: 10:#include "y.tab.h" -: 11:#include "symtab.h" -: 12:#include "pop2lex.h" -: 13: -: 14:/* We classify characters as -: 15: -: 16: digits (0-9) -: 17: ASCII letters (10-35) -: 18: other letters (36) -: 19: underscore (37) -: 20: symbols (38) #$&+-./:<=>?@\^|~ + Latin1 symbols -: 21: dollar (39) $ -: 22: quote (40) "' -: 23: punctuation (41) !%(),;[]{} -: 24: illegal (42) most controls, backquote -: 25: end of file (43) EOF, Ctrl-Z -: 26: line terminator (44) carriage return, line feed -: 27: white space (45) space, tab, nbsp, form feed -: 28:*/ -: 29: -: 30:#define OTH 36 -: 31:#define USC 37 -: 32:#define SYM 38 -: 33:#define DOL 39 -: 34:#define SDQ 40 -: 35:#define PCT 41 -: 36:#define ILL 42 -: 37:#define EF 43 -: 38:#define LT 44 -: 39:#define WS 45 -: 40: -: 41:static char cc[257] = { -: 42: EF, /* EOF */ -: 43: ILL, ILL, ILL, EF, EF, ILL, ILL, ILL, /* Ctrl-@ - Ctrl-G */ -: 44: ILL, WS, LT, ILL, WS, LT, ILL, ILL, /* Ctrl-H - Ctrl-O */ -: 45: ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, /* Ctrl-P - Ctrl-W */ -: 46: ILL, ILL, EF, ILL, ILL, ILL, ILL, ILL, /* Ctrl-Z - Ctrl-_ */ -: 47: WS, PCT, SDQ, SYM, SYM, PCT, SYM, SDQ, /* !"#$%&' */ -: 48: PCT, PCT, SYM, SYM, PCT, SYM, SYM, SYM, /* ()*+,-./ */ -: 49: 0, 1, 2, 3, 4, 5, 6, 7, /* 01234567 */ -: 50: 8, 9, SYM, PCT, SYM, SYM, SYM, SYM, /* 89:;<=>? */ -: 51: SYM, 10, 11, 12, 13, 14, 15, 16, /* @ABCDEFG */ -: 52: 17, 18, 19, 20, 21, 22, 23, 24, /* HIJKLMNO */ -: 53: 25, 26, 27, 28, 29, 30, 31, 32, /* PQRSTUVW */ -: 54: 33, 34, 35, PCT, SYM, PCT, SYM, USC, /* XYZ[\]^_ */ -: 55: ILL, 10, 11, 12, 13, 14, 15, 16, /* `abcdefg */ -: 56: 17, 18, 19, 20, 21, 22, 23, 24, /* hijklmno */ -: 57: 25, 26, 27, 28, 29, 30, 31, 32, /* pqrstuvw */ -: 58: 33, 34, 35, PCT, SYM, PCT, SYM, ILL, /* xyz{|}~ */ -: 59: ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, /* C1 controls */ -: 60: ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, /* C1 controls */ -: 61: ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, /* C1 controls */ -: 62: ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, /* C1 controls */ -: 63: WS, SYM, SYM, SYM, SYM, SYM, SYM, SYM, -: 64: ILL, SYM, OTH, ILL, SYM, ILL, SYM, ILL, -: 65: SYM, SYM, ILL, ILL, ILL, OTH, SYM, ILL, -: 66: ILL, ILL, OTH, ILL, ILL, ILL, ILL, SYM, -: 67: OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, -: 68: OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, -: 69: OTH, OTH, OTH, OTH, OTH, OTH, OTH, SYM, -: 70: OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, -: 71: OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, -: 72: OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, -: 73: OTH, OTH, OTH, OTH, OTH, OTH, OTH, SYM, -: 74: OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH -: 75:}; -: 76: -: 77:/* Within list brackets [...] all identifiers act as if quoted. -: 78: Also, we want the "attached sign" rule to apply there and -: 79: only there. So we need to keep a bracket stack. -: 80: Brackets include -: 81: "section" ... "endsection" -: 82: "function"|"operation"|"lambda" ... "end" -: 83: "loopif|"|"if" ... "close" -: 84: "(" ... ")" -: 85: "[" ... "]" -: 86: "{" ... "}" -: 87: except that (sigh) "function" "operation" are NOT always brackets. -: 88: For now, we just track ([{}]) and whether % has occurred an even -: 89: or odd number of times at that level. -: 90:*/ -: 91:static struct { -: 92: short token; -: 93: short flag; -: 94:} bracket_stack[2048] = {{LP,0}}, -: 95: *bsp = &bracket_stack[0]; -: 96: #####: 97:static void bracket_error(int token) { #####: 98: fprintf(stderr, "Bracket error: "); #####: 99: switch (bsp->token) { #####: 100: case LP: fprintf(stderr, "("); break; #####: 101: case LB: fprintf(stderr, "["); break; #####: 102: case LC: fprintf(stderr, "{"); break; #####: 103: case CANCEL: fprintf(stderr, "cancel"); break; #####: 104: default: fprintf(stderr, "<%d>", bsp->token); break; -: 105: } #####: 106: if (bsp->flag != 0) fprintf(stderr, "%%"); #####: 107: fprintf(stderr, " does not correspond to "); #####: 108: switch (token) { #####: 109: case RP: fprintf(stderr, ")"); break; #####: 110: case RB: fprintf(stderr, "]"); break; #####: 111: case RC: fprintf(stderr, "}"); break; #####: 112: case SEMICOLON: fprintf(stderr, ";"); break; #####: 113: default: fprintf(stderr, "<%d>", token); break; -: 114: } #####: 115: fprintf(stderr, "\n"); #####: 116: exit(EXIT_FAILURE); -: 117:} -: 118: -: 119:/* In classic Pop-2, all numbers are non-negative. Leading signs are -: 120: not part of number syntax. How then are we to write -: 121: -1 -> n; -: 122: considering that operands of binary operators are optional? -: 123: The answer is the after certain tokens + and - are taken as unary. -: 124: Page 93 of the Silver Book gives the list as -: 125: ; , ( (% [% if loopif and or then else elseif -: 126: to which we add { : and OP1..OP9 so that x > -1 works, -: 127: and return, so that return -2 works. -: 128:*/ -: 129:static int last_token = SEMICOLON; -: 130:#define Return return last_token = -: 131:#define Return_Op(x) Return (last_token == NONOP ? IDENTIFIER : x) -: 132: 1144: 133:static int unary_wanted(void) { 1144: 134: switch (last_token) { -: 135: case LOOPIF: -: 136: case ELSEIF: -: 137: case IF: -: 138: case THEN: -: 139: case ELSE: -: 140: case RETURN: -: 141: case LP: -: 142: case LB: -: 143: case LC: -: 144: case DECORATOR: -: 145: case COMMA: -: 146: case SEMICOLON: -: 147: case COLON: -: 148: case UNARY: -: 149:#if 0 /* these cases seem wrong */ -: 150: case OP1: -: 151: case OP2: -: 152: case OP3: -: 153: case OP4: -: 154: case OP5: -: 155: case OP6: -: 156: case OP7: -: 157:#endif -: 158: case OP8: -: 159: case OP9: -: 160: case AND: -: 161: case OR: -: 162:#ifdef CASE -: 163: case CASE: -: 164: case WHEN: -: 165:#endif 105: 166: return 1; -: 167: default: 1039: 168: return 0; -: 169: } -: 170:} -: 171: -: 172:/* This approach is temporary. -: 173: It should be replaced by symtab integration. -: 174:*/ -: 175:static char kw_ok[7]; -: 176: 1: 177:void enable_keyword(char const *kw) { 1: 178: if (0 == strcmp(kw, "do")) kw_ok[5] = 1; else 1: 179: if (0 == strcmp(kw, "enddo")) kw_ok[6] = 1; else 1: 180: if (0 == strcmp(kw, "forall")) kw_ok[0] = 1; else #####: 181: if (0 == strcmp(kw, "routine")) kw_ok[1] = 1; else #####: 182: if (0 == strcmp(kw, "unless")) kw_ok[2] = 1; else #####: 183: if (0 == strcmp(kw, "until")) kw_ok[3] = 1; else #####: 184: if (0 == strcmp(kw, "while")) kw_ok[4] = 1; else #####: 185: fprintf(stderr, "Unknown keyword %s\n", kw), exit(EXIT_FAILURE); 1: 186:} -: 187: -: 188:char yytext[1024]; -: 189:union { -: 190: long long int ival; -: 191: double dval; -: 192:} numval; -: 193: -: 194:static int lastc = '\n'; -: 195:static FILE *input; -: 196: 1: 197:void set_source(FILE *new_input) { 1: 198: input = new_input; -: 199: /* set line number to 1 */ 1: 200:} -: 201: -: 202:#ifdef getc_unlocked -: 203:# define GET_ getc_unlocked -: 204:#else -: 205:# define GET_ getc -: 206:#endif -: 207:#ifdef putc_unlocked -: 208:# define PUT_ putc_unlocked -: 209:#else -: 210:# define PUT_ putc -: 211:#endif -: 212:#ifdef TRACE -: 213:# define get(c) (void)((c = GET_(card)) >= 0 || PUT_(c, stderr)) -: 214:#else -: 215:# define get(c) (void)(c = GET_(card)) -: 216:#endif -: 217:#define unget(x) (void)ungetc(x, card) -: 218: -: 219:#ifdef NDEBUG -: 220:int yylex(void) { -: 221:#else 67740: 222:static int prelex(void) { -: 223:#endif 67740: 224: register FILE *card = input; -: 225: register int c; -: 226: register char *p; -: 227: int d; 67740: 228: int sign = 1; -: 229: -: 230: for (;;) { 71339: 231: c = lastc; -: 232: /* Skip white space and line terminators. */ 71339: 233: while (cc[c-EOF] >= LT) get(c); 71339: 234: p = yytext; -: 235: 71339: 236: get(d); 71339: 237: unget(d); 71339: 238: if ((cc[c-EOF] < 10) 68783: 239: || (cc[d-EOF] < 10 && (c == '.' || c == 0xB7 /*middle dot*/)) -: 240: ) { -: 241: /* Process a number. */ 2559: 242: if (c == '.' || c == 0xB7 /*middle dot*/) { 3: 243: *p++ = '0'; -: 244: } else { 2556: 245: *p++ = c; -: 246: for (;;) { 3038: 247: get(c); 3038: 248: if (cc[c-EOF] < 10) { 482: 249: *p++ = c; -: 250: } else 2556: 251: if (c != '_') break; 482: 252: } -: 253: } 2559: 254: *p = 0; 2559: 255: errno = 0; 2559: 256: if (c == ':' || c == 'r' || c == 'R') { 25: 257: int b = strtol(yytext, (char **)0, 10); 25: 258: get(d); 25: 259: if (b >= 2 && b <= 36 && cc[d-EOF] < b) { 23: 260: p = yytext; 23: 261: *p++ = d; -: 262: for (;;) { 61: 263: get(c); 61: 264: if (cc[c-EOF] < b) { 38: 265: *p++ = c; -: 266: } else 23: 267: if (c != '_') break; 38: 268: } 23: 269: *p = 0; 23: 270: errno = 0; 23: 271: numval.ival = sign*strtoll(yytext, (char **)0, b); 46: 272: if (errno != 0) { #####: 273: perror(yytext); #####: 274: exit(EXIT_FAILURE); -: 275: } -: 276: } else { 2: 277: if (errno != 0) { #####: 278: perror(yytext); #####: 279: exit(EXIT_FAILURE); -: 280: } 2: 281: unget(d); -: 282: } 25: 283: lastc = c; 25: 284: if (last_token == OPERATION) { #####: 285: if (numval.ival > 9) { #####: 286: fprintf(stderr, "operation %lld : " -: 287: "precedence exceeds 9\n", numval.ival); #####: 288: exit(EXIT_FAILURE); -: 289: } #####: 290: last_token = NONOP; -: 291: } else { 25: 292: last_token = INTEGER; -: 293: } 25: 294: return INTEGER; -: 295: } 2534: 296: if (c == '.' || c == 0xB7 /*middle dot*/) { 408: 297: get(d); 408: 298: if (cc[d-EOF] < 10) { 317: 299: *p++ = '.'; 317: 300: *p++ = d; -: 301: for (;;) { 2567: 302: get(c); 2567: 303: if (cc[c-EOF] < 10) { 2250: 304: *p++ = c; -: 305: } else 317: 306: if (c != '_') break; 2250: 307: } 317: 308: *p = 0; -: 309: } else { 91: 310: unget(d); -: 311: } -: 312: } 2534: 313: if (c == 'e' || c == 'E') { 76: 314: get(d); 152: 315: if (d == '-' || d == '+' || cc[d-EOF] < 10) { 76: 316: if (strchr(yytext, '.') == 0) { 2: 317: *p++ = '.', *p++ = '0'; -: 318: } 76: 319: *p++ = 'e'; 76: 320: if (d == '-' || d == '+') { 38: 321: if (d == '-') *p++ = '-'; 38: 322: get(c); 76: 323: if (cc[c-EOF] >= 10) { #####: 324: fprintf(stderr, "No digit after e%c\n", d); #####: 325: exit(EXIT_FAILURE); -: 326: } -: 327: } else { 38: 328: c = d; -: 329: } -: 330: for (;;) { 165: 331: if (cc[c-EOF] < 10) { 89: 332: *p++ = c; -: 333: } else 76: 334: if (c != '_') break; 89: 335: get(c); 89: 336: } -: 337: } else { #####: 338: unget(d); -: 339: } 76: 340: *p = 0; -: 341: } 2534: 342: lastc = c; 2534: 343: if (strchr(yytext, '.') != 0) { 319: 344: errno = 0; 319: 345: numval.dval = sign*strtod(yytext, (char **)0); 319: 346: if (errno != 0) { #####: 347: perror(yytext); #####: 348: exit(EXIT_FAILURE); -: 349: } 319: 350: Return REAL; -: 351: } else { 2215: 352: errno = 0; 2215: 353: numval.ival = sign*strtoll(yytext, (char **)0, 10); 2215: 354: if (errno != 0) { #####: 355: perror(yytext); #####: 356: exit(EXIT_FAILURE); -: 357: } 2215: 358: if (last_token == OPERATION) { 87: 359: if (numval.ival > 9) { #####: 360: fprintf(stderr, "operation %lld : " -: 361: "precedence exceeds 9\n", numval.ival); #####: 362: exit(EXIT_FAILURE); -: 363: } 87: 364: last_token = NONOP; -: 365: } else { 2128: 366: last_token = INTEGER; -: 367: } 2215: 368: return INTEGER; -: 369: } -: 370: } 68780: 371: if (cc[c-EOF] <= SYM) { 45198: 372: if (cc[c-EOF] == SYM) { -: 373: do { 14378: 374: *p++ = c; 14378: 375: get(c); 14378: 376: } while (cc[c-EOF] == SYM); -: 377: } else { -: 378: do { 131793: 379: *p++ = c; 131793: 380: get(c); 131793: 381: } while (cc[c-EOF] <= OTH); -: 382: } 95613: 383: while (c == '_' || c == 0xB7 /* middle dot */) { 5743: 384: *p++ = c; 5743: 385: get(c); 5743: 386: if (cc[c-EOF] <= OTH) { -: 387: do { 5939: 388: *p++ = c; 5939: 389: get(c); 5939: 390: }while (cc[c-EOF] <= OTH); -: 391: } else 4283: 392: if (cc[c-EOF] <= SYM) { 622: 393: if (c == '.') { 526: 394: get(d); 526: 395: unget(d); 526: 396: if (cc[d-EOF] != SYM) break; -: 397: } -: 398: do { 112: 399: *p++ = c; 112: 400: get(c); 112: 401: } while (cc[c-EOF] == SYM); -: 402: } -: 403: } 45198: 404: *p = 0; 45198: 405: lastc = c; 45198: 406: p = yytext; 45198: 407: if (bsp->token != LP && bsp->flag == 0) { 1002: 408: if ((p[0] == '+' || p[0] == '-') && p[1] == 0) { -: 409: /* apply the attached sign rule */ 15: 410: sign = p[0] == '-' ? -1 : 1; 15: 411: if (cc[c-EOF] < 10) continue; 9: 412: if (c == '.') { #####: 413: get(d); #####: 414: unget(d); #####: 415: if (cc[d-EOF] < 10) continue; -: 416: } -: 417: } 996: 418: return WORD; -: 419: } 44196: 420: if (last_token == NONMAC) Return IDENTIFIER; 44180: 421: switch (p[0]) { 7: 422: case '^': if (p[1] == 0) Return_Op(OP3); -: 423: /* NEXT LINE FOR TESTING answers.pop */ #####: 424: if (p[1] == '^' && p[2] == 0) Return_Op(OP3); #####: 425: break; 893: 426: case '=': if (p[1] == 0) Return_Op(OP8); 335: 427: if (p[1] == '=' && p[2] == 0) Return_Op(OP8); 316: 428: if (p[1] == '<' && p[2] == 0) Return_Op(OP8); 177: 429: if (p[1] == '>' && p[2] == 0) { 173: 430: lastc = ';'; 173: 431: unget(c); 173: 432: Return FAT_ARROW; -: 433: } 4: 434: break; 264: 435: case '<': if (p[1] == 0) Return_Op(OP8); 8: 436: if (p[1] == '>' && p[2] == 0) Return_Op(OP2); 2: 437: break; 349: 438: case '>': if (p[1] == 0) Return_Op(OP8); 111: 439: if (p[1] == '=' && p[2] == 0) Return_Op(OP8); 6: 440: break; 77: 441: case ':': if (p[1] == 0) Return COLON; 71: 442: if (p[1] == ':' && p[2] == 0) Return_Op(OP2); #####: 443: break; 290: 444: case '/': if (p[1] == 0) Return_Op(OP4); 189: 445: if (p[1] == '/' && p[2] == 0) Return_Op(OP4); 146: 446: if (p[1] == '\\' && p[2] == 0) Return_Op(OP6); 135: 447: if (p[1] == '=' && p[2] == 0) Return_Op(OP8); 6: 448: if (p[1] == '=' && p[2] == '=' 4: 449: && p[3] == 0) Return_Op(OP8); 2: 450: break; 8: 451: case'\\': if (p[1] == '/' && p[2] == 0) Return_Op(OP7); #####: 452: break; 334: 453: case '*': if (p[1] == 0) Return_Op(OP4); -: 454: /* NEXT LINE FOR TESTING answers.pop */ #####: 455: if (p[1] == '*' && p[2] == 0) Return_Op(OP4); #####: 456: break; 621: 457: case '+': if (p[1] == 0) { 617: 458: if (unary_wanted()) Return UNARY; 611: 459: Return_Op(OP5); -: 460: } 4: 461: if (p[1] == '+' && p[2] == 0) Return_Op(OP2); #####: 462: break; 3942: 463: case '-': if (p[1] == 0) { 527: 464: if (unary_wanted()) Return UNARY; 428: 465: Return_Op(OP5); -: 466: } 3415: 467: if (p[1] == '>' && p[2] == 0) Return THIN_ARROW; 3: 468: if (p[1] == '>' && p[2] == '>' 3: 469: && p[3] == 0) Return THIN_ARROW; -: 470: /* NEXT LINE FOR TESTING answers.pop */ #####: 471: if (p[1] == '-' && p[2] == 0) Return_Op(OP4); #####: 472: break; 2873: 473: case '.': if (p[1] == 0) Return DOT; #####: 474: break; 509: 475: case '$': if (p[1] == 0) { 509: 476: if (c != '\'') Return DOLLAR; 380: 477: get(d); 380: 478: get(c); 380: 479: if (c != '\'') { #####: 480: fprintf(stderr, -: 481: "$'%c' missing second '\n",d); #####: 482: exit(EXIT_FAILURE); -: 483: } 380: 484: get(c); 380: 485: if (d == '\'' && c == d) get(c); 380: 486: numval.ival = d; 380: 487: lastc = c; 380: 488: Return INTEGER; -: 489: } #####: 490: break; 1809: 491: case 'a': if (0 == strcmp(p+1,"nd")) Return AND; 1514: 492: break; 3121: 493: case 'c': if (0 == strcmp(p+1,"ancel")) { -: 494: /* operators can be cancelled without NONOP. -: 495: Syntax words can be cancelled. -: 496: But macros are active! -: 497: */ 42: 498: bsp++; bsp->token = CANCEL, bsp->flag = 0; 42: 499: Return CANCEL; -: 500: } 3079: 501: if (0 == strcmp(p+1,"lose")) Return CLOSE; -: 502:#ifdef CASE 1725: 503: if (0 == strcmp(p+1,"ase")) Return CASE; -: 504:#endif 1717: 505: if (0 == strcmp(p+1,"omment")) { -: 506: /* We want to stop at ILLegal characters, -: 507: End of File characters, and semicolons. -: 508: The first character has already been read. -: 509: */ 10038: 510: while (d < ILL ? c != ';' : d > EF) { 9992: 511: get(c); 9992: 512: d = cc[c-EOF]; -: 513: } 23: 514: lastc = '\n'; 23: 515: continue; -: 516: } 1694: 517: break; 1122: 518: case 'd': if (0 == strcmp(p+1, "o") #####: 519: && kw_ok[5]) Return THEN; 1122: 520: break; 2814: 521: case 'e': if (0 == strcmp(p+1,"lse")) Return ELSE; 2283: 522: if (0 == strcmp(p+1,"lseif")) Return ELSEIF; 2052: 523: if (0 == strcmp(p+1,"nd")) Return END; 748: 524: if (0 == strcmp(p+1,"ndsection")) Return ENDSECTION; 747: 525: if (0 == strcmp(p+1,"xit")) Return EXIT; 560: 526: if (0 == strcmp(p+1,"nddo") #####: 527: && kw_ok[6]) Return CLOSE; 560: 528: break; 3320: 529: case 'f': if (0 == strcmp(p+1,"unction")) Return FUNCTION; 1481: 530: if (0 == strcmp(p+1,"orall") 18: 531: && kw_ok[0]) Return FORALL; 1463: 532: break; 270: 533: case 'g': if (0 == strcmp(p+1,"oto")) Return GOTO; 264: 534: break; 3294: 535: case 'i': if (p[1] == 'f' && p[2] == 0) Return IF; 2218: 536: break; 1419: 537: case 'l': if (0 == strcmp(p+1,"ambda")) Return LAMBDA; 1131: 538: if (0 == strcmp(p+1,"oopif")) Return LOOPIF; 692: 539: break; 482: 540: case 'm': if (0 == strcmp(p+1,"acro")) { 16: 541: last_token = NONMAC; 16: 542: return MACRO; -: 543: } 466: 544: break; 1880: 545: case 'n': if (0 == strcmp(p+1,"onmac")) { #####: 546: last_token = NONMAC; #####: 547: continue; -: 548: } else 1880: 549: if (0 == strcmp(p+1, "onop")) { 52: 550: last_token = NONOP; 52: 551: continue; -: 552: } 1828: 553: break; 356: 554: case 'o': if (0 == strcmp(p+1,"peration")) Return OPERATION; 269: 555: if (p[1] == 'r' && p[2] == 0) Return OR; 135: 556: break; 1406: 557: case 'p': if (0 == strcmp(p+1,"rotected")) Return PROTECT; 1405: 558: break; 584: 559: case 'r': if (0 == strcmp(p+1,"eturn")) Return RETURN; 575: 560: if (0 == strcmp(p+1,"ecordclass"))Return RECORDCLASS; 574: 561: if (0 == strcmp(p+1,"outine") #####: 562: && kw_ok[1]) Return ROUTINE; 574: 563: break; 1601: 564: case 's': if (0 == strcmp(p+1,"ection")) Return SECTION; 1600: 565: if (0 == strcmp(p+1,"tripclass")) Return STRIPCLASS; 1600: 566: if (0 == strcmp(p+1,"witch")) Return SWITCH; 1600: 567: break; 2847: 568: case 't': if (0 == strcmp(p+1,"hen")) Return THEN; 1054: 569: break; 378: 570: case 'u': if (0 == strcmp(p+1,"nless") #####: 571: && kw_ok[2]) Return IF; 378: 572: if (0 == strcmp(p+1,"ntil") #####: 573: && kw_ok[3]) Return LOOPIF; 378: 574: break; 1640: 575: case 'v': if (0 == strcmp(p+1,"ars")) Return VARS; 267: 576: break; 201: 577: case 'w': if (0 == strcmp(p+1,"hile") #####: 578: && kw_ok[4]) Return LOOPIF; -: 579:#ifdef CASE 201: 580: if (0 == strcmp(p+1,"hen")) Return WHEN; -: 581:#endif 154: 582: break; -: 583: default: 5469: 584: break; -: 585: } 22871: 586: Return IDENTIFIER; -: 587: } 23582: 588: switch (cc[c-EOF]) { -: 589: case SDQ: 1325: 590: d = c; -: 591: for (;;) { 16968: 592: get(c); 16968: 593: if (c < 0) { #####: 594: fprintf(stderr, "EOF in %ctext%c\n", d, d); #####: 595: yyerror("Missing closing quote"); #####: 596: exit(EXIT_FAILURE); -: 597: } 16968: 598: if (c == d) { 1327: 599: get(c); 1327: 600: if (c != d) break; -: 601: } 15643: 602: *p++ = c; 15643: 603: } 1325: 604: *p = 0; 1325: 605: lastc = c; 1325: 606: Return d == '"' ? WORD : STRING; -: 607: case PCT: 22256: 608: lastc = ' '; 22256: 609: p[0] = c, p[1] = 0; 22256: 610: switch (c) { -: 611: case '!': -: 612: /* We want to stop at ILLegal characters, -: 613: End of File characters, Line Terminators, -: 614: and exclamation marks. But whoops, ` -: 615: and a bunch of other characters are ILL. -: 616: */ -: 617: do { 144204: 618: get(c); 144204: 619: d = cc[c-EOF]; 144209: 620: } while (d < ILL ? c != '!' -: 621: : d > ILL ? d == WS 144209: 622: : (c&127) >= 32); 3456: 623: lastc = '\n'; 3456: 624: continue; 2727: 625: case '(': bsp++; bsp->token = LP, bsp->flag = 0; 2727: 626: Return LP; 2727: 627: case ')': if (bsp->token != LP || bsp->flag != 0) #####: 628: bracket_error(RP); 2727: 629: bsp--; 2727: 630: Return RP; 569: 631: case '[': bsp++; bsp->token = LB; bsp->flag = 0; 569: 632: Return LB; 569: 633: case ']': if (bsp->token != LB || bsp->flag != 0) #####: 634: bracket_error(RB); 569: 635: bsp--; 569: 636: Return RB; 25: 637: case '{': bsp++; bsp->token = LC, bsp->flag = 0; 25: 638: Return LC; 25: 639: case '}': if (bsp->token != LC || bsp->flag != 0) #####: 640: bracket_error(RC); 25: 641: bsp--; 25: 642: Return RC; 610: 643: case '%': bsp->flag ^= 1; 610: 644: Return DECORATOR; 2984: 645: case ',': Return COMMA; -: 646: case ';': 8564: 647: get(c); 8564: 648: if (c == ';') { 63: 649: get(d); 63: 650: if (d == ';') { -: 651: do { 2624: 652: get(c); 2624: 653: d = cc[c-EOF]; 2624: 654: } while (d < ILL || d == WS); 62: 655: lastc = c; 62: 656: continue; -: 657: } 1: 658: unget(d); 1: 659: lastc = c; -: 660: } 8502: 661: if (bsp->token == CANCEL) bsp--; 8502: 662: Return SEMICOLON; -: 663: default: #####: 664: fprintf(stderr, "Unreachable\n"); #####: 665: exit(EXIT_FAILURE); -: 666: } -: 667: case EF: 1: 668: lastc = c; 1: 669: Return 0; -: 670: default: #####: 671: fprintf(stderr, -: 672: "'%c' (0x%02x) cannot be part of a Pop-2 token.\n", #####: 673: (char)c, (unsigned)c); #####: 674: exit(EXIT_FAILURE); -: 675: } 3599: 676: } -: 677:} -: 678: -: 679:#ifndef NDEBUG -: 680: 67740: 681:int yylex(void) { 67740: 682: int n = prelex(); 67740: 683: fprintf(stderr, "%3d ", n); 67740: 684: switch (n) { 2620: 685: case INTEGER: fprintf(stderr, "%lld\n", numval.ival); break; 319: 686: case REAL: fprintf(stderr, "%g\n", numval.dval); break; 268: 687: case STRING: fprintf(stderr, "'%s'\n", yytext); break; 2053: 688: case WORD: fprintf(stderr, "\"%s\"\n", yytext); break; 62480: 689: default: fprintf(stderr, "%s\n", yytext); break; -: 690: } 67740: 691: return n; -: 692:} -: 693: -: 694:#endif -: 695: