1 /*
2 //
3 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6 //
7
8 This file contains the Lex specification for GLSL ES.
9 Based on ANSI C grammar, Lex specification:
10 http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
11
12 IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN scripts/run_code_generation.py
13 WHICH GENERATES THE GLSL ES LEXER (glslang_lex_autogen.cpp).
14 */
15
16 %top{
17 // GENERATED FILE - DO NOT EDIT.
18 // Generated by generate_parser.py from glslang.l
19 //
20 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
21 // Use of this source code is governed by a BSD-style license that can be
22 // found in the LICENSE file.
23 //
24 // glslang.l:
25 // Lexer for the OpenGL shading language.
26
27 // Ignore errors in auto-generated code.
28 #if defined(__GNUC__)
29 #pragma GCC diagnostic ignored "-Wswitch-enum"
30 #pragma GCC diagnostic ignored "-Wunused-function"
31 #pragma GCC diagnostic ignored "-Wunused-variable"
32 #elif defined(_MSC_VER)
33 #pragma warning(disable: 4005)
34 #pragma warning(disable: 4065)
35 #pragma warning(disable: 4189)
36 #pragma warning(disable: 4244)
37 #pragma warning(disable: 4505)
38 #pragma warning(disable: 4701)
39 #pragma warning(disable: 4702)
40 #endif
41 #if defined(__clang__)
42 #pragma clang diagnostic ignored "-Wimplicit-fallthrough"
43 #if defined(__APPLE__)
44 // Older clang versions don't have -Wextra-semi-stmt, and detecting Apple clang versions is
45 // difficult because they use different yet overlapping version numbers vs. regular clang.
46 #pragma clang diagnostic ignored "-Wunknown-warning-option"
47 #endif
48 // Flex isn't semi-colon clean.
49 #pragma clang diagnostic ignored "-Wextra-semi-stmt"
50 #pragma clang diagnostic ignored "-Wunreachable-code"
51 #endif
52 }
53
54 %{
55 #include "compiler/translator/glslang.h"
56 #include "compiler/translator/ParseContext.h"
57 #include "compiler/preprocessor/Token.h"
58 #include "compiler/translator/util.h"
59 #include "compiler/translator/length_limits.h"
60
61 using namespace sh;
62
63 #include "glslang_tab_autogen.h"
64
65 /* windows only pragma */
66 #ifdef _MSC_VER
67 #pragma warning(disable : 4102)
68 #endif
69
70 // Workaround for flex using the register keyword, deprecated in C++11.
71 #ifdef __cplusplus
72 #if __cplusplus > 199711L
73 #define register
74 #endif
75 #endif
76
77 #define YY_NO_INPUT
78 #define YY_USER_ACTION \
79 yylloc->first_file = yylloc->last_file = yycolumn; \
80 yylloc->first_line = yylloc->last_line = yylineno;
81
82 #define YY_INPUT(buf, result, max_size) \
83 result = string_input(buf, max_size, yyscanner);
84
85 static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner);
86 static int check_type(yyscan_t yyscanner);
87 static int reserved_word(yyscan_t yyscanner);
88 // Tests if an extension is enabled. If the extension is promoted to core, this function returns true.
89 static bool is_extension_enabled_or_is_core(TParseContext *context,
90 int extension_version, TExtension extension, int promotion_version);
91 // Helpers to determine if a symbol is reserved, keyword in extension or core, or identifier.
92 // Formatted as:
93 //
94 // [V1_reserved_][V2_extension_][V3_keyword]
95 //
96 // which means in version V1, the symbol is reserved, and remains reserved until V3. From versions
97 // V2 until V3, it's a keyword if the extension is enabled. From version V3 on, it's a keyword in
98 // the spec itself. Prior to V1, the symbol can be used as identifier.
99 static int ES2_extensions_ES3_keyword(TParseContext *context, TExtension extension1, TExtension extension2, TExtension extension3, int token);
100 static int ES2_reserved_ES3_keyword(TParseContext *context, int token);
101 static int ES2_keyword_ES3_reserved(TParseContext *context, int token);
102 static int ES3_keyword(TParseContext *context, int token);
103 static int ES3_reserved_ES3_1_keyword(TParseContext *context, int token);
104 static int ES2_reserved_ES3_1_keyword(TParseContext *context, int token);
105 static int ES3_1_keyword(TParseContext *context, int token);
106 static int ES2_reserved_ES2_extension_ES3_keyword(TParseContext *context, TExtension extension, int token);
107 static int ES3_extension(TParseContext *context, TExtension extension, int token);
108 static int ES3_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token);
109 static int ES3_reserved_ES3_extension(TParseContext *context, TExtension extension, int token);
110 static int ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext *context, TExtension extension, int token);
111 static int ES3_reserved_ES3_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token);
112 static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token);
113 static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token1, int token2);
114 static int ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token1, int token2);
115 static int WEBGL_video_texture_extension(TParseContext *context, int token);
116 static int uint_constant(TParseContext *context);
117 static int int_constant(TParseContext *context);
118 static int float_constant(yyscan_t yyscanner);
119 static int floatsuffix_check(TParseContext* context);
120 static int yuvcscstandardext_constant(TParseContext *context);
121 %}
122
123 %option noyywrap nounput never-interactive
124 %option yylineno reentrant bison-bridge bison-locations
125 %option extra-type="TParseContext*"
126 %x FIELDS
127
128 D [0-9]
129 L [a-zA-Z_]
130 H [a-fA-F0-9]
131 E [Ee][+-]?{D}+
132 O [0-7]
133
134 %%
135
136 %{
137 TParseContext* context = yyextra;
138 %}
139
140 "invariant" { return INVARIANT; }
141 "highp" { return HIGH_PRECISION; }
142 "mediump" { return MEDIUM_PRECISION; }
143 "lowp" { return LOW_PRECISION; }
144 "precision" { return PRECISION; }
145
146 "attribute" { return ES2_keyword_ES3_reserved(context, ATTRIBUTE); }
147 "const" { return CONST_QUAL; }
148 "uniform" { return UNIFORM; }
149 "buffer" { return ES3_1_keyword(context, BUFFER); }
150 "varying" { return ES2_keyword_ES3_reserved(context, VARYING); }
151
152 "break" { return BREAK; }
153 "continue" { return CONTINUE; }
154 "do" { return DO; }
155 "for" { return FOR; }
156 "while" { return WHILE; }
157
158 "if" { return IF; }
159 "else" { return ELSE; }
160 "switch" { return ES2_reserved_ES3_keyword(context, SWITCH); }
161 "case" { return ES3_keyword(context, CASE); }
162 "default" { return ES2_reserved_ES3_keyword(context, DEFAULT); }
163
164 "centroid" { return ES3_keyword(context, CENTROID); }
165 "flat" { return ES2_reserved_ES3_keyword(context, FLAT); }
166 "smooth" { return ES3_keyword(context, SMOOTH); }
167 "noperspective" { return ES3_reserved_ES3_extension(context, TExtension::NV_shader_noperspective_interpolation, NOPERSPECTIVE); }
168
169 "patch" { return ES3_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::EXT_tessellation_shader, PATCH); }
170
171 "in" { return IN_QUAL; }
172 "out" { return OUT_QUAL; }
173 "inout" { return INOUT_QUAL; }
174 "shared" { return ES3_1_keyword(context, SHARED); }
175
176 "float" { return FLOAT_TYPE; }
177 "int" { return INT_TYPE; }
178 "uint" { return ES3_keyword(context, UINT_TYPE); }
179 "void" { return VOID_TYPE; }
180 "bool" { return BOOL_TYPE; }
181 "true" { yylval->lex.b = true; return BOOLCONSTANT; }
182 "false" { yylval->lex.b = false; return BOOLCONSTANT; }
183
184 "discard" { return DISCARD; }
185 "return" { return RETURN; }
186
187 "mat2" { return MATRIX2; }
188 "mat3" { return MATRIX3; }
189 "mat4" { return MATRIX4; }
190
191 "mat2x2" { return ES3_keyword(context, MATRIX2); }
192 "mat3x3" { return ES3_keyword(context, MATRIX3); }
193 "mat4x4" { return ES3_keyword(context, MATRIX4); }
194
195 "mat2x3" { return ES3_keyword(context, MATRIX2x3); }
196 "mat3x2" { return ES3_keyword(context, MATRIX3x2); }
197 "mat2x4" { return ES3_keyword(context, MATRIX2x4); }
198 "mat4x2" { return ES3_keyword(context, MATRIX4x2); }
199 "mat3x4" { return ES3_keyword(context, MATRIX3x4); }
200 "mat4x3" { return ES3_keyword(context, MATRIX4x3); }
201
202 "vec2" { return VEC2; }
203 "vec3" { return VEC3; }
204 "vec4" { return VEC4; }
205 "ivec2" { return IVEC2; }
206 "ivec3" { return IVEC3; }
207 "ivec4" { return IVEC4; }
208 "bvec2" { return BVEC2; }
209 "bvec3" { return BVEC3; }
210 "bvec4" { return BVEC4; }
211 "uvec2" { return ES3_keyword(context, UVEC2); }
212 "uvec3" { return ES3_keyword(context, UVEC3); }
213 "uvec4" { return ES3_keyword(context, UVEC4); }
214
215 "sampler2D" { return SAMPLER2D; }
216 "samplerCube" { return SAMPLERCUBE; }
217 "samplerExternalOES" { return SAMPLER_EXTERNAL_OES; }
218 "sampler3D" { return ES2_reserved_ES2_extension_ES3_keyword(context, TExtension::OES_texture_3D, SAMPLER3D); }
219 "sampler3DRect" { return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); }
220 "sampler2DRect" { return SAMPLER2DRECT; }
221 "sampler2DArray" { return ES3_keyword(context, SAMPLER2DARRAY); }
222 "sampler2DMS" { return ES3_reserved_ES3_extension_ES3_1_keyword(context, TExtension::ANGLE_texture_multisample, SAMPLER2DMS); }
223 "isampler2D" { return ES3_keyword(context, ISAMPLER2D); }
224 "isampler3D" { return ES3_keyword(context, ISAMPLER3D); }
225 "isamplerCube" { return ES3_keyword(context, ISAMPLERCUBE); }
226 "isampler2DArray" { return ES3_keyword(context, ISAMPLER2DARRAY); }
227 "isampler2DMS" { return ES3_reserved_ES3_extension_ES3_1_keyword(context, TExtension::ANGLE_texture_multisample, ISAMPLER2DMS); }
228 "usampler2D" { return ES3_keyword(context, USAMPLER2D); }
229 "usampler3D" { return ES3_keyword(context, USAMPLER3D); }
230 "usamplerCube" { return ES3_keyword(context, USAMPLERCUBE); }
231 "usampler2DArray" { return ES3_keyword(context, USAMPLER2DARRAY); }
232 "usampler2DMS" { return ES3_reserved_ES3_extension_ES3_1_keyword(context, TExtension::ANGLE_texture_multisample, USAMPLER2DMS); }
233 "sampler2DShadow" { return ES2_reserved_ES2_extension_ES3_keyword(context, TExtension::EXT_shadow_samplers, SAMPLER2DSHADOW); }
234 "samplerCubeShadow" { return ES3_keyword(context, SAMPLERCUBESHADOW); }
235 "sampler2DArrayShadow" { return ES3_keyword(context, SAMPLER2DARRAYSHADOW); }
236 "__samplerExternal2DY2YEXT" { return ES3_extension(context, TExtension::EXT_YUV_target, SAMPLEREXTERNAL2DY2YEXT); }
237 "sampler2DMSArray" { return ES3_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::OES_texture_storage_multisample_2d_array, SAMPLER2DMSARRAY); }
238 "isampler2DMSArray" { return ES3_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::OES_texture_storage_multisample_2d_array, ISAMPLER2DMSARRAY); }
239 "usampler2DMSArray" { return ES3_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::OES_texture_storage_multisample_2d_array, USAMPLER2DMSARRAY); }
240 "samplerCubeArray" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, SAMPLERCUBEARRAYOES, SAMPLERCUBEARRAYEXT); }
241 "samplerBuffer" { return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer, SAMPLERBUFFER, SAMPLERBUFFER); }
242 "samplerCubeArrayShadow" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, SAMPLERCUBEARRAYSHADOWOES, SAMPLERCUBEARRAYSHADOWEXT); }
243 "isamplerCubeArray" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, ISAMPLERCUBEARRAYOES, ISAMPLERCUBEARRAYEXT); }
244 "isamplerBuffer" { return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer, ISAMPLERBUFFER, ISAMPLERBUFFER); }
245 "usamplerCubeArray" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, USAMPLERCUBEARRAYOES, USAMPLERCUBEARRAYEXT); }
246 "usamplerBuffer" { return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer, USAMPLERBUFFER, USAMPLERBUFFER); }
247 "samplerVideoWEBGL" { return WEBGL_video_texture_extension(context, SAMPLERVIDEOWEBGL); }
248 "struct" { return STRUCT; }
249
250 "layout" { return ES2_extensions_ES3_keyword(context, TExtension::EXT_shader_framebuffer_fetch, TExtension::EXT_shader_framebuffer_fetch_non_coherent, TExtension::KHR_blend_equation_advanced, LAYOUT); }
251
252 "yuvCscStandardEXT" { return ES3_extension(context, TExtension::EXT_YUV_target, YUVCSCSTANDARDEXT); }
253 "itu_601" { return yuvcscstandardext_constant(context); }
254 "itu_601_full_range" { return yuvcscstandardext_constant(context); }
255 "itu_709" { return yuvcscstandardext_constant(context); }
256
257 "image2D" { return ES3_reserved_ES3_1_keyword(context, IMAGE2D); }
258 "iimage2D" { return ES3_reserved_ES3_1_keyword(context, IIMAGE2D); }
259 "uimage2D" { return ES3_reserved_ES3_1_keyword(context, UIMAGE2D); }
260 "image2DArray" { return ES3_reserved_ES3_1_keyword(context, IMAGE2DARRAY); }
261 "iimage2DArray" { return ES3_reserved_ES3_1_keyword(context, IIMAGE2DARRAY); }
262 "uimage2DArray" { return ES3_reserved_ES3_1_keyword(context, UIMAGE2DARRAY); }
263 "image3D" { return ES3_reserved_ES3_1_keyword(context, IMAGE3D); }
264 "uimage3D" { return ES3_reserved_ES3_1_keyword(context, UIMAGE3D); }
265 "iimage3D" { return ES3_reserved_ES3_1_keyword(context, IIMAGE3D); }
266 "iimageCube" { return ES3_reserved_ES3_1_keyword(context, IIMAGECUBE); }
267 "uimageCube" { return ES3_reserved_ES3_1_keyword(context, UIMAGECUBE); }
268 "imageCube" { return ES3_reserved_ES3_1_keyword(context, IMAGECUBE); }
269 "imageCubeArray" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, IMAGECUBEARRAYOES, IMAGECUBEARRAYEXT); }
270 "iimageCubeArray" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, IIMAGECUBEARRAYOES, IIMAGECUBEARRAYEXT); }
271 "uimageCubeArray" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, UIMAGECUBEARRAYOES, UIMAGECUBEARRAYEXT); }
272 "imageBuffer" { return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer, IMAGEBUFFER, IMAGEBUFFER); }
273 "iimageBuffer" { return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer, IIMAGEBUFFER, IIMAGEBUFFER); }
274 "uimageBuffer" { return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer, UIMAGEBUFFER, UIMAGEBUFFER); }
275 "readonly" { return ES3_reserved_ES3_1_keyword(context, READONLY); }
276 "writeonly" { return ES3_reserved_ES3_1_keyword(context, WRITEONLY); }
277 "coherent" { return ES3_reserved_ES3_1_keyword(context, COHERENT); }
278 "restrict" { return ES3_reserved_ES3_1_keyword(context, RESTRICT); }
279 "volatile" { return ES2_reserved_ES3_1_keyword(context, VOLATILE); }
280 "atomic_uint" { return ES3_reserved_ES3_1_keyword(context, ATOMICUINT); }
281 "sample" { return ES3_reserved_ES3_extension_ES3_2_keyword(context, TExtension::OES_shader_multisample_interpolation, SAMPLE); }
282 "precise" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::EXT_gpu_shader5, PRECISE); }
283
284 /* ANGLE_shader_pixel_local_storage */
285 "pixelLocalANGLE" { return ES3_extension(context, TExtension::ANGLE_shader_pixel_local_storage, PIXELLOCALANGLE); }
286 "ipixelLocalANGLE" { return ES3_extension(context, TExtension::ANGLE_shader_pixel_local_storage, IPIXELLOCALANGLE); }
287 "upixelLocalANGLE" { return ES3_extension(context, TExtension::ANGLE_shader_pixel_local_storage, UPIXELLOCALANGLE); }
288
289 /* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */
290 "resource" |
291 "subroutine" |
292 "common" |
293 "partition" |
294 "active" |
295
296 "filter" |
297 "image1D" |
298 "iimage1D" |
299 "uimage1D" |
300 "image1DArray" |
301 "iimage1DArray" |
302 "uimage1DArray" |
303
304 "sampler1DArray" |
305 "sampler1DArrayShadow" |
306 "isampler1D" |
307 "isampler1DArray" |
308 "usampler1D" |
309 "usampler1DArray" |
310 "isampler2DRect" |
311 "usampler2DRect" {
312 if (context->getShaderVersion() < 300) {
313 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
314 return check_type(yyscanner);
315 }
316 return reserved_word(yyscanner);
317 }
318
319 /* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */
320 "packed" {
321 if (context->getShaderVersion() >= 300)
322 {
323 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
324 return check_type(yyscanner);
325 }
326
327 return reserved_word(yyscanner);
328 }
329
330 /* Reserved keywords in WebGL that not reserved in GL */
331 "image1DShadow" |
332 "image2DShadow" |
333 "image1DArrayShadow" |
334 "image2DArrayShadow" {
335 if(!IsWebGLBasedSpec(context->getShaderSpec()))
336 {
337 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
338 return check_type(yyscanner);
339 }
340
341 return reserved_word(yyscanner);
342 }
343
344 /* Reserved keywords */
345 "asm" |
346
347 "class" |
348 "union" |
349 "enum" |
350 "typedef" |
351 "template" |
352 "this" |
353
354 "goto" |
355
356 "inline" |
357 "noinline" |
358 "public" |
359 "static" |
360 "extern" |
361 "external" |
362 "interface" |
363
364 "long" |
365 "short" |
366 "double" |
367 "half" |
368 "fixed" |
369 "unsigned" |
370 "superp" |
371
372 "input" |
373 "output" |
374
375 "hvec2" |
376 "hvec3" |
377 "hvec4" |
378 "dvec2" |
379 "dvec3" |
380 "dvec4" |
381 "fvec2" |
382 "fvec3" |
383 "fvec4" |
384
385 "sampler1D" |
386 "sampler1DShadow" |
387 "sampler2DRectShadow" |
388
389 "sizeof" |
390 "cast" |
391
392 "namespace" |
393 "using" { return reserved_word(yyscanner); }
394
395 {L}({L}|{D})* {
396 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
397 return check_type(yyscanner);
398 }
399
400 0[xX]{H}+ { return int_constant(context); }
401 0{O}+ { return int_constant(context); }
402 {D}+ { return int_constant(context); }
403
404 0[xX]{H}+[uU] { return uint_constant(context); }
405 0{O}+[uU] { return uint_constant(context); }
406 {D}+[uU] { return uint_constant(context); }
407
408 {D}+{E} { return float_constant(yyscanner); }
409 {D}+"."{D}*({E})? { return float_constant(yyscanner); }
410 "."{D}+({E})? { return float_constant(yyscanner); }
411
412 {D}+{E}[fF] { return floatsuffix_check(context); }
413 {D}+"."{D}*({E})?[fF] { return floatsuffix_check(context); }
414 "."{D}+({E})?[fF] { return floatsuffix_check(context); }
415
416 "+=" { return ADD_ASSIGN; }
417 "-=" { return SUB_ASSIGN; }
418 "*=" { return MUL_ASSIGN; }
419 "/=" { return DIV_ASSIGN; }
420 "%=" { return MOD_ASSIGN; }
421 "<<=" { return LEFT_ASSIGN; }
422 ">>=" { return RIGHT_ASSIGN; }
423 "&=" { return AND_ASSIGN; }
424 "^=" { return XOR_ASSIGN; }
425 "|=" { return OR_ASSIGN; }
426
427 "++" { return INC_OP; }
428 "--" { return DEC_OP; }
429 "&&" { return AND_OP; }
430 "||" { return OR_OP; }
431 "^^" { return XOR_OP; }
432 "<=" { return LE_OP; }
433 ">=" { return GE_OP; }
434 "==" { return EQ_OP; }
435 "!=" { return NE_OP; }
436 "<<" { return LEFT_OP; }
437 ">>" { return RIGHT_OP; }
438 ";" { return SEMICOLON; }
439 ("{"|"<%") { return LEFT_BRACE; }
440 ("}"|"%>") { return RIGHT_BRACE; }
441 "," { return COMMA; }
442 ":" { return COLON; }
443 "=" { return EQUAL; }
444 "(" { return LEFT_PAREN; }
445 ")" { return RIGHT_PAREN; }
446 ("["|"<:") { return LEFT_BRACKET; }
447 ("]"|":>") { return RIGHT_BRACKET; }
448 "." { BEGIN(FIELDS); return DOT; }
449 "!" { return BANG; }
450 "-" { return DASH; }
451 "~" { return TILDE; }
452 "+" { return PLUS; }
453 "*" { return STAR; }
454 "/" { return SLASH; }
455 "%" { return PERCENT; }
456 "<" { return LEFT_ANGLE; }
457 ">" { return RIGHT_ANGLE; }
458 "|" { return VERTICAL_BAR; }
459 "^" { return CARET; }
460 "&" { return AMPERSAND; }
461 "?" { return QUESTION; }
462
463 <FIELDS>{L}({L}|{D})* {
464 BEGIN(INITIAL);
465 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
466 return FIELD_SELECTION;
467 }
468 <FIELDS>[ \t\v\f\r] {}
469 <FIELDS>. {
470 yyextra->error(*yylloc, "Illegal character at fieldname start", yytext);
471 return 0;
472 }
473
474 [ \t\v\n\f\r] { }
475 <*><<EOF>> { yyterminate(); }
476 <*>. { assert(false); return 0; }
477
478 %%
479
480 yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
481 angle::pp::Token token;
482 yyget_extra(yyscanner)->getPreprocessor().lex(&token);
483 yy_size_t len = token.type == angle::pp::Token::LAST ? 0 : token.text.size();
484 if (len < max_size)
485 memcpy(buf, token.text.c_str(), len);
486 yyset_column(token.location.file, yyscanner);
487 yyset_lineno(token.location.line, yyscanner);
488
489 if (len >= max_size)
490 YY_FATAL_ERROR("Input buffer overflow");
491 else if (len > 0)
492 buf[len++] = ' ';
493 return len;
494 }
495
check_type(yyscan_t yyscanner)496 int check_type(yyscan_t yyscanner) {
497 struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
498
499 int token = IDENTIFIER;
500 // Note that the ImmutableString used here isn't static or pool allocated - but it's fine since yytext is valid for the duration of its use.
501 const TSymbol* symbol = yyextra->symbolTable.find(ImmutableString(yytext, yyleng), yyextra->getShaderVersion());
502 if (symbol && symbol->isStruct())
503 {
504 token = TYPE_NAME;
505 }
506 yylval->lex.symbol = symbol;
507 return token;
508 }
509
reserved_word(yyscan_t yyscanner)510 int reserved_word(yyscan_t yyscanner) {
511 struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
512
513 yyextra->error(*yylloc, "Illegal use of reserved word", yytext);
514 return 0;
515 }
516
is_extension_enabled_or_is_core(TParseContext * context,int extension_version,TExtension extension,int promotion_version)517 static bool is_extension_enabled_or_is_core(TParseContext *context,
518 int extension_version, TExtension extension, int promotion_version)
519 {
520 int version = context->getShaderVersion();
521
522 // If version is at least promotion_version, symbol is definitely keyword. Otherwise it's a
523 // keyword if version is at least extension_version (where the extension was introduced) and
524 // the extension is enabled.
525 return version >= promotion_version ||
526 (version >= extension_version && context->isExtensionEnabled(extension));
527 }
528
ES2_reserved_ES3_keyword(TParseContext * context,int token)529 int ES2_reserved_ES3_keyword(TParseContext *context, int token)
530 {
531 yyscan_t yyscanner = (yyscan_t) context->getScanner();
532
533 if (context->getShaderVersion() < 300)
534 {
535 return reserved_word(yyscanner);
536 }
537
538 return token;
539 }
540
ES2_keyword_ES3_reserved(TParseContext * context,int token)541 int ES2_keyword_ES3_reserved(TParseContext *context, int token)
542 {
543 yyscan_t yyscanner = (yyscan_t) context->getScanner();
544
545 if (context->getShaderVersion() >= 300)
546 {
547 return reserved_word(yyscanner);
548 }
549
550 return token;
551 }
552
ES3_reserved_ES3_1_keyword(TParseContext * context,int token)553 int ES3_reserved_ES3_1_keyword(TParseContext *context, int token)
554 {
555 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
556 yyscan_t yyscanner = (yyscan_t) context->getScanner();
557
558 if (context->getShaderVersion() < 300)
559 {
560 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
561 return check_type(yyscanner);
562 }
563 else if (context->getShaderVersion() == 300)
564 {
565 return reserved_word(yyscanner);
566 }
567
568 return token;
569 }
570
ES3_keyword(TParseContext * context,int token)571 int ES3_keyword(TParseContext *context, int token)
572 {
573 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
574 yyscan_t yyscanner = (yyscan_t) context->getScanner();
575
576 // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
577 if (context->getShaderVersion() < 300)
578 {
579 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
580 return check_type(yyscanner);
581 }
582
583 return token;
584 }
585
ES2_reserved_ES3_1_keyword(TParseContext * context,int token)586 int ES2_reserved_ES3_1_keyword(TParseContext *context, int token)
587 {
588 yyscan_t yyscanner = (yyscan_t) context->getScanner();
589
590 if (context->getShaderVersion() < 310)
591 {
592 return reserved_word(yyscanner);
593 }
594
595 return token;
596 }
597
ES3_1_keyword(TParseContext * context,int token)598 int ES3_1_keyword(TParseContext *context, int token)
599 {
600 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
601 yyscan_t yyscanner = (yyscan_t) context->getScanner();
602
603 // A keyword in GLSL ES 3.10.
604 if (context->getShaderVersion() >= 310)
605 {
606 return token;
607 }
608
609 // Otherwise can be used as an identifier/type name
610 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
611 return check_type(yyscanner);
612 }
613
WEBGL_video_texture_extension(TParseContext * context,int token)614 int WEBGL_video_texture_extension(TParseContext *context, int token)
615 {
616 // Available with WEBGL_video_texture_extension
617 if (context->isExtensionEnabled(TExtension::WEBGL_video_texture))
618 {
619 return token;
620 }
621
622 // Otherwise can be used as an identifier/type name
623 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
624 yyscan_t yyscanner = (yyscan_t) context->getScanner();
625
626 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
627 return check_type(yyscanner);
628 }
629
ES2_extensions_ES3_keyword(TParseContext * context,TExtension extension1,TExtension extension2,TExtension extension3,int token)630 int ES2_extensions_ES3_keyword(TParseContext *context, TExtension extension1, TExtension extension2, TExtension extension3, int token)
631 {
632 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
633 yyscan_t yyscanner = (yyscan_t) context->getScanner();
634
635 // A keyword in GLSL ES 3.00 or GLSL ES 1.00 with enabled extension.
636 if (is_extension_enabled_or_is_core(context, 100, extension1, 300))
637 {
638 return token;
639 }
640 else if (is_extension_enabled_or_is_core(context, 100, extension2, 300))
641 {
642 return token;
643 }
644 else if (is_extension_enabled_or_is_core(context, 100, extension3, 300))
645 {
646 return token;
647 }
648
649 // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
650 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
651 return check_type(yyscanner);
652 }
653
ES2_reserved_ES2_extension_ES3_keyword(TParseContext * context,TExtension extension,int token)654 int ES2_reserved_ES2_extension_ES3_keyword(TParseContext *context, TExtension extension, int token)
655 {
656 yyscan_t yyscanner = (yyscan_t) context->getScanner();
657
658 // A keyword in GLSL ES 3.00 or GLSL ES 1.00 with enabled extension.
659 if (is_extension_enabled_or_is_core(context, 100, extension, 300))
660 {
661 return token;
662 }
663
664 // Reserved otherwise.
665 return reserved_word(yyscanner);
666 }
667
ES3_extension(TParseContext * context,TExtension extension,int token)668 int ES3_extension(TParseContext *context, TExtension extension, int token)
669 {
670 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
671 yyscan_t yyscanner = (yyscan_t) context->getScanner();
672
673 // a keyword word in GLSL ES 3.00 with enabled extension.
674 if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(extension))
675 {
676 return token;
677 }
678
679 // Otherwise can be used as an identifier/type name
680 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
681 return check_type(yyscanner);
682 }
683
ES3_reserved_ES3_1_extension_ES3_2_keyword(TParseContext * context,TExtension extension,int token)684 int ES3_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token)
685 {
686 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
687 yyscan_t yyscanner = (yyscan_t) context->getScanner();
688
689 // a keyword in GLSL ES 3.10 with enabled extension
690 if (is_extension_enabled_or_is_core(context, 310, extension, 320))
691 {
692 return token;
693 }
694 // a reserved word in GLSL ES 3.00+
695 if (context->getShaderVersion() >= 300)
696 {
697 return reserved_word(yyscanner);
698 }
699
700 // Otherwise can be used as an identifier/type name
701 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
702 return check_type(yyscanner);
703 }
704
ES3_reserved_ES3_extension(TParseContext * context,TExtension extension,int token)705 int ES3_reserved_ES3_extension(TParseContext *context, TExtension extension, int token)
706 {
707 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
708 yyscan_t yyscanner = (yyscan_t) context->getScanner();
709
710 if(context->getShaderVersion() >= 300)
711 {
712 if (context->isExtensionEnabled(extension)) {
713 return token;
714 } else {
715 return reserved_word(yyscanner);
716 }
717 }
718
719 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
720 return check_type(yyscanner);
721 }
722
ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext * context,TExtension extension,int token)723 int ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext *context, TExtension extension, int token)
724 {
725 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
726 yyscan_t yyscanner = (yyscan_t) context->getScanner();
727
728 // A keyword in GLSL ES 3.00 with enabled extension or in GLSL ES 3.10
729 if (is_extension_enabled_or_is_core(context, 300, extension, 310))
730 {
731 return token;
732 }
733
734 if(context->getShaderVersion() == 300)
735 {
736 return reserved_word(yyscanner);
737 }
738
739 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
740 return check_type(yyscanner);
741 }
742
ES3_reserved_ES3_extension_ES3_2_keyword(TParseContext * context,TExtension extension,int token)743 int ES3_reserved_ES3_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token)
744 {
745 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
746 yyscan_t yyscanner = (yyscan_t) context->getScanner();
747
748 // A keyword in GLSL ES 3.00 with enabled extension or in GLSL ES 3.20
749 if (is_extension_enabled_or_is_core(context, 300, extension, 320))
750 {
751 return token;
752 }
753
754 if(context->getShaderVersion() == 300 ||context->getShaderVersion() == 310)
755 {
756 return reserved_word(yyscanner);
757 }
758
759 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
760 return check_type(yyscanner);
761 }
762
ES3_1_reserved_ES3_1_extension_ES3_2_keyword(TParseContext * context,TExtension extension,int token)763 static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token)
764 {
765 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
766 yyscan_t yyscanner = (yyscan_t) context->getScanner();
767
768 // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
769 if (is_extension_enabled_or_is_core(context, 310, extension, 320))
770 {
771 return token;
772 }
773
774 // A reserved word in GLSL ES 3.10
775 if (context->getShaderVersion() == 310)
776 {
777 return reserved_word(yyscanner);
778 }
779
780 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
781 return check_type(yyscanner);
782 }
783
ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext * context,TExtension extension1,TExtension extension2,int token1,int token2)784 static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token1, int token2)
785 {
786 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
787 yyscan_t yyscanner = (yyscan_t) context->getScanner();
788
789 // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
790 if (is_extension_enabled_or_is_core(context, 310, extension1, 320))
791 {
792 return token1;
793 }
794 else if (is_extension_enabled_or_is_core(context, 310, extension2, 320))
795 {
796 return token2;
797 }
798
799 // A reserved word in GLSL ES 3.10
800 if (context->getShaderVersion() == 310)
801 {
802 return reserved_word(yyscanner);
803 }
804
805 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
806 return check_type(yyscanner);
807 }
808
ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext * context,TExtension extension1,TExtension extension2,int token1,int token2)809 static int ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token1, int token2)
810 {
811 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
812 yyscan_t yyscanner = (yyscan_t) context->getScanner();
813
814 // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
815 if (is_extension_enabled_or_is_core(context, 310, extension1, 320))
816 {
817 return token1;
818 }
819 else if (is_extension_enabled_or_is_core(context, 310, extension2, 320))
820 {
821 return token2;
822 }
823
824 // A reserved word in GLSL ES 3.00 and 3.10
825 if (context->getShaderVersion() >= 300)
826 {
827 return reserved_word(yyscanner);
828 }
829
830 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
831 return check_type(yyscanner);
832 }
833
uint_constant(TParseContext * context)834 int uint_constant(TParseContext *context)
835 {
836 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
837
838 if (context->getShaderVersion() < 300)
839 {
840 context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext);
841 return 0;
842 }
843
844 if (!atoi_clamp(yytext, &(yylval->lex.u)))
845 yyextra->error(*yylloc, "Integer overflow", yytext);
846
847 return UINTCONSTANT;
848 }
849
floatsuffix_check(TParseContext * context)850 int floatsuffix_check(TParseContext* context)
851 {
852 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
853
854 if (context->getShaderVersion() < 300)
855 {
856 context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext);
857 return 0;
858 }
859
860 std::string text = yytext;
861 text.resize(text.size() - 1);
862 if (!strtof_clamp(text, &(yylval->lex.f)))
863 yyextra->warning(*yylloc, "Float overflow", yytext);
864
865 return(FLOATCONSTANT);
866 }
867
yyerror(YYLTYPE * lloc,TParseContext * context,void * scanner,const char * reason)868 void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* reason) {
869 context->error(*lloc, reason, yyget_text(scanner));
870 }
871
int_constant(TParseContext * context)872 int int_constant(TParseContext *context) {
873 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
874
875 unsigned int u;
876 if (!atoi_clamp(yytext, &u))
877 {
878 if (context->getShaderVersion() >= 300)
879 yyextra->error(*yylloc, "Integer overflow", yytext);
880 else
881 yyextra->warning(*yylloc, "Integer overflow", yytext);
882 }
883 yylval->lex.i = static_cast<int>(u);
884 return INTCONSTANT;
885 }
886
float_constant(yyscan_t yyscanner)887 int float_constant(yyscan_t yyscanner) {
888 struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
889
890 if (!strtof_clamp(yytext, &(yylval->lex.f)))
891 yyextra->warning(*yylloc, "Float overflow", yytext);
892 return FLOATCONSTANT;
893 }
894
yuvcscstandardext_constant(TParseContext * context)895 int yuvcscstandardext_constant(TParseContext *context)
896 {
897 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
898 yyscan_t yyscanner = (yyscan_t) context->getScanner();
899
900 // a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an identifier/type name
901 if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(TExtension::EXT_YUV_target))
902 {
903 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
904 return YUVCSCSTANDARDEXTCONSTANT;
905 }
906
907 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
908 return check_type(yyscanner);
909 }
910
glslang_initialize(TParseContext * context)911 int glslang_initialize(TParseContext* context) {
912 yyscan_t scanner = NULL;
913 if (yylex_init_extra(context, &scanner))
914 return 1;
915
916 context->setScanner(scanner);
917 return 0;
918 }
919
glslang_finalize(TParseContext * context)920 int glslang_finalize(TParseContext* context) {
921 yyscan_t scanner = context->getScanner();
922 if (scanner == NULL) return 0;
923
924 context->setScanner(NULL);
925 yylex_destroy(scanner);
926
927 return 0;
928 }
929
glslang_scan(size_t count,const char * const string[],const int length[],TParseContext * context)930 int glslang_scan(size_t count, const char* const string[], const int length[],
931 TParseContext* context) {
932 yyrestart(NULL, context->getScanner());
933 yyset_column(0, context->getScanner());
934 yyset_lineno(1, context->getScanner());
935
936 // Initialize preprocessor.
937 angle::pp::Preprocessor *preprocessor = &context->getPreprocessor();
938
939 if (!preprocessor->init(count, string, length))
940 return 1;
941
942 if (context->getFragmentPrecisionHigh())
943 preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
944
945 preprocessor->setMaxTokenSize(sh::GetGlobalMaxTokenSize(context->getShaderSpec()));
946
947 return 0;
948 }
949