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