]> git.mxchange.org Git - flightgear.git/blob - Scenery/scanner.l
Initial revision.
[flightgear.git] / Scenery / scanner.l
1 /**************************************************************************
2  * scenery.l -- Lexical Analyzer for scenery files
3  *
4  * Written by Curtis Olson, started May 1997.
5  *
6  * NOTE: Compiles with flex and gcc.
7  *
8  * $Id$
9  * (Log is kept at end of this file)
10  **************************************************************************/
11
12
13 /* C Pass Through */
14 %{
15     #include <stdio.h>
16     #include "parser.h"
17
18     int line_num = 1;
19     char c;
20
21     /* custom print routine */
22     static int scanner_debug = 0;
23     static int scanner_msg_len;
24     static char scanner_msg[1024];
25
26     static void scanner_print(char *s) {
27         if ( scanner_debug ) {
28             printf("%s", s);
29         }
30     }
31
32     /* Routines to manage a stack of nested input buffers (for
33        processing the #include directive */
34     #define MAX_INCLUDE_DEPTH 10
35     static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
36     static int include_stack_ptr = 0;
37
38     int push_input_stream ( char *input ) { 
39         FILE *yyin_save;
40         if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) {
41             fprintf( stderr, "Scanner says:  Includes nested too deeply\n" );
42             return(0);
43         }
44
45         /* save yyin in case the following fails */
46         yyin_save = yyin;
47
48         yyin = fopen( input, "r" );
49         if ( ! yyin ) {
50             fprintf( stderr, "Scanner says:  cannot open '%s'\n", input );
51
52             /* The failed attempt destroyed yyin, so restore it */
53             yyin = yyin_save;
54
55             return(0);
56         }
57  
58         include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
59         yy_switch_to_buffer( yy_create_buffer(yyin, YY_BUF_SIZE) );
60
61         return(1);
62     }
63
64     int pop_input_stream () { 
65         if ( --include_stack_ptr < 1 ) {
66             /* end of last input stream */
67             return(0);
68         } else {
69             /* end of current input stream, restore previous and continue */
70             yy_delete_buffer( YY_CURRENT_BUFFER );
71             yy_switch_to_buffer( include_stack[include_stack_ptr] );
72             return(1);
73         }
74     }
75 %}
76
77
78 /* Definitions */
79 letter          [A-Za-z]
80 digit           [0-9]
81 connecter       [_-]
82 ident           {letter}({letter}|{digit}|{connecter})*
83
84 integer         [+-]?{digit}+
85
86 plain_real      {integer}"."{integer}
87 short_exp_real  {integer}[Ee][+-]?{integer}
88 exp_real        {plain_real}[Ee][+-]?{integer}
89 real            [+-]?{plain_real}|{short_exp_real}|{exp_real}
90
91 number          {real}|{integer}
92
93 string          \"[^"\n]+\"
94
95 bad_string      \"([^"\n]|\n)+\"
96
97 ws              [ \t]+
98 other           .
99
100
101 /* Rules */ 
102 %%
103
104 include         { scanner_print("return IncludeSym\n");
105                   return IncludeSym;
106                 }
107
108 mesh            { scanner_print("return MeshSym\n");
109                   return MeshSym;
110                 }
111
112 row             { scanner_print("return RowSym\n");
113                   return RowSym;
114                 }
115
116 chunk           { scanner_print("return ChunkSym\n");
117                   return ChunkSym;
118                 }
119
120 bounds          { scanner_print("return BoundsSym\n");
121                   return BoundsSym;
122                 }
123
124 place           { scanner_print("return PlaceSym\n");
125                   return PlaceSym;
126                 }
127
128 {ident}         { scanner_msg_len = snprintf(scanner_msg, 1024, 
129                            "return Identifier = %s\n", yytext);
130                   scanner_msg[scanner_msg_len] = '\0';
131                   scanner_print(scanner_msg);
132                   return Identifier;
133                 }
134
135 {number}        { scanner_print("return Number\n");
136                   return Number;
137                 }
138
139 {string}        { scanner_msg_len = snprintf(scanner_msg, 1024,
140                            "return StringLiteral = %s\n", yytext);
141                   scanner_msg[scanner_msg_len] = '\0';
142                   scanner_print(scanner_msg);
143                   return StringLiteral;
144                 }
145
146 {bad_string}    { scanner_msg_len = snprintf(scanner_msg, 1024,
147                            "return BadStringLiteral = %s\n", yytext);
148                   scanner_msg[scanner_msg_len] = '\0';
149                   scanner_print(scanner_msg);
150                   return BadStringLiteral; 
151                 }
152
153 "\n"            { line_num++; 
154                   scanner_msg_len = snprintf(scanner_msg, 1024,
155                            "Line number = %d\n", line_num);
156                   scanner_msg[scanner_msg_len] = '\0';
157                   scanner_print(scanner_msg);
158                 }
159
160 "#"             { scanner_print("return HashSym\n");
161                   return HashSym; 
162                 }
163
164 "="             { scanner_print("return EqualSym\n");
165                   return EqualSym; 
166                 }
167
168 ","             { scanner_print("return CommaSym\n");
169                   return CommaSym; 
170                 }
171
172 "{"             { scanner_print("return LBraceSym\n");
173                   return LBraceSym; 
174                 }
175
176 "}"             { scanner_print("return RBraceSym\n");
177                   return RBraceSym;
178                 }
179
180 "("             { scanner_print("return LParenSym\n");
181                   return LParenSym; 
182                 }
183
184 ")"             { scanner_print("return RParenSym\n");
185                   return RParenSym;
186                 }
187
188 "//"            { /* burn through "#" comment */ 
189                   c = input();
190                   while ( (c != '\n') ) {
191                       c = input();
192                       /* scanner_print("%c", c); */
193                   }
194                   unput(c);
195                   /* line_num++; */
196                 }
197
198 {ws}            { ; }
199
200 {other}         { scanner_msg_len = snprintf(scanner_msg, 1024,
201                            "Scanned some unexpected text = `%s'\n", yytext);
202                   scanner_msg[scanner_msg_len] = '\0';
203                   scanner_print(scanner_msg);
204                   return ErrorMisc; 
205                 }
206
207 <<EOF>>         { if ( pop_input_stream() == 0 ) {
208                       /* End of last input stream */
209                       yyterminate();
210                   }
211                 }