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