1 /**************************************************************************
2 * scenery.l -- Lexical Analyzer for scenery files
4 * Written by Curtis Olson, started May 1997.
6 * NOTE: Compiles with flex and gcc.
9 * (Log is kept at end of this file)
10 **************************************************************************/
21 /* custom print routine */
22 static int scanner_debug = 0;
23 static int scanner_msg_len;
24 static char scanner_msg[1024];
26 static void scanner_print(char *s) {
27 if ( scanner_debug ) {
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;
38 int push_input_stream ( char *input ) {
40 if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) {
41 fprintf( stderr, "Scanner says: Includes nested too deeply\n" );
45 /* save yyin in case the following fails */
48 yyin = fopen( input, "r" );
50 fprintf( stderr, "Scanner says: cannot open '%s'\n", input );
52 /* The failed attempt destroyed yyin, so restore it */
58 include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
59 yy_switch_to_buffer( yy_create_buffer(yyin, YY_BUF_SIZE) );
64 int pop_input_stream () {
65 if ( --include_stack_ptr < 1 ) {
66 /* end of last input stream */
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] );
82 ident {letter}({letter}|{digit}|{connecter})*
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}
91 number {real}|{integer}
95 bad_string \"([^"\n]|\n)+\"
104 include { scanner_print("return IncludeSym\n");
108 mesh { scanner_print("return MeshSym\n");
112 row { scanner_print("return RowSym\n");
116 chunk { scanner_print("return ChunkSym\n");
120 bounds { scanner_print("return BoundsSym\n");
124 place { scanner_print("return PlaceSym\n");
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);
135 {number} { scanner_print("return Number\n");
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;
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;
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);
160 "#" { scanner_print("return HashSym\n");
164 "=" { scanner_print("return EqualSym\n");
168 "," { scanner_print("return CommaSym\n");
172 "{" { scanner_print("return LBraceSym\n");
176 "}" { scanner_print("return RBraceSym\n");
180 "(" { scanner_print("return LParenSym\n");
184 ")" { scanner_print("return RParenSym\n");
188 "//" { /* burn through "#" comment */
190 while ( (c != '\n') ) {
192 /* scanner_print("%c", c); */
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);
207 <<EOF>> { if ( pop_input_stream() == 0 ) {
208 /* End of last input stream */