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