|
|
1.1.1.2 root 1: /*
1.1 root 2: * Mach Operating System
3: * Copyright (c) 1991,1990 Carnegie Mellon University
4: * All Rights Reserved.
1.1.1.2 root 5: *
1.1 root 6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
1.1.1.2 root 11: *
1.1 root 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1.1.1.2 root 15: *
1.1 root 16: * Carnegie Mellon requests users of this software to return to
1.1.1.2 root 17: *
1.1 root 18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
1.1.1.2 root 22: *
1.1 root 23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: * Author: David B. Golub, Carnegie Mellon University
28: * Date: 7/90
29: */
1.1.1.3 root 30:
1.1 root 31: #if MACH_KDB
32:
33: /*
34: * Lexical analyzer.
35: */
1.1.1.3 root 36: #include <string.h>
1.1 root 37: #include <machine/db_machdep.h>
1.1.1.3 root 38: #include <ddb/db_command.h>
39: #include <ddb/db_examine.h>
40: #include <ddb/db_input.h>
1.1 root 41: #include <ddb/db_lex.h>
1.1.1.3 root 42: #include <ddb/db_output.h>
1.1 root 43:
44: char db_line[DB_LEX_LINE_SIZE];
45: char db_last_line[DB_LEX_LINE_SIZE];
46: char *db_lp, *db_endlp;
47: char *db_last_lp;
48: int db_look_char = 0;
49: db_expr_t db_look_token = 0;
50:
51: int
52: db_read_line(repeat_last)
1.1.1.4 ! root 53: const char *repeat_last;
1.1 root 54: {
55: int i;
56:
57: i = db_readline(db_line, sizeof(db_line));
58: if (i == 0)
59: return (0); /* EOI */
60: if (repeat_last) {
61: if (strncmp(db_line, repeat_last, strlen(repeat_last)) == 0) {
62: db_strcpy(db_line, db_last_line);
63: db_printf("%s", db_line);
64: i = strlen(db_line);
65: } else if (db_line[0] != '\n' && db_line[0] != 0)
66: db_strcpy(db_last_line, db_line);
67: }
68: db_lp = db_line;
69: db_endlp = db_lp + i;
70: db_last_lp = db_lp;
71: db_look_char = 0;
72: db_look_token = 0;
73: return (i);
74: }
75:
76: void
1.1.1.3 root 77: db_flush_line(void)
1.1 root 78: {
79: db_lp = db_line;
80: db_last_lp = db_lp;
81: db_endlp = db_line;
82: }
83:
84: void
1.1.1.4 ! root 85: db_switch_input(
! 86: char *buffer,
! 87: int size)
1.1 root 88: {
89: db_lp = buffer;
90: db_last_lp = db_lp;
91: db_endlp = buffer + size;
92: db_look_char = 0;
93: db_look_token = 0;
94: }
95:
96: void
1.1.1.4 ! root 97: db_save_lex_context(struct db_lex_context *lp)
1.1 root 98: {
99: lp->l_ptr = db_lp;
100: lp->l_eptr = db_endlp;
101: lp->l_char = db_look_char;
102: lp->l_token = db_look_token;
103: }
104:
105: void
106: db_restore_lex_context(lp)
1.1.1.4 ! root 107: const struct db_lex_context *lp;
1.1 root 108: {
109: db_lp = lp->l_ptr;
110: db_last_lp = db_lp;
111: db_endlp = lp->l_eptr;
112: db_look_char = lp->l_char;
113: db_look_token = lp->l_token;
114: }
115:
116: int
1.1.1.3 root 117: db_read_char(void)
1.1 root 118: {
119: int c;
120:
121: if (db_look_char != 0) {
122: c = db_look_char;
123: db_look_char = 0;
124: }
125: else if (db_lp >= db_endlp)
126: c = -1;
1.1.1.2 root 127: else
1.1 root 128: c = *db_lp++;
129: return (c);
130: }
131:
132: void
1.1.1.4 ! root 133: db_unread_char(int c)
1.1 root 134: {
135: db_look_char = c;
136: }
137:
138: void
1.1.1.4 ! root 139: db_unread_token(int t)
1.1 root 140: {
141: db_look_token = t;
142: }
143:
144: int
1.1.1.3 root 145: db_read_token(void)
1.1 root 146: {
147: int t;
148:
149: if (db_look_token) {
150: t = db_look_token;
151: db_look_token = 0;
152: }
153: else {
154: db_last_lp = db_lp;
155: if (db_look_char)
156: db_last_lp--;
157: t = db_lex();
158: }
159: return (t);
160: }
161:
162: db_expr_t db_tok_number;
163: char db_tok_string[TOK_STRING_SIZE];
164: db_expr_t db_radix = 16;
165:
166: void
1.1.1.3 root 167: db_flush_lex(void)
1.1 root 168: {
169: db_flush_line();
170: db_look_char = 0;
171: db_look_token = 0;
172: }
173:
174: #define DB_DISP_SKIP 40 /* number of chars to display skip */
175:
176: void
1.1.1.3 root 177: db_skip_to_eol(void)
1.1 root 178: {
1.1.1.4 ! root 179: int skip;
! 180: int t;
! 181: int n;
! 182: char *p;
1.1 root 183:
184: t = db_read_token();
185: p = db_last_lp;
186: for (skip = 0; t != tEOL && t != tSEMI_COLON && t != tEOF; skip++)
187: t = db_read_token();
188: if (t == tSEMI_COLON)
189: db_unread_token(t);
190: if (skip != 0) {
191: while (p < db_last_lp && (*p == ' ' || *p == '\t'))
192: p++;
193: db_printf("Warning: Skipped input data \"");
194: for (n = 0; n < DB_DISP_SKIP && p < db_last_lp; n++)
195: db_printf("%c", *p++);
196: if (n >= DB_DISP_SKIP)
197: db_printf("....");
198: db_printf("\"\n");
199: }
200: }
201:
202: int
1.1.1.3 root 203: db_lex(void)
1.1 root 204: {
1.1.1.4 ! root 205: char *cp;
! 206: int c;
1.1 root 207:
208: c = db_read_char();
209: while (c <= ' ' || c > '~') {
210: if (c == '\n' || c == -1)
211: return (tEOL);
212: c = db_read_char();
213: }
214:
215: cp = db_tok_string;
216: *cp++ = c;
217:
218: if (c >= '0' && c <= '9') {
219: /* number */
220: int r, digit;
221:
222: if (c > '0')
223: r = db_radix;
224: else {
225: c = db_read_char();
226: if (c == 'O' || c == 'o')
227: r = 8;
228: else if (c == 'T' || c == 't')
229: r = 10;
230: else if (c == 'X' || c == 'x')
231: r = 16;
232: else {
233: cp--;
234: r = db_radix;
235: db_unread_char(c);
236: }
237: c = db_read_char();
238: *cp++ = c;
239: }
240: db_tok_number = 0;
241: for (;;) {
242: if (c >= '0' && c <= ((r == 8) ? '7' : '9'))
243: digit = c - '0';
244: else if (r == 16 && ((c >= 'A' && c <= 'F') ||
245: (c >= 'a' && c <= 'f'))) {
246: if (c >= 'a')
247: digit = c - 'a' + 10;
248: else
249: digit = c - 'A' + 10;
250: }
251: else
252: break;
253: db_tok_number = db_tok_number * r + digit;
254: c = db_read_char();
255: if (cp < &db_tok_string[sizeof(db_tok_string)-1])
256: *cp++ = c;
257: }
258: cp[-1] = 0;
259: if ((c >= '0' && c <= '9') ||
260: (c >= 'A' && c <= 'Z') ||
261: (c >= 'a' && c <= 'z') ||
262: (c == '_'))
263: {
1.1.1.2 root 264: db_printf("Bad character '%c' after number %s\n",
1.1 root 265: c, db_tok_string);
266: db_error(0);
267: db_flush_lex();
268: return (tEOF);
269: }
270: db_unread_char(c);
271: return (tNUMBER);
272: }
273: if ((c >= 'A' && c <= 'Z') ||
274: (c >= 'a' && c <= 'z') ||
275: c == '_' || c == '\\' || c == ':')
276: {
277: /* identifier */
278: if (c == '\\') {
279: c = db_read_char();
280: if (c == '\n' || c == -1)
281: db_error("Bad '\\' at the end of line\n");
282: cp[-1] = c;
283: }
284: while (1) {
285: c = db_read_char();
286: if ((c >= 'A' && c <= 'Z') ||
287: (c >= 'a' && c <= 'z') ||
288: (c >= '0' && c <= '9') ||
289: c == '_' || c == '\\' || c == ':' || c == '.')
290: {
291: if (c == '\\') {
292: c = db_read_char();
293: if (c == '\n' || c == -1)
294: db_error("Bad '\\' at the end of line\n");
295: }
296: *cp++ = c;
297: if (cp == db_tok_string+sizeof(db_tok_string)) {
298: db_error("String too long\n");
299: db_flush_lex();
300: return (tEOF);
301: }
302: continue;
303: }
304: else {
305: *cp = '\0';
306: break;
307: }
308: }
309: db_unread_char(c);
310: return (tIDENT);
311: }
312:
313: *cp = 0;
314: switch (c) {
315: case '+':
316: return (tPLUS);
317: case '-':
318: return (tMINUS);
319: case '.':
320: c = db_read_char();
321: if (c == '.') {
322: *cp++ = c;
323: *cp = 0;
324: return (tDOTDOT);
325: }
326: db_unread_char(c);
327: return (tDOT);
328: case '*':
329: return (tSTAR);
330: case '/':
331: return (tSLASH);
332: case '=':
333: c = db_read_char();
334: if (c == '=') {
335: *cp++ = c;
336: *cp = 0;
337: return(tLOG_EQ);
338: }
339: db_unread_char(c);
340: return (tEQ);
341: case '%':
342: return (tPCT);
343: case '#':
344: return (tHASH);
345: case '(':
346: return (tLPAREN);
347: case ')':
348: return (tRPAREN);
349: case ',':
350: return (tCOMMA);
351: case '\'':
352: return (tQUOTE);
353: case '"':
354: /* string */
355: cp = db_tok_string;
356: c = db_read_char();
357: while (c != '"' && c > 0 && c != '\n') {
358: if (cp >= &db_tok_string[sizeof(db_tok_string)-1]) {
359: db_error("Too long string\n");
360: db_flush_lex();
361: return (tEOF);
362: }
363: if (c == '\\') {
364: c = db_read_char();
365: switch(c) {
366: case 'n':
367: c = '\n'; break;
368: case 't':
369: c = '\t'; break;
370: case '\\':
371: case '"':
372: break;
373: default:
374: db_printf("Bad escape sequence '\\%c'\n", c);
375: db_error(0);
376: db_flush_lex();
377: return (tEOF);
378: }
379: }
380: *cp++ = c;
381: c = db_read_char();
382: }
383: *cp = 0;
384: if (c != '"') {
385: db_error("Non terminated string constant\n");
386: db_flush_lex();
387: return (tEOF);
388: }
389: return (tSTRING);
390: case '$':
391: return (tDOLLAR);
392: case '!':
393: c = db_read_char();
394: if (c == '=') {
395: *cp++ = c;
396: *cp = 0;
397: return(tLOG_NOT_EQ);
398: }
399: db_unread_char(c);
400: return (tEXCL);
401: case '&':
402: c = db_read_char();
403: if (c == '&') {
404: *cp++ = c;
405: *cp = 0;
406: return(tLOG_AND);
407: }
408: db_unread_char(c);
409: return(tBIT_AND);
410: case '|':
411: c = db_read_char();
412: if (c == '|') {
413: *cp++ = c;
414: *cp = 0;
415: return(tLOG_OR);
416: }
417: db_unread_char(c);
418: return(tBIT_OR);
419: case '<':
420: c = db_read_char();
421: *cp++ = c;
422: *cp = 0;
423: if (c == '<')
424: return (tSHIFT_L);
425: if (c == '=')
426: return (tLESS_EQ);
427: cp[-1] = 0;
428: db_unread_char(c);
429: return(tLESS);
430: break;
431: case '>':
432: c = db_read_char();
433: *cp++ = c;
434: *cp = 0;
435: if (c == '>')
436: return (tSHIFT_R);
437: if (c == '=')
438: return (tGREATER_EQ);
439: cp[-1] = 0;
440: db_unread_char(c);
441: return (tGREATER);
442: break;
443: case ';':
444: return (tSEMI_COLON);
445: case '?':
446: return (tQUESTION);
447: case -1:
448: db_strcpy(db_tok_string, "<EOL>");
449: return (tEOF);
450: }
451: db_printf("Bad character '%c'\n", c);
452: db_flush_lex();
453: return (tEOF);
454: }
455:
1.1.1.2 root 456: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.