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_reserved_ES3_keyword(TParseContext *context, int token);
100 static int ES2_keyword_ES3_reserved(TParseContext *context, int token);
101 static int ES3_keyword(TParseContext *context, int token);
102 static int ES3_reserved_ES3_1_keyword(TParseContext *context, int token);
103 static int ES2_reserved_ES3_1_keyword(TParseContext *context, int token);
104 static int ES3_1_keyword(TParseContext *context, int token);
105 static int ES2_reserved_ES2_extension_ES3_keyword(TParseContext *context, TExtension extension, int token);
106 static int ES3_extension(TParseContext *context, TExtension extension, int token);
107 static int ES3_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token);
108 static int ES3_reserved_ES3_extension(TParseContext *context, TExtension extension, int token);
109 static int ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext *context, TExtension extension, int token);
110 static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token);
111 static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token1, int token2);
112 static int WEBGL_video_texture_extension(TParseContext *context, int token);
113 static int uint_constant(TParseContext *context);
114 static int int_constant(TParseContext *context);
115 static int float_constant(yyscan_t yyscanner);
116 static int floatsuffix_check(TParseContext* context);
117 static int yuvcscstandardext_constant(TParseContext *context);
118 %}
119
120 %option noyywrap nounput never-interactive
121 %option yylineno reentrant bison-bridge bison-locations
122 %option extra-type="TParseContext*"
123 %x FIELDS
124
125 D [0-9]
126 L [a-zA-Z_]
127 H [a-fA-F0-9]
128 E [Ee][+-]?{D}+
129 O [0-7]
130
131 %%
132
133 %{
134 TParseContext* context = yyextra;
135 %}
136
137 "invariant" { return INVARIANT; }
138 "highp" { return HIGH_PRECISION; }
139 "mediump" { return MEDIUM_PRECISION; }
140 "lowp" { return LOW_PRECISION; }
141 "precision" { return PRECISION; }
142
143 "attribute" { return ES2_keyword_ES3_reserved(context, ATTRIBUTE); }
144 "const" { return CONST_QUAL; }
145 "uniform" { return UNIFORM; }
146 "buffer" { return ES3_1_keyword(context, BUFFER); }
147 "varying" { return ES2_keyword_ES3_reserved(context, VARYING); }
148
149 "break" { return BREAK; }
150 "continue" { return CONTINUE; }
151 "do" { return DO; }
152 "for" { return FOR; }
153 "while" { return WHILE; }
154
155 "if" { return IF; }
156 "else" { return ELSE; }
157 "switch" { return ES2_reserved_ES3_keyword(context, SWITCH); }
158 "case" { return ES3_keyword(context, CASE); }
159 "default" { return ES2_reserved_ES3_keyword(context, DEFAULT); }
160
161 "centroid" { return ES3_keyword(context, CENTROID); }
162 "flat" { return ES2_reserved_ES3_keyword(context, FLAT); }
163 "smooth" { return ES3_keyword(context, SMOOTH); }
164 "noperspective" { return ES3_reserved_ES3_extension(context, TExtension::NV_shader_noperspective_interpolation, NOPERSPECTIVE); }
165
166 "in" { return IN_QUAL; }
167 "out" { return OUT_QUAL; }
168 "inout" { return INOUT_QUAL; }
169 "shared" { return ES3_1_keyword(context, SHARED); }
170
171 "float" { return FLOAT_TYPE; }
172 "int" { return INT_TYPE; }
173 "uint" { return ES3_keyword(context, UINT_TYPE); }
174 "void" { return VOID_TYPE; }
175 "bool" { return BOOL_TYPE; }
176 "true" { yylval->lex.b = true; return BOOLCONSTANT; }
177 "false" { yylval->lex.b = false; return BOOLCONSTANT; }
178
179 "discard" { return DISCARD; }
180 "return" { return RETURN; }
181
182 "mat2" { return MATRIX2; }
183 "mat3" { return MATRIX3; }
184 "mat4" { return MATRIX4; }
185
186 "mat2x2" { return ES3_keyword(context, MATRIX2); }
187 "mat3x3" { return ES3_keyword(context, MATRIX3); }
188 "mat4x4" { return ES3_keyword(context, MATRIX4); }
189
190 "mat2x3" { return ES3_keyword(context, MATRIX2x3); }
191 "mat3x2" { return ES3_keyword(context, MATRIX3x2); }
192 "mat2x4" { return ES3_keyword(context, MATRIX2x4); }
193 "mat4x2" { return ES3_keyword(context, MATRIX4x2); }
194 "mat3x4" { return ES3_keyword(context, MATRIX3x4); }
195 "mat4x3" { return ES3_keyword(context, MATRIX4x3); }
196
197 "vec2" { return VEC2; }
198 "vec3" { return VEC3; }
199 "vec4" { return VEC4; }
200 "ivec2" { return IVEC2; }
201 "ivec3" { return IVEC3; }
202 "ivec4" { return IVEC4; }
203 "bvec2" { return BVEC2; }
204 "bvec3" { return BVEC3; }
205 "bvec4" { return BVEC4; }
206 "uvec2" { return ES3_keyword(context, UVEC2); }
207 "uvec3" { return ES3_keyword(context, UVEC3); }
208 "uvec4" { return ES3_keyword(context, UVEC4); }
209
210 "sampler2D" { return SAMPLER2D; }
211 "samplerCube" { return SAMPLERCUBE; }
212 "samplerExternalOES" { return SAMPLER_EXTERNAL_OES; }
213 "sampler3D" { return ES2_reserved_ES2_extension_ES3_keyword(context, TExtension::OES_texture_3D, SAMPLER3D); }
214 "sampler3DRect" { return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); }
215 "sampler2DRect" { return SAMPLER2DRECT; }
216 "sampler2DArray" { return ES3_keyword(context, SAMPLER2DARRAY); }
217 "sampler2DMS" { return ES3_reserved_ES3_extension_ES3_1_keyword(context, TExtension::ANGLE_texture_multisample, SAMPLER2DMS); }
218 "isampler2D" { return ES3_keyword(context, ISAMPLER2D); }
219 "isampler3D" { return ES3_keyword(context, ISAMPLER3D); }
220 "isamplerCube" { return ES3_keyword(context, ISAMPLERCUBE); }
221 "isampler2DArray" { return ES3_keyword(context, ISAMPLER2DARRAY); }
222 "isampler2DMS" { return ES3_reserved_ES3_extension_ES3_1_keyword(context, TExtension::ANGLE_texture_multisample, ISAMPLER2DMS); }
223 "usampler2D" { return ES3_keyword(context, USAMPLER2D); }
224 "usampler3D" { return ES3_keyword(context, USAMPLER3D); }
225 "usamplerCube" { return ES3_keyword(context, USAMPLERCUBE); }
226 "usampler2DArray" { return ES3_keyword(context, USAMPLER2DARRAY); }
227 "usampler2DMS" { return ES3_reserved_ES3_extension_ES3_1_keyword(context, TExtension::ANGLE_texture_multisample, USAMPLER2DMS); }
228 "sampler2DShadow" { return ES2_reserved_ES3_keyword(context, SAMPLER2DSHADOW); }
229 "samplerCubeShadow" { return ES3_keyword(context, SAMPLERCUBESHADOW); }
230 "sampler2DArrayShadow" { return ES3_keyword(context, SAMPLER2DARRAYSHADOW); }
231 "__samplerExternal2DY2YEXT" { return ES3_extension(context, TExtension::EXT_YUV_target, SAMPLEREXTERNAL2DY2YEXT); }
232 "sampler2DMSArray" { return ES3_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::OES_texture_storage_multisample_2d_array, SAMPLER2DMSARRAY); }
233 "isampler2DMSArray" { return ES3_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::OES_texture_storage_multisample_2d_array, ISAMPLER2DMSARRAY); }
234 "usampler2DMSArray" { return ES3_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::OES_texture_storage_multisample_2d_array, USAMPLER2DMSARRAY); }
235 "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); }
236 "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); }
237 "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); }
238 "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); }
239 "samplerVideoWEBGL" { return WEBGL_video_texture_extension(context, SAMPLERVIDEOWEBGL); }
240 "struct" { return STRUCT; }
241
242 "layout" { return ES3_keyword(context, LAYOUT); }
243
244 "yuvCscStandardEXT" { return ES3_extension(context, TExtension::EXT_YUV_target, YUVCSCSTANDARDEXT); }
245 "itu_601" { return yuvcscstandardext_constant(context); }
246 "itu_601_full_range" { return yuvcscstandardext_constant(context); }
247 "itu_709" { return yuvcscstandardext_constant(context); }
248
249 "image2D" { return ES3_reserved_ES3_1_keyword(context, IMAGE2D); }
250 "iimage2D" { return ES3_reserved_ES3_1_keyword(context, IIMAGE2D); }
251 "uimage2D" { return ES3_reserved_ES3_1_keyword(context, UIMAGE2D); }
252 "image2DArray" { return ES3_reserved_ES3_1_keyword(context, IMAGE2DARRAY); }
253 "iimage2DArray" { return ES3_reserved_ES3_1_keyword(context, IIMAGE2DARRAY); }
254 "uimage2DArray" { return ES3_reserved_ES3_1_keyword(context, UIMAGE2DARRAY); }
255 "image3D" { return ES3_reserved_ES3_1_keyword(context, IMAGE3D); }
256 "uimage3D" { return ES3_reserved_ES3_1_keyword(context, UIMAGE3D); }
257 "iimage3D" { return ES3_reserved_ES3_1_keyword(context, IIMAGE3D); }
258 "iimageCube" { return ES3_reserved_ES3_1_keyword(context, IIMAGECUBE); }
259 "uimageCube" { return ES3_reserved_ES3_1_keyword(context, UIMAGECUBE); }
260 "imageCube" { return ES3_reserved_ES3_1_keyword(context, IMAGECUBE); }
261 "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); }
262 "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); }
263 "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); }
264 "readonly" { return ES3_reserved_ES3_1_keyword(context, READONLY); }
265 "writeonly" { return ES3_reserved_ES3_1_keyword(context, WRITEONLY); }
266 "coherent" { return ES3_reserved_ES3_1_keyword(context, COHERENT); }
267 "restrict" { return ES3_reserved_ES3_1_keyword(context, RESTRICT); }
268 "volatile" { return ES2_reserved_ES3_1_keyword(context, VOLATILE); }
269 "atomic_uint" { return ES3_reserved_ES3_1_keyword(context, ATOMICUINT); }
270
271 "precise" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::EXT_gpu_shader5, PRECISE); }
272
273 /* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */
274 "resource" |
275 "patch" |
276 "sample" |
277 "subroutine" |
278 "common" |
279 "partition" |
280 "active" |
281
282 "filter" |
283 "image1D" |
284 "iimage1D" |
285 "uimage1D" |
286 "image1DArray" |
287 "iimage1DArray" |
288 "uimage1DArray" |
289 "image1DShadow" |
290 "image2DShadow" |
291 "image1DArrayShadow" |
292 "image2DArrayShadow" |
293 "imageBuffer" |
294 "iimageBuffer" |
295 "uimageBuffer" |
296
297 "sampler1DArray" |
298 "sampler1DArrayShadow" |
299 "isampler1D" |
300 "isampler1DArray" |
301 "usampler1D" |
302 "usampler1DArray" |
303 "isampler2DRect" |
304 "usampler2DRect" |
305 "samplerBuffer" |
306 "isamplerBuffer" |
307 "usamplerBuffer" {
308 if (context->getShaderVersion() < 300) {
309 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
310 return check_type(yyscanner);
311 }
312 return reserved_word(yyscanner);
313 }
314
315 /* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */
316 "packed" {
317 if (context->getShaderVersion() >= 300)
318 {
319 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
320 return check_type(yyscanner);
321 }
322
323 return reserved_word(yyscanner);
324 }
325
326 /* Reserved keywords */
327 "asm" |
328
329 "class" |
330 "union" |
331 "enum" |
332 "typedef" |
333 "template" |
334 "this" |
335
336 "goto" |
337
338 "inline" |
339 "noinline" |
340 "public" |
341 "static" |
342 "extern" |
343 "external" |
344 "interface" |
345
346 "long" |
347 "short" |
348 "double" |
349 "half" |
350 "fixed" |
351 "unsigned" |
352 "superp" |
353
354 "input" |
355 "output" |
356
357 "hvec2" |
358 "hvec3" |
359 "hvec4" |
360 "dvec2" |
361 "dvec3" |
362 "dvec4" |
363 "fvec2" |
364 "fvec3" |
365 "fvec4" |
366
367 "sampler1D" |
368 "sampler1DShadow" |
369 "sampler2DRectShadow" |
370
371 "sizeof" |
372 "cast" |
373
374 "namespace" |
375 "using" { return reserved_word(yyscanner); }
376
377 {L}({L}|{D})* {
378 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
379 return check_type(yyscanner);
380 }
381
382 0[xX]{H}+ { return int_constant(context); }
383 0{O}+ { return int_constant(context); }
384 {D}+ { return int_constant(context); }
385
386 0[xX]{H}+[uU] { return uint_constant(context); }
387 0{O}+[uU] { return uint_constant(context); }
388 {D}+[uU] { return uint_constant(context); }
389
390 {D}+{E} { return float_constant(yyscanner); }
391 {D}+"."{D}*({E})? { return float_constant(yyscanner); }
392 "."{D}+({E})? { return float_constant(yyscanner); }
393
394 {D}+{E}[fF] { return floatsuffix_check(context); }
395 {D}+"."{D}*({E})?[fF] { return floatsuffix_check(context); }
396 "."{D}+({E})?[fF] { return floatsuffix_check(context); }
397
398 "+=" { return ADD_ASSIGN; }
399 "-=" { return SUB_ASSIGN; }
400 "*=" { return MUL_ASSIGN; }
401 "/=" { return DIV_ASSIGN; }
402 "%=" { return MOD_ASSIGN; }
403 "<<=" { return LEFT_ASSIGN; }
404 ">>=" { return RIGHT_ASSIGN; }
405 "&=" { return AND_ASSIGN; }
406 "^=" { return XOR_ASSIGN; }
407 "|=" { return OR_ASSIGN; }
408
409 "++" { return INC_OP; }
410 "--" { return DEC_OP; }
411 "&&" { return AND_OP; }
412 "||" { return OR_OP; }
413 "^^" { return XOR_OP; }
414 "<=" { return LE_OP; }
415 ">=" { return GE_OP; }
416 "==" { return EQ_OP; }
417 "!=" { return NE_OP; }
418 "<<" { return LEFT_OP; }
419 ">>" { return RIGHT_OP; }
420 ";" { return SEMICOLON; }
421 ("{"|"<%") { return LEFT_BRACE; }
422 ("}"|"%>") { return RIGHT_BRACE; }
423 "," { return COMMA; }
424 ":" { return COLON; }
425 "=" { return EQUAL; }
426 "(" { return LEFT_PAREN; }
427 ")" { return RIGHT_PAREN; }
428 ("["|"<:") { return LEFT_BRACKET; }
429 ("]"|":>") { return RIGHT_BRACKET; }
430 "." { BEGIN(FIELDS); return DOT; }
431 "!" { return BANG; }
432 "-" { return DASH; }
433 "~" { return TILDE; }
434 "+" { return PLUS; }
435 "*" { return STAR; }
436 "/" { return SLASH; }
437 "%" { return PERCENT; }
438 "<" { return LEFT_ANGLE; }
439 ">" { return RIGHT_ANGLE; }
440 "|" { return VERTICAL_BAR; }
441 "^" { return CARET; }
442 "&" { return AMPERSAND; }
443 "?" { return QUESTION; }
444
445 <FIELDS>{L}({L}|{D})* {
446 BEGIN(INITIAL);
447 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
448 return FIELD_SELECTION;
449 }
450 <FIELDS>[ \t\v\f\r] {}
451 <FIELDS>. {
452 yyextra->error(*yylloc, "Illegal character at fieldname start", yytext);
453 return 0;
454 }
455
456 [ \t\v\n\f\r] { }
457 <*><<EOF>> { yyterminate(); }
458 <*>. { assert(false); return 0; }
459
460 %%
461
462 yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
463 angle::pp::Token token;
464 yyget_extra(yyscanner)->getPreprocessor().lex(&token);
465 yy_size_t len = token.type == angle::pp::Token::LAST ? 0 : token.text.size();
466 if (len < max_size)
467 memcpy(buf, token.text.c_str(), len);
468 yyset_column(token.location.file, yyscanner);
469 yyset_lineno(token.location.line, yyscanner);
470
471 if (len >= max_size)
472 YY_FATAL_ERROR("Input buffer overflow");
473 else if (len > 0)
474 buf[len++] = ' ';
475 return len;
476 }
477
check_type(yyscan_t yyscanner)478 int check_type(yyscan_t yyscanner) {
479 struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
480
481 int token = IDENTIFIER;
482 // 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.
483 const TSymbol* symbol = yyextra->symbolTable.find(ImmutableString(yytext, yyleng), yyextra->getShaderVersion());
484 if (symbol && symbol->isStruct())
485 {
486 token = TYPE_NAME;
487 }
488 yylval->lex.symbol = symbol;
489 return token;
490 }
491
reserved_word(yyscan_t yyscanner)492 int reserved_word(yyscan_t yyscanner) {
493 struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
494
495 yyextra->error(*yylloc, "Illegal use of reserved word", yytext);
496 return 0;
497 }
498
is_extension_enabled_or_is_core(TParseContext * context,int extension_version,TExtension extension,int promotion_version)499 static bool is_extension_enabled_or_is_core(TParseContext *context,
500 int extension_version, TExtension extension, int promotion_version)
501 {
502 int version = context->getShaderVersion();
503
504 // If version is at least promotion_version, symbol is definitely keyword. Otherwise it's a
505 // keyword if version is at least extension_version (where the extension was introduced) and
506 // the extension is enabled.
507 return version >= promotion_version ||
508 (version >= extension_version && context->isExtensionEnabled(extension));
509 }
510
ES2_reserved_ES3_keyword(TParseContext * context,int token)511 int ES2_reserved_ES3_keyword(TParseContext *context, int token)
512 {
513 yyscan_t yyscanner = (yyscan_t) context->getScanner();
514
515 if (context->getShaderVersion() < 300)
516 {
517 return reserved_word(yyscanner);
518 }
519
520 return token;
521 }
522
ES2_keyword_ES3_reserved(TParseContext * context,int token)523 int ES2_keyword_ES3_reserved(TParseContext *context, int token)
524 {
525 yyscan_t yyscanner = (yyscan_t) context->getScanner();
526
527 if (context->getShaderVersion() >= 300)
528 {
529 return reserved_word(yyscanner);
530 }
531
532 return token;
533 }
534
ES3_reserved_ES3_1_keyword(TParseContext * context,int token)535 int ES3_reserved_ES3_1_keyword(TParseContext *context, int token)
536 {
537 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
538 yyscan_t yyscanner = (yyscan_t) context->getScanner();
539
540 if (context->getShaderVersion() < 300)
541 {
542 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
543 return check_type(yyscanner);
544 }
545 else if (context->getShaderVersion() == 300)
546 {
547 return reserved_word(yyscanner);
548 }
549
550 return token;
551 }
552
ES3_keyword(TParseContext * context,int token)553 int ES3_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 // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
559 if (context->getShaderVersion() < 300)
560 {
561 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
562 return check_type(yyscanner);
563 }
564
565 return token;
566 }
567
ES2_reserved_ES3_1_keyword(TParseContext * context,int token)568 int ES2_reserved_ES3_1_keyword(TParseContext *context, int token)
569 {
570 yyscan_t yyscanner = (yyscan_t) context->getScanner();
571
572 if (context->getShaderVersion() < 310)
573 {
574 return reserved_word(yyscanner);
575 }
576
577 return token;
578 }
579
ES3_1_keyword(TParseContext * context,int token)580 int ES3_1_keyword(TParseContext *context, int token)
581 {
582 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
583 yyscan_t yyscanner = (yyscan_t) context->getScanner();
584
585 // A keyword in GLSL ES 3.10.
586 if (context->getShaderVersion() >= 310)
587 {
588 return token;
589 }
590
591 // Otherwise can be used as an identifier/type name
592 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
593 return check_type(yyscanner);
594 }
595
WEBGL_video_texture_extension(TParseContext * context,int token)596 int WEBGL_video_texture_extension(TParseContext *context, int token)
597 {
598 // Available with WEBGL_video_texture_extension
599 if (context->isExtensionEnabled(TExtension::WEBGL_video_texture))
600 {
601 return token;
602 }
603
604 // Otherwise can be used as an identifier/type name
605 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
606 yyscan_t yyscanner = (yyscan_t) context->getScanner();
607
608 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
609 return check_type(yyscanner);
610 }
611
ES2_reserved_ES2_extension_ES3_keyword(TParseContext * context,TExtension extension,int token)612 int ES2_reserved_ES2_extension_ES3_keyword(TParseContext *context, TExtension extension, int token)
613 {
614 yyscan_t yyscanner = (yyscan_t) context->getScanner();
615
616 // A keyword in GLSL ES 3.00 or GLSL ES 1.00 with enabled extension.
617 if (is_extension_enabled_or_is_core(context, 100, extension, 300))
618 {
619 return token;
620 }
621
622 // Reserved otherwise.
623 return reserved_word(yyscanner);
624 }
625
ES3_extension(TParseContext * context,TExtension extension,int token)626 int ES3_extension(TParseContext *context, TExtension extension, int token)
627 {
628 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
629 yyscan_t yyscanner = (yyscan_t) context->getScanner();
630
631 // a keyword word in GLSL ES 3.00 with enabled extension.
632 if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(extension))
633 {
634 return token;
635 }
636
637 // Otherwise can be used as an identifier/type name
638 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
639 return check_type(yyscanner);
640 }
641
ES3_reserved_ES3_1_extension_ES3_2_keyword(TParseContext * context,TExtension extension,int token)642 int ES3_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token)
643 {
644 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
645 yyscan_t yyscanner = (yyscan_t) context->getScanner();
646
647 // a keyword in GLSL ES 3.10 with enabled extension
648 if (is_extension_enabled_or_is_core(context, 310, extension, 320))
649 {
650 return token;
651 }
652 // a reserved word in GLSL ES 3.00+
653 if (context->getShaderVersion() >= 300)
654 {
655 return reserved_word(yyscanner);
656 }
657
658 // Otherwise can be used as an identifier/type name
659 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
660 return check_type(yyscanner);
661 }
662
ES3_reserved_ES3_extension(TParseContext * context,TExtension extension,int token)663 int ES3_reserved_ES3_extension(TParseContext *context, TExtension extension, int token)
664 {
665 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
666 yyscan_t yyscanner = (yyscan_t) context->getScanner();
667
668 if(context->getShaderVersion() >= 300)
669 {
670 if (context->isExtensionEnabled(extension)) {
671 return token;
672 } else {
673 return reserved_word(yyscanner);
674 }
675 }
676
677 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
678 return check_type(yyscanner);
679 }
680
ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext * context,TExtension extension,int token)681 int ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext *context, TExtension extension, int token)
682 {
683 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
684 yyscan_t yyscanner = (yyscan_t) context->getScanner();
685
686 // A keyword in GLSL ES 3.00 with enabled extension or in GLSL ES 3.10
687 if (is_extension_enabled_or_is_core(context, 300, extension, 310))
688 {
689 return token;
690 }
691
692 if(context->getShaderVersion() == 300)
693 {
694 return reserved_word(yyscanner);
695 }
696
697 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
698 return check_type(yyscanner);
699 }
700
ES3_1_reserved_ES3_1_extension_ES3_2_keyword(TParseContext * context,TExtension extension,int token)701 static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token)
702 {
703 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
704 yyscan_t yyscanner = (yyscan_t) context->getScanner();
705
706 // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
707 if (is_extension_enabled_or_is_core(context, 310, extension, 320))
708 {
709 return token;
710 }
711
712 // A reserved word in GLSL ES 3.10
713 if (context->getShaderVersion() == 310)
714 {
715 return reserved_word(yyscanner);
716 }
717
718 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
719 return check_type(yyscanner);
720 }
721
ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext * context,TExtension extension1,TExtension extension2,int token1,int token2)722 static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token1, int token2)
723 {
724 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
725 yyscan_t yyscanner = (yyscan_t) context->getScanner();
726
727 // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
728 if (is_extension_enabled_or_is_core(context, 310, extension1, 320))
729 {
730 return token1;
731 }
732 else if (is_extension_enabled_or_is_core(context, 310, extension2, 320))
733 {
734 return token2;
735 }
736
737 // A reserved word in GLSL ES 3.10
738 if (context->getShaderVersion() == 310)
739 {
740 return reserved_word(yyscanner);
741 }
742
743 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
744 return check_type(yyscanner);
745 }
746
uint_constant(TParseContext * context)747 int uint_constant(TParseContext *context)
748 {
749 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
750
751 if (context->getShaderVersion() < 300)
752 {
753 context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext);
754 return 0;
755 }
756
757 if (!atoi_clamp(yytext, &(yylval->lex.u)))
758 yyextra->error(*yylloc, "Integer overflow", yytext);
759
760 return UINTCONSTANT;
761 }
762
floatsuffix_check(TParseContext * context)763 int floatsuffix_check(TParseContext* context)
764 {
765 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
766
767 if (context->getShaderVersion() < 300)
768 {
769 context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext);
770 return 0;
771 }
772
773 std::string text = yytext;
774 text.resize(text.size() - 1);
775 if (!strtof_clamp(text, &(yylval->lex.f)))
776 yyextra->warning(*yylloc, "Float overflow", yytext);
777
778 return(FLOATCONSTANT);
779 }
780
yyerror(YYLTYPE * lloc,TParseContext * context,void * scanner,const char * reason)781 void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* reason) {
782 context->error(*lloc, reason, yyget_text(scanner));
783 }
784
int_constant(TParseContext * context)785 int int_constant(TParseContext *context) {
786 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
787
788 unsigned int u;
789 if (!atoi_clamp(yytext, &u))
790 {
791 if (context->getShaderVersion() >= 300)
792 yyextra->error(*yylloc, "Integer overflow", yytext);
793 else
794 yyextra->warning(*yylloc, "Integer overflow", yytext);
795 }
796 yylval->lex.i = static_cast<int>(u);
797 return INTCONSTANT;
798 }
799
float_constant(yyscan_t yyscanner)800 int float_constant(yyscan_t yyscanner) {
801 struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
802
803 if (!strtof_clamp(yytext, &(yylval->lex.f)))
804 yyextra->warning(*yylloc, "Float overflow", yytext);
805 return FLOATCONSTANT;
806 }
807
yuvcscstandardext_constant(TParseContext * context)808 int yuvcscstandardext_constant(TParseContext *context)
809 {
810 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
811 yyscan_t yyscanner = (yyscan_t) context->getScanner();
812
813 // a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an identifier/type name
814 if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(TExtension::EXT_YUV_target))
815 {
816 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
817 return YUVCSCSTANDARDEXTCONSTANT;
818 }
819
820 yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
821 return check_type(yyscanner);
822 }
823
glslang_initialize(TParseContext * context)824 int glslang_initialize(TParseContext* context) {
825 yyscan_t scanner = NULL;
826 if (yylex_init_extra(context, &scanner))
827 return 1;
828
829 context->setScanner(scanner);
830 return 0;
831 }
832
glslang_finalize(TParseContext * context)833 int glslang_finalize(TParseContext* context) {
834 yyscan_t scanner = context->getScanner();
835 if (scanner == NULL) return 0;
836
837 context->setScanner(NULL);
838 yylex_destroy(scanner);
839
840 return 0;
841 }
842
glslang_scan(size_t count,const char * const string[],const int length[],TParseContext * context)843 int glslang_scan(size_t count, const char* const string[], const int length[],
844 TParseContext* context) {
845 yyrestart(NULL, context->getScanner());
846 yyset_column(0, context->getScanner());
847 yyset_lineno(1, context->getScanner());
848
849 // Initialize preprocessor.
850 angle::pp::Preprocessor *preprocessor = &context->getPreprocessor();
851
852 if (!preprocessor->init(count, string, length))
853 return 1;
854
855 // Define extension macros.
856 const TExtensionBehavior& extBehavior = context->extensionBehavior();
857 for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
858 iter != extBehavior.end(); ++iter) {
859 // OVR_multiview should not be defined for WebGL spec'ed shaders.
860 if (sh::IsWebGLBasedSpec(context->getShaderSpec()) &&
861 iter->first == TExtension::OVR_multiview) {
862 continue;
863 }
864 preprocessor->predefineMacro(GetExtensionNameString(iter->first), 1);
865 }
866 if (context->getFragmentPrecisionHigh())
867 preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
868
869 preprocessor->setMaxTokenSize(sh::GetGlobalMaxTokenSize(context->getShaderSpec()));
870
871 return 0;
872 }
873