|
|
1.1 ! root 1: %{ ! 2: /* Copyright (c) 1982 Regents of the University of California */ ! 3: ! 4: static char sccsid[] = "@(#)token.lex 1.3 1/25/82"; ! 5: ! 6: /* ! 7: * Token definitions for pdx scanner. ! 8: */ ! 9: ! 10: #include "defs.h" ! 11: #include "command.h" ! 12: #include "y.tab.h" ! 13: #include "main.h" ! 14: #include "symtab.h" ! 15: #include "sym.h" ! 16: #include "process.h" ! 17: #include "process/pxinfo.h" ! 18: ! 19: char *initfile = ".pdxinit"; ! 20: ! 21: /* ! 22: * This is a silly "lex" thing. ! 23: */ ! 24: ! 25: #define yywrap() (1) ! 26: ! 27: /* ! 28: * Override Lex default input macros. ! 29: */ ! 30: ! 31: #undef input ! 32: #undef unput ! 33: ! 34: #define unput(c) ungetc(c, yyin) ! 35: ! 36: %} ! 37: ! 38: blank [ \t] ! 39: white {blank}+ ! 40: alpha [a-zA-Z] ! 41: digit [0-9] ! 42: n {digit}+ ! 43: h [0-9a-fA-F]+ ! 44: e (("e"|"E")("+"|"-")?{n}) ! 45: alphanum [a-zA-Z0-9] ! 46: ident {alpha}{alphanum}* ! 47: filenm [^ \t\n"<>!*"]+ ! 48: qfilenm {filenm}/":" ! 49: string '[^']+'('[^']*')* ! 50: newline "\n" ! 51: char . ! 52: ! 53: %Start file sh ! 54: ! 55: %% ! 56: ! 57: {white} ; ! 58: ^sh{white}.*$ { BEGIN 0; yylval.y_string = &yytext[3]; return(SH); } ! 59: ^sh { BEGIN 0; yylval.y_string = NIL; return(SH); } ! 60: ^{ident} { return(findcmd(yytext)); } ! 61: <file>{filenm} { yylval.y_string = strdup(yytext); return(FILENAME); } ! 62: {qfilenm} { yylval.y_string = strdup(yytext); return(FILENAME); } ! 63: {n}?\.{n}{e}? { yylval.y_real = atof(yytext); return(REAL); } ! 64: 0{n} { yylval.y_long = octal(yytext); return(INT); } ! 65: 0x{h} { yylval.y_long = hex(yytext); return(INT); } ! 66: {n} { yylval.y_long = atol(yytext); return(INT); } ! 67: at { return(AT); } ! 68: {ident} { return(ident(yytext)); } ! 69: {string} { yylval.y_string = yytext; return(STRING); } ! 70: "%dp" { yylval.y_long = (long) DP; return(INT); } ! 71: {newline} { BEGIN 0; nlflag = TRUE; return('\n'); } ! 72: {char} { return(yylval.y_int = yytext[0]); } ! 73: ! 74: %% ! 75: ! 76: LOCAL SYMTAB *dbtab, *specialtab; ! 77: ! 78: /* ! 79: * Look for the given string in the debugger keyword table. ! 80: * If it's there, return the associated token, otherwise report an error. ! 81: */ ! 82: ! 83: LOCAL int findcmd(s) ! 84: char *s; ! 85: { ! 86: register SYM *p; ! 87: ! 88: if ((p = st_lookup(dbtab, s)) == NIL) { ! 89: error("\"%s\" is not a command", s); ! 90: } ! 91: yylval.y_int = tokval(p); ! 92: switch (toknum(p)) { ! 93: case ALIAS: ! 94: case DUMP: ! 95: case EDIT: ! 96: case CHFILE: ! 97: case RUN: ! 98: case SOURCE: ! 99: case STATUS: ! 100: BEGIN file; ! 101: break; ! 102: ! 103: default: ! 104: /* do nothing */; ! 105: } ! 106: return(toknum(p)); ! 107: } ! 108: ! 109: /* ! 110: * Look for a symbol, first in the special table (if, in, etc.) ! 111: * then in the symbol table. If it's there, return the SYM pointer, ! 112: * otherwise it's an error. ! 113: */ ! 114: ! 115: LOCAL int ident(s) ! 116: char *s; ! 117: { ! 118: register SYM *p; ! 119: ! 120: if ((p = st_lookup(specialtab, s)) != NIL) { ! 121: yylval.y_sym = p; ! 122: return(toknum(p)); ! 123: } ! 124: p = st_lookup(symtab, s); ! 125: if (p == NIL) { ! 126: if (strcmp(s, "nil") == 0) { ! 127: yylval.y_long = 0L; ! 128: return(INT); ! 129: } else { ! 130: error("\"%s\" is not defined", s); ! 131: } ! 132: } ! 133: yylval.y_sym = p; ! 134: return(NAME); ! 135: } ! 136: ! 137: /* ! 138: * Convert a string to octal. No check that digits are less than 8. ! 139: */ ! 140: ! 141: LOCAL int octal(s) ! 142: char *s; ! 143: { ! 144: register char *p; ! 145: register int n; ! 146: ! 147: n = 0; ! 148: for (p = s; *p != '\0'; p++) { ! 149: n = 8*n + (*p - '0'); ! 150: } ! 151: return(n); ! 152: } ! 153: ! 154: /* ! 155: * Convert a string to hex. ! 156: */ ! 157: ! 158: LOCAL int hex(s) ! 159: char *s; ! 160: { ! 161: register char *p; ! 162: register int n; ! 163: ! 164: n = 0; ! 165: for (p = s+2; *p != '\0'; p++) { ! 166: n *= 16; ! 167: if (*p >= 'a' && *p <= 'f') { ! 168: n += (*p - 'a' + 10); ! 169: } else if (*p >= 'A' && *p <= 'F') { ! 170: n += (*p - 'A' + 10); ! 171: } else { ! 172: n += (*p - '0'); ! 173: } ! 174: } ! 175: return(n); ! 176: } ! 177: ! 178: /* ! 179: * Initialize the debugger keyword table (dbtab) and special symbol ! 180: * table (specialtab). ! 181: */ ! 182: ! 183: #define db_keyword(nm, n) make_keyword(dbtab, nm, n) ! 184: #define sp_keyword(nm, n) make_keyword(specialtab, nm, n) ! 185: ! 186: lexinit() ! 187: { ! 188: dbtab = st_creat(150); ! 189: db_keyword("alias", ALIAS); ! 190: db_keyword("assign", ASSIGN); ! 191: db_keyword("call", CALL); ! 192: db_keyword("cont", CONT); ! 193: db_keyword("delete", DELETE); ! 194: db_keyword("dump", DUMP); ! 195: db_keyword("edit", EDIT); ! 196: db_keyword("file", CHFILE); ! 197: db_keyword("gripe", GRIPE); ! 198: db_keyword("help", HELP); ! 199: db_keyword("list", LIST); ! 200: db_keyword("next", NEXT); ! 201: db_keyword("pi", REMAKE); ! 202: db_keyword("print", PRINT); ! 203: db_keyword("quit", QUIT); ! 204: db_keyword("run", RUN); ! 205: db_keyword("sh", SH); ! 206: db_keyword("source", SOURCE); ! 207: db_keyword("status", STATUS); ! 208: db_keyword("step", STEP); ! 209: db_keyword("stop", STOP); ! 210: db_keyword("stopi", STOPI); ! 211: db_keyword("trace", TRACE); ! 212: db_keyword("tracei", TRACEI); ! 213: db_keyword("whatis", WHATIS); ! 214: db_keyword("where", WHERE); ! 215: db_keyword("which", WHICH); ! 216: db_keyword("xd", XD); ! 217: db_keyword("xi", XI); ! 218: ! 219: specialtab = st_creat(10); ! 220: sp_keyword("div", DIV); ! 221: sp_keyword("mod", MOD); ! 222: sp_keyword("in", IN); ! 223: sp_keyword("if", IF); ! 224: sp_keyword("and", AND); ! 225: sp_keyword("or", OR); ! 226: } ! 227: ! 228: /* ! 229: * Send an alias directive over to the symbol table manager. ! 230: */ ! 231: ! 232: alias(new, old) ! 233: char *new, *old; ! 234: { ! 235: if (old == NIL) { ! 236: print_alias(dbtab, new); ! 237: } else { ! 238: enter_alias(dbtab, new, old); ! 239: } ! 240: } ! 241: ! 242: /* ! 243: * Input file management routines, "yyin" is Lex's idea of ! 244: * where the input comes from. ! 245: */ ! 246: ! 247: #define MAXINPUT 10 ! 248: ! 249: LOCAL FILE *infp[MAXINPUT]; ! 250: LOCAL FILE **curfp = &infp[0]; ! 251: ! 252: LOCAL BOOLEAN isnewfile; ! 253: LOCAL BOOLEAN firsttime; ! 254: ! 255: /* ! 256: * Initially, we set the input to the initfile if it exists. ! 257: * If it does exist, we play a game or two to avoid generating ! 258: * multiple prompts. ! 259: */ ! 260: ! 261: initinput() ! 262: { ! 263: FILE *fp; ! 264: ! 265: firsttime = FALSE; ! 266: fp = fopen(initfile, "r"); ! 267: if (fp != NIL) { ! 268: fclose(fp); ! 269: setinput(initfile); ! 270: if (!option('r')) { ! 271: firsttime = TRUE; ! 272: } ! 273: } ! 274: nlflag = TRUE; ! 275: } ! 276: ! 277: /* ! 278: * Set the input to the named file. It is expected that the file exists ! 279: * and is readable. ! 280: */ ! 281: ! 282: setinput(filename) ! 283: char *filename; ! 284: { ! 285: register FILE *fp; ! 286: ! 287: if ((fp = fopen(filename, "r")) == NIL) { ! 288: error("can't open %s", filename); ! 289: } ! 290: if (curfp >= &infp[MAXINPUT]) { ! 291: error("unreasonable input nesting on %s", filename); ! 292: } ! 293: *curfp++ = yyin; ! 294: yyin = fp; ! 295: isnewfile = TRUE; ! 296: } ! 297: ! 298: BOOLEAN isstdin() ! 299: { ! 300: return((BOOLEAN) (yyin == stdin)); ! 301: } ! 302: ! 303: LOCAL int input() ! 304: { ! 305: register int c; ! 306: ! 307: if (isnewfile) { ! 308: isnewfile = FALSE; ! 309: return('\n'); ! 310: } ! 311: while ((c = getc(yyin)) == EOF) { ! 312: if (curfp == &infp[0]) { ! 313: return(0); ! 314: } else { ! 315: fclose(yyin); ! 316: yyin = *--curfp; ! 317: if (yyin == stdin) { ! 318: if (firsttime) { ! 319: firsttime = FALSE; ! 320: } else { ! 321: prompt(); ! 322: } ! 323: } ! 324: } ! 325: } ! 326: return(c); ! 327: } ! 328: ! 329: /* ! 330: * Handle an input string by stripping the quotes and converting ! 331: * two interior quotes to one. Copy to newly allocated space and ! 332: * return a pointer to it. ! 333: * ! 334: * The handling of strings here is not particularly efficient, ! 335: * nor need it be. ! 336: */ ! 337: ! 338: LOCAL char *pstring(p) ! 339: char *p; ! 340: { ! 341: int i, len; ! 342: char *r, *newp; ! 343: ! 344: len = strlen(p); ! 345: r = newp = alloc(len - 2 + 1, char); ! 346: for (i = 1; i < len - 1; i++) { ! 347: if (p[i] == '\'' && p[i+1] == '\'') { ! 348: i++; ! 349: } ! 350: *newp++ = p[i]; ! 351: } ! 352: *newp = '\0'; ! 353: return(r); ! 354: } ! 355: ! 356: /* ! 357: * prompt for a command ! 358: */ ! 359: ! 360: prompt() ! 361: { ! 362: nlflag = FALSE; ! 363: if (yyin == stdin) { ! 364: printf("> "); ! 365: fflush(stdout); ! 366: } ! 367: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.