xref: /aosp_15_r20/external/angle/src/compiler/translator/glslang.l (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token);
110 static int ES3_reserved_ES3_extension(TParseContext *context, TExtension extension, int token);
111 static int ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext *context, TExtension extension, int token);
112 static int ES3_reserved_ES3_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_2(context, TExtension::EXT_tessellation_shader, TExtension::OES_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_2(context, TExtension::EXT_gpu_shader5, TExtension::OES_gpu_shader5, PRECISE, 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 "sampler2DRectShadow" |
386 "sampler1D"    |
387 "sampler1DShadow" |
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_1_extension_ES3_2_keyword_2(TParseContext * context,TExtension extension1,TExtension extension2,int token)705 int ES3_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token)
706 {
707     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
708     yyscan_t yyscanner = (yyscan_t) context->getScanner();
709 
710     // a keyword in GLSL ES 3.10 with enabled extension
711     if (is_extension_enabled_or_is_core(context, 310, extension1, 320))
712     {
713         return token;
714     }
715     else if (is_extension_enabled_or_is_core(context, 310, extension2, 320))
716     {
717         return token;
718     }
719     // a reserved word in GLSL ES 3.00+
720     if (context->getShaderVersion() >= 300)
721     {
722         return reserved_word(yyscanner);
723     }
724 
725     // Otherwise can be used as an identifier/type name
726     yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
727     return check_type(yyscanner);
728 }
729 
ES3_reserved_ES3_extension(TParseContext * context,TExtension extension,int token)730 int ES3_reserved_ES3_extension(TParseContext *context, TExtension extension, int token)
731 {
732     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
733     yyscan_t yyscanner = (yyscan_t) context->getScanner();
734 
735     if(context->getShaderVersion() >= 300)
736     {
737         if (context->isExtensionEnabled(extension)) {
738             return token;
739         } else {
740             return reserved_word(yyscanner);
741         }
742     }
743 
744     yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
745     return check_type(yyscanner);
746 }
747 
ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext * context,TExtension extension,int token)748 int ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext *context, TExtension extension, int token)
749 {
750     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
751     yyscan_t yyscanner = (yyscan_t) context->getScanner();
752 
753     // A keyword in GLSL ES 3.00 with enabled extension or in GLSL ES 3.10
754     if (is_extension_enabled_or_is_core(context, 300, extension, 310))
755     {
756         return token;
757     }
758 
759     if(context->getShaderVersion() == 300)
760     {
761         return reserved_word(yyscanner);
762     }
763 
764     yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
765     return check_type(yyscanner);
766 }
767 
ES3_reserved_ES3_extension_ES3_2_keyword(TParseContext * context,TExtension extension,int token)768 int ES3_reserved_ES3_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token)
769 {
770     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
771     yyscan_t yyscanner = (yyscan_t) context->getScanner();
772 
773     // A keyword in GLSL ES 3.00 with enabled extension or in GLSL ES 3.20
774     if (is_extension_enabled_or_is_core(context, 300, extension, 320))
775     {
776         return token;
777     }
778 
779     if(context->getShaderVersion() == 300 ||context->getShaderVersion() == 310)
780     {
781         return reserved_word(yyscanner);
782     }
783 
784     yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
785     return check_type(yyscanner);
786 }
787 
ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext * context,TExtension extension1,TExtension extension2,int token1,int token2)788 static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token1, int token2)
789 {
790    struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
791     yyscan_t yyscanner = (yyscan_t) context->getScanner();
792 
793     // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
794     if (is_extension_enabled_or_is_core(context, 310, extension1, 320))
795     {
796         return token1;
797     }
798     else if (is_extension_enabled_or_is_core(context, 310, extension2, 320))
799     {
800         return token2;
801     }
802 
803     // A reserved word in GLSL ES 3.10
804     if (context->getShaderVersion() == 310)
805     {
806         return reserved_word(yyscanner);
807     }
808 
809     yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
810     return check_type(yyscanner);
811 }
812 
ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext * context,TExtension extension1,TExtension extension2,int token1,int token2)813 static int ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token1, int token2)
814 {
815    struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
816     yyscan_t yyscanner = (yyscan_t) context->getScanner();
817 
818     // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
819     if (is_extension_enabled_or_is_core(context, 310, extension1, 320))
820     {
821         return token1;
822     }
823     else if (is_extension_enabled_or_is_core(context, 310, extension2, 320))
824     {
825         return token2;
826     }
827 
828     // A reserved word in GLSL ES 3.00 and 3.10
829     if (context->getShaderVersion() >= 300)
830     {
831         return reserved_word(yyscanner);
832     }
833 
834     yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
835     return check_type(yyscanner);
836 }
837 
uint_constant(TParseContext * context)838 int uint_constant(TParseContext *context)
839 {
840     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
841 
842     if (context->getShaderVersion() < 300)
843     {
844         context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext);
845         return 0;
846     }
847 
848     if (!atoi_clamp(yytext, &(yylval->lex.u)))
849         yyextra->error(*yylloc, "Integer overflow", yytext);
850 
851     return UINTCONSTANT;
852 }
853 
floatsuffix_check(TParseContext * context)854 int floatsuffix_check(TParseContext* context)
855 {
856     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
857 
858     if (context->getShaderVersion() < 300)
859     {
860         context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext);
861         return 0;
862     }
863 
864     std::string text = yytext;
865     text.resize(text.size() - 1);
866     if (!strtof_clamp(text, &(yylval->lex.f)))
867         yyextra->warning(*yylloc, "Float overflow", yytext);
868 
869     return(FLOATCONSTANT);
870 }
871 
yyerror(YYLTYPE * lloc,TParseContext * context,void * scanner,const char * reason)872 void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* reason) {
873     context->error(*lloc, reason, yyget_text(scanner));
874 }
875 
int_constant(TParseContext * context)876 int int_constant(TParseContext *context) {
877     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
878 
879     unsigned int u;
880     if (!atoi_clamp(yytext, &u))
881     {
882         if (context->getShaderVersion() >= 300)
883             yyextra->error(*yylloc, "Integer overflow", yytext);
884         else
885             yyextra->warning(*yylloc, "Integer overflow", yytext);
886     }
887     yylval->lex.i = static_cast<int>(u);
888     return INTCONSTANT;
889 }
890 
float_constant(yyscan_t yyscanner)891 int float_constant(yyscan_t yyscanner) {
892     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
893 
894     if (!strtof_clamp(yytext, &(yylval->lex.f)))
895         yyextra->warning(*yylloc, "Float overflow", yytext);
896     return FLOATCONSTANT;
897 }
898 
yuvcscstandardext_constant(TParseContext * context)899 int yuvcscstandardext_constant(TParseContext *context)
900 {
901     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
902     yyscan_t yyscanner = (yyscan_t) context->getScanner();
903 
904     // a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an identifier/type name
905     if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(TExtension::EXT_YUV_target))
906     {
907         yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
908         return YUVCSCSTANDARDEXTCONSTANT;
909     }
910 
911     yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
912     return check_type(yyscanner);
913 }
914 
glslang_initialize(TParseContext * context)915 int glslang_initialize(TParseContext* context) {
916     yyscan_t scanner = NULL;
917     if (yylex_init_extra(context, &scanner))
918         return 1;
919 
920     context->setScanner(scanner);
921     return 0;
922 }
923 
glslang_finalize(TParseContext * context)924 int glslang_finalize(TParseContext* context) {
925     yyscan_t scanner = context->getScanner();
926     if (scanner == NULL) return 0;
927 
928     context->setScanner(NULL);
929     yylex_destroy(scanner);
930 
931     return 0;
932 }
933 
glslang_scan(size_t count,const char * const string[],const int length[],TParseContext * context)934 int glslang_scan(size_t count, const char* const string[], const int length[],
935                  TParseContext* context) {
936     yyrestart(NULL, context->getScanner());
937     yyset_column(0, context->getScanner());
938     yyset_lineno(1, context->getScanner());
939 
940     // Initialize preprocessor.
941     angle::pp::Preprocessor *preprocessor = &context->getPreprocessor();
942 
943     if (!preprocessor->init(count, string, length))
944         return 1;
945 
946     if (context->getFragmentPrecisionHigh())
947         preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
948 
949     preprocessor->setMaxTokenSize(sh::GetGlobalMaxTokenSize(context->getShaderSpec()));
950 
951     return 0;
952 }
953