Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / legion / src / parser / lexer.l
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: lexer.l
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23%{
24 /* any C includes here */
25#include <stdio.h>
26#include <stdlib.h>
27#include <unistd.h>
28#include <string.h>
29#include <stdarg.h>
30#include <errno.h>
31
32#include "basics.h"
33#include "allocate.h"
34#include "lexer.h"
35#include "simcore.h"
36#include "config.h"
37#include "fatal.h"
38
39lexer_t lex; /* additional return value info */
40
41#if TESTRIG /* { */
42#include <stdarg.h>
43#include <errno.h>
44void fatal(char *s,...);
45#endif /* } */
46
47%}
48
49DECNUM ("0"|([1-9][0-9]*))
50
51%x comment
52%x string
53
54%%
55
56<<EOF>> return T_EOF;
57
58"{" return T_L_Brace;
59
60"}" return T_R_Brace;
61
62";" return T_S_Colon;
63
64"+" return T_Plus;
65
66"-" return T_Minus;
67
68"," return T_Comma;
69
70"@" return T_Amp;
71
72^"#"[ \t].*$ {
73 char lbuf[1024];
74 int num;
75 if (sscanf(lextext,"# %d \"%[^\"]\"", &num, lbuf)!=2)
76 lex_fatal("Illegal # directive");
77 lex.linenum = num-1;
78 if (lex.fnamep != (char*)0) Xfree(lex.fnamep);
79 lex.fnamep = Xstrdup(lbuf);
80 }
81
82\" BEGIN(string);
83<string>\" BEGIN(INITIAL);
84
85<string>([^"\n]|(\\\"))* {
86 lex.strp = lextext;
87 return T_String;
88 }
89
90<string>\n {
91 lex_fatal("unterminated string");
92 }
93
94
95"0x"[0-9A-F][0-9A-F]* {
96 lex.strp = lextext;
97 lex.val = strtoull(lextext, (char **)NULL, 16);
98 return T_Number;
99 }
100
101"0x"[0-9a-f][0-9a-f]* {
102 lex.strp = lextext;
103 lex.val = strtoull(lextext, (char **)NULL, 16);
104 return T_Number;
105 }
106
107{DECNUM} {
108 lex.strp = lextext;
109 lex.val = atoll(lextext);
110 return T_Number;
111 }
112
113[0-9a-f][0-9a-f]* {
114 lex.strp = lextext;
115 lex.val = strtoull(lextext, (char **)NULL, 16);
116 return T_HexString;
117 }
118
119[0-9A-F][0-9A-F]* {
120 lex.strp = lextext;
121 lex.val = strtoull(lextext, (char **)NULL, 16);
122 return T_HexString;
123 }
124
125{DECNUM}[KkMmGg] {
126 char * ep;
127 lex.val = strtoull(lextext, &ep, 10);
128 switch(*ep) {
129 case 'G': case 'g':
130 lex.val <<= 30;
131 break;
132 case 'M': case 'm':
133 lex.val <<= 20;
134 break;
135 case 'K': case 'k':
136 lex.val <<= 10;
137 break;
138 default:
139 lex_fatal("parsing number");
140 }
141 lex.strp = lextext;
142 return T_Number;
143 }
144
145
146[A-Za-z_][A-Za-z_0-9]* {
147 lex.strp = lextext;
148 return T_Token;
149 }
150
151 /* Note: . = any character EXCEPT newline */
152\/\/ {
153 lex.strp = lextext;
154 return T_String;
155 }
156
157[\t ]* { /* nada - swallow white space */ }
158
159
160"\n" {
161 lex.linenum ++;
162 }
163
164. {
165 lex_fatal("Illegal character %s", lextext);
166 }
167
168%%
169
170
171
172
173
174
175
176void init_lexer(char * fnamep, FILE *fp, char * cleanup_filep)
177{
178 lex.cleanup_filep = cleanup_filep ? Xstrdup(cleanup_filep) : (char*)0;
179 lex.linenum = 1;
180 lex.fnamep = Xstrdup(fnamep);
181
182 lex.ungot_available = false;
183 lex.last_token = T_Error;
184
185 lexin = fp;
186}
187
188
189lexer_tok_t lex_get_token()
190{
191 if (lex.ungot_available) {
192 lex.ungot_available = false;
193 return lex.last_token;
194 }
195
196 lex.last_token = lexlex();
197
198 return lex.last_token;
199}
200
201
202
203void lex_unget()
204{
205 if (lex.ungot_available) fatal("Internal error, lex_unget with token already ungot");
206
207 lex.ungot_available = true;
208}
209
210
211void lex_get(lexer_tok_t expected)
212{
213 lexer_tok_t tok;
214 char *s;
215 char buffer[1024];
216
217 tok = lex_get_token();
218
219 if (tok == expected) return;
220
221 switch(tok) {
222 case T_EOF: s="end of file"; break;
223 case T_L_Brace: s="{"; break;
224 case T_R_Brace: s="}"; break;
225 case T_S_Colon: s=";"; break;
226 case T_Plus: s="+"; break;
227 case T_Minus: s="-"; break;
228 case T_Number: s="number"; break;
229 case T_HexString: s="hex string"; break;
230 case T_String: s="string"; break;
231 case T_Token:
232 sprintf(buffer,"token %s", lex.strp);
233 s=buffer;
234 break;
235 case T_Error: s="error"; break;
236 default:
237 s="unknown token - internal error";
238 break;
239 }
240
241 lex_fatal("unexpected %s", s);
242}
243
244
245 /*
246 * Special version of fatal for the lexer
247 * to enable cleanup of stuff before death
248 */
249
250void lex_fatal(char * fmt, ...)
251{
252 va_list args;
253
254 if (errno!=0) perror("FATAL: "); else fprintf(stderr,"FATAL: ");
255 if (fmt) {
256 va_start(args, fmt);
257 (void)vfprintf(stderr, fmt, args);
258
259 va_end(args);
260 }
261
262 if (lex.cleanup_filep != (char *)0) {
263 unlink(lex.cleanup_filep);
264 Xfree(lex.cleanup_filep);
265 }
266 fprintf(stderr," at line %d of %s\n", lex.linenum, lex.fnamep);
267 Xfree(lex.fnamep);
268
269SANITY( lex.fnamep = (char*)0; );
270SANITY( lex.cleanup_filep = (char*)0; );
271 exit(1);
272}
273
274
275
276int lexwrap()
277{
278 return 1;
279}
280
281#if TESTRIG /* { */
282main()
283{
284 lexer_tok_t tok;
285
286 lex.linenum = 1;
287 lex.fnamep = "test";
288
289 do {
290 tok = lexlex();
291
292 fprintf(stderr,"token = %d at line %d in %s\n",tok, lex.linenum, lex.fnamep);
293 } while (tok!=T_Error && tok!=T_EOF);
294}
295
296
297void fatal(char* fmt, ...)
298{
299 va_list args;
300 int status;
301
302 if (errno!=0) perror("FATAL: "); else fprintf(stderr,"FATAL: ");
303 if (fmt) {
304 va_start(args, fmt);
305 (void)vfprintf(stderr, fmt, args);
306
307 va_end(args);
308 }
309
310 fprintf(stderr,"\n");
311 fflush(stderr);
312 fflush(stdout);
313
314 thr_exit(&status);
315}
316
317#endif /* } */