Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / hypervisor / src / support / mdgen / mdlex.l
CommitLineData
920dae64
AT
1/*
2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6
7%{
8
9#pragma ident "@(#)mdlex.l 1.3 05/11/03 SMI"
10
11/* any C includes here */
12#include <stdio.h>
13#include <stdlib.h>
14#include <unistd.h>
15#include <string.h>
16#include <stdarg.h>
17#include <errno.h>
18
19#include "basics.h"
20#include "allocate.h"
21#include "lexer.h"
22#include "fatal.h"
23
24lexer_t lex; /* additional return value info */
25#define MAX_STR_LEN (1024+1)
26static struct {
27 char base[MAX_STR_LEN];
28 char * ptr;
29} sbuffer;
30
31#if TESTRIG /* { */
32#include <stdarg.h>
33#include <errno.h>
34void fatal(char *s,...);
35#endif /* } */
36
37#define SBUFFER_INS(_c) do { \
38 if ((sbuffer.ptr - sbuffer.base)>=MAX_STR_LEN) \
39 lex_fatal("Parse string too long - maximum is %d characters", MAX_STR_LEN); \
40 *sbuffer.ptr++ = (_c); \
41 } while(0)
42%}
43
44DECNUM ("0"|([1-9][0-9]*))
45
46%x comment
47%x string
48
49%%
50
51<<EOF>> return T_EOF;
52
53"{" return T_L_Brace;
54
55"}" return T_R_Brace;
56
57")" return T_R_Bracket;
58
59"," return T_Comma;
60
61";" return T_S_Colon;
62
63"+" return T_Plus;
64
65"*" return T_Multiply;
66
67"-" return T_Minus;
68
69"&" return T_And;
70
71"|" return T_Or;
72
73"^" return T_Xor;
74
75"~" return T_Not;
76
77"<<" return T_LShift;
78
79"=" return T_Equals;
80
81"]" return T_R_Bracket;
82
83"[" return T_L_Bracket;
84
85^"#"[ \t].*$ {
86 char lbuf[1024];
87 int num;
88 if (sscanf(mdlextext,"# %d \"%[^\"]\"", &num, lbuf)!=2)
89 lex_fatal("Illegal # directive");
90 lex.linenum = num-1;
91 if (lex.fnamep != (char*)0) Xfree(lex.fnamep);
92 lex.fnamep = Xstrdup(lbuf);
93 }
94
95"node" return T_KW_node;
96
97"proto" return T_KW_proto;
98
99"include" return T_KW_include;
100
101"(" return T_KW_expr;
102
103"expr(" return T_KW_expr;
104
105"lookup(" return T_KW_lookup;
106
107"setprop(" return T_KW_setprop;
108
109"->" return T_KW_arc;
110
111
112\" {
113 sbuffer.ptr = sbuffer.base;
114 BEGIN(string);
115 }
116
117<string>\" { /* closing quote - wrap up string and return it */
118 BEGIN(INITIAL);
119 sbuffer.ptr[0]='\0';
120 lex.strp = sbuffer.base;
121 return T_String;
122 }
123
124<string>\n {
125 lex_fatal("unterminated string");
126 }
127
128<string>\\[0-7]{1,3} {
129 /* octal escape sequence */
130 int result;
131
132 result=-1;
133 (void) sscanf( mdlextext + 1, "%o", &result );
134
135 if ( result<0 || result>0xff )
136 lex_fatal("error, constant is out-of-bounds");
137
138 SBUFFER_INS( result );
139 }
140
141<string>\\[0-9]+ {
142 lex_fatal("illegal escape sequence");
143 }
144
145<string>\\n SBUFFER_INS( '\n' );
146<string>\\t SBUFFER_INS( '\t' );
147<string>\\r SBUFFER_INS( '\r' );
148<string>\\b SBUFFER_INS( '\b' );
149<string>\\f SBUFFER_INS( '\f' );
150
151<string>\\(.|\n) SBUFFER_INS( mdlextext[1] );
152
153<string>[^\\\n\"]+ {
154 char *iptr = mdlextext;
155
156 while ( *iptr ) SBUFFER_INS( *iptr++ );
157 }
158
159
160
161
162"0x"[0-9A-F][0-9A-F]* {
163 lex.val = strtoull(mdlextext, (char **)NULL, 16);
164 return T_Number;
165 }
166
167"0x"[0-9a-f][0-9a-f]* {
168 lex.val = strtoull(mdlextext, (char **)NULL, 16);
169
170 return T_Number;
171 }
172
173{DECNUM}[KkMmGg] {
174 char * ep;
175 lex.val = strtoll(mdlextext, &ep, 10);
176 switch(*ep) {
177 case 'G': case 'g':
178 lex.val <<= 30;
179 break;
180 case 'M': case 'm':
181 lex.val <<= 20;
182 break;
183 case 'K': case 'k':
184 lex.val <<= 10;
185 break;
186 default:
187 lex_fatal("parsing number");
188 }
189 return T_Number;
190 }
191
192{DECNUM} {
193 lex.val = atoll(mdlextext);
194 return T_Number;
195 }
196
197\-{DECNUM} {
198 lex.val = atoll(mdlextext);
199 return T_Number;
200 }
201
202
203[A-Za-z_#?$][A-Za-z_#\-?$0-9]* {
204 lex.strp = mdlextext;
205 return T_Token;
206 }
207
208 /* Note: . = any character EXCEPT newline */
209\/\/.* { /* nada - swallow single line comments */ }
210
211[\t ]* { /* nada - swallow white space */ }
212
213
214"\n" {
215 lex.linenum ++;
216 }
217
218. {
219 lex_fatal("Illegal character %s", mdlextext);
220 }
221
222%%
223
224
225
226
227
228
229
230void init_lexer(char * fnamep, FILE *fp, char * cleanup_filep)
231{
232 lex.cleanup_filep = cleanup_filep ? Xstrdup(cleanup_filep) : (char*)0;
233 lex.linenum = 1;
234 lex.fnamep = Xstrdup(fnamep);
235
236 lex.ungot_available = false;
237 lex.last_token = T_Error;
238
239 mdlexin = fp;
240}
241
242
243lexer_tok_t lex_get_token()
244{
245 if (lex.ungot_available) {
246 lex.ungot_available = false;
247 return lex.last_token;
248 }
249
250 lex.last_token = mdlexlex();
251
252 return lex.last_token;
253}
254
255
256
257void lex_unget()
258{
259 if (lex.ungot_available) fatal("Internal error, lex_unget with token already ungot");
260
261 lex.ungot_available = true;
262}
263
264
265void lex_get(lexer_tok_t expected)
266{
267 lexer_tok_t tok;
268 char *s;
269 char buffer[1024];
270
271 tok = lex_get_token();
272
273 if (tok == expected) return;
274
275 switch(tok) {
276 case T_EOF: s="end of file"; break;
277 case T_L_Brace: s="{"; break;
278 case T_R_Brace: s="}"; break;
279 case T_S_Colon: s=";"; break;
280 case T_Plus: s="+"; break;
281 case T_Minus: s="-"; break;
282 case T_Equals: s="="; break;
283 case T_Number: s="number"; break;
284 case T_String: s="string"; break;
285 case T_Token:
286 sprintf(buffer,"token %s", lex.strp);
287 s=buffer;
288 break;
289 case T_KW_node: s="node"; break;
290 case T_KW_proto: s="proto"; break;
291 case T_KW_include: s="include("; break;
292 case T_KW_expr: s="expr("; break;
293 case T_KW_lookup: s="lookup("; break;
294 case T_KW_setprop: s="setprop("; break;
295
296 case T_Error: s="error"; break;
297 default:
298 s="unknown token - internal error";
299 break;
300 }
301
302 lex_fatal("unexpected %s", s);
303}
304
305
306/*
307 * Special version of fatal for the lexer
308 * to enable cleanup of stuff before death
309 */
310void
311lex_fatal(char * fmt, ...)
312{
313 va_list args;
314
315 if (errno != 0)
316 perror("FATAL: ");
317 else
318 fprintf(stderr,"FATAL: ");
319 if (fmt) {
320 va_start(args, fmt);
321 (void) vfprintf(stderr, fmt, args);
322
323 va_end(args);
324 }
325
326 if (lex.cleanup_filep != (char *)0) {
327 unlink(lex.cleanup_filep);
328 Xfree(lex.cleanup_filep);
329 }
330 fprintf(stderr," at line %d of %s\n", lex.linenum, lex.fnamep);
331 Xfree(lex.fnamep);
332
333 SANITY( lex.fnamep = NULL; );
334 SANITY( lex.cleanup_filep = NULL; );
335 exit(1);
336}
337
338
339
340int
341mdlexwrap(void)
342{
343 return (1);
344}
345
346#if TESTRIG /* { */
347main()
348{
349 lexer_tok_t tok;
350
351 lex.linenum = 1;
352 lex.fnamep = "test";
353
354 do {
355 tok = lexlex();
356
357 fprintf(stderr,"token = %d at line %d in %s\n",tok, lex.linenum, lex.fnamep);
358 } while (tok!=T_Error && tok!=T_EOF);
359}
360
361
362void fatal(char* fmt, ...)
363{
364 va_list args;
365 int status;
366
367 if (errno!=0) perror("FATAL: "); else fprintf(stderr,"FATAL: ");
368 if (fmt) {
369 va_start(args, fmt);
370 (void)vfprintf(stderr, fmt, args);
371
372 va_end(args);
373 }
374
375 fprintf(stderr,"\n");
376 fflush(stderr);
377 fflush(stdout);
378
379 thr_exit(&status);
380}
381
382#endif /* } */