ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/BASS_parse/BASS.l
Revision: 10
Committed: Tue Jul 9 18:40:59 2002 UTC (22 years ago) by mmeineke
Original Path: branches/mmeineke/mdtools/BASS_parse/BASS.l
File size: 9063 byte(s)
Log Message:
everything you need to make libmdtools

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