Line data Source code
1 : /* $OpenBSD: db_lex.c,v 1.14 2016/04/19 12:23:25 mpi Exp $ */
2 : /* $NetBSD: db_lex.c,v 1.8 1996/02/05 01:57:05 christos Exp $ */
3 :
4 : /*
5 : * Mach Operating System
6 : * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
7 : * All Rights Reserved.
8 : *
9 : * Permission to use, copy, modify and distribute this software and its
10 : * documentation is hereby granted, provided that both the copyright
11 : * notice and this permission notice appear in all copies of the
12 : * software, derivative works or modified versions, and any portions
13 : * thereof, and that both notices appear in supporting documentation.
14 : *
15 : * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 : * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
17 : * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 : *
19 : * Carnegie Mellon requests users of this software to return to
20 : *
21 : * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22 : * School of Computer Science
23 : * Carnegie Mellon University
24 : * Pittsburgh PA 15213-3890
25 : *
26 : * any improvements or extensions that they make and grant Carnegie Mellon
27 : * the rights to redistribute these changes.
28 : *
29 : * Author: David B. Golub, Carnegie Mellon University
30 : * Date: 7/90
31 : */
32 :
33 : /*
34 : * Lexical analyzer.
35 : */
36 : #include <sys/param.h>
37 : #include <sys/systm.h>
38 :
39 : #include <machine/db_machdep.h>
40 :
41 : #include <ddb/db_lex.h>
42 : #include <ddb/db_output.h>
43 : #include <ddb/db_command.h>
44 : #include <ddb/db_extern.h>
45 : #include <ddb/db_var.h>
46 :
47 : char db_line[120];
48 : char * db_lp, *db_endlp;
49 :
50 : db_expr_t db_tok_number;
51 : char db_tok_string[TOK_STRING_SIZE];
52 :
53 : void db_flush_line(void);
54 : int db_read_char(void);
55 : void db_unread_char(int);
56 :
57 : int
58 0 : db_read_line(void)
59 : {
60 : int i;
61 :
62 0 : i = db_readline(db_line, sizeof(db_line));
63 0 : if (i == 0)
64 0 : return (0); /* EOI */
65 0 : db_lp = db_line;
66 0 : db_endlp = db_lp + i;
67 0 : return (i);
68 0 : }
69 :
70 : void
71 0 : db_flush_line(void)
72 : {
73 0 : db_lp = db_line;
74 0 : db_endlp = db_line;
75 0 : }
76 :
77 : int db_look_char = 0;
78 :
79 : int
80 0 : db_read_char(void)
81 : {
82 : int c;
83 :
84 0 : if (db_look_char != 0) {
85 : c = db_look_char;
86 0 : db_look_char = 0;
87 0 : }
88 0 : else if (db_lp >= db_endlp)
89 0 : c = -1;
90 : else
91 0 : c = *db_lp++;
92 0 : return (c);
93 : }
94 :
95 : void
96 0 : db_unread_char(int c)
97 : {
98 0 : db_look_char = c;
99 0 : }
100 :
101 : int db_look_token = 0;
102 :
103 : void
104 0 : db_unread_token(int t)
105 : {
106 0 : db_look_token = t;
107 0 : }
108 :
109 : int
110 0 : db_read_token(void)
111 : {
112 : int t;
113 :
114 0 : if (db_look_token) {
115 : t = db_look_token;
116 0 : db_look_token = 0;
117 0 : }
118 : else
119 0 : t = db_lex();
120 0 : return (t);
121 : }
122 :
123 : void
124 0 : db_flush_lex(void)
125 : {
126 0 : db_flush_line();
127 0 : db_look_char = 0;
128 0 : db_look_token = 0;
129 0 : }
130 :
131 : int
132 0 : db_lex(void)
133 : {
134 : int c;
135 :
136 0 : c = db_read_char();
137 0 : while (c <= ' ' || c > '~') {
138 0 : if (c == '\n' || c == -1)
139 0 : return (tEOL);
140 0 : c = db_read_char();
141 : }
142 :
143 0 : if (c >= '0' && c <= '9') {
144 : /* number */
145 : int r, digit = 0;
146 :
147 0 : if (c > '0')
148 0 : r = db_radix;
149 : else {
150 0 : c = db_read_char();
151 0 : if (c == 'O' || c == 'o')
152 0 : r = 8;
153 0 : else if (c == 'T' || c == 't')
154 0 : r = 10;
155 0 : else if (c == 'X' || c == 'x')
156 0 : r = 16;
157 : else {
158 0 : r = db_radix;
159 0 : db_unread_char(c);
160 : }
161 0 : c = db_read_char();
162 : }
163 0 : db_tok_number = 0;
164 0 : for (;;) {
165 0 : if (c >= '0' && c <= ((r == 8) ? '7' : '9'))
166 0 : digit = c - '0';
167 0 : else if (r == 16 && ((c >= 'A' && c <= 'F') ||
168 0 : (c >= 'a' && c <= 'f'))) {
169 0 : if (c >= 'a')
170 0 : digit = c - 'a' + 10;
171 0 : else if (c >= 'A')
172 0 : digit = c - 'A' + 10;
173 : }
174 : else
175 : break;
176 0 : db_tok_number = db_tok_number * r + digit;
177 0 : c = db_read_char();
178 : }
179 0 : if ((c >= '0' && c <= '9') ||
180 0 : (c >= 'A' && c <= 'Z') ||
181 0 : (c >= 'a' && c <= 'z') ||
182 0 : (c == '_'))
183 : {
184 0 : db_error("Bad character in number\n");
185 : /*NOTREACHED*/
186 0 : }
187 0 : db_unread_char(c);
188 : return (tNUMBER);
189 : }
190 0 : if ((c >= 'A' && c <= 'Z') ||
191 0 : (c >= 'a' && c <= 'z') ||
192 0 : c == '_' || c == '\\')
193 : {
194 : /* string */
195 : char *cp;
196 :
197 : cp = db_tok_string;
198 0 : if (c == '\\') {
199 0 : c = db_read_char();
200 0 : if (c == '\n' || c == -1) {
201 0 : db_error("Bad escape\n");
202 : /*NOTREACHED*/
203 0 : }
204 : }
205 0 : *cp++ = c;
206 0 : while (1) {
207 0 : c = db_read_char();
208 0 : if ((c >= 'A' && c <= 'Z') ||
209 0 : (c >= 'a' && c <= 'z') ||
210 0 : (c >= '0' && c <= '9') ||
211 0 : c == '_' || c == '\\' || c == ':')
212 : {
213 0 : if (c == '\\') {
214 0 : c = db_read_char();
215 0 : if (c == '\n' || c == -1) {
216 0 : db_error("Bad escape\n");
217 : /*NOTREACHED*/
218 0 : }
219 : }
220 0 : *cp++ = c;
221 0 : if (cp == db_tok_string+sizeof(db_tok_string)) {
222 0 : db_error("String too long\n");
223 : /*NOTREACHED*/
224 0 : }
225 0 : continue;
226 : }
227 : else {
228 0 : *cp = '\0';
229 : break;
230 : }
231 : }
232 0 : db_unread_char(c);
233 : return (tIDENT);
234 : }
235 :
236 0 : switch (c) {
237 : case '+':
238 0 : return (tPLUS);
239 : case '-':
240 0 : return (tMINUS);
241 : case '.':
242 0 : c = db_read_char();
243 0 : if (c == '.')
244 0 : return (tDOTDOT);
245 0 : db_unread_char(c);
246 0 : return (tDOT);
247 : case '*':
248 0 : return (tSTAR);
249 : case '/':
250 0 : return (tSLASH);
251 : case '=':
252 0 : return (tEQ);
253 : case '%':
254 0 : return (tPCT);
255 : case '#':
256 0 : return (tHASH);
257 : case '(':
258 0 : return (tLPAREN);
259 : case ')':
260 0 : return (tRPAREN);
261 : case ',':
262 0 : return (tCOMMA);
263 : case '"':
264 0 : return (tDITTO);
265 : case '$':
266 0 : return (tDOLLAR);
267 : case '!':
268 0 : return (tEXCL);
269 : case '<':
270 0 : c = db_read_char();
271 0 : if (c == '<')
272 0 : return (tSHIFT_L);
273 0 : db_unread_char(c);
274 0 : break;
275 : case '>':
276 0 : c = db_read_char();
277 0 : if (c == '>')
278 0 : return (tSHIFT_R);
279 0 : db_unread_char(c);
280 0 : break;
281 : case -1:
282 0 : return (tEOF);
283 : }
284 0 : db_printf("Bad character\n");
285 0 : db_flush_lex();
286 0 : return (tEOF);
287 0 : }
|