ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/BASS_parse/BASS.l
Revision: 157
Committed: Tue Oct 29 21:48:25 2002 UTC (21 years, 8 months ago) by mmeineke
File size: 9224 byte(s)
Log Message:
adding in simError

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