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