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