[DMUSIC]
[reactos.git] / reactos / dll / opengl / mesa / src / glsl / glcpp / glcpp-lex.l
1 %{
2 /*
3 * Copyright © 2010 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <ctype.h>
28
29 #include "glcpp.h"
30 #include "glcpp-parse.h"
31
32 /* Flex annoyingly generates some functions without making them
33 * static. Let's declare them here. */
34 int glcpp_get_column (yyscan_t yyscanner);
35 void glcpp_set_column (int column_no , yyscan_t yyscanner);
36
37 #ifdef _MSC_VER
38 #define YY_NO_UNISTD_H
39 #endif
40
41 #define YY_NO_INPUT
42
43 #define YY_USER_ACTION \
44 do { \
45 yylloc->first_column = yycolumn + 1; \
46 yylloc->first_line = yylineno; \
47 yycolumn += yyleng; \
48 } while(0);
49
50 #define YY_USER_INIT \
51 do { \
52 yylineno = 1; \
53 yycolumn = 1; \
54 yylloc->source = 0; \
55 } while(0)
56 %}
57
58 %option bison-bridge bison-locations reentrant noyywrap
59 %option extra-type="glcpp_parser_t *"
60 %option prefix="glcpp_"
61 %option stack
62 %option never-interactive
63
64 %x DONE COMMENT UNREACHABLE SKIP
65
66 SPACE [[:space:]]
67 NONSPACE [^[:space:]]
68 NEWLINE [\n]
69 HSPACE [ \t]
70 HASH ^{HSPACE}*#{HSPACE}*
71 IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
72 PUNCTUATION [][(){}.&*~!/%<>^|;,=+-]
73
74 /* The OTHER class is simply a catch-all for things that the CPP
75 parser just doesn't care about. Since flex regular expressions that
76 match longer strings take priority over those matching shorter
77 strings, we have to be careful to avoid OTHER matching and hiding
78 something that CPP does care about. So we simply exclude all
79 characters that appear in any other expressions. */
80
81 OTHER [^][_#[:space:]#a-zA-Z0-9(){}.&*~!/%<>^|;,=+-]
82
83 DIGITS [0-9][0-9]*
84 DECIMAL_INTEGER [1-9][0-9]*[uU]?
85 OCTAL_INTEGER 0[0-7]*[uU]?
86 HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
87
88 %%
89 /* Implicitly switch between SKIP and INITIAL (non-skipping);
90 * don't switch if some other state was explicitly set.
91 */
92 glcpp_parser_t *parser = yyextra;
93 if (YY_START == 0 || YY_START == SKIP) {
94 if (parser->lexing_if || parser->skip_stack == NULL || parser->skip_stack->type == SKIP_NO_SKIP) {
95 BEGIN 0;
96 } else {
97 BEGIN SKIP;
98 }
99 }
100
101 /* Single-line comments */
102 "//"[^\n]* {
103 }
104
105 /* Multi-line comments */
106 "/*" { yy_push_state(COMMENT, yyscanner); }
107 <COMMENT>[^*\n]*
108 <COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
109 <COMMENT>"*"+[^*/\n]*
110 <COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
111 <COMMENT>"*"+"/" {
112 yy_pop_state(yyscanner);
113 if (yyextra->space_tokens)
114 return SPACE;
115 }
116
117 {HASH}version {
118 yylval->str = ralloc_strdup (yyextra, yytext);
119 yyextra->space_tokens = 0;
120 return HASH_VERSION;
121 }
122
123 /* glcpp doesn't handle #extension, #version, or #pragma directives.
124 * Simply pass them through to the main compiler's lexer/parser. */
125 {HASH}(extension|pragma)[^\n]+ {
126 yylval->str = ralloc_strdup (yyextra, yytext);
127 yylineno++;
128 yycolumn = 0;
129 return OTHER;
130 }
131
132 {HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ {
133 /* Eat characters until the first digit is
134 * encountered
135 */
136 char *ptr = yytext;
137 while (!isdigit(*ptr))
138 ptr++;
139
140 /* Subtract one from the line number because
141 * yylineno is zero-based instead of
142 * one-based.
143 */
144 yylineno = strtol(ptr, &ptr, 0) - 1;
145 yylloc->source = strtol(ptr, NULL, 0);
146 }
147
148 {HASH}line{HSPACE}+{DIGITS}{HSPACE}*$ {
149 /* Eat characters until the first digit is
150 * encountered
151 */
152 char *ptr = yytext;
153 while (!isdigit(*ptr))
154 ptr++;
155
156 /* Subtract one from the line number because
157 * yylineno is zero-based instead of
158 * one-based.
159 */
160 yylineno = strtol(ptr, &ptr, 0) - 1;
161 }
162
163 <SKIP,INITIAL>{
164 {HASH}ifdef {
165 yyextra->lexing_if = 1;
166 yyextra->space_tokens = 0;
167 return HASH_IFDEF;
168 }
169
170 {HASH}ifndef {
171 yyextra->lexing_if = 1;
172 yyextra->space_tokens = 0;
173 return HASH_IFNDEF;
174 }
175
176 {HASH}if/[^_a-zA-Z0-9] {
177 yyextra->lexing_if = 1;
178 yyextra->space_tokens = 0;
179 return HASH_IF;
180 }
181
182 {HASH}elif {
183 yyextra->lexing_if = 1;
184 yyextra->space_tokens = 0;
185 return HASH_ELIF;
186 }
187
188 {HASH}else {
189 yyextra->space_tokens = 0;
190 return HASH_ELSE;
191 }
192
193 {HASH}endif {
194 yyextra->space_tokens = 0;
195 return HASH_ENDIF;
196 }
197 }
198
199 <SKIP>[^\n] ;
200
201 {HASH}error.* {
202 char *p;
203 for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */
204 p += 5; /* skip "error" */
205 glcpp_error(yylloc, yyextra, "#error%s", p);
206 }
207
208 {HASH}define{HSPACE}+/{IDENTIFIER}"(" {
209 yyextra->space_tokens = 0;
210 return HASH_DEFINE_FUNC;
211 }
212
213 {HASH}define {
214 yyextra->space_tokens = 0;
215 return HASH_DEFINE_OBJ;
216 }
217
218 {HASH}undef {
219 yyextra->space_tokens = 0;
220 return HASH_UNDEF;
221 }
222
223 {HASH} {
224 yyextra->space_tokens = 0;
225 return HASH;
226 }
227
228 {DECIMAL_INTEGER} {
229 yylval->str = ralloc_strdup (yyextra, yytext);
230 return INTEGER_STRING;
231 }
232
233 {OCTAL_INTEGER} {
234 yylval->str = ralloc_strdup (yyextra, yytext);
235 return INTEGER_STRING;
236 }
237
238 {HEXADECIMAL_INTEGER} {
239 yylval->str = ralloc_strdup (yyextra, yytext);
240 return INTEGER_STRING;
241 }
242
243 "<<" {
244 return LEFT_SHIFT;
245 }
246
247 ">>" {
248 return RIGHT_SHIFT;
249 }
250
251 "<=" {
252 return LESS_OR_EQUAL;
253 }
254
255 ">=" {
256 return GREATER_OR_EQUAL;
257 }
258
259 "==" {
260 return EQUAL;
261 }
262
263 "!=" {
264 return NOT_EQUAL;
265 }
266
267 "&&" {
268 return AND;
269 }
270
271 "||" {
272 return OR;
273 }
274
275 "##" {
276 return PASTE;
277 }
278
279 "defined" {
280 return DEFINED;
281 }
282
283 {IDENTIFIER} {
284 yylval->str = ralloc_strdup (yyextra, yytext);
285 return IDENTIFIER;
286 }
287
288 {PUNCTUATION} {
289 return yytext[0];
290 }
291
292 {OTHER}+ {
293 yylval->str = ralloc_strdup (yyextra, yytext);
294 return OTHER;
295 }
296
297 {HSPACE}+ {
298 if (yyextra->space_tokens) {
299 return SPACE;
300 }
301 }
302
303 <SKIP,INITIAL>\n {
304 yyextra->lexing_if = 0;
305 yylineno++;
306 yycolumn = 0;
307 return NEWLINE;
308 }
309
310 /* Handle missing newline at EOF. */
311 <INITIAL><<EOF>> {
312 BEGIN DONE; /* Don't keep matching this rule forever. */
313 yyextra->lexing_if = 0;
314 return NEWLINE;
315 }
316
317 /* We don't actually use the UNREACHABLE start condition. We
318 only have this action here so that we can pretend to call some
319 generated functions, (to avoid "defined but not used"
320 warnings. */
321 <UNREACHABLE>. {
322 unput('.');
323 yy_top_state(yyextra);
324 }
325
326 %%
327
328 void
329 glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
330 {
331 yy_scan_string(shader, parser->scanner);
332 }