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