glsl: Refactor variable declaration handling.
[mesa.git] / src / glsl / glsl_lexer.lpp
1 %{
2 /*
3 * Copyright © 2008, 2009 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 #include <ctype.h>
25 #include "ast.h"
26 #include "glsl_parser_extras.h"
27 #include "glsl_parser.h"
28
29 #define YY_USER_ACTION \
30 do { \
31 yylloc->source = 0; \
32 yylloc->first_column = yycolumn + 1; \
33 yylloc->first_line = yylineno + 1; \
34 yycolumn += yyleng; \
35 } while(0);
36
37 #define YY_USER_INIT yylineno = 0; yycolumn = 0;
38
39 #define TOKEN_OR_IDENTIFIER(version, token) \
40 do { \
41 if (yyextra->language_version >= version) { \
42 return token; \
43 } else { \
44 yylval->identifier = strdup(yytext); \
45 return IDENTIFIER; \
46 } \
47 } while (0)
48
49 #define RESERVED_WORD(version, token) \
50 do { \
51 if (yyextra->language_version >= version) { \
52 return token; \
53 } else { \
54 _mesa_glsl_error(yylloc, yyextra, \
55 "Illegal use of reserved word `%s'", yytext); \
56 return ERROR_TOK; \
57 } \
58 } while (0)
59 %}
60
61 %option bison-bridge bison-locations reentrant noyywrap
62 %option nounput noyy_top_state
63 %option never-interactive
64 %option prefix="_mesa_glsl_"
65 %option extra-type="struct _mesa_glsl_parse_state *"
66
67 %x PP
68
69 DEC_INT [1-9][0-9]*
70 HEX_INT 0[xX][0-9a-fA-F]+
71 OCT_INT 0[0-7]*
72 INT ({DEC_INT}|{HEX_INT}|{OCT_INT})
73 SPC [ \t]*
74 SPCP [ \t]+
75 HASH ^{SPC}#{SPC}
76 %%
77
78 [ \r\t]+ ;
79
80 /* Preprocessor tokens. */
81 ^[ \t]*#[ \t]*$ ;
82 ^[ \t]*#[ \t]*version { BEGIN PP; return VERSION; }
83 ^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; }
84 {HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ {
85 /* Eat characters until the first digit is
86 * encountered
87 */
88 char *ptr = yytext;
89 while (!isdigit(*ptr))
90 ptr++;
91
92 /* Subtract one from the line number because
93 * yylineno is zero-based instead of
94 * one-based.
95 */
96 yylineno = strtol(ptr, &ptr, 0) - 1;
97 yylloc->source = strtol(ptr, NULL, 0);
98 }
99 {HASH}line{SPCP}{INT}{SPC}$ {
100 /* Eat characters until the first digit is
101 * encountered
102 */
103 char *ptr = yytext;
104 while (!isdigit(*ptr))
105 ptr++;
106
107 /* Subtract one from the line number because
108 * yylineno is zero-based instead of
109 * one-based.
110 */
111 yylineno = strtol(ptr, &ptr, 0) - 1;
112 }
113 ^[ \t]*#[ \t]*pragma { BEGIN PP; return PRAGMA; }
114 <PP>\/\/[^\n]* { }
115 <PP>[ \t\r]* { }
116 <PP>: return COLON;
117 <PP>[_a-zA-Z][_a-zA-Z0-9]* {
118 yylval->identifier = strdup(yytext);
119 return IDENTIFIER;
120 }
121 <PP>[1-9][0-9]* {
122 yylval->n = strtol(yytext, NULL, 10);
123 return INTCONSTANT;
124 }
125 <PP>\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; }
126
127 \n { yylineno++; yycolumn = 0; }
128
129 attribute return ATTRIBUTE;
130 const return CONST_TOK;
131 bool return BOOL_TOK;
132 float return FLOAT_TOK;
133 int return INT_TOK;
134
135 break return BREAK;
136 continue return CONTINUE;
137 do return DO;
138 while return WHILE;
139 else return ELSE;
140 for return FOR;
141 if return IF;
142 discard return DISCARD;
143 return return RETURN;
144
145 bvec2 return BVEC2;
146 bvec3 return BVEC3;
147 bvec4 return BVEC4;
148 ivec2 return IVEC2;
149 ivec3 return IVEC3;
150 ivec4 return IVEC4;
151 vec2 return VEC2;
152 vec3 return VEC3;
153 vec4 return VEC4;
154 mat2 return MAT2X2;
155 mat3 return MAT3X3;
156 mat4 return MAT4X4;
157 mat2x2 TOKEN_OR_IDENTIFIER(120, MAT2X2);
158 mat2x3 TOKEN_OR_IDENTIFIER(120, MAT2X3);
159 mat2x4 TOKEN_OR_IDENTIFIER(120, MAT2X4);
160 mat3x2 TOKEN_OR_IDENTIFIER(120, MAT3X2);
161 mat3x3 TOKEN_OR_IDENTIFIER(120, MAT3X3);
162 mat3x4 TOKEN_OR_IDENTIFIER(120, MAT3X4);
163 mat4x2 TOKEN_OR_IDENTIFIER(120, MAT4X2);
164 mat4x3 TOKEN_OR_IDENTIFIER(120, MAT4X3);
165 mat4x4 TOKEN_OR_IDENTIFIER(120, MAT4X4);
166
167 in return IN_TOK;
168 out return OUT_TOK;
169 inout return INOUT_TOK;
170 uniform return UNIFORM;
171 varying return VARYING;
172 centroid TOKEN_OR_IDENTIFIER(120, CENTROID);
173 invariant TOKEN_OR_IDENTIFIER(120, INVARIANT);
174
175 flat TOKEN_OR_IDENTIFIER(130, FLAT);
176 smooth TOKEN_OR_IDENTIFIER(130, SMOOTH);
177 noperspective TOKEN_OR_IDENTIFIER(130, NOPERSPECTIVE);
178
179 sampler1D return SAMPLER1D;
180 sampler2D return SAMPLER2D;
181 sampler3D return SAMPLER3D;
182 samplerCube return SAMPLERCUBE;
183 sampler1DShadow return SAMPLER1DSHADOW;
184 sampler2DShadow return SAMPLER2DSHADOW;
185
186 struct return STRUCT;
187 void return VOID_TOK;
188
189 layout {
190 if ((yyextra->language_version >= 140)
191 || (yyextra->ARB_fragment_coord_conventions_enable)){
192 return LAYOUT_TOK;
193 } else {
194 yylval->identifier = strdup(yytext);
195 return IDENTIFIER;
196 }
197 }
198
199 \+\+ return INC_OP;
200 -- return DEC_OP;
201 \<= return LE_OP;
202 >= return GE_OP;
203 == return EQ_OP;
204 != return NE_OP;
205 && return AND_OP;
206 \|\| return OR_OP;
207 "^^" return XOR_OP;
208
209 \*= return MUL_ASSIGN;
210 \/= return DIV_ASSIGN;
211 \+= return ADD_ASSIGN;
212 \%= return MOD_ASSIGN;
213 \<\<= return LEFT_ASSIGN;
214 >>= return RIGHT_ASSIGN;
215 &= return AND_ASSIGN;
216 ^= return XOR_ASSIGN;
217 \|= return OR_ASSIGN;
218 -= return SUB_ASSIGN;
219
220 [1-9][0-9]* {
221 yylval->n = strtol(yytext, NULL, 10);
222 return INTCONSTANT;
223 }
224 0[xX][0-9a-fA-F]+ {
225 yylval->n = strtol(yytext + 2, NULL, 16);
226 return INTCONSTANT;
227 }
228 0[0-7]* {
229 yylval->n = strtol(yytext, NULL, 8);
230 return INTCONSTANT;
231 }
232
233 [0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
234 yylval->real = strtod(yytext, NULL);
235 return FLOATCONSTANT;
236 }
237 \.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
238 yylval->real = strtod(yytext, NULL);
239 return FLOATCONSTANT;
240 }
241 [0-9]+\.([eE][+-]?[0-9]+)?[fF]? {
242 yylval->real = strtod(yytext, NULL);
243 return FLOATCONSTANT;
244 }
245 [0-9]+[eE][+-]?[0-9]+[fF]? {
246 yylval->real = strtod(yytext, NULL);
247 return FLOATCONSTANT;
248 }
249 [0-9]+[fF] {
250 yylval->real = strtod(yytext, NULL);
251 return FLOATCONSTANT;
252 }
253
254 true {
255 yylval->n = 1;
256 return BOOLCONSTANT;
257 }
258 false {
259 yylval->n = 0;
260 return BOOLCONSTANT;
261 }
262
263
264 /* Reserved words in GLSL 1.10. */
265 asm RESERVED_WORD(999, ASM);
266 class RESERVED_WORD(999, CLASS);
267 union RESERVED_WORD(999, UNION);
268 enum RESERVED_WORD(999, ENUM);
269 typedef RESERVED_WORD(999, TYPEDEF);
270 template RESERVED_WORD(999, TEMPLATE);
271 this RESERVED_WORD(999, THIS);
272 packed RESERVED_WORD(999, PACKED_TOK);
273 goto RESERVED_WORD(999, GOTO);
274 switch RESERVED_WORD(130, SWITCH);
275 default RESERVED_WORD(130, DEFAULT);
276 inline RESERVED_WORD(999, INLINE_TOK);
277 noinline RESERVED_WORD(999, NOINLINE);
278 volatile RESERVED_WORD(999, VOLATILE);
279 public RESERVED_WORD(999, PUBLIC_TOK);
280 static RESERVED_WORD(999, STATIC);
281 extern RESERVED_WORD(999, EXTERN);
282 external RESERVED_WORD(999, EXTERNAL);
283 interface RESERVED_WORD(999, INTERFACE);
284 long RESERVED_WORD(999, LONG_TOK);
285 short RESERVED_WORD(999, SHORT_TOK);
286 double RESERVED_WORD(999, DOUBLE_TOK);
287 half RESERVED_WORD(999, HALF);
288 fixed RESERVED_WORD(999, FIXED_TOK);
289 unsigned RESERVED_WORD(999, UNSIGNED);
290 input RESERVED_WORD(999, INPUT_TOK);
291 output RESERVED_WORD(999, OUTPUT);
292 hvec2 RESERVED_WORD(999, HVEC2);
293 hvec3 RESERVED_WORD(999, HVEC3);
294 hvec4 RESERVED_WORD(999, HVEC4);
295 dvec2 RESERVED_WORD(999, DVEC2);
296 dvec3 RESERVED_WORD(999, DVEC3);
297 dvec4 RESERVED_WORD(999, DVEC4);
298 fvec2 RESERVED_WORD(999, FVEC2);
299 fvec3 RESERVED_WORD(999, FVEC3);
300 fvec4 RESERVED_WORD(999, FVEC4);
301 sampler2DRect return SAMPLER2DRECT;
302 sampler3DRect RESERVED_WORD(999, SAMPLER3DRECT);
303 sampler2DRectShadow return SAMPLER2DRECTSHADOW;
304 sizeof RESERVED_WORD(999, SIZEOF);
305 cast RESERVED_WORD(999, CAST);
306 namespace RESERVED_WORD(999, NAMESPACE);
307 using RESERVED_WORD(999, USING);
308
309 /* Additional reserved words in GLSL 1.20. */
310 lowp TOKEN_OR_IDENTIFIER(120, LOWP);
311 mediump TOKEN_OR_IDENTIFIER(120, MEDIUMP);
312 highp TOKEN_OR_IDENTIFIER(120, HIGHP);
313 precision TOKEN_OR_IDENTIFIER(120, PRECISION);
314
315 /* Additional reserved words in GLSL 1.30. */
316 common TOKEN_OR_IDENTIFIER(130, COMMON);
317 partition TOKEN_OR_IDENTIFIER(130, PARTITION);
318 active TOKEN_OR_IDENTIFIER(130, ACTIVE);
319 superp TOKEN_OR_IDENTIFIER(130, SUPERP);
320 samplerBuffer TOKEN_OR_IDENTIFIER(130, SAMPLERBUFFER);
321 filter TOKEN_OR_IDENTIFIER(130, FILTER);
322 image1D TOKEN_OR_IDENTIFIER(130, IMAGE1D);
323 image2D TOKEN_OR_IDENTIFIER(130, IMAGE2D);
324 image3D TOKEN_OR_IDENTIFIER(130, IMAGE3D);
325 imageCube TOKEN_OR_IDENTIFIER(130, IMAGECUBE);
326 iimage1D TOKEN_OR_IDENTIFIER(130, IIMAGE1D);
327 iimage2D TOKEN_OR_IDENTIFIER(130, IIMAGE2D);
328 iimage3D TOKEN_OR_IDENTIFIER(130, IIMAGE3D);
329 iimageCube TOKEN_OR_IDENTIFIER(130, IIMAGECUBE);
330 uimage1D TOKEN_OR_IDENTIFIER(130, UIMAGE1D);
331 uimage2D TOKEN_OR_IDENTIFIER(130, UIMAGE2D);
332 uimage3D TOKEN_OR_IDENTIFIER(130, UIMAGE3D);
333 uimageCube TOKEN_OR_IDENTIFIER(130, UIMAGECUBE);
334 image1DArray TOKEN_OR_IDENTIFIER(130, IMAGE1DARRAY);
335 image2DArray TOKEN_OR_IDENTIFIER(130, IMAGE2DARRAY);
336 iimage1DArray TOKEN_OR_IDENTIFIER(130, IIMAGE1DARRAY);
337 iimage2DArray TOKEN_OR_IDENTIFIER(130, IIMAGE2DARRAY);
338 uimage1DArray TOKEN_OR_IDENTIFIER(130, UIMAGE1DARRAY);
339 uimage2DArray TOKEN_OR_IDENTIFIER(130, UIMAGE2DARRAY);
340 image1DShadow TOKEN_OR_IDENTIFIER(130, IMAGE1DSHADOW);
341 image2DShadow TOKEN_OR_IDENTIFIER(130, IMAGE2DSHADOW);
342 imageBuffer TOKEN_OR_IDENTIFIER(130, IMAGEBUFFER);
343 iimageBuffer TOKEN_OR_IDENTIFIER(130, IIMAGEBUFFER);
344 uimageBuffer TOKEN_OR_IDENTIFIER(130, UIMAGEBUFFER);
345 row_major TOKEN_OR_IDENTIFIER(130, ROW_MAJOR);
346
347 [_a-zA-Z][_a-zA-Z0-9]* {
348 struct _mesa_glsl_parse_state *state = yyextra;
349 void *ctx = state;
350 yylval->identifier = talloc_strdup(ctx, yytext);
351 return IDENTIFIER;
352 }
353
354 . { return yytext[0]; }
355
356 %%
357
358 void
359 _mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string)
360 {
361 yylex_init_extra(state, & state->scanner);
362 yy_scan_string(string, state->scanner);
363 }
364
365 void
366 _mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state)
367 {
368 yylex_destroy(state->scanner);
369 }