FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_lex.c
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 Software.Distribution@CS.CMU.EDU
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 * $FreeBSD: releng/5.0/sys/ddb/db_lex.c 92756 2002-03-20 05:14:42Z alfred $
27 */
28
29 /*
30 * Author: David B. Golub, Carnegie Mellon University
31 * Date: 7/90
32 */
33 /*
34 * Lexical analyzer.
35 */
36 #include <sys/param.h>
37
38 #include <ddb/ddb.h>
39 #include <ddb/db_lex.h>
40
41 static char db_line[120];
42 static char * db_lp, *db_endlp;
43
44 static int db_lex(void);
45 static void db_flush_line(void);
46 static int db_read_char(void);
47 static void db_unread_char(int);
48
49 int
50 db_read_line()
51 {
52 int i;
53
54 i = db_readline(db_line, sizeof(db_line));
55 if (i == 0)
56 return (0); /* EOI */
57 db_lp = db_line;
58 db_endlp = db_lp + i;
59 return (i);
60 }
61
62 static void
63 db_flush_line()
64 {
65 db_lp = db_line;
66 db_endlp = db_line;
67 }
68
69 static int db_look_char = 0;
70
71 static int
72 db_read_char()
73 {
74 int c;
75
76 if (db_look_char != 0) {
77 c = db_look_char;
78 db_look_char = 0;
79 }
80 else if (db_lp >= db_endlp)
81 c = -1;
82 else
83 c = *db_lp++;
84 return (c);
85 }
86
87 static void
88 db_unread_char(c)
89 int c;
90 {
91 db_look_char = c;
92 }
93
94 static int db_look_token = 0;
95
96 void
97 db_unread_token(t)
98 int t;
99 {
100 db_look_token = t;
101 }
102
103 int
104 db_read_token()
105 {
106 int t;
107
108 if (db_look_token) {
109 t = db_look_token;
110 db_look_token = 0;
111 }
112 else
113 t = db_lex();
114 return (t);
115 }
116
117 db_expr_t db_tok_number;
118 char db_tok_string[TOK_STRING_SIZE];
119
120 db_expr_t db_radix = 16;
121
122 void
123 db_flush_lex()
124 {
125 db_flush_line();
126 db_look_char = 0;
127 db_look_token = 0;
128 }
129
130 static int
131 db_lex()
132 {
133 int c;
134
135 c = db_read_char();
136 while (c <= ' ' || c > '~') {
137 if (c == '\n' || c == -1)
138 return (tEOL);
139 c = db_read_char();
140 }
141
142 if (c >= '' && c <= '9') {
143 /* number */
144 int r, digit = 0;
145
146 if (c > '')
147 r = db_radix;
148 else {
149 c = db_read_char();
150 if (c == 'O' || c == 'o')
151 r = 8;
152 else if (c == 'T' || c == 't')
153 r = 10;
154 else if (c == 'X' || c == 'x')
155 r = 16;
156 else {
157 r = db_radix;
158 db_unread_char(c);
159 }
160 c = db_read_char();
161 }
162 db_tok_number = 0;
163 for (;;) {
164 if (c >= '' && c <= ((r == 8) ? '7' : '9'))
165 digit = c - '';
166 else if (r == 16 && ((c >= 'A' && c <= 'F') ||
167 (c >= 'a' && c <= 'f'))) {
168 if (c >= 'a')
169 digit = c - 'a' + 10;
170 else if (c >= 'A')
171 digit = c - 'A' + 10;
172 }
173 else
174 break;
175 db_tok_number = db_tok_number * r + digit;
176 c = db_read_char();
177 }
178 if ((c >= '' && c <= '9') ||
179 (c >= 'A' && c <= 'Z') ||
180 (c >= 'a' && c <= 'z') ||
181 (c == '_'))
182 {
183 db_error("Bad character in number\n");
184 db_flush_lex();
185 return (tEOF);
186 }
187 db_unread_char(c);
188 return (tNUMBER);
189 }
190 if ((c >= 'A' && c <= 'Z') ||
191 (c >= 'a' && c <= 'z') ||
192 c == '_' || c == '\\')
193 {
194 /* string */
195 char *cp;
196
197 cp = db_tok_string;
198 if (c == '\\') {
199 c = db_read_char();
200 if (c == '\n' || c == -1)
201 db_error("Bad escape\n");
202 }
203 *cp++ = c;
204 while (1) {
205 c = db_read_char();
206 if ((c >= 'A' && c <= 'Z') ||
207 (c >= 'a' && c <= 'z') ||
208 (c >= '' && c <= '9') ||
209 c == '_' || c == '\\' || c == ':' || c == '.')
210 {
211 if (c == '\\') {
212 c = db_read_char();
213 if (c == '\n' || c == -1)
214 db_error("Bad escape\n");
215 }
216 *cp++ = c;
217 if (cp == db_tok_string+sizeof(db_tok_string)) {
218 db_error("String too long\n");
219 db_flush_lex();
220 return (tEOF);
221 }
222 continue;
223 }
224 else {
225 *cp = '\0';
226 break;
227 }
228 }
229 db_unread_char(c);
230 return (tIDENT);
231 }
232
233 switch (c) {
234 case '+':
235 return (tPLUS);
236 case '-':
237 return (tMINUS);
238 case '.':
239 c = db_read_char();
240 if (c == '.')
241 return (tDOTDOT);
242 db_unread_char(c);
243 return (tDOT);
244 case '*':
245 return (tSTAR);
246 case '/':
247 return (tSLASH);
248 case '=':
249 return (tEQ);
250 case '%':
251 return (tPCT);
252 case '#':
253 return (tHASH);
254 case '(':
255 return (tLPAREN);
256 case ')':
257 return (tRPAREN);
258 case ',':
259 return (tCOMMA);
260 case '"':
261 return (tDITTO);
262 case '$':
263 return (tDOLLAR);
264 case '!':
265 return (tEXCL);
266 case '<':
267 c = db_read_char();
268 if (c == '<')
269 return (tSHIFT_L);
270 db_unread_char(c);
271 break;
272 case '>':
273 c = db_read_char();
274 if (c == '>')
275 return (tSHIFT_R);
276 db_unread_char(c);
277 break;
278 case -1:
279 return (tEOF);
280 }
281 db_printf("Bad character\n");
282 db_flush_lex();
283 return (tEOF);
284 }
Cache object: 56ed7c8c6e89e26f1666ab5761ea1e70
|