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