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