|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1991,1990 Carnegie Mellon University
4: * All Rights Reserved.
5: *
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.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie the
24: * rights to redistribute these changes.
25: */
26: /*
27: * HISTORY
28: * $Log: db_lex.c,v $
1.1.1.2 ! root 29: * Revision 1.1.1.1 1993/03/21 09:46:26 cgd
! 30: * initial import of 386bsd-0.1 sources
! 31: *
1.1 root 32: * Revision 1.1 1992/03/25 21:45:13 pace
33: * Initial revision
34: *
35: * Revision 2.3 91/02/05 17:06:36 mrt
36: * Changed to new Mach copyright
37: * [91/01/31 16:18:20 mrt]
38: *
39: * Revision 2.2 90/08/27 21:51:10 dbg
40: * Add 'dotdot' token.
41: * [90/08/22 dbg]
42: *
43: * Allow backslash to quote any character into an identifier.
44: * Allow colon in identifier for symbol table qualification.
45: * [90/08/16 dbg]
46: * Reduce lint.
47: * [90/08/07 dbg]
48: * Created.
49: * [90/07/25 dbg]
50: *
51: */
52: /*
53: * Author: David B. Golub, Carnegie Mellon University
54: * Date: 7/90
55: */
56: /*
57: * Lexical analyzer.
58: */
59: #include <ddb/db_lex.h>
60:
61: char db_line[120];
62: char * db_lp, *db_endlp;
63:
64: int
65: db_read_line()
66: {
67: int i;
68:
69: i = db_readline(db_line, sizeof(db_line));
70: if (i == 0)
71: return (0); /* EOI */
72: db_lp = db_line;
73: db_endlp = db_lp + i;
74: return (i);
75: }
76:
77: void
78: db_flush_line()
79: {
80: db_lp = db_line;
81: db_endlp = db_line;
82: }
83:
84: int db_look_char = 0;
85:
86: int
87: db_read_char()
88: {
89: int c;
90:
91: if (db_look_char != 0) {
92: c = db_look_char;
93: db_look_char = 0;
94: }
95: else if (db_lp >= db_endlp)
96: c = -1;
97: else
98: c = *db_lp++;
99: return (c);
100: }
101:
102: void
103: db_unread_char(c)
104: {
105: db_look_char = c;
106: }
107:
108: int db_look_token = 0;
109:
110: void
111: db_unread_token(t)
112: int t;
113: {
114: db_look_token = t;
115: }
116:
117: int
118: db_read_token()
119: {
120: int t;
121:
122: if (db_look_token) {
123: t = db_look_token;
124: db_look_token = 0;
125: }
126: else
127: t = db_lex();
128: return (t);
129: }
130:
131: int db_tok_number;
132: char db_tok_string[TOK_STRING_SIZE];
133:
134: int db_radix = 16;
135:
136: void
137: db_flush_lex()
138: {
139: db_flush_line();
140: db_look_char = 0;
141: db_look_token = 0;
142: }
143:
144: int
145: db_lex()
146: {
147: int c;
148:
149: c = db_read_char();
150: while (c <= ' ' || c > '~') {
151: if (c == '\n' || c == -1)
152: return (tEOL);
153: c = db_read_char();
154: }
155:
156: if (c >= '0' && c <= '9') {
157: /* number */
158: int r, digit;
159:
160: if (c > '0')
161: r = db_radix;
162: else {
163: c = db_read_char();
164: if (c == 'O' || c == 'o')
165: r = 8;
166: else if (c == 'T' || c == 't')
167: r = 10;
168: else if (c == 'X' || c == 'x')
169: r = 16;
170: else {
171: r = db_radix;
172: db_unread_char(c);
173: }
174: c = db_read_char();
175: }
176: db_tok_number = 0;
177: for (;;) {
178: if (c >= '0' && c <= ((r == 8) ? '7' : '9'))
179: digit = c - '0';
180: else if (r == 16 && ((c >= 'A' && c <= 'F') ||
181: (c >= 'a' && c <= 'f'))) {
182: if (c >= 'a')
183: digit = c - 'a' + 10;
184: else if (c >= 'A')
185: digit = c - 'A' + 10;
186: }
187: else
188: break;
189: db_tok_number = db_tok_number * r + digit;
190: c = db_read_char();
191: }
192: if ((c >= '0' && c <= '9') ||
193: (c >= 'A' && c <= 'Z') ||
194: (c >= 'a' && c <= 'z') ||
195: (c == '_'))
196: {
197: db_error("Bad character in number\n");
198: db_flush_lex();
199: return (tEOF);
200: }
201: db_unread_char(c);
202: return (tNUMBER);
203: }
204: if ((c >= 'A' && c <= 'Z') ||
205: (c >= 'a' && c <= 'z') ||
206: c == '_' || c == '\\')
207: {
208: /* string */
209: char *cp;
210:
211: cp = db_tok_string;
212: if (c == '\\') {
213: c = db_read_char();
214: if (c == '\n' || c == -1)
215: db_error("Bad escape\n");
216: }
217: *cp++ = c;
218: while (1) {
219: c = db_read_char();
220: if ((c >= 'A' && c <= 'Z') ||
221: (c >= 'a' && c <= 'z') ||
222: (c >= '0' && c <= '9') ||
223: c == '_' || c == '\\' || c == ':')
224: {
225: if (c == '\\') {
226: c = db_read_char();
227: if (c == '\n' || c == -1)
228: db_error("Bad escape\n");
229: }
230: *cp++ = c;
231: if (cp == db_tok_string+sizeof(db_tok_string)) {
232: db_error("String too long\n");
233: db_flush_lex();
234: return (tEOF);
235: }
236: continue;
237: }
238: else {
239: *cp = '\0';
240: break;
241: }
242: }
243: db_unread_char(c);
244: return (tIDENT);
245: }
246:
247: switch (c) {
248: case '+':
249: return (tPLUS);
250: case '-':
251: return (tMINUS);
252: case '.':
253: c = db_read_char();
254: if (c == '.')
255: return (tDOTDOT);
256: db_unread_char(c);
257: return (tDOT);
258: case '*':
259: return (tSTAR);
260: case '/':
261: return (tSLASH);
262: case '=':
263: return (tEQ);
264: case '%':
265: return (tPCT);
266: case '#':
267: return (tHASH);
268: case '(':
269: return (tLPAREN);
270: case ')':
271: return (tRPAREN);
272: case ',':
273: return (tCOMMA);
274: case '"':
275: return (tDITTO);
276: case '$':
277: return (tDOLLAR);
278: case '!':
279: return (tEXCL);
280: case '<':
281: c = db_read_char();
282: if (c == '<')
283: return (tSHIFT_L);
284: db_unread_char(c);
285: break;
286: case '>':
287: c = db_read_char();
288: if (c == '>')
289: return (tSHIFT_R);
290: db_unread_char(c);
291: break;
292: case -1:
293: return (tEOF);
294: }
295: db_printf("Bad character\n");
296: db_flush_lex();
297: return (tEOF);
298: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.