• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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