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