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