15476Slinton %{ 25476Slinton /* Copyright (c) 1982 Regents of the University of California */ 35476Slinton 4*5608Slinton static char sccsid[] = "@(#)token.l 1.2 01/23/82"; 55476Slinton 65476Slinton /* 75476Slinton * Token definitions for pdx scanner. 85476Slinton */ 95476Slinton 105476Slinton #include "defs.h" 115476Slinton #include "command.h" 125476Slinton #include "y.tab.h" 135476Slinton #include "symtab.h" 145476Slinton #include "sym.h" 155476Slinton #include "process.h" 165476Slinton #include "process/pxinfo.h" 175476Slinton 185476Slinton char *initfile = ".pdxinit"; 195476Slinton 205476Slinton /* 215476Slinton * This is a silly "lex" thing. 225476Slinton */ 235476Slinton 245476Slinton #define yywrap() (1) 255476Slinton 265476Slinton /* 275476Slinton * Override Lex default input macros. 285476Slinton */ 295476Slinton 305476Slinton #undef input 315476Slinton #undef unput 325476Slinton 335476Slinton #define unput(c) ungetc(c, yyin) 345476Slinton 355476Slinton %} 365476Slinton 375476Slinton blank [ \t] 385476Slinton white {blank}+ 395476Slinton alpha [a-zA-Z] 405476Slinton digit [0-9] 415476Slinton n {digit}+ 425476Slinton h [0-9a-fA-F]+ 435476Slinton e (("e"|"E")("+"|"-")?{n}) 445476Slinton alphanum [a-zA-Z0-9] 455476Slinton ident {alpha}{alphanum}* 465476Slinton filenm [^ \t\n"<>!*"]+ 475476Slinton qfilenm {filenm}/":" 485476Slinton string '[^']+'('[^']*')* 495476Slinton newline "\n" 505476Slinton char . 515476Slinton 525476Slinton %Start file sh 535476Slinton 545476Slinton %% 555476Slinton 565476Slinton {white} ; 575476Slinton ^sh{white}.*$ { BEGIN 0; yylval.y_string = &yytext[3]; return(SH); } 585476Slinton ^sh { BEGIN 0; yylval.y_string = NIL; return(SH); } 595476Slinton ^{ident} { return(findcmd(yytext)); } 60*5608Slinton <file>{filenm} { yylval.y_string = strdup(yytext); return(FILENAME); } 61*5608Slinton {qfilenm} { yylval.y_string = strdup(yytext); return(FILENAME); } 625476Slinton {n}?\.{n}{e}? { yylval.y_real = atof(yytext); return(REAL); } 635476Slinton 0{n} { yylval.y_long = octal(yytext); return(INT); } 645476Slinton 0x{h} { yylval.y_long = hex(yytext); return(INT); } 655476Slinton {n} { yylval.y_long = atol(yytext); return(INT); } 665476Slinton at { return(AT); } 675476Slinton {ident} { return(ident(yytext)); } 685476Slinton {string} { yylval.y_string = yytext; return(STRING); } 695476Slinton "%dp" { yylval.y_long = (long) DP; return(INT); } 705476Slinton {newline} { BEGIN 0; nlflag = TRUE; return('\n'); } 715476Slinton {char} { return(yylval.y_int = yytext[0]); } 725476Slinton 735476Slinton %% 745476Slinton 755476Slinton LOCAL SYMTAB *dbtab, *specialtab; 765476Slinton 775476Slinton /* 785476Slinton * Look for the given string in the debugger keyword table. 795476Slinton * If it's there, return the associated token, otherwise report an error. 805476Slinton */ 815476Slinton 825476Slinton LOCAL int findcmd(s) 835476Slinton char *s; 845476Slinton { 855476Slinton register SYM *p; 865476Slinton 875476Slinton if ((p = st_lookup(dbtab, s)) == NIL) { 885476Slinton error("\"%s\" is not a command", s); 895476Slinton } 905476Slinton yylval.y_int = tokval(p); 915476Slinton switch (toknum(p)) { 925476Slinton case ALIAS: 935476Slinton case DUMP: 945476Slinton case EDIT: 955476Slinton case CHFILE: 965476Slinton case RUN: 975476Slinton case SOURCE: 985476Slinton case STATUS: 995476Slinton BEGIN file; 1005476Slinton break; 1015476Slinton 1025476Slinton default: 1035476Slinton /* do nothing */; 1045476Slinton } 1055476Slinton return(toknum(p)); 1065476Slinton } 1075476Slinton 1085476Slinton /* 1095476Slinton * Look for a symbol, first in the special table (if, in, etc.) 1105476Slinton * then in the symbol table. If it's there, return the SYM pointer, 1115476Slinton * otherwise it's an error. 1125476Slinton */ 1135476Slinton 1145476Slinton LOCAL int ident(s) 1155476Slinton char *s; 1165476Slinton { 1175476Slinton register SYM *p; 1185476Slinton 1195476Slinton if ((p = st_lookup(specialtab, s)) != NIL) { 1205476Slinton yylval.y_sym = p; 1215476Slinton return(toknum(p)); 1225476Slinton } 1235476Slinton p = st_lookup(symtab, s); 1245476Slinton if (p == NIL) { 1255476Slinton if (strcmp(s, "nil") == 0) { 1265476Slinton yylval.y_long = 0L; 1275476Slinton return(INT); 1285476Slinton } else { 1295476Slinton error("\"%s\" is not defined", s); 1305476Slinton } 1315476Slinton } 1325476Slinton yylval.y_sym = p; 1335476Slinton return(NAME); 1345476Slinton } 1355476Slinton 1365476Slinton /* 1375476Slinton * Convert a string to octal. No check that digits are less than 8. 1385476Slinton */ 1395476Slinton 1405476Slinton LOCAL int octal(s) 1415476Slinton char *s; 1425476Slinton { 1435476Slinton register char *p; 1445476Slinton register int n; 1455476Slinton 1465476Slinton n = 0; 1475476Slinton for (p = s; *p != '\0'; p++) { 1485476Slinton n = 8*n + (*p - '0'); 1495476Slinton } 1505476Slinton return(n); 1515476Slinton } 1525476Slinton 1535476Slinton /* 1545476Slinton * Convert a string to hex. 1555476Slinton */ 1565476Slinton 1575476Slinton LOCAL int hex(s) 1585476Slinton char *s; 1595476Slinton { 1605476Slinton register char *p; 1615476Slinton register int n; 1625476Slinton 1635476Slinton n = 0; 1645476Slinton for (p = s+2; *p != '\0'; p++) { 1655476Slinton n *= 16; 1665476Slinton if (*p >= 'a' && *p <= 'f') { 1675476Slinton n += (*p - 'a' + 10); 1685476Slinton } else if (*p >= 'A' && *p <= 'F') { 1695476Slinton n += (*p - 'A' + 10); 1705476Slinton } else { 1715476Slinton n += (*p - '0'); 1725476Slinton } 1735476Slinton } 1745476Slinton return(n); 1755476Slinton } 1765476Slinton 1775476Slinton /* 1785476Slinton * Initialize the debugger keyword table (dbtab) and special symbol 1795476Slinton * table (specialtab). 1805476Slinton */ 1815476Slinton 1825476Slinton #define db_keyword(nm, n) make_keyword(dbtab, nm, n) 1835476Slinton #define sp_keyword(nm, n) make_keyword(specialtab, nm, n) 1845476Slinton 1855476Slinton lexinit() 1865476Slinton { 1875476Slinton dbtab = st_creat(150); 1885476Slinton db_keyword("alias", ALIAS); 1895476Slinton db_keyword("assign", ASSIGN); 1905476Slinton db_keyword("call", CALL); 1915476Slinton db_keyword("cont", CONT); 1925476Slinton db_keyword("delete", DELETE); 1935476Slinton db_keyword("dump", DUMP); 1945476Slinton db_keyword("edit", EDIT); 1955476Slinton db_keyword("file", CHFILE); 1965476Slinton db_keyword("gripe", GRIPE); 1975476Slinton db_keyword("help", HELP); 1985476Slinton db_keyword("list", LIST); 1995476Slinton db_keyword("next", NEXT); 2005476Slinton db_keyword("pi", REMAKE); 2015476Slinton db_keyword("print", PRINT); 2025476Slinton db_keyword("quit", QUIT); 2035476Slinton db_keyword("run", RUN); 2045476Slinton db_keyword("sh", SH); 2055476Slinton db_keyword("source", SOURCE); 2065476Slinton db_keyword("status", STATUS); 2075476Slinton db_keyword("step", STEP); 2085476Slinton db_keyword("stop", STOP); 2095476Slinton db_keyword("stopi", STOPI); 2105476Slinton db_keyword("trace", TRACE); 2115476Slinton db_keyword("tracei", TRACEI); 2125476Slinton db_keyword("whatis", WHATIS); 2135476Slinton db_keyword("where", WHERE); 2145476Slinton db_keyword("which", WHICH); 2155476Slinton db_keyword("xd", XD); 2165476Slinton db_keyword("xi", XI); 2175476Slinton 2185476Slinton specialtab = st_creat(10); 2195476Slinton sp_keyword("div", DIV); 2205476Slinton sp_keyword("mod", MOD); 2215476Slinton sp_keyword("in", IN); 2225476Slinton sp_keyword("if", IF); 2235476Slinton sp_keyword("and", AND); 2245476Slinton sp_keyword("or", OR); 2255476Slinton } 2265476Slinton 2275476Slinton /* 2285476Slinton * Send an alias directive over to the symbol table manager. 2295476Slinton */ 2305476Slinton 2315476Slinton alias(new, old) 2325476Slinton char *new, *old; 2335476Slinton { 2345476Slinton if (old == NIL) { 2355476Slinton print_alias(dbtab, new); 2365476Slinton } else { 2375476Slinton enter_alias(dbtab, new, old); 2385476Slinton } 2395476Slinton } 2405476Slinton 2415476Slinton /* 2425476Slinton * Input file management routines, "yyin" is Lex's idea of 2435476Slinton * where the input comes from. 2445476Slinton */ 2455476Slinton 2465476Slinton #define MAXINPUT 10 2475476Slinton 2485476Slinton LOCAL FILE *infp[MAXINPUT]; 2495476Slinton LOCAL FILE **curfp = &infp[0]; 2505476Slinton 2515476Slinton LOCAL BOOLEAN isnewfile; 2525476Slinton 2535476Slinton /* 2545476Slinton * Initially, we set the input to the initfile if it exists. 2555476Slinton * If it does exist, we play a game or two to avoid generating 2565476Slinton * multiple prompts. 2575476Slinton */ 2585476Slinton 2595476Slinton initinput() 2605476Slinton { 2615476Slinton FILE *fp; 2625476Slinton 2635476Slinton fp = fopen(initfile, "r"); 2645476Slinton if (fp != NIL) { 2655476Slinton fclose(fp); 2665476Slinton setinput(initfile); 2675476Slinton } 2685476Slinton nlflag = TRUE; 2695476Slinton } 2705476Slinton 2715476Slinton /* 2725476Slinton * Set the input to the named file. It is expected that the file exists 2735476Slinton * and is readable. 2745476Slinton */ 2755476Slinton 2765476Slinton setinput(filename) 2775476Slinton char *filename; 2785476Slinton { 2795476Slinton register FILE *fp; 2805476Slinton 2815476Slinton if ((fp = fopen(filename, "r")) == NIL) { 2825476Slinton error("can't open %s", filename); 2835476Slinton } 2845476Slinton if (curfp >= &infp[MAXINPUT]) { 2855476Slinton error("unreasonable input nesting on %s", filename); 2865476Slinton } 2875476Slinton *curfp++ = yyin; 2885476Slinton yyin = fp; 2895476Slinton isnewfile = TRUE; 2905476Slinton } 2915476Slinton 2925476Slinton BOOLEAN isstdin() 2935476Slinton { 2945476Slinton return((BOOLEAN) (yyin == stdin)); 2955476Slinton } 2965476Slinton 2975476Slinton LOCAL int input() 2985476Slinton { 2995476Slinton register int c; 3005476Slinton 3015476Slinton if (isnewfile) { 3025476Slinton isnewfile = FALSE; 3035476Slinton return('\n'); 3045476Slinton } 3055476Slinton while ((c = getc(yyin)) == EOF) { 3065476Slinton if (curfp == &infp[0]) { 3075476Slinton return(0); 3085476Slinton } else { 3095476Slinton fclose(yyin); 3105476Slinton yyin = *--curfp; 3115476Slinton if (yyin == stdin) { 3125476Slinton prompt(); 3135476Slinton } 3145476Slinton } 3155476Slinton } 3165476Slinton return(c); 3175476Slinton } 3185476Slinton 3195476Slinton /* 3205476Slinton * Handle an input string by stripping the quotes and converting 3215476Slinton * two interior quotes to one. Copy to newly allocated space and 3225476Slinton * return a pointer to it. 3235476Slinton * 3245476Slinton * The handling of strings here is not particularly efficient, 3255476Slinton * nor need it be. 3265476Slinton */ 3275476Slinton 3285476Slinton LOCAL char *pstring(p) 3295476Slinton char *p; 3305476Slinton { 3315476Slinton int i, len; 3325476Slinton char *r, *newp; 3335476Slinton 3345476Slinton len = strlen(p); 3355476Slinton r = newp = alloc(len - 2 + 1, char); 3365476Slinton for (i = 1; i < len - 1; i++) { 3375476Slinton if (p[i] == '\'' && p[i+1] == '\'') { 3385476Slinton i++; 3395476Slinton } 3405476Slinton *newp++ = p[i]; 3415476Slinton } 3425476Slinton *newp = '\0'; 3435476Slinton return(r); 3445476Slinton } 3455476Slinton 3465476Slinton /* 3475476Slinton * prompt for a command 3485476Slinton */ 3495476Slinton 3505476Slinton prompt() 3515476Slinton { 3525476Slinton nlflag = FALSE; 3535476Slinton if (yyin == stdin) { 3545476Slinton printf("> "); 3555476Slinton fflush(stdout); 3565476Slinton } 3575476Slinton } 358