|
|
1.1 root 1: %{
2: /* Copyright (c) 1982 Regents of the University of California */
3:
4: static char sccsid[] = "@(#)token.lex 1.3 1/25/82";
5:
6: /*
7: * Token definitions for pdx scanner.
8: */
9:
10: #include "defs.h"
11: #include "command.h"
12: #include "y.tab.h"
13: #include "main.h"
14: #include "symtab.h"
15: #include "sym.h"
16: #include "process.h"
17: #include "process/pxinfo.h"
18:
19: char *initfile = ".pdxinit";
20:
21: /*
22: * This is a silly "lex" thing.
23: */
24:
25: #define yywrap() (1)
26:
27: /*
28: * Override Lex default input macros.
29: */
30:
31: #undef input
32: #undef unput
33:
34: #define unput(c) ungetc(c, yyin)
35:
36: %}
37:
38: blank [ \t]
39: white {blank}+
40: alpha [a-zA-Z]
41: digit [0-9]
42: n {digit}+
43: h [0-9a-fA-F]+
44: e (("e"|"E")("+"|"-")?{n})
45: alphanum [a-zA-Z0-9]
46: ident {alpha}{alphanum}*
47: filenm [^ \t\n"<>!*"]+
48: qfilenm {filenm}/":"
49: string '[^']+'('[^']*')*
50: newline "\n"
51: char .
52:
53: %Start file sh
54:
55: %%
56:
57: {white} ;
58: ^sh{white}.*$ { BEGIN 0; yylval.y_string = &yytext[3]; return(SH); }
59: ^sh { BEGIN 0; yylval.y_string = NIL; return(SH); }
60: ^{ident} { return(findcmd(yytext)); }
61: <file>{filenm} { yylval.y_string = strdup(yytext); return(FILENAME); }
62: {qfilenm} { yylval.y_string = strdup(yytext); return(FILENAME); }
63: {n}?\.{n}{e}? { yylval.y_real = atof(yytext); return(REAL); }
64: 0{n} { yylval.y_long = octal(yytext); return(INT); }
65: 0x{h} { yylval.y_long = hex(yytext); return(INT); }
66: {n} { yylval.y_long = atol(yytext); return(INT); }
67: at { return(AT); }
68: {ident} { return(ident(yytext)); }
69: {string} { yylval.y_string = yytext; return(STRING); }
70: "%dp" { yylval.y_long = (long) DP; return(INT); }
71: {newline} { BEGIN 0; nlflag = TRUE; return('\n'); }
72: {char} { return(yylval.y_int = yytext[0]); }
73:
74: %%
75:
76: LOCAL SYMTAB *dbtab, *specialtab;
77:
78: /*
79: * Look for the given string in the debugger keyword table.
80: * If it's there, return the associated token, otherwise report an error.
81: */
82:
83: LOCAL int findcmd(s)
84: char *s;
85: {
86: register SYM *p;
87:
88: if ((p = st_lookup(dbtab, s)) == NIL) {
89: error("\"%s\" is not a command", s);
90: }
91: yylval.y_int = tokval(p);
92: switch (toknum(p)) {
93: case ALIAS:
94: case DUMP:
95: case EDIT:
96: case CHFILE:
97: case RUN:
98: case SOURCE:
99: case STATUS:
100: BEGIN file;
101: break;
102:
103: default:
104: /* do nothing */;
105: }
106: return(toknum(p));
107: }
108:
109: /*
110: * Look for a symbol, first in the special table (if, in, etc.)
111: * then in the symbol table. If it's there, return the SYM pointer,
112: * otherwise it's an error.
113: */
114:
115: LOCAL int ident(s)
116: char *s;
117: {
118: register SYM *p;
119:
120: if ((p = st_lookup(specialtab, s)) != NIL) {
121: yylval.y_sym = p;
122: return(toknum(p));
123: }
124: p = st_lookup(symtab, s);
125: if (p == NIL) {
126: if (strcmp(s, "nil") == 0) {
127: yylval.y_long = 0L;
128: return(INT);
129: } else {
130: error("\"%s\" is not defined", s);
131: }
132: }
133: yylval.y_sym = p;
134: return(NAME);
135: }
136:
137: /*
138: * Convert a string to octal. No check that digits are less than 8.
139: */
140:
141: LOCAL int octal(s)
142: char *s;
143: {
144: register char *p;
145: register int n;
146:
147: n = 0;
148: for (p = s; *p != '\0'; p++) {
149: n = 8*n + (*p - '0');
150: }
151: return(n);
152: }
153:
154: /*
155: * Convert a string to hex.
156: */
157:
158: LOCAL int hex(s)
159: char *s;
160: {
161: register char *p;
162: register int n;
163:
164: n = 0;
165: for (p = s+2; *p != '\0'; p++) {
166: n *= 16;
167: if (*p >= 'a' && *p <= 'f') {
168: n += (*p - 'a' + 10);
169: } else if (*p >= 'A' && *p <= 'F') {
170: n += (*p - 'A' + 10);
171: } else {
172: n += (*p - '0');
173: }
174: }
175: return(n);
176: }
177:
178: /*
179: * Initialize the debugger keyword table (dbtab) and special symbol
180: * table (specialtab).
181: */
182:
183: #define db_keyword(nm, n) make_keyword(dbtab, nm, n)
184: #define sp_keyword(nm, n) make_keyword(specialtab, nm, n)
185:
186: lexinit()
187: {
188: dbtab = st_creat(150);
189: db_keyword("alias", ALIAS);
190: db_keyword("assign", ASSIGN);
191: db_keyword("call", CALL);
192: db_keyword("cont", CONT);
193: db_keyword("delete", DELETE);
194: db_keyword("dump", DUMP);
195: db_keyword("edit", EDIT);
196: db_keyword("file", CHFILE);
197: db_keyword("gripe", GRIPE);
198: db_keyword("help", HELP);
199: db_keyword("list", LIST);
200: db_keyword("next", NEXT);
201: db_keyword("pi", REMAKE);
202: db_keyword("print", PRINT);
203: db_keyword("quit", QUIT);
204: db_keyword("run", RUN);
205: db_keyword("sh", SH);
206: db_keyword("source", SOURCE);
207: db_keyword("status", STATUS);
208: db_keyword("step", STEP);
209: db_keyword("stop", STOP);
210: db_keyword("stopi", STOPI);
211: db_keyword("trace", TRACE);
212: db_keyword("tracei", TRACEI);
213: db_keyword("whatis", WHATIS);
214: db_keyword("where", WHERE);
215: db_keyword("which", WHICH);
216: db_keyword("xd", XD);
217: db_keyword("xi", XI);
218:
219: specialtab = st_creat(10);
220: sp_keyword("div", DIV);
221: sp_keyword("mod", MOD);
222: sp_keyword("in", IN);
223: sp_keyword("if", IF);
224: sp_keyword("and", AND);
225: sp_keyword("or", OR);
226: }
227:
228: /*
229: * Send an alias directive over to the symbol table manager.
230: */
231:
232: alias(new, old)
233: char *new, *old;
234: {
235: if (old == NIL) {
236: print_alias(dbtab, new);
237: } else {
238: enter_alias(dbtab, new, old);
239: }
240: }
241:
242: /*
243: * Input file management routines, "yyin" is Lex's idea of
244: * where the input comes from.
245: */
246:
247: #define MAXINPUT 10
248:
249: LOCAL FILE *infp[MAXINPUT];
250: LOCAL FILE **curfp = &infp[0];
251:
252: LOCAL BOOLEAN isnewfile;
253: LOCAL BOOLEAN firsttime;
254:
255: /*
256: * Initially, we set the input to the initfile if it exists.
257: * If it does exist, we play a game or two to avoid generating
258: * multiple prompts.
259: */
260:
261: initinput()
262: {
263: FILE *fp;
264:
265: firsttime = FALSE;
266: fp = fopen(initfile, "r");
267: if (fp != NIL) {
268: fclose(fp);
269: setinput(initfile);
270: if (!option('r')) {
271: firsttime = TRUE;
272: }
273: }
274: nlflag = TRUE;
275: }
276:
277: /*
278: * Set the input to the named file. It is expected that the file exists
279: * and is readable.
280: */
281:
282: setinput(filename)
283: char *filename;
284: {
285: register FILE *fp;
286:
287: if ((fp = fopen(filename, "r")) == NIL) {
288: error("can't open %s", filename);
289: }
290: if (curfp >= &infp[MAXINPUT]) {
291: error("unreasonable input nesting on %s", filename);
292: }
293: *curfp++ = yyin;
294: yyin = fp;
295: isnewfile = TRUE;
296: }
297:
298: BOOLEAN isstdin()
299: {
300: return((BOOLEAN) (yyin == stdin));
301: }
302:
303: LOCAL int input()
304: {
305: register int c;
306:
307: if (isnewfile) {
308: isnewfile = FALSE;
309: return('\n');
310: }
311: while ((c = getc(yyin)) == EOF) {
312: if (curfp == &infp[0]) {
313: return(0);
314: } else {
315: fclose(yyin);
316: yyin = *--curfp;
317: if (yyin == stdin) {
318: if (firsttime) {
319: firsttime = FALSE;
320: } else {
321: prompt();
322: }
323: }
324: }
325: }
326: return(c);
327: }
328:
329: /*
330: * Handle an input string by stripping the quotes and converting
331: * two interior quotes to one. Copy to newly allocated space and
332: * return a pointer to it.
333: *
334: * The handling of strings here is not particularly efficient,
335: * nor need it be.
336: */
337:
338: LOCAL char *pstring(p)
339: char *p;
340: {
341: int i, len;
342: char *r, *newp;
343:
344: len = strlen(p);
345: r = newp = alloc(len - 2 + 1, char);
346: for (i = 1; i < len - 1; i++) {
347: if (p[i] == '\'' && p[i+1] == '\'') {
348: i++;
349: }
350: *newp++ = p[i];
351: }
352: *newp = '\0';
353: return(r);
354: }
355:
356: /*
357: * prompt for a command
358: */
359:
360: prompt()
361: {
362: nlflag = FALSE;
363: if (yyin == stdin) {
364: printf("> ");
365: fflush(stdout);
366: }
367: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.