ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libBASS/BASSlex.l
Revision: 718
Committed: Mon Aug 25 21:51:30 2003 UTC (20 years, 10 months ago) by gezelter
File size: 9257 byte(s)
Log Message:
*** empty log message ***

File Contents

# Content
1
2 /* define some search patterns */
3
4 digit [0-9]
5 letter [A-Za-z]
6 natural {digit}+
7 signedNat ("+"|"-")?{natural}
8 number {signedNat}("."{natural})?([Ee]{signedNat})?
9 identifier ("_"|{letter})({letter}|{digit}|"-"|"_")*
10
11 /* define start states */
12
13 %x PRE_P
14 %x INCL
15 %x DEF
16 %x IFDEF
17 %x IFNDEF
18 %x ESCAPE
19 %x CHECK_ESCAPE
20
21 /* what to put at the top of the lex code */
22
23 %{
24 #include <stdio.h>
25 #include <string.h>
26
27 #include <BASSyacc.h>
28 #include <BASS_parse.h>
29 #include <simError.h>
30 #ifdef IS_MPI
31 #define __is_lex__
32 #include <mpiBASS.h>
33 #endif
34
35 typedef unsigned short int r_short;
36 typedef unsigned short u_short;
37
38 extern void change_in_file( FILE* in_file );
39
40 // the following is used by the include start state
41
42 #define MAX_BUFFER_DEPTH 10
43 YY_BUFFER_STATE buffer_stack[MAX_BUFFER_DEPTH]; // a stack of the include buffers
44 int buffer_stack_ptr = 0;
45 struct filename_list{
46 char my_name[300];
47 struct filename_list* next;
48 };
49 struct filename_list* yyfile_name;
50 struct filename_list* temp_yyfile_name;
51 int yylineno_stack[MAX_BUFFER_DEPTH];
52
53
54 // the following is a check against the define buffer length
55
56 void check_def_buff( char* defined, int index );
57
58 //these are used by the ifdef and ifndef statements
59
60 int escape_stack_ptr = 0; //keeps track of the escape stack
61
62
63 %}
64
65 %option yylineno
66
67 %%
68
69 {signedNat} {
70 yylval.i_val = atoi( yytext );
71 return INTEGER;
72 }
73
74 {number} {
75 yylval.d_val = atof( yytext );
76 return DOUBLE;
77 }
78
79 {identifier} {
80 int token;
81 token = res_word( yytext );
82
83 if( token == DEFINED ){
84
85 if( buffer_stack_ptr >= MAX_BUFFER_DEPTH ){
86 fprintf( stderr,
87 "Maximum buffer depth exceeded for %s.\n",
88 yytext );
89 exit(1);
90 }
91
92 buffer_stack[buffer_stack_ptr] = YY_CURRENT_BUFFER;
93 buffer_stack_ptr++;
94
95 yy_scan_string( get_definition( yytext ) );
96 }
97 else if( token ){
98 return token;
99 }
100 else{
101 yylval.s_ptr = strdup( yytext );
102 return IDENTIFIER;
103 }
104 }
105
106 \".*\" {
107 /* little routine to strip off the quotes */
108
109 u_short i;
110 i = 0; // index
111 while( yytext[i+1] != '\"' ){
112
113 yytext[i] = yytext[i+1];
114 i++;
115 }
116 yytext[i] = '\0';
117 yylval.s_ptr = strdup( yytext );
118 return QUOTED_STRING;
119 }
120
121 \[{natural}\] {
122 int index;
123 sscanf(yytext, "[%d]", &index);
124 yylval.i_val = index;
125 return ARRAY_INDEX;
126 }
127
128 [ \t\n]+ /* ignore whitespace */;
129
130 "/*" {
131 /* ignore comments */
132 u_short done;
133 char c;
134
135 done = 0;
136 while( !done ){
137
138 c = input();
139 while( c != '*' ){
140
141 c = input();
142 }
143 while( c == '*' ){
144
145 c = input();
146 }
147 if( c == '/' ) done = 1;
148 }
149 }
150
151 "//".*\n /* ignore comments */;
152
153 "#" BEGIN(PRE_P);
154
155 . {
156 // pass everything else to yacc
157 return yytext[0];
158 }
159
160 <PRE_P>"include" BEGIN(INCL);
161 <PRE_P>"define" BEGIN(DEF);
162 <PRE_P>"ifdef" BEGIN(IFDEF);
163 <PRE_P>"ifndef" BEGIN(IFNDEF);
164 <PRE_P>"endif" /* do nothing */;
165 <PRE_P>\n BEGIN(INITIAL);
166
167 <INCL>[ \t]* /* eat white space */
168 <INCL>\".*\" {
169 char foo_name[300];
170
171 // little routine to strip off the quotes
172
173 u_short i;
174 i = 0; // index
175 while( yytext[i+1] != '\"' ){
176
177 yytext[i] = yytext[i+1];
178 i++;
179 }
180
181 yytext[i] = '\0';
182 strcpy( foo_name, yytext );
183
184 // now we have the include file name
185
186 if( buffer_stack_ptr >= MAX_BUFFER_DEPTH ){
187
188 fprintf( stderr, "Includes nested too deeply\n" );
189 exit(1);
190 }
191
192 buffer_stack[buffer_stack_ptr] = YY_CURRENT_BUFFER;
193 yylineno_stack[buffer_stack_ptr] = yylineno;
194 buffer_stack_ptr++;
195
196 yyin = fopen( yytext, "r" );
197 if( yyin == NULL ){
198 fprintf( stderr, "Unable to include file %s\n", yytext );
199 exit(1);
200 }
201
202 yy_switch_to_buffer( yy_create_buffer( yyin, YY_BUF_SIZE ) );
203 yylineno = 0;
204
205 temp_yyfile_name = (struct filename_list* )malloc( sizeof( struct filename_list ) );
206 temp_yyfile_name->next = yyfile_name;
207 yyfile_name = temp_yyfile_name;
208 strcpy( yyfile_name->my_name, foo_name );
209
210
211 BEGIN(INITIAL);
212 }
213 <INCL>\n BEGIN(INITIAL);
214 <INCL>. /* ignore everything else */
215
216 <DEF>[ \t]* /* eat white space */;
217 <DEF>{identifier} {
218 char c;
219 char definition[ DEFINED_BUFFER_SIZE ];
220 short int done;
221 short int c_done; // a done marker for the comments
222 int def_ptr;
223
224 // initialize the definition buffer
225
226 for( def_ptr = 0; def_ptr < DEFINED_BUFFER_SIZE; def_ptr++ ){
227 definition[def_ptr] = '\0';
228 }
229
230 def_ptr =0;
231 done = 0;
232 c_done = 0;
233
234 while( !done ){
235
236 c = input();
237 if( c == '\"' ){
238
239 // shove the whole quoted string into the macro
240
241 definition[def_ptr] = c;
242 //fprintf( stderr, "%c", c );
243 def_ptr++;
244 check_def_buff( yytext, def_ptr );
245
246 c = input();
247 while( c != '\"' ){
248
249 definition[def_ptr] = c;
250 //fprintf( stderr, "%c", c );
251 def_ptr++;
252 check_def_buff( yytext, def_ptr );
253
254 c = input();
255 }
256 definition[def_ptr] = c;
257 //fprintf( stderr, "%c", c );
258 def_ptr++;
259 check_def_buff( yytext, def_ptr );
260 c = input();
261 }
262
263 // handle comments
264
265 if( c == '/' ){
266 c = input();
267 switch( c ){
268
269 case '/':
270 while( c != '\n' && c != '\\' ){
271 c = input();
272 }
273 break;
274
275 case '*':
276 c_done = 0;
277 while( !c_done ){
278 c = input();
279 while( c != '*' ){
280 c = input();
281 }
282 while( c == '*' ){
283 c = input();
284 }
285 if( c == '/' ) c_done = 1;
286 }
287 c = input();
288 break;
289
290 default:
291 // the '/' char was a normal symbol
292 definition[def_ptr] = '/';
293 //fprintf( stderr, "%c", c );
294 def_ptr++;
295 check_def_buff( yytext, def_ptr );
296 break;
297 }
298 }
299
300
301 if( c == '\n' ){
302 done = 1;
303 }
304
305 else{
306
307 // check for the line wrap character '\'
308
309 if( c == '\\' ){
310
311 // skip the rest of the line until the line return
312
313 c = input();
314 while( c != '\n' ){
315 c = input();
316 }
317 }
318
319 else{
320
321 // we now know the character is a good one
322
323 definition[def_ptr] = c;
324 //fprintf( stderr, "%c", c );
325 def_ptr++;
326 check_def_buff( yytext, def_ptr );
327 }
328 }
329 }
330
331 insert_define( yytext, definition );
332 BEGIN(INITIAL);
333 }
334 <DEF>\n BEGIN(INITIAL);
335 <DEF>. /* ignore everything else */;
336
337 <IFDEF>[ \t]* /* eat white space */;
338 <IFDEF>{identifier} {
339 if( !is_defined( yytext ) ){
340 escape_stack_ptr++;
341 BEGIN(ESCAPE);
342 }
343 }
344 <IFDEF>\n BEGIN(INITIAL);
345 <IFDEF>. /* ignore everything else */;
346
347 <IFNDEF>[ \t]* /* eat the white space */;
348 <IFNDEF>{identifier} {
349 if( is_defined( yytext ) ){
350 escape_stack_ptr++;
351 BEGIN(ESCAPE);
352 }
353 }
354 <IFNDEF>\n BEGIN(INITIAL);
355 <IFNDEF>. /* ignore everything else */;
356
357 <ESCAPE>\".*\" /* do nothing */;
358 <ESCAPE>"//".*\n /* ignore comments */;
359 <ESCAPE>"/*" {
360 /* ignore comments */
361 u_short done;
362 char c;
363
364 done = 0;
365 while( !done ){
366
367 c = input();
368 while( c != '*' ){
369
370 c = input();
371 }
372
373 while( c == '*' ){
374
375 c = input();
376 }
377
378 if( c == '/' ) done = 1;
379 }
380 }
381 <ESCAPE>"#" BEGIN(CHECK_ESCAPE);
382 <ESCAPE>. /* ignore everything else */;
383
384 <CHECK_ESCAPE>[ \t] /* ignore whitespace */;
385 <CHECK_ESCAPE>"ifdef" { escape_stack_ptr++; BEGIN(ESCAPE); }
386 <CHECK_ESCAPE>"ifndef" { escape_stack_ptr++; BEGIN(ESCAPE); }
387 <CHECK_ESCAPE>"endif" {
388 escape_stack_ptr--;
389 if( escape_stack_ptr <= 0){
390 escape_stack_ptr = 0; // just in case something flubbed
391 BEGIN(INITIAL);
392 }
393 }
394 <CHECK_ESCAPE>\n BEGIN(ESCAPE);
395 <CHECK_ESCAPE>. /* ignore everything else */;
396
397 <<EOF>> {
398 buffer_stack_ptr--;
399 if( buffer_stack_ptr < 0 ){
400
401 yyterminate();
402 }
403
404 else{
405
406 yy_delete_buffer( YY_CURRENT_BUFFER );
407 yy_switch_to_buffer( buffer_stack[buffer_stack_ptr] );
408 yylineno = yylineno_stack[buffer_stack_ptr];
409
410 temp_yyfile_name = yyfile_name;
411 yyfile_name = temp_yyfile_name->next;
412 free( temp_yyfile_name );
413 }
414 }
415
416 %%
417
418 void check_def_buff( char* defined, int index ){
419
420 if( index >= DEFINED_BUFFER_SIZE ){
421
422 sprintf( painCave.errMsg, "Define buffer size exceeded for %s\n", defined );
423 painCave.isFatal = 1;
424 simError();
425 }
426 }
427
428 int yywrap(void){
429 return 1;
430 }
431
432 void change_in_file( FILE* in_file ){
433
434 yyin = in_file;
435 }