1 | %{ |
---|
2 | /* |
---|
3 | * vl2mv: Verilog to BLIF-MV Translator Distribution |
---|
4 | * |
---|
5 | * Copyright (c) 1992, 1993 |
---|
6 | * Regents of the University of California |
---|
7 | * All rights reserved. |
---|
8 | * |
---|
9 | * Use and copying of this software and preparation of derivative works |
---|
10 | * based upon this software are permitted. However, any distribution of |
---|
11 | * this software or derivative works must include the above copyright |
---|
12 | * notice. |
---|
13 | * |
---|
14 | * This software is made available AS IS, and neither the Electronics |
---|
15 | * Research Laboratory or the Universify of California make any |
---|
16 | * warranty about the software, its performance or its conformity to |
---|
17 | * any specification. |
---|
18 | * |
---|
19 | * |
---|
20 | * $Header: /projects/development/hsv/CVSRepository/vl2mv/src/parser/verilog.l,v 1.4 2009/03/09 20:25:57 fabio Exp $ |
---|
21 | * |
---|
22 | * Lexical Scanner for Verilog |
---|
23 | * |
---|
24 | * Author: Szu-Tsung Cheng, stcheng@ic.berkeley.edu |
---|
25 | * |
---|
26 | * Date: September 18, 1992 |
---|
27 | */ |
---|
28 | |
---|
29 | #include <stdio.h> |
---|
30 | #include "util.h" |
---|
31 | #include "st.h" |
---|
32 | #include "list.h" |
---|
33 | #include "array.h" |
---|
34 | #include "set.h" |
---|
35 | #include "stack.h" |
---|
36 | #include "vl_defs.h" |
---|
37 | #include "vl_types.h" |
---|
38 | #include "vlr_int.h" |
---|
39 | #include "verilog_yacc.h" |
---|
40 | #include "verilog.h" |
---|
41 | |
---|
42 | #ifdef FLEX_SCANNER |
---|
43 | #ifndef YY_FLEX_LEX_COMPAT |
---|
44 | #define YYLMAX YY_BUF_SIZE |
---|
45 | #else |
---|
46 | #define MAX_INCLUDE_DEPTH 20 |
---|
47 | YY_BUFFER_STATE buffer_stack[MAX_INCLUDE_DEPTH]; |
---|
48 | int buffer_stack_ptr = 0; |
---|
49 | #endif |
---|
50 | #endif |
---|
51 | |
---|
52 | extern vl_descPtr mod_list; |
---|
53 | extern char *vl_filename; |
---|
54 | extern st_table *aux_st; |
---|
55 | extern int reserve_type_name; |
---|
56 | extern int Loop_Unrolling; |
---|
57 | |
---|
58 | static int scan_table = 0; |
---|
59 | char yyid[MAXSTRLEN]; |
---|
60 | char brep[MAXSTRLEN]; |
---|
61 | int bexp0, bexp1; |
---|
62 | char last_macro[MAXSTRLEN]; /* last macro name get expanded */ |
---|
63 | char curr_macro[MAXSTRLEN]; |
---|
64 | char yytypetoken[MAXSTRLEN]; |
---|
65 | st_table *macros; |
---|
66 | char ifelse_stack[MAXSTRLEN]; |
---|
67 | int ifelseSP=0; |
---|
68 | |
---|
69 | %} |
---|
70 | |
---|
71 | %option yylineno |
---|
72 | |
---|
73 | %a 3000 |
---|
74 | %e 1700 |
---|
75 | %k 1000 |
---|
76 | %n 700 |
---|
77 | %o 4000 |
---|
78 | %p 5000 |
---|
79 | |
---|
80 | %Start Snormal Stable Sskip |
---|
81 | |
---|
82 | Space [\f\n\r\t\b ] |
---|
83 | Alpha [a-zA-Z] |
---|
84 | AlphaU [a-zA-Z_] |
---|
85 | AlphaNum [a-zA-Z0-9] |
---|
86 | AlphaNumU [a-zA-Z0-9_] |
---|
87 | Digit [0-9] |
---|
88 | DigitU [0-9_] |
---|
89 | Number {Digit}{DigitU}* |
---|
90 | Decimal ({Number})?'[dD][ ]*{Number} |
---|
91 | Octal ({Number})?'[oO][ ]*[0-7xXzZ?][0-7xXzZ?_]* |
---|
92 | Hexdecimal ({Number})?'[hH][ ]*[0-9a-fA-FxXzZ?][0-9a-fA-FxXzZ?_]* |
---|
93 | Binary ({Number})?'[bB][ ]*[01xXzZ?][01xXzZ?_]* |
---|
94 | |
---|
95 | %% |
---|
96 | |
---|
97 | strcpy(last_macro, curr_macro); |
---|
98 | curr_macro[0]='\0'; |
---|
99 | |
---|
100 | if (ifelseSP==0) { |
---|
101 | if (scan_table) |
---|
102 | BEGIN Stable; |
---|
103 | else |
---|
104 | BEGIN Snormal; |
---|
105 | } |
---|
106 | |
---|
107 | <Sskip,Snormal,Stable>{Space}+ { |
---|
108 | #ifdef FLEX_SCANNER |
---|
109 | int i; |
---|
110 | for (i=0; i<yyleng; i++) |
---|
111 | if (yytext[i] == '\n') yylineno++; |
---|
112 | #endif |
---|
113 | continue; |
---|
114 | } |
---|
115 | |
---|
116 | <Sskip,Snormal,Stable>`ifdef[^\n]*\n { |
---|
117 | if (find_macro(yytext)) { |
---|
118 | ifelse_stack[ifelseSP++] = 1; |
---|
119 | } else { |
---|
120 | ifelse_stack[ifelseSP++] = 0; |
---|
121 | BEGIN Sskip; |
---|
122 | } |
---|
123 | if (ifelseSP == MAXSTRLEN) |
---|
124 | lex_panic("nested `if/`else too deep"); |
---|
125 | } |
---|
126 | <Sskip,Snormal,Stable>`ifndef[^\n]*\n { |
---|
127 | if (find_not_macro(yytext)) { |
---|
128 | ifelse_stack[ifelseSP++] = 1; |
---|
129 | } else { |
---|
130 | ifelse_stack[ifelseSP++] = 0; |
---|
131 | BEGIN Sskip; |
---|
132 | } |
---|
133 | if (ifelseSP == MAXSTRLEN) |
---|
134 | lex_panic("nested `if/`else too deep"); |
---|
135 | } |
---|
136 | <Sskip,Snormal,Stable>`else { |
---|
137 | if (ifelse_stack[ifelseSP-1]) { |
---|
138 | ifelse_stack[ifelseSP-1] = 0; |
---|
139 | BEGIN Sskip; |
---|
140 | } else { |
---|
141 | if (scan_table) |
---|
142 | BEGIN Stable; |
---|
143 | else |
---|
144 | BEGIN Snormal; |
---|
145 | } |
---|
146 | } |
---|
147 | <Sskip,Snormal,Stable>`endif { |
---|
148 | if (!ifelse_stack[--ifelseSP]) { |
---|
149 | if (scan_table) |
---|
150 | BEGIN Stable; |
---|
151 | else |
---|
152 | BEGIN Snormal; |
---|
153 | } |
---|
154 | } |
---|
155 | <Sskip>[^\f\n\r\t\b ]+ { continue; } |
---|
156 | |
---|
157 | <Snormal,Stable>"/*" { skipcommentblock(); continue; } |
---|
158 | <Snormal,Stable>"//" { skipcommentline(); continue; } |
---|
159 | |
---|
160 | <Snormal,Stable>`timescale[^\n]*\n { continue; } |
---|
161 | |
---|
162 | <Snormal,Stable>`define[^\n]*\n { |
---|
163 | #ifdef FLEX_SCANNER |
---|
164 | yylineno++; |
---|
165 | #endif |
---|
166 | memorize_macro(yytext, macros); |
---|
167 | continue; |
---|
168 | } |
---|
169 | <Snormal,Stable>`include[^\n]*\n { char *cp; |
---|
170 | #ifdef FLEX_SCANNER |
---|
171 | yylineno++; |
---|
172 | #endif |
---|
173 | yytext[strlen(yytext)-1] = '\0'; |
---|
174 | cp = strstr(yytext, "`include"); |
---|
175 | cp += strlen("`include"); |
---|
176 | while (*cp==' ' || *cp=='\t' || *cp=='\r') |
---|
177 | cp++; |
---|
178 | push_open_file(cp); |
---|
179 | } |
---|
180 | |
---|
181 | <Snormal,Stable>`VL2MVDataVar[^\n]*\n { |
---|
182 | char *cp; |
---|
183 | char varname[MAXSTRLEN], |
---|
184 | vartype[MAXSTRLEN]; |
---|
185 | int i; |
---|
186 | vl_id_range *id_sym; |
---|
187 | #ifdef FLEX_SCANNER |
---|
188 | yylineno++; |
---|
189 | #endif |
---|
190 | cp = strstr(yytext, "`VL2MVDataVar"); |
---|
191 | cp += strlen("`Vl2MVDataVar"); |
---|
192 | while (*cp==' '||*cp=='\t'||*cp=='\r') |
---|
193 | cp++; |
---|
194 | i =0; |
---|
195 | while (*cp!=' '&&*cp!='\t'&&*cp!='\r'&& |
---|
196 | *cp!='\0') { |
---|
197 | varname[i++] = *cp; |
---|
198 | cp++; |
---|
199 | } |
---|
200 | varname[i] = '\0'; |
---|
201 | while (*cp==' '||*cp=='\t'||*cp=='\r') |
---|
202 | cp++; |
---|
203 | i =0; |
---|
204 | while (*cp!=' '&&*cp!='\t'&&*cp!='\r'&& |
---|
205 | *cp!='\0'&&*cp!='\n') { |
---|
206 | vartype[i++] = *cp; |
---|
207 | cp++; |
---|
208 | } |
---|
209 | vartype[i] = '\0'; |
---|
210 | if (vl_currentModule) { |
---|
211 | if (st_lookup(vl_currentModule->sig_st, |
---|
212 | varname, |
---|
213 | (char**)&id_sym)) { |
---|
214 | if (id_sym->unintType) |
---|
215 | vl_chk_free(id_sym->unintType); |
---|
216 | id_sym->unintType = |
---|
217 | vlStrdup(vartype); |
---|
218 | } |
---|
219 | } |
---|
220 | } |
---|
221 | |
---|
222 | <Snormal,Stable>`VL2MVClock[^\n]*\n { char *cp, cname[MAXSTRLEN], |
---|
223 | buf[MAXSTRLEN]; |
---|
224 | int i; |
---|
225 | int edge, pi; |
---|
226 | float rho; |
---|
227 | /* VL2MVClock 1:0:-1 0 0.0 */ |
---|
228 | #ifdef FLEX_SCANNER |
---|
229 | yylineno++; |
---|
230 | #endif |
---|
231 | yytext[strlen(yytext)-1] = '\0'; |
---|
232 | cp = strstr(yytext, "`VL2MVClock"); |
---|
233 | cp += strlen("`VL2MVClock"); |
---|
234 | /* name */ |
---|
235 | while (*cp==' '||*cp=='\t'||*cp=='\r') |
---|
236 | cp++; |
---|
237 | i=0; |
---|
238 | while (*cp!=' ' && *cp!='\t' && |
---|
239 | *cp!='\r' && *cp!='\0') { |
---|
240 | cname[i++] = *cp; cp++; |
---|
241 | } |
---|
242 | cname[i] = '\0'; |
---|
243 | |
---|
244 | /* pi */ |
---|
245 | while (*cp==' '||*cp=='\t'||*cp=='\r') |
---|
246 | cp++; |
---|
247 | i=0; |
---|
248 | while (*cp!=' ' && *cp!='\t' && |
---|
249 | *cp!='\r' && *cp!='\0') { |
---|
250 | buf[i++] = *cp; cp++; |
---|
251 | } |
---|
252 | pi = atoi(buf); |
---|
253 | |
---|
254 | /* edge */ |
---|
255 | while (*cp==' '||*cp=='\t'||*cp=='\r') |
---|
256 | cp++; |
---|
257 | i=0; |
---|
258 | while (*cp!=' ' && *cp!='\t' && |
---|
259 | *cp!='\r' && *cp!='\0') { |
---|
260 | buf[i++] = *cp; cp++; |
---|
261 | } |
---|
262 | edge = atoi(buf); |
---|
263 | |
---|
264 | /* rho */ |
---|
265 | while (*cp==' '||*cp=='\t'||*cp=='\r') |
---|
266 | cp++; |
---|
267 | i=0; |
---|
268 | while (*cp!=' ' && *cp!='\t' && |
---|
269 | *cp!='\r' && *cp!='\0') { |
---|
270 | buf[i++] = *cp; cp++; |
---|
271 | } |
---|
272 | rho = atof(buf); |
---|
273 | |
---|
274 | register_vl2mv_synClock(cname, |
---|
275 | edge, pi, rho); |
---|
276 | continue; |
---|
277 | } |
---|
278 | |
---|
279 | <Snormal,Stable>`VL2MVundefMod[^\n]*\n { char *cp, modname[MAXSTRLEN]; |
---|
280 | int i; |
---|
281 | #ifdef FLEX_SCANNER |
---|
282 | yylineno++; |
---|
283 | #endif |
---|
284 | i=0; |
---|
285 | yytext[strlen(yytext)-1] = '\0'; |
---|
286 | cp = strstr(yytext, |
---|
287 | "`VL2MVundefMod"); |
---|
288 | cp += strlen("`VL2MVundefMod"); |
---|
289 | while (*cp==' ' || *cp=='\t' || |
---|
290 | *cp=='\r') |
---|
291 | cp++; |
---|
292 | while (*cp!=' ' && *cp!='\t' && |
---|
293 | *cp!='\r' && *cp!='\0') { |
---|
294 | modname[i++] = *cp; |
---|
295 | cp++; |
---|
296 | } |
---|
297 | modname[i] = '\0'; |
---|
298 | if (mod_list) |
---|
299 | st_insert(mod_list->mod_holes, |
---|
300 | vlStrdup(modname), 0); |
---|
301 | continue; |
---|
302 | } |
---|
303 | |
---|
304 | <Snormal>">=" { return YYGEQ; } |
---|
305 | <Snormal>"=<" { return YYLEQ; } |
---|
306 | <Snormal>"&&" { return YYLOGAND; } |
---|
307 | <Snormal>"||" { return YYLOGOR; } |
---|
308 | <Snormal>"===" { return YYCASEEQUALITY; } |
---|
309 | <Snormal>"==" { return YYLOGEQUALITY; } |
---|
310 | <Snormal>"!==" { return YYCASEINEQUALITY; } |
---|
311 | <Snormal>"!=" { return YYLOGINEQUALITY; } |
---|
312 | <Snormal>"^~" { return YYLOGXNOR; } |
---|
313 | <Snormal>"~^" { return YYLOGXNOR; } |
---|
314 | <Snormal>"~&" { return YYLOGNAND; } |
---|
315 | <Snormal>"~|" { return YYLOGNOR; } |
---|
316 | <Snormal>"<<" { return YYLSHIFT; } |
---|
317 | <Snormal>">>" { return YYRSHIFT; } |
---|
318 | <Snormal>"?:" { return YYCONDITIONAL; } |
---|
319 | |
---|
320 | <Snormal>\"[^"]*\" { return YYSTRING; } |
---|
321 | |
---|
322 | <Snormal>always { return YYALWAYS; } |
---|
323 | <Snormal>"*>" { return YYALLPATH; } |
---|
324 | <Snormal>and { return YYAND; } |
---|
325 | <Snormal>assign { return YYASSIGN; } |
---|
326 | <Snormal>begin { return YYBEGIN; } |
---|
327 | <Snormal>buf { return YYBUF; } |
---|
328 | <Snormal>bufif0 { return YYBUFIF0; } |
---|
329 | <Snormal>bufif1 { return YYBUFIF1; } |
---|
330 | <Snormal>case { return YYCASE; } |
---|
331 | <Snormal>casex { return YYCASEX; } |
---|
332 | <Snormal>casez { return YYCASEZ; } |
---|
333 | <Snormal>cmos { return YYCMOS; } |
---|
334 | <Snormal>deassign { return YYDEASSIGN; } |
---|
335 | <Snormal>default { return YYDEFAULT; } |
---|
336 | <Snormal>defparam { return YYDEFPARAM; } |
---|
337 | <Snormal>disable { return YYDISABLE; } |
---|
338 | <Snormal>edge { return YYEDGE; } |
---|
339 | <Snormal>else { return YYELSE; } |
---|
340 | <Snormal>end { return YYEND; } |
---|
341 | <Snormal>endcase { return YYENDCASE; } |
---|
342 | <Snormal>endfunction { return YYENDFUNCTION; } |
---|
343 | <Snormal>endmodule { return YYENDMODULE; } |
---|
344 | <Snormal>endprimitive { return YYENDPRIMITIVE; } |
---|
345 | <Snormal>endspecify { return YYENDSPECIFY; } |
---|
346 | <Stable>endtable { scan_table = 0; return YYENDTABLE; } |
---|
347 | <Snormal>endtask { return YYENDTASK; } |
---|
348 | <Snormal>enum { return YYENUM; } |
---|
349 | <Snormal>event { return YYEVENT; } |
---|
350 | <Snormal>for { return YYFOR; } |
---|
351 | <Snormal>forever { return YYFOREVER; } |
---|
352 | <Snormal>fork { return YYFORK; } |
---|
353 | <Snormal>function { return YYFUNCTION; } |
---|
354 | <Snormal>highz0 { return YYHIGHZ0; } |
---|
355 | <Snormal>highz1 { return YYHIGHZ1; } |
---|
356 | <Snormal>if { return YYIF; } |
---|
357 | <Snormal>initial { return YYINITIAL; } |
---|
358 | <Snormal>inout { return YYINOUT; } |
---|
359 | <Snormal>input { return YYINPUT; } |
---|
360 | <Snormal>integer { return YYINTEGER; } |
---|
361 | <Snormal>join { return YYJOIN; } |
---|
362 | <Snormal>large { return YYLARGE; } |
---|
363 | <Snormal>"=>" { return YYLEADTO; } |
---|
364 | <Snormal>macromodule { return YYMACROMODULE; } |
---|
365 | <Snormal>medium { return YYMEDIUM; } |
---|
366 | <Snormal>module { return YYMODULE; } |
---|
367 | <Snormal>mREG { return YYMREG; } |
---|
368 | <Snormal>"<=" { return YYNBASSIGN; } |
---|
369 | <Snormal>nand { return YYNAND; } |
---|
370 | <Snormal>negedge { return YYNEGEDGE; } |
---|
371 | <Snormal>nmos { return YYNMOS; } |
---|
372 | <Snormal>nor { return YYNOR; } |
---|
373 | <Snormal>not { return YYNOT; } |
---|
374 | <Snormal>notif0 { return YYNOTIF0; } |
---|
375 | <Snormal>notif1 { return YYNOTIF1; } |
---|
376 | <Snormal>or { return YYOR; } |
---|
377 | <Snormal>output { return YYOUTPUT; } |
---|
378 | <Snormal>parameter { return YYPARAMETER; } |
---|
379 | <Snormal>pmos { return YYPMOS; } |
---|
380 | <Snormal>posedge { return YYPOSEDGE; } |
---|
381 | <Snormal>primitive { return YYPRIMITIVE; } |
---|
382 | <Snormal>pull0 { return YYPULL0; } |
---|
383 | <Snormal>pull1 { return YYPULL1; } |
---|
384 | <Snormal>pulldown { return YYPULLDOWN; } |
---|
385 | <Snormal>pullup { return YYPULLUP; } |
---|
386 | <Snormal>rcmos { return YYRCMOS; } |
---|
387 | <Snormal>real { return YYREAL; } |
---|
388 | <Snormal>reg { return YYREG; } |
---|
389 | <Snormal>repeat { return YYREPEAT; } |
---|
390 | <Snormal>"->" { return YYRIGHTARROW; } |
---|
391 | <Snormal>rnmos { return YYRNMOS; } |
---|
392 | <Snormal>rpmos { return YYRPMOS; } |
---|
393 | <Snormal>rtran { return YYRTRAN; } |
---|
394 | <Snormal>rtranif0 { return YYRTRANIF0; } |
---|
395 | <Snormal>rtranif1 { return YYRTRANIF1; } |
---|
396 | <Snormal>scalered { return YYSCALARED; } |
---|
397 | <Snormal>small { return YYSMALL; } |
---|
398 | <Snormal>specify { return YYSPECIFY; } |
---|
399 | <Snormal>specparam { return YYSPECPARAM; } |
---|
400 | <Snormal>strong0 { return YYSTRONG0; } |
---|
401 | <Snormal>strong1 { return YYSTRONG1; } |
---|
402 | <Snormal>supply0 { return YYSUPPLY0; } |
---|
403 | <Snormal>supply1 { return YYSUPPLY1; } |
---|
404 | <Snormal>swire { return YYSWIRE; } |
---|
405 | <Snormal>table { scan_table = 1; return YYTABLE; } |
---|
406 | <Snormal>task { return YYTASK; } |
---|
407 | <Snormal>teslaTimer { return YYTESLATIMER; } |
---|
408 | <Snormal>time { return YYTIME; } |
---|
409 | <Snormal>tran { return YYTRAN; } |
---|
410 | <Snormal>tranif0 { return YYTRANIF0; } |
---|
411 | <Snormal>tranif1 { return YYTRANIF1; } |
---|
412 | <Snormal>tri { return YYTRI; } |
---|
413 | <Snormal>tri0 { return YYTRI0; } |
---|
414 | <Snormal>tri1 { return YYTRI1; } |
---|
415 | <Snormal>triand { return YYTRIAND; } |
---|
416 | <Snormal>trior { return YYTRIOR; } |
---|
417 | <Snormal>trireg { return YYTRIREG; } |
---|
418 | <Snormal>typedef { return YYTYPEDEF; } |
---|
419 | <Snormal>vectored { return YYVECTORED; } |
---|
420 | <Snormal>wait { return YYWAIT; } |
---|
421 | <Snormal>wand { return YYWAND; } |
---|
422 | <Snormal>weak0 { return YYWEAK0; } |
---|
423 | <Snormal>weak1 { return YYWEAK1; } |
---|
424 | <Snormal>while { return YYWHILE; } |
---|
425 | <Snormal>wire { return YYWIRE; } |
---|
426 | <Snormal>wor { return YYWOR; } |
---|
427 | <Snormal>xnor { return YYXNOR; } |
---|
428 | <Snormal>xor { return YYXOR; } |
---|
429 | |
---|
430 | <Snormal>\$setup { return YYsysSETUP; } |
---|
431 | <Snormal>\$NDset { return YYsysND; } |
---|
432 | <Snormal>\$ND { return YYsysND; } |
---|
433 | <Snormal>\${AlphaU}{AlphaNumU}* { return YYsysID; } |
---|
434 | |
---|
435 | <Snormal>`{AlphaU}{AlphaNumU}* { |
---|
436 | char *macro; |
---|
437 | |
---|
438 | strcpy(yyid, yytext); |
---|
439 | /* macro expansion */ |
---|
440 | if (st_lookup(macros, yyid+1, ¯o)) { |
---|
441 | expand_macro(yyid+1, macros); |
---|
442 | continue; |
---|
443 | } |
---|
444 | return YYIDE; |
---|
445 | } |
---|
446 | <Snormal>{AlphaU}{AlphaNumU}* { |
---|
447 | vl_type *var_type; |
---|
448 | |
---|
449 | yytypetoken[0] = '\0'; |
---|
450 | strcpy(yyid, yytext); |
---|
451 | |
---|
452 | /* type name checking */ |
---|
453 | if (reserve_type_name) |
---|
454 | if (st_lookup(mod_list->type_st, |
---|
455 | yytext, (char**)&var_type)) |
---|
456 | return YYuTYPE; |
---|
457 | |
---|
458 | /* enum name */ |
---|
459 | if (aux_st) { |
---|
460 | vl_enumerator *enum_elt; |
---|
461 | if (st_lookup(aux_st, |
---|
462 | yytext, (char**)&enum_elt)){ |
---|
463 | sprintf(yytypetoken, yytext); |
---|
464 | sprintf(yytext, "%d", enum_elt->val); |
---|
465 | return YYINUMBER; |
---|
466 | } |
---|
467 | } |
---|
468 | |
---|
469 | |
---|
470 | return YYIDE; |
---|
471 | } |
---|
472 | <Snormal>\\[^\n\t\b\r\f ]* { |
---|
473 | strcpy(yyid, yytext); |
---|
474 | return YYIDE; |
---|
475 | } |
---|
476 | |
---|
477 | <Snormal>{Number}*\.{Number}+ { return YYRNUMBER; } |
---|
478 | <Snormal>{Number}+\.{Number}* { return YYRNUMBER; } |
---|
479 | <Snormal>{Number} { return YYINUMBER; } |
---|
480 | <Snormal>{Binary} { |
---|
481 | binbin(yytext, brep); |
---|
482 | encodebit(brep, &bexp1, &bexp0); |
---|
483 | return YYINUMBER; |
---|
484 | } |
---|
485 | <Snormal>{Octal} { |
---|
486 | octbin(yytext, brep); |
---|
487 | encodebit(brep, &bexp1, &bexp0); |
---|
488 | return YYINUMBER; |
---|
489 | } |
---|
490 | <Snormal>{Decimal} { |
---|
491 | decbin(yytext, brep); |
---|
492 | encodebit(brep, &bexp1, &bexp0); |
---|
493 | return YYINUMBER; |
---|
494 | } |
---|
495 | <Snormal>{Hexdecimal} { |
---|
496 | hexbin(yytext, brep); |
---|
497 | encodebit(brep, &bexp1, &bexp0); |
---|
498 | return YYINUMBER; |
---|
499 | } |
---|
500 | |
---|
501 | <Stable>\(\?\?\) { return '*'; } |
---|
502 | <Stable>\(01\) { return 'r'; } |
---|
503 | <Stable>\(10\) { return 'f'; } |
---|
504 | <Snormal,Stable>. { return yytext[0]; } |
---|
505 | |
---|
506 | %% |
---|
507 | |
---|
508 | int yywrap() |
---|
509 | { |
---|
510 | if (!empty_file_stack()) { |
---|
511 | pop_close_file(); |
---|
512 | return 0; |
---|
513 | } else { |
---|
514 | return 1; |
---|
515 | } |
---|
516 | } |
---|
517 | |
---|
518 | void skipcommentblock() |
---|
519 | { |
---|
520 | int done, level = 0; |
---|
521 | char c; |
---|
522 | |
---|
523 | for (done=0; !done; yyleng = (yyleng > YYLMAX-2) ? YYLMAX-2 : yyleng) { |
---|
524 | if ((c = input()) == '*') { |
---|
525 | yytext[yyleng++] = c; |
---|
526 | if ((c = input()) == '/') { |
---|
527 | done = (level-- == 0); |
---|
528 | } else { |
---|
529 | unput(c); |
---|
530 | } |
---|
531 | } else if (c == '/') { |
---|
532 | yytext[yyleng++] = c; |
---|
533 | if ((c = input()) == '*') { |
---|
534 | level++; |
---|
535 | } else { |
---|
536 | unput(c); |
---|
537 | } |
---|
538 | } else if (c == 0) { |
---|
539 | char buf[MAXSTRLEN]; |
---|
540 | sprintf(buf, "incomplete comment (%d)\n", yylineno); |
---|
541 | fail(buf); |
---|
542 | } else { |
---|
543 | #ifdef FLEX_SCANNER |
---|
544 | if (c == '\n') yylineno++; |
---|
545 | #endif |
---|
546 | yytext[yyleng++] = c; |
---|
547 | } |
---|
548 | } |
---|
549 | } |
---|
550 | |
---|
551 | void skipcommentline() |
---|
552 | { |
---|
553 | int done; |
---|
554 | char c; |
---|
555 | |
---|
556 | for (done=0; !done; yyleng = (yyleng > YYLMAX-2) ? YYLMAX-2 : yyleng) { |
---|
557 | if ((c = input()) == '\n') { |
---|
558 | done = 1; |
---|
559 | } else { |
---|
560 | yytext[yyleng++] = c; |
---|
561 | } |
---|
562 | } |
---|
563 | yytext[yyleng] = '\0'; |
---|
564 | #ifdef FLEX_SCANNER |
---|
565 | yylineno++; |
---|
566 | #endif |
---|
567 | |
---|
568 | } |
---|
569 | |
---|
570 | void binbin(instr, outstr) |
---|
571 | char *instr; |
---|
572 | char *outstr; |
---|
573 | { |
---|
574 | char *cp, *firstcp; |
---|
575 | int blen = 0, bpos=0; |
---|
576 | |
---|
577 | blen = atoi(instr); |
---|
578 | blen = (blen==0) ? MAXBITNUM : blen; |
---|
579 | firstcp = strpbrk(instr, "bB")+1; |
---|
580 | cp = instr + strlen(instr) - 1; |
---|
581 | outstr[blen] = '\0'; |
---|
582 | for (bpos = blen-1; bpos >=0 && cp >= firstcp; cp--) { |
---|
583 | if (*cp != '_' && *cp != ' ') { |
---|
584 | outstr[bpos] = *cp; |
---|
585 | bpos--; |
---|
586 | } |
---|
587 | } |
---|
588 | for (; bpos >=0; bpos--) { |
---|
589 | outstr[bpos] = '0'; |
---|
590 | } |
---|
591 | } |
---|
592 | |
---|
593 | char *hexnum[16] = {"0000","0001","0010","0011", |
---|
594 | "0100","0101","0110","0111", |
---|
595 | "1000","1001","1010","1011", |
---|
596 | "1100","1101","1110","1111"}; |
---|
597 | |
---|
598 | void decbin(instr, outstr) |
---|
599 | char *instr; |
---|
600 | char *outstr; |
---|
601 | { |
---|
602 | char *firstcp, buf[MAXSTRLEN]; |
---|
603 | int num, blen = 0; |
---|
604 | |
---|
605 | utol(instr); |
---|
606 | blen = atoi(instr); |
---|
607 | blen = (blen==0) ? MAXBITNUM : blen; |
---|
608 | firstcp = strpbrk(instr, "dD")+1; |
---|
609 | while (*firstcp==' ') firstcp++; |
---|
610 | num = atoi(firstcp); /* don't put x, z, ? in decimal string */ |
---|
611 | sprintf(buf, "%d'h%x", blen, num); |
---|
612 | hexbin(buf, outstr); |
---|
613 | } |
---|
614 | |
---|
615 | void octbin(instr, outstr) |
---|
616 | char *instr; |
---|
617 | char *outstr; |
---|
618 | { |
---|
619 | char *cp, *firstcp; |
---|
620 | int blen = 0, bpos=0, i; |
---|
621 | |
---|
622 | utol(instr); |
---|
623 | blen = atoi(instr); |
---|
624 | blen = (blen==0) ? MAXBITNUM : blen; |
---|
625 | firstcp = strpbrk(instr, "oO")+1; |
---|
626 | cp = instr + strlen(instr) - 1; |
---|
627 | outstr[blen] = '\0'; |
---|
628 | for (bpos = blen-1; bpos >=0 && cp >= firstcp; cp--) { |
---|
629 | if (*cp != '_' && *cp != ' ') { |
---|
630 | for (i = 3; i >= 1; i--) { |
---|
631 | if (bpos >= 0) { |
---|
632 | if (*cp=='x' || *cp=='z' || *cp=='?') { |
---|
633 | outstr[bpos] = *cp; |
---|
634 | bpos--; |
---|
635 | } else if (isdigit(*cp)) { |
---|
636 | outstr[bpos] = hexnum[*cp-'0'][i]; |
---|
637 | bpos--; |
---|
638 | } |
---|
639 | } |
---|
640 | } |
---|
641 | } |
---|
642 | } |
---|
643 | for (; bpos >=0; bpos--) { |
---|
644 | outstr[bpos] = '0'; |
---|
645 | } |
---|
646 | } |
---|
647 | |
---|
648 | void hexbin(instr, outstr) |
---|
649 | char *instr; |
---|
650 | char *outstr; |
---|
651 | { |
---|
652 | char *cp, *firstcp; |
---|
653 | int blen = 0, bpos=0, i; |
---|
654 | |
---|
655 | utol(instr); |
---|
656 | blen = atoi(instr); |
---|
657 | blen = (blen==0) ? MAXBITNUM : blen; |
---|
658 | firstcp = strpbrk(instr, "hH")+1; |
---|
659 | cp = instr + strlen(instr) - 1; |
---|
660 | outstr[blen] = '\0'; |
---|
661 | for (bpos = blen-1; bpos >=0 && cp >= firstcp; cp--) { |
---|
662 | if (*cp != '_' && *cp != ' ') { |
---|
663 | for (i = 3; i >= 0; i--) { |
---|
664 | if (bpos >= 0) { |
---|
665 | if (*cp=='x' || *cp=='z' || *cp=='?') { |
---|
666 | outstr[bpos] = *cp; |
---|
667 | bpos--; |
---|
668 | } else if (isdigit(*cp)) { |
---|
669 | outstr[bpos] = hexnum[*cp-'0'][i]; |
---|
670 | bpos--; |
---|
671 | } else if (isxdigit(*cp)) { |
---|
672 | outstr[bpos] = hexnum[*cp-'a'+10][i]; |
---|
673 | bpos--; |
---|
674 | } |
---|
675 | } |
---|
676 | } |
---|
677 | } |
---|
678 | } |
---|
679 | for (; bpos >=0; bpos--) { |
---|
680 | outstr[bpos] = '0'; |
---|
681 | } |
---|
682 | } |
---|
683 | |
---|
684 | char *utol(str) |
---|
685 | char *str; |
---|
686 | { |
---|
687 | char *cp; |
---|
688 | |
---|
689 | for (cp = str; *cp!='\0'; cp++) { |
---|
690 | if (isupper(*cp)) *cp = tolower(*cp); |
---|
691 | } |
---|
692 | return str; |
---|
693 | } |
---|
694 | |
---|
695 | void encodebit(char *instr, int *part1, int *part0) |
---|
696 | { |
---|
697 | int i, bmask; |
---|
698 | |
---|
699 | *part1 = *part0 = 0; |
---|
700 | i = strlen(instr); |
---|
701 | i = (i > MAXBITNUM) ? MAXBITNUM-1 : i-1; |
---|
702 | for (bmask = 1; i>=0; bmask <<= 1, i--) { |
---|
703 | switch (instr[i]) { |
---|
704 | case '1': *part1 |= bmask; break; |
---|
705 | case '0': *part0 |= bmask; break; |
---|
706 | case 'x': |
---|
707 | case '?': *part1 |= bmask; *part0 |= bmask; break; |
---|
708 | case 'z': break; |
---|
709 | } |
---|
710 | } |
---|
711 | } |
---|
712 | |
---|
713 | /* |
---|
714 | * memorize_macro |
---|
715 | * |
---|
716 | * insert a argumentless macro into macro table |
---|
717 | */ |
---|
718 | void memorize_macro(instr, macros) |
---|
719 | char *instr; |
---|
720 | st_table *macros; |
---|
721 | { |
---|
722 | char *cp, *cp1, *cp2; |
---|
723 | char mname[MAXSTRLEN]; |
---|
724 | |
---|
725 | cp = strstr(instr,MACRO_DEFINE) + strlen(MACRO_DEFINE); |
---|
726 | sscanf(cp, "%s", mname); |
---|
727 | cp = strstr(cp, mname) + strlen(mname); |
---|
728 | cp1 = strstr(cp, "//"); |
---|
729 | cp2 = strstr(cp, "/*"); |
---|
730 | if (cp1 || cp2) { |
---|
731 | if (cp1) *cp1='\0'; |
---|
732 | if (cp2) *cp2='\0'; |
---|
733 | } |
---|
734 | |
---|
735 | st_insert(macros, vlStrdup(mname), vlStrdup(cp)); |
---|
736 | } |
---|
737 | |
---|
738 | /* |
---|
739 | * expand_macro |
---|
740 | * |
---|
741 | * expand an argumentless macro into input stream (using unput) |
---|
742 | */ |
---|
743 | void expand_macro(mname, macros) |
---|
744 | char *mname; |
---|
745 | st_table *macros; |
---|
746 | { |
---|
747 | char *mbody; |
---|
748 | int i; |
---|
749 | |
---|
750 | if (st_lookup(macros, mname, &mbody)) { |
---|
751 | for (i=strlen(mbody)-1; i>=0; i--) { |
---|
752 | unput(mbody[i]); |
---|
753 | } |
---|
754 | strcpy(curr_macro, mname); |
---|
755 | } |
---|
756 | } |
---|
757 | |
---|
758 | stack_t file_stack; |
---|
759 | stack_t fname_stack; |
---|
760 | stack_t lineno_stack; |
---|
761 | stack_t buffer_stack; |
---|
762 | |
---|
763 | void push_open_file(char *fname) |
---|
764 | { |
---|
765 | FILE *infile; |
---|
766 | char *filename; |
---|
767 | char buf[MAXSTRLEN]; |
---|
768 | |
---|
769 | filename = vlStrdup(fname); |
---|
770 | if (*filename == '"') { |
---|
771 | unsigned int i, j; |
---|
772 | j = strlen(filename)-1; |
---|
773 | while (filename[j] == ' ' || filename[j] == '\t' || |
---|
774 | filename[j] == '\r') j--; |
---|
775 | if (filename[j] != '"') { |
---|
776 | sprintf(buf, "unbalanced \"\n"); |
---|
777 | yyerror(buf); |
---|
778 | } |
---|
779 | filename[j] = '\0'; |
---|
780 | for(i=0; i<strlen(filename); i++) filename[i] = filename[i+1]; |
---|
781 | } |
---|
782 | if ((infile = fopen(filename,"r"))==NULL) { |
---|
783 | sprintf(buf, "fail to open file '%s'", filename); |
---|
784 | yyerror(buf); |
---|
785 | } |
---|
786 | |
---|
787 | pushd(filename); |
---|
788 | |
---|
789 | push_stack(file_stack, (void*)yyin); |
---|
790 | push_stack(fname_stack, (void*)vl_filename); |
---|
791 | push_stack(lineno_stack, (void*)yylineno); |
---|
792 | |
---|
793 | #if defined(FLEX_SCANNER) && !defined(YY_FLEX_LEX_COMPAT) |
---|
794 | push_stack(buffer_stack, (void*) YY_CURRENT_BUFFER); |
---|
795 | yy_switch_to_buffer(yy_create_buffer(infile, YY_BUF_SIZE)); |
---|
796 | #else |
---|
797 | yyin = infile; |
---|
798 | #endif |
---|
799 | yylineno = 1; |
---|
800 | vl_filename = filename; |
---|
801 | } |
---|
802 | |
---|
803 | void pop_close_file() |
---|
804 | { |
---|
805 | FILE *infile; |
---|
806 | int old_yylineno; |
---|
807 | char *filename; |
---|
808 | #ifdef FLEX_SCANNER |
---|
809 | YY_BUFFER_STATE buffer; |
---|
810 | #endif |
---|
811 | |
---|
812 | fclose(yyin); |
---|
813 | pop_stack(file_stack, (void**)&infile); |
---|
814 | pop_stack(fname_stack, (void**)&filename); |
---|
815 | pop_stack(lineno_stack, (void**)&old_yylineno); |
---|
816 | popd(); |
---|
817 | #if defined(FLEX_SCANNER) && !defined(YY_FLEX_LEX_COMPAT) |
---|
818 | yy_delete_buffer(YY_CURRENT_BUFFER); |
---|
819 | pop_stack(buffer_stack, (void**)&buffer); |
---|
820 | yy_switch_to_buffer(buffer); |
---|
821 | #else |
---|
822 | yyin = infile; |
---|
823 | #endif |
---|
824 | yylineno = old_yylineno; |
---|
825 | vl_chk_free(vl_filename); |
---|
826 | vl_filename = filename; |
---|
827 | } |
---|
828 | |
---|
829 | int empty_file_stack() |
---|
830 | { |
---|
831 | return (lsLength(file_stack)==0); |
---|
832 | } |
---|
833 | |
---|
834 | int find_macro(char *str) |
---|
835 | { |
---|
836 | char *cp; |
---|
837 | char *dummy; |
---|
838 | char mname[MAXSTRLEN]; |
---|
839 | |
---|
840 | cp = strstr(str,MACRO_IFDEF) + strlen(MACRO_IFDEF); |
---|
841 | sscanf(cp, "%s", mname); |
---|
842 | return (st_lookup(macros, mname, &dummy)); |
---|
843 | } |
---|
844 | |
---|
845 | int find_not_macro(char *str) |
---|
846 | { |
---|
847 | char *cp; |
---|
848 | char *dummy; |
---|
849 | char mname[MAXSTRLEN]; |
---|
850 | |
---|
851 | cp = strstr(str,MACRO_IFNDEF) + strlen(MACRO_IFNDEF); |
---|
852 | sscanf(cp, "%s", mname); |
---|
853 | return (!st_lookup(macros, mname, &dummy)); |
---|
854 | } |
---|
855 | |
---|
856 | void lex_panic(char *mesg) |
---|
857 | { |
---|
858 | fprintf(stderr, "%s\n", mesg); |
---|
859 | exit(1); |
---|
860 | } |
---|
861 | |
---|
862 | |
---|
863 | static stack_t dir_stack=0; |
---|
864 | |
---|
865 | void pushd(char *filename) |
---|
866 | { |
---|
867 | int i; |
---|
868 | char cwd[MAXSTRLEN], pwd[MAXSTRLEN]; |
---|
869 | |
---|
870 | if (!dir_stack) dir_stack = create_stack(); |
---|
871 | |
---|
872 | getcwd(pwd, MAXSTRLEN-1); |
---|
873 | |
---|
874 | for (i=strlen(filename)-1; i>=0; i--) |
---|
875 | if (filename[i] == '/') break; |
---|
876 | |
---|
877 | strcpy(cwd, filename); |
---|
878 | if (i==-1) { cwd[0]='.'; cwd[1]='\0'; } |
---|
879 | else { cwd[i]='\0'; } |
---|
880 | |
---|
881 | push_stack(dir_stack, vlStrdup(pwd)); |
---|
882 | chdir(cwd); |
---|
883 | } |
---|
884 | |
---|
885 | void popd() |
---|
886 | { |
---|
887 | char *cwd; |
---|
888 | |
---|
889 | pop_stack(dir_stack, (void**)&cwd); |
---|
890 | chdir(cwd); |
---|
891 | free(cwd); |
---|
892 | } |
---|