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