|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <ctype.h> ! 3: #include "pico.h" ! 4: #include "y.tab.h" ! 5: ! 6: #define Prompt2 /* if (INPUT == stdin) fprintf(stderr, ":%d ", pline) */ ! 7: ! 8: extern FILE *INPUT; ! 9: ! 10: Symbol *whichcmd(), *lookup(), *getname(); ! 11: char *getstring(); ! 12: ! 13: int linenumber = 1; ! 14: int pline = 0; ! 15: int lexlast = -1; ! 16: int LO = -1; ! 17: char lastyy = '\n'; ! 18: char nolf = 1; ! 19: char nesting = 0; ! 20: char operator = 0; ! 21: char lastdepth = 0; ! 22: ! 23: /* ! 24: * if the last token seen was not an operator the next ! 25: * newline will be interpreted as a statement separator ! 26: */ ! 27: ! 28: #define ADDEQ 210 ! 29: #define SUBEQ 211 ! 30: #define MULEQ 212 ! 31: #define DIVEQ 213 ! 32: #define MODEQ 214 ! 33: #define INC 215 ! 34: #define DEC 216 ! 35: ! 36: yylex() ! 37: { int c; ! 38: while ((c = ylexlex()) == SCOM) ! 39: { do c = ylexlex(); ! 40: while (c != ECOM); ! 41: } ! 42: /* fprintf(stderr, "lex: %d [[%c]]\n", c, (isalnum(c))?c:'-');/* */ ! 43: switch (c) { ! 44: case '+': case '-': case '*': ! 45: case '/': case '%': case '^': ! 46: case POW: case GT: case GE: ! 47: case LT: case LE: case EQ: ! 48: case NE: case ANDAND: case OROR: ! 49: case OR: case AND: case LSH: ! 50: case RSH: case ',': case NOT: ! 51: case '~': case '?': case ':': ! 52: case ASSIGN: case '(': case '[': ! 53: operator = 1; ! 54: break; ! 55: case ADDEQ: operator = 1; LO = OADD; return OPER; ! 56: case SUBEQ: operator = 1; LO = OSUB; return OPER; ! 57: case MULEQ: operator = 1; LO = OMUL; return OPER; ! 58: case DIVEQ: operator = 1; LO = DIVV; return OPER; ! 59: case MODEQ: operator = 1; LO = MODU; return OPER; ! 60: case INC: operator = 0; LO = OADD; return POST; ! 61: case DEC: operator = 0; LO = OSUB; return POST; ! 62: default: ! 63: operator = 0; ! 64: break; ! 65: } ! 66: return c; ! 67: } ! 68: ! 69: ylexlex() ! 70: { int c; ! 71: ! 72: again: switch (c = getc(INPUT)) { ! 73: case EOF: undirect(); checkit(); ! 74: case ' ': ! 75: case 27: ! 76: case '\t': goto again; ! 77: ! 78: case '\\': if ((c = getc(INPUT)) == '\n') ! 79: goto again; ! 80: else ! 81: break; ! 82: case '\n': if (nesting > 0 && (operator || lastyy == '\n')) ! 83: { Prompt2; ! 84: pline++; ! 85: goto again; ! 86: } ! 87: default : break; ! 88: } ! 89: ! 90: nolf = (c != '\n'); ! 91: ! 92: if (c == '\"') ! 93: { yylval.resu = (int) getstring(); ! 94: lastyy = '\0'; ! 95: return STRING; ! 96: } ! 97: if (isdigit(c)) ! 98: { lexlast = 0; ! 99: do ! 100: { lexlast = lexlast*10 + c - '0'; ! 101: c = getc(INPUT); ! 102: } while (isdigit(c)); ! 103: ungetc(c, INPUT); ! 104: lastyy = '\0'; ! 105: ! 106: yylval.resu = lexlast; ! 107: return VAL; ! 108: } ! 109: ! 110: if (isalpha(c) || c == '_') ! 111: { yylval.sym = getname(c); ! 112: lastyy = '\0'; ! 113: return yylval.sym->type; ! 114: } ! 115: ! 116: lastyy = '\0'; ! 117: switch (c) { ! 118: case '{' : if (++nesting == 1) pline = 1; lastyy = '\n'; return OPEN; ! 119: case '}' : sympurge(); ! 120: if (nesting-- == 1) pline = 0; ! 121: else ungetc(';', INPUT); ! 122: return CLOSE; ! 123: case '/' : return follow('=', DIVEQ, follow('*', SCOM, '/')); ! 124: case '%' : return follow('=', MODEQ, '%'); ! 125: case '+' : return follow('+', INC, follow('=', ADDEQ, '+')); ! 126: case '-' : return follow('-', DEC, follow('=', SUBEQ, '-')); ! 127: case '*' : return follow('*', POW, follow('=',MULEQ, follow('/',ECOM,'*'))); ! 128: case '>' : return follow('=', GE, follow('>', RSH, GT)); ! 129: case '<' : return follow('=', LE, follow('<', LSH, LT)); ! 130: case '=' : return follow('=', EQ, ASSIGN); ! 131: case '!' : return follow('=', NE, NOT); ! 132: case '|' : return follow('|', OROR, OR); ! 133: case '&' : return follow('&', ANDAND, AND); ! 134: case '\n': if (nesting == 0) ! 135: linenumber++; /* fall through */ ! 136: else ! 137: { Prompt2; ! 138: pline++; ! 139: } ! 140: case ';' : lastyy = '\n'; ! 141: return ';'; ! 142: default : return c; ! 143: } ! 144: } ! 145: ! 146: follow(expect, ifyes, ifno) ! 147: { ! 148: int c = getc(INPUT); ! 149: ! 150: if (c == expect) ! 151: return ifyes; ! 152: ! 153: ungetc(c, INPUT); ! 154: return ifno; ! 155: } ! 156: ! 157: Symbol * ! 158: getname(cc) ! 159: char cc; ! 160: { char c=cc, sbuf[128], *p = sbuf; ! 161: ! 162: do ! 163: { if (p >= sbuf + sizeof(sbuf) - 1) ! 164: { *p = '\0'; ! 165: yyerror("name too long: %s", sbuf); ! 166: } ! 167: *p++ = c; ! 168: } while ((c=getc(INPUT)) != EOF && (isalnum(c) || c == '_')); ! 169: ungetc(c, INPUT); ! 170: *p = '\0'; ! 171: ! 172: if (nesting == 0 && lastyy == '\n') ! 173: return whichcmd(sbuf); ! 174: else ! 175: return lookup(sbuf); ! 176: } ! 177: ! 178: char * ! 179: getstring() ! 180: { char c, *sbuf, *p; ! 181: sbuf = (char *) Emalloc(512); ! 182: p = sbuf; ! 183: ! 184: while ((c=getc(INPUT)) != EOF && c != '\"') ! 185: { if (c == '\\') ! 186: c = follow('n', '\n', follow('t', '\t', '\\')); ! 187: *p++ = c; ! 188: if (p >= sbuf + 512 - 1) ! 189: { *p = '\0'; ! 190: yyerror("string too long: %s", sbuf); ! 191: } ! 192: } ; ! 193: *p = '\0'; ! 194: ! 195: return sbuf; ! 196: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.