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