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 <limits.h>
26#include "strtod.h"
27#include "ast.h"
28#include "glsl_parser_extras.h"
29#include "glsl_parser.h"
30
31static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
32
33#ifdef _MSC_VER
34#define YY_NO_UNISTD_H
35#endif
36
37#define YY_USER_ACTION						\
38   do {								\
39      yylloc->source = 0;					\
40      yylloc->first_column = yycolumn + 1;			\
41      yylloc->first_line = yylineno + 1;			\
42      yycolumn += yyleng;					\
43   } while(0);
44
45#define YY_USER_INIT yylineno = 0; yycolumn = 0;
46
47/* A macro for handling reserved words and keywords across language versions.
48 *
49 * Certain words start out as identifiers, become reserved words in
50 * later language revisions, and finally become language keywords.
51 *
52 * For example, consider the following lexer rule:
53 * samplerBuffer       KEYWORD(130, 140, SAMPLERBUFFER)
54 *
55 * This means that "samplerBuffer" will be treated as:
56 * - a keyword (SAMPLERBUFFER token)         ...in GLSL >= 1.40
57 * - a reserved word - error                 ...in GLSL >= 1.30
58 * - an identifier                           ...in GLSL <  1.30
59 */
60#define KEYWORD(reserved_version, allowed_version, token)		\
61   do {									\
62      if (yyextra->language_version >= allowed_version) {		\
63	 return token;							\
64      } else if (yyextra->language_version >= reserved_version) {	\
65	 _mesa_glsl_error(yylloc, yyextra,				\
66			  "Illegal use of reserved word `%s'", yytext);	\
67	 return ERROR_TOK;						\
68      } else {								\
69	 yylval->identifier = strdup(yytext);				\
70	 return classify_identifier(yyextra, yytext);			\
71      }									\
72   } while (0)
73
74/* The ES macro can be used in KEYWORD checks:
75 *
76 *    word      KEYWORD(110 || ES, 400, TOKEN)
77 * ...means the word is reserved in GLSL ES 1.00, while
78 *
79 *    word      KEYWORD(110, 130 || ES, TOKEN)
80 * ...means the word is a legal keyword in GLSL ES 1.00.
81 */
82#define ES yyextra->es_shader
83
84static int
85literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state,
86		YYSTYPE *lval, YYLTYPE *lloc, int base)
87{
88   bool is_uint = (text[len - 1] == 'u' ||
89		   text[len - 1] == 'U');
90   const char *digits = text;
91
92   /* Skip "0x" */
93   if (base == 16)
94      digits += 2;
95
96#ifdef _MSC_VER
97   unsigned __int64 value = _strtoui64(digits, NULL, base);
98#else
99   unsigned long long value = strtoull(digits, NULL, base);
100#endif
101
102   lval->n = (int)value;
103
104   if (value > UINT_MAX) {
105      /* Note that signed 0xffffffff is valid, not out of range! */
106      if (state->language_version >= 130) {
107	 _mesa_glsl_error(lloc, state,
108			  "Literal value `%s' out of range", text);
109      } else {
110	 _mesa_glsl_warning(lloc, state,
111			    "Literal value `%s' out of range", text);
112      }
113   } else if (base == 10 && !is_uint && (unsigned)value > (unsigned)INT_MAX + 1) {
114      /* Tries to catch unintentionally providing a negative value.
115       * Note that -2147483648 is parsed as -(2147483648), so we don't
116       * want to warn for INT_MAX.
117       */
118      _mesa_glsl_warning(lloc, state,
119			 "Signed literal value `%s' is interpreted as %d",
120			 text, lval->n);
121   }
122   return is_uint ? UINTCONSTANT : INTCONSTANT;
123}
124
125#define LITERAL_INTEGER(base) \
126   literal_integer(yytext, yyleng, yyextra, yylval, yylloc, base)
127
128%}
129
130%option bison-bridge bison-locations reentrant noyywrap
131%option nounput noyy_top_state
132%option never-interactive
133%option prefix="_mesa_glsl_"
134%option extra-type="struct _mesa_glsl_parse_state *"
135
136%x PP PRAGMA
137
138DEC_INT		[1-9][0-9]*
139HEX_INT		0[xX][0-9a-fA-F]+
140OCT_INT		0[0-7]*
141INT		({DEC_INT}|{HEX_INT}|{OCT_INT})
142SPC		[ \t]*
143SPCP		[ \t]+
144HASH		^{SPC}#{SPC}
145%%
146
147[ \r\t]+		;
148
149    /* Preprocessor tokens. */
150^[ \t]*#[ \t]*$			;
151^[ \t]*#[ \t]*version		{ BEGIN PP; return VERSION_TOK; }
152^[ \t]*#[ \t]*extension		{ BEGIN PP; return EXTENSION; }
153{HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ {
154				   /* Eat characters until the first digit is
155				    * encountered
156				    */
157				   char *ptr = yytext;
158				   while (!isdigit(*ptr))
159				      ptr++;
160
161				   /* Subtract one from the line number because
162				    * yylineno is zero-based instead of
163				    * one-based.
164				    */
165				   yylineno = strtol(ptr, &ptr, 0) - 1;
166				   yylloc->source = strtol(ptr, NULL, 0);
167				}
168{HASH}line{SPCP}{INT}{SPC}$	{
169				   /* Eat characters until the first digit is
170				    * encountered
171				    */
172				   char *ptr = yytext;
173				   while (!isdigit(*ptr))
174				      ptr++;
175
176				   /* Subtract one from the line number because
177				    * yylineno is zero-based instead of
178				    * one-based.
179				    */
180				   yylineno = strtol(ptr, &ptr, 0) - 1;
181				}
182^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}on{SPC}\) {
183				  BEGIN PP;
184				  return PRAGMA_DEBUG_ON;
185				}
186^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}off{SPC}\) {
187				  BEGIN PP;
188				  return PRAGMA_DEBUG_OFF;
189				}
190^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}on{SPC}\) {
191				  BEGIN PP;
192				  return PRAGMA_OPTIMIZE_ON;
193				}
194^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}off{SPC}\) {
195				  BEGIN PP;
196				  return PRAGMA_OPTIMIZE_OFF;
197				}
198^{SPC}#{SPC}pragma{SPCP}STDGL{SPCP}invariant{SPC}\({SPC}all{SPC}\) {
199				  BEGIN PP;
200				  return PRAGMA_INVARIANT_ALL;
201				}
202^{SPC}#{SPC}pragma{SPCP}	{ BEGIN PRAGMA; }
203
204<PRAGMA>\n			{ BEGIN 0; yylineno++; yycolumn = 0; }
205<PRAGMA>.			{ }
206
207<PP>\/\/[^\n]*			{ }
208<PP>[ \t\r]*			{ }
209<PP>:				return COLON;
210<PP>[_a-zA-Z][_a-zA-Z0-9]*	{
211				   yylval->identifier = strdup(yytext);
212				   return IDENTIFIER;
213				}
214<PP>[1-9][0-9]*			{
215				    yylval->n = strtol(yytext, NULL, 10);
216				    return INTCONSTANT;
217				}
218<PP>\n				{ BEGIN 0; yylineno++; yycolumn = 0; return EOL; }
219
220\n		{ yylineno++; yycolumn = 0; }
221
222attribute	return ATTRIBUTE;
223const		return CONST_TOK;
224bool		return BOOL_TOK;
225float		return FLOAT_TOK;
226int		return INT_TOK;
227uint		KEYWORD(130, 130, UINT_TOK);
228
229break		return BREAK;
230continue	return CONTINUE;
231do		return DO;
232while		return WHILE;
233else		return ELSE;
234for		return FOR;
235if		return IF;
236discard		return DISCARD;
237return		return RETURN;
238
239bvec2		return BVEC2;
240bvec3		return BVEC3;
241bvec4		return BVEC4;
242ivec2		return IVEC2;
243ivec3		return IVEC3;
244ivec4		return IVEC4;
245uvec2		KEYWORD(130, 130, UVEC2);
246uvec3		KEYWORD(130, 130, UVEC3);
247uvec4		KEYWORD(130, 130, UVEC4);
248vec2		return VEC2;
249vec3		return VEC3;
250vec4		return VEC4;
251mat2		return MAT2X2;
252mat3		return MAT3X3;
253mat4		return MAT4X4;
254mat2x2		KEYWORD(120, 120, MAT2X2);
255mat2x3		KEYWORD(120, 120, MAT2X3);
256mat2x4		KEYWORD(120, 120, MAT2X4);
257mat3x2		KEYWORD(120, 120, MAT3X2);
258mat3x3		KEYWORD(120, 120, MAT3X3);
259mat3x4		KEYWORD(120, 120, MAT3X4);
260mat4x2		KEYWORD(120, 120, MAT4X2);
261mat4x3		KEYWORD(120, 120, MAT4X3);
262mat4x4		KEYWORD(120, 120, MAT4X4);
263
264in		return IN_TOK;
265out		return OUT_TOK;
266inout		return INOUT_TOK;
267uniform		return UNIFORM;
268varying		return VARYING;
269centroid	KEYWORD(120, 120, CENTROID);
270invariant	KEYWORD(120 || ES, 120 || ES, INVARIANT);
271flat		KEYWORD(130 || ES, 130, FLAT);
272smooth		KEYWORD(130, 130, SMOOTH);
273noperspective	KEYWORD(130, 130, NOPERSPECTIVE);
274
275sampler1D	return SAMPLER1D;
276sampler2D	return SAMPLER2D;
277sampler3D	return SAMPLER3D;
278samplerCube	return SAMPLERCUBE;
279sampler1DArray	KEYWORD(130, 130, SAMPLER1DARRAY);
280sampler2DArray	KEYWORD(130, 130, SAMPLER2DARRAY);
281sampler1DShadow	return SAMPLER1DSHADOW;
282sampler2DShadow	return SAMPLER2DSHADOW;
283samplerCubeShadow	KEYWORD(130, 130, SAMPLERCUBESHADOW);
284sampler1DArrayShadow	KEYWORD(130, 130, SAMPLER1DARRAYSHADOW);
285sampler2DArrayShadow	KEYWORD(130, 130, SAMPLER2DARRAYSHADOW);
286isampler1D		KEYWORD(130, 130, ISAMPLER1D);
287isampler2D		KEYWORD(130, 130, ISAMPLER2D);
288isampler3D		KEYWORD(130, 130, ISAMPLER3D);
289isamplerCube		KEYWORD(130, 130, ISAMPLERCUBE);
290isampler1DArray		KEYWORD(130, 130, ISAMPLER1DARRAY);
291isampler2DArray		KEYWORD(130, 130, ISAMPLER2DARRAY);
292usampler1D		KEYWORD(130, 130, USAMPLER1D);
293usampler2D		KEYWORD(130, 130, USAMPLER2D);
294usampler3D		KEYWORD(130, 130, USAMPLER3D);
295usamplerCube		KEYWORD(130, 130, USAMPLERCUBE);
296usampler1DArray		KEYWORD(130, 130, USAMPLER1DARRAY);
297usampler2DArray		KEYWORD(130, 130, USAMPLER2DARRAY);
298
299samplerExternalOES	{
300			  if (yyextra->OES_EGL_image_external_enable)
301			     return SAMPLEREXTERNALOES;
302			  else
303			     return IDENTIFIER;
304			}
305
306
307struct		return STRUCT;
308void		return VOID_TOK;
309
310layout		{
311		  if ((yyextra->language_version >= 140)
312		      || yyextra->AMD_conservative_depth_enable
313		      || yyextra->ARB_conservative_depth_enable
314		      || yyextra->ARB_explicit_attrib_location_enable
315		      || yyextra->ARB_uniform_buffer_object_enable
316		      || yyextra->ARB_fragment_coord_conventions_enable) {
317		      return LAYOUT_TOK;
318		   } else {
319		      yylval->identifier = strdup(yytext);
320		      return IDENTIFIER;
321		   }
322		}
323
324\+\+		return INC_OP;
325--		return DEC_OP;
326\<=		return LE_OP;
327>=		return GE_OP;
328==		return EQ_OP;
329!=		return NE_OP;
330&&		return AND_OP;
331\|\|		return OR_OP;
332"^^"		return XOR_OP;
333"<<"		return LEFT_OP;
334">>"		return RIGHT_OP;
335
336\*=		return MUL_ASSIGN;
337\/=		return DIV_ASSIGN;
338\+=		return ADD_ASSIGN;
339\%=		return MOD_ASSIGN;
340\<\<=		return LEFT_ASSIGN;
341>>=		return RIGHT_ASSIGN;
342&=		return AND_ASSIGN;
343"^="		return XOR_ASSIGN;
344\|=		return OR_ASSIGN;
345-=		return SUB_ASSIGN;
346
347[1-9][0-9]*[uU]?	{
348			    return LITERAL_INTEGER(10);
349			}
3500[xX][0-9a-fA-F]+[uU]?	{
351			    return LITERAL_INTEGER(16);
352			}
3530[0-7]*[uU]?		{
354			    return LITERAL_INTEGER(8);
355			}
356
357[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]?	{
358			    yylval->real = glsl_strtod(yytext, NULL);
359			    return FLOATCONSTANT;
360			}
361\.[0-9]+([eE][+-]?[0-9]+)?[fF]?		{
362			    yylval->real = glsl_strtod(yytext, NULL);
363			    return FLOATCONSTANT;
364			}
365[0-9]+\.([eE][+-]?[0-9]+)?[fF]?		{
366			    yylval->real = glsl_strtod(yytext, NULL);
367			    return FLOATCONSTANT;
368			}
369[0-9]+[eE][+-]?[0-9]+[fF]?		{
370			    yylval->real = glsl_strtod(yytext, NULL);
371			    return FLOATCONSTANT;
372			}
373[0-9]+[fF]		{
374			    yylval->real = glsl_strtod(yytext, NULL);
375			    return FLOATCONSTANT;
376			}
377
378true			{
379			    yylval->n = 1;
380			    return BOOLCONSTANT;
381			}
382false			{
383			    yylval->n = 0;
384			    return BOOLCONSTANT;
385			}
386
387
388    /* Reserved words in GLSL 1.10. */
389asm		KEYWORD(110 || ES, 999, ASM);
390class		KEYWORD(110 || ES, 999, CLASS);
391union		KEYWORD(110 || ES, 999, UNION);
392enum		KEYWORD(110 || ES, 999, ENUM);
393typedef		KEYWORD(110 || ES, 999, TYPEDEF);
394template	KEYWORD(110 || ES, 999, TEMPLATE);
395this		KEYWORD(110 || ES, 999, THIS);
396packed		KEYWORD(110 || ES, 140 || yyextra->ARB_uniform_buffer_object_enable, PACKED_TOK);
397goto		KEYWORD(110 || ES, 999, GOTO);
398switch		KEYWORD(110 || ES, 130, SWITCH);
399default		KEYWORD(110 || ES, 130, DEFAULT);
400inline		KEYWORD(110 || ES, 999, INLINE_TOK);
401noinline	KEYWORD(110 || ES, 999, NOINLINE);
402volatile	KEYWORD(110 || ES, 999, VOLATILE);
403public		KEYWORD(110 || ES, 999, PUBLIC_TOK);
404static		KEYWORD(110 || ES, 999, STATIC);
405extern		KEYWORD(110 || ES, 999, EXTERN);
406external	KEYWORD(110 || ES, 999, EXTERNAL);
407interface	KEYWORD(110 || ES, 999, INTERFACE);
408long		KEYWORD(110 || ES, 999, LONG_TOK);
409short		KEYWORD(110 || ES, 999, SHORT_TOK);
410double		KEYWORD(110 || ES, 400, DOUBLE_TOK);
411half		KEYWORD(110 || ES, 999, HALF);
412fixed		KEYWORD(110 || ES, 999, FIXED_TOK);
413unsigned	KEYWORD(110 || ES, 999, UNSIGNED);
414input		KEYWORD(110 || ES, 999, INPUT_TOK);
415output		KEYWORD(110 || ES, 999, OUTPUT);
416hvec2		KEYWORD(110 || ES, 999, HVEC2);
417hvec3		KEYWORD(110 || ES, 999, HVEC3);
418hvec4		KEYWORD(110 || ES, 999, HVEC4);
419dvec2		KEYWORD(110 || ES, 400, DVEC2);
420dvec3		KEYWORD(110 || ES, 400, DVEC3);
421dvec4		KEYWORD(110 || ES, 400, DVEC4);
422fvec2		KEYWORD(110 || ES, 999, FVEC2);
423fvec3		KEYWORD(110 || ES, 999, FVEC3);
424fvec4		KEYWORD(110 || ES, 999, FVEC4);
425sampler2DRect		return SAMPLER2DRECT;
426sampler3DRect		KEYWORD(110 || ES, 999, SAMPLER3DRECT);
427sampler2DRectShadow	return SAMPLER2DRECTSHADOW;
428sizeof		KEYWORD(110 || ES, 999, SIZEOF);
429cast		KEYWORD(110 || ES, 999, CAST);
430namespace	KEYWORD(110 || ES, 999, NAMESPACE);
431using		KEYWORD(110 || ES, 999, USING);
432
433    /* Additional reserved words in GLSL 1.20. */
434lowp		KEYWORD(120, 130 || ES, LOWP);
435mediump		KEYWORD(120, 130 || ES, MEDIUMP);
436highp		KEYWORD(120, 130 || ES, HIGHP);
437precision	KEYWORD(120, 130 || ES, PRECISION);
438
439    /* Additional reserved words in GLSL 1.30. */
440case		KEYWORD(130, 130, CASE);
441common		KEYWORD(130, 999, COMMON);
442partition	KEYWORD(130, 999, PARTITION);
443active		KEYWORD(130, 999, ACTIVE);
444superp		KEYWORD(130 || ES, 999, SUPERP);
445samplerBuffer	KEYWORD(130, 140, SAMPLERBUFFER);
446filter		KEYWORD(130, 999, FILTER);
447image1D		KEYWORD(130, 999, IMAGE1D);
448image2D		KEYWORD(130, 999, IMAGE2D);
449image3D		KEYWORD(130, 999, IMAGE3D);
450imageCube	KEYWORD(130, 999, IMAGECUBE);
451iimage1D	KEYWORD(130, 999, IIMAGE1D);
452iimage2D	KEYWORD(130, 999, IIMAGE2D);
453iimage3D	KEYWORD(130, 999, IIMAGE3D);
454iimageCube	KEYWORD(130, 999, IIMAGECUBE);
455uimage1D	KEYWORD(130, 999, UIMAGE1D);
456uimage2D	KEYWORD(130, 999, UIMAGE2D);
457uimage3D	KEYWORD(130, 999, UIMAGE3D);
458uimageCube	KEYWORD(130, 999, UIMAGECUBE);
459image1DArray	KEYWORD(130, 999, IMAGE1DARRAY);
460image2DArray	KEYWORD(130, 999, IMAGE2DARRAY);
461iimage1DArray	KEYWORD(130, 999, IIMAGE1DARRAY);
462iimage2DArray	KEYWORD(130, 999, IIMAGE2DARRAY);
463uimage1DArray	KEYWORD(130, 999, UIMAGE1DARRAY);
464uimage2DArray	KEYWORD(130, 999, UIMAGE2DARRAY);
465image1DShadow	KEYWORD(130, 999, IMAGE1DSHADOW);
466image2DShadow	KEYWORD(130, 999, IMAGE2DSHADOW);
467image1DArrayShadow KEYWORD(130, 999, IMAGE1DARRAYSHADOW);
468image2DArrayShadow KEYWORD(130, 999, IMAGE2DARRAYSHADOW);
469imageBuffer	KEYWORD(130, 999, IMAGEBUFFER);
470iimageBuffer	KEYWORD(130, 999, IIMAGEBUFFER);
471uimageBuffer	KEYWORD(130, 999, UIMAGEBUFFER);
472row_major	KEYWORD(130, 140 || yyextra->ARB_uniform_buffer_object_enable, ROW_MAJOR);
473
474    /* Additional reserved words in GLSL 1.40 */
475isampler2DRect	KEYWORD(140, 140, ISAMPLER2DRECT);
476usampler2DRect	KEYWORD(140, 140, USAMPLER2DRECT);
477isamplerBuffer	KEYWORD(140, 140, ISAMPLERBUFFER);
478usamplerBuffer	KEYWORD(140, 140, USAMPLERBUFFER);
479
480[_a-zA-Z][_a-zA-Z0-9]*	{
481			    struct _mesa_glsl_parse_state *state = yyextra;
482			    void *ctx = state;
483			    yylval->identifier = ralloc_strdup(ctx, yytext);
484			    return classify_identifier(state, yytext);
485			}
486
487.			{ return yytext[0]; }
488
489%%
490
491int
492classify_identifier(struct _mesa_glsl_parse_state *state, const char *name)
493{
494   if (state->symbols->get_variable(name) || state->symbols->get_function(name))
495      return IDENTIFIER;
496   else if (state->symbols->get_type(name))
497      return TYPE_IDENTIFIER;
498   else
499      return NEW_IDENTIFIER;
500}
501
502void
503_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string)
504{
505   yylex_init_extra(state, & state->scanner);
506   yy_scan_string(string, state->scanner);
507}
508
509void
510_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state)
511{
512   yylex_destroy(state->scanner);
513}
514