• 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 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