15476Slinton %{
222762Smckusick /*
322762Smckusick  * Copyright (c) 1982 Regents of the University of California.
422762Smckusick  * All rights reserved.  The Berkeley software License Agreement
522762Smckusick  * specifies the terms and conditions for redistribution.
622762Smckusick  */
75476Slinton 
822762Smckusick #ifndef lint
9*44651Sbostic static char sccsid[] = "@(#)token.l	5.3 (Berkeley) 06/29/90";
1022762Smckusick #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 
27*44651Sbostic /* override Lex default input macro. */
28*44651Sbostic LOCAL int pdxinput();
295476Slinton 
30*44651Sbostic #undef  YY_INPUT
31*44651Sbostic #define YY_INPUT(buf,result,max_size)	\
32*44651Sbostic 	{				\
33*44651Sbostic 	int c = pdxinput();		\
34*44651Sbostic 	if ( c == EOF )			\
35*44651Sbostic 		result = YY_NULL;	\
36*44651Sbostic 	else				\
37*44651Sbostic 		{			\
38*44651Sbostic 		buf[0] = c;		\
39*44651Sbostic 		result = 1;		\
40*44651Sbostic 		}			\
41*44651Sbostic 	}
425476Slinton 
435476Slinton %}
445476Slinton 
455476Slinton blank		[ \t]
465476Slinton white		{blank}+
475476Slinton alpha		[a-zA-Z]
485476Slinton digit		[0-9]
495476Slinton n		{digit}+
505476Slinton h		[0-9a-fA-F]+
515476Slinton e		(("e"|"E")("+"|"-")?{n})
525476Slinton alphanum	[a-zA-Z0-9]
535476Slinton ident		{alpha}{alphanum}*
545476Slinton filenm		[^ \t\n"<>!*"]+
555476Slinton string		'[^']+'('[^']*')*
565476Slinton newline		"\n"
575476Slinton char		.
585476Slinton 
59*44651Sbostic %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)); }
67*44651Sbostic <File>{filenm}	{ yylval.y_string = strdup(yytext); return(FILENAME); }
68*44651Sbostic {filenm}/":"	{ 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:
106*44651Sbostic 			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 
309*44651Sbostic LOCAL int pdxinput()
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  * prompt for a command
3375476Slinton  */
3385476Slinton 
3395476Slinton prompt()
3405476Slinton {
3415476Slinton 	nlflag = FALSE;
3425476Slinton 	if (yyin == stdin) {
3435476Slinton 		printf("> ");
3445476Slinton 		fflush(stdout);
3455476Slinton 	}
3465476Slinton }
347