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