ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/BASS_parse/BASS.l
Revision: 118
Committed: Wed Sep 25 22:51:14 2002 UTC (21 years, 9 months ago) by chuckv
File size: 9160 byte(s)
Log Message:
begin the pain that is MPI.

abandon all hope ye who check out this branch..

P.S. we've added consistent BASS error checking

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