1 /*
2 //
3 // Copyright (c) 2002-2013 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 generate_parser.sh,
13 WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
14 */
15 
16 %top{
17 //
18 // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
19 // Use of this source code is governed by a BSD-style license that can be
20 // found in the LICENSE file.
21 //
22 
23 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
24 
25 /* clang-format off */
26 
27 // Ignore errors in auto-generated code.
28 #if defined(__GNUC__)
29 #pragma GCC diagnostic ignored "-Wunused-function"
30 #pragma GCC diagnostic ignored "-Wunused-variable"
31 #pragma GCC diagnostic ignored "-Wswitch-enum"
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 }
42 
43 %{
44 #include "compiler/translator/glslang.h"
45 #include "compiler/translator/ParseContext.h"
46 #include "compiler/preprocessor/Token.h"
47 #include "compiler/translator/util.h"
48 #include "compiler/translator/length_limits.h"
49 
50 using namespace sh;
51 
52 #include "glslang_tab.h"
53 
54 /* windows only pragma */
55 #ifdef _MSC_VER
56 #pragma warning(disable : 4102)
57 #endif
58 
59 // Workaround for flex using the register keyword, deprecated in C++11.
60 #ifdef __cplusplus
61 #if __cplusplus > 199711L
62 #define register
63 #endif
64 #endif
65 
66 #define YY_USER_ACTION                                 \
67     yylloc->first_file = yylloc->last_file = yycolumn; \
68     yylloc->first_line = yylloc->last_line = yylineno;
69 
70 #define YY_INPUT(buf, result, max_size) \
71     result = string_input(buf, max_size, yyscanner);
72 
73 static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner);
74 static int check_type(yyscan_t yyscanner);
75 static int reserved_word(yyscan_t yyscanner);
76 static int ES2_reserved_ES3_keyword(TParseContext *context, int token);
77 static int ES2_keyword_ES3_reserved(TParseContext *context, int token);
78 static int ES2_ident_ES3_keyword(TParseContext *context, int token);
79 static int ES2_ident_ES3_keyword_multiview_keyword(TParseContext *context, int token);
80 static int ES2_ident_ES3_reserved_ES3_1_keyword(TParseContext *context, int token);
81 static int ES2_and_ES3_reserved_ES3_1_keyword(TParseContext *context, int token);
82 static int ES2_and_ES3_ident_ES3_1_keyword(TParseContext *context, int token);
83 static int ES3_extension_keyword_else_ident(TParseContext *context, TExtension extension, int token);
84 static int uint_constant(TParseContext *context);
85 static int int_constant(TParseContext *context);
86 static int float_constant(yyscan_t yyscanner);
87 static int floatsuffix_check(TParseContext* context);
88 static int yuvcscstandardext_constant(TParseContext *context);
89 %}
90 
91 %option noyywrap nounput never-interactive
92 %option yylineno reentrant bison-bridge bison-locations
93 %option extra-type="TParseContext*"
94 %x FIELDS
95 
96 D           [0-9]
97 L           [a-zA-Z_]
98 H           [a-fA-F0-9]
99 E           [Ee][+-]?{D}+
100 O           [0-7]
101 
102 %%
103 
104 %{
105     TParseContext* context = yyextra;
106 %}
107 
108 "invariant"    { return INVARIANT; }
109 "highp"        { return HIGH_PRECISION; }
110 "mediump"      { return MEDIUM_PRECISION; }
111 "lowp"         { return LOW_PRECISION; }
112 "precision"    { return PRECISION; }
113 
114 "attribute"    { return ES2_keyword_ES3_reserved(context, ATTRIBUTE); }
115 "const"        { return CONST_QUAL; }
116 "uniform"      { return UNIFORM; }
117 "buffer"       { return ES2_and_ES3_ident_ES3_1_keyword(context, BUFFER); }
118 "varying"      { return ES2_keyword_ES3_reserved(context, VARYING); }
119 
120 "break"        { return BREAK; }
121 "continue"     { return CONTINUE; }
122 "do"           { return DO; }
123 "for"          { return FOR; }
124 "while"        { return WHILE; }
125 
126 "if"           { return IF; }
127 "else"         { return ELSE; }
128 "switch"       { return ES2_reserved_ES3_keyword(context, SWITCH); }
129 "case"         { return ES2_ident_ES3_keyword(context, CASE); }
130 "default"      { return ES2_reserved_ES3_keyword(context, DEFAULT); }
131 
132 "centroid"     { return ES2_ident_ES3_keyword(context, CENTROID); }
133 "flat"         { return ES2_reserved_ES3_keyword(context, FLAT); }
134 "smooth"       { return ES2_ident_ES3_keyword(context, SMOOTH); }
135 
136 "in"           { return IN_QUAL; }
137 "out"          { return OUT_QUAL; }
138 "inout"        { return INOUT_QUAL; }
139 "shared"       { return ES2_and_ES3_ident_ES3_1_keyword(context, SHARED); }
140 
141 "float"        { return FLOAT_TYPE; }
142 "int"          { return INT_TYPE; }
143 "uint"         { return ES2_ident_ES3_keyword(context, UINT_TYPE); }
144 "void"         { return VOID_TYPE; }
145 "bool"         { return BOOL_TYPE; }
146 "true"         { yylval->lex.b = true;  return BOOLCONSTANT; }
147 "false"        { yylval->lex.b = false; return BOOLCONSTANT; }
148 
149 "discard"      { return DISCARD; }
150 "return"       { return RETURN; }
151 
152 "mat2"         { return MATRIX2; }
153 "mat3"         { return MATRIX3; }
154 "mat4"         { return MATRIX4; }
155 
156 "mat2x2"         { return ES2_ident_ES3_keyword(context, MATRIX2); }
157 "mat3x3"         { return ES2_ident_ES3_keyword(context, MATRIX3); }
158 "mat4x4"         { return ES2_ident_ES3_keyword(context, MATRIX4); }
159 
160 "mat2x3"         { return ES2_ident_ES3_keyword(context, MATRIX2x3); }
161 "mat3x2"         { return ES2_ident_ES3_keyword(context, MATRIX3x2); }
162 "mat2x4"         { return ES2_ident_ES3_keyword(context, MATRIX2x4); }
163 "mat4x2"         { return ES2_ident_ES3_keyword(context, MATRIX4x2); }
164 "mat3x4"         { return ES2_ident_ES3_keyword(context, MATRIX3x4); }
165 "mat4x3"         { return ES2_ident_ES3_keyword(context, MATRIX4x3); }
166 
167 "vec2"         { return VEC2; }
168 "vec3"         { return VEC3; }
169 "vec4"         { return VEC4; }
170 "ivec2"        { return IVEC2; }
171 "ivec3"        { return IVEC3; }
172 "ivec4"        { return IVEC4; }
173 "bvec2"        { return BVEC2; }
174 "bvec3"        { return BVEC3; }
175 "bvec4"        { return BVEC4; }
176 "uvec2"        { return ES2_ident_ES3_keyword(context, UVEC2); }
177 "uvec3"        { return ES2_ident_ES3_keyword(context, UVEC3); }
178 "uvec4"        { return ES2_ident_ES3_keyword(context, UVEC4); }
179 
180 "sampler2D"            { return SAMPLER2D; }
181 "samplerCube"          { return SAMPLERCUBE; }
182 "samplerExternalOES"   { return SAMPLER_EXTERNAL_OES; }
183 "sampler3D"            { return ES2_reserved_ES3_keyword(context, SAMPLER3D); }
184 "sampler3DRect"        { return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); }
185 "sampler2DRect"        { return SAMPLER2DRECT; }
186 "sampler2DArray"       { return ES2_ident_ES3_keyword(context, SAMPLER2DARRAY); }
187 "sampler2DMS"          { return ES2_ident_ES3_reserved_ES3_1_keyword(context, SAMPLER2DMS); }
188 "isampler2D"           { return ES2_ident_ES3_keyword(context, ISAMPLER2D); }
189 "isampler3D"           { return ES2_ident_ES3_keyword(context, ISAMPLER3D); }
190 "isamplerCube"         { return ES2_ident_ES3_keyword(context, ISAMPLERCUBE); }
191 "isampler2DArray"      { return ES2_ident_ES3_keyword(context, ISAMPLER2DARRAY); }
192 "isampler2DMS"         { return ES2_ident_ES3_reserved_ES3_1_keyword(context, ISAMPLER2DMS); }
193 "usampler2D"           { return ES2_ident_ES3_keyword(context, USAMPLER2D); }
194 "usampler3D"           { return ES2_ident_ES3_keyword(context, USAMPLER3D); }
195 "usamplerCube"         { return ES2_ident_ES3_keyword(context, USAMPLERCUBE); }
196 "usampler2DArray"      { return ES2_ident_ES3_keyword(context, USAMPLER2DARRAY); }
197 "usampler2DMS"         { return ES2_ident_ES3_reserved_ES3_1_keyword(context, USAMPLER2DMS); }
198 "sampler2DShadow"      { return ES2_reserved_ES3_keyword(context, SAMPLER2DSHADOW); }
199 "samplerCubeShadow"    { return ES2_ident_ES3_keyword(context, SAMPLERCUBESHADOW); }
200 "sampler2DArrayShadow" { return ES2_ident_ES3_keyword(context, SAMPLER2DARRAYSHADOW); }
201 "__samplerExternal2DY2YEXT"   { return ES3_extension_keyword_else_ident(context, TExtension::EXT_YUV_target, SAMPLEREXTERNAL2DY2YEXT); }
202 
203 "struct"       { return STRUCT; }
204 
205 "layout"  { return ES2_ident_ES3_keyword_multiview_keyword(context, LAYOUT); }
206 
207 "yuvCscStandardEXT"    { return ES3_extension_keyword_else_ident(context, TExtension::EXT_YUV_target, YUVCSCSTANDARDEXT); }
208 "itu_601"              { return yuvcscstandardext_constant(context); }
209 "itu_601_full_range"   { return yuvcscstandardext_constant(context); }
210 "itu_709"              { return yuvcscstandardext_constant(context); }
211 
212 "image2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE2D); }
213 "iimage2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE2D); }
214 "uimage2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE2D); }
215 "image2DArray" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE2DARRAY); }
216 "iimage2DArray" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE2DARRAY); }
217 "uimage2DArray" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE2DARRAY); }
218 "image3D"  { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE3D); }
219 "uimage3D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE3D); }
220 "iimage3D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE3D); }
221 "iimageCube" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGECUBE); }
222 "uimageCube" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGECUBE); }
223 "imageCube"	{ return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGECUBE); }
224 "readonly" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, READONLY); }
225 "writeonly" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, WRITEONLY); }
226 "coherent" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, COHERENT); }
227 "restrict" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, RESTRICT); }
228 "volatile" { return ES2_and_ES3_reserved_ES3_1_keyword(context, VOLATILE); }
229 "atomic_uint" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, ATOMICUINT); }
230 
231     /* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */
232 "resource"          |
233 "noperspective"     |
234 "patch"             |
235 "sample"            |
236 "subroutine"        |
237 "common"            |
238 "partition"         |
239 "active"            |
240 
241 "filter"            |
242 "image1D"           |
243 "iimage1D"          |
244 "uimage1D"          |
245 "image1DArray"      |
246 "iimage1DArray"     |
247 "uimage1DArray"     |
248 "image1DShadow"     |
249 "image2DShadow"     |
250 "image1DArrayShadow" |
251 "image2DArrayShadow" |
252 "imageBuffer"       |
253 "iimageBuffer"      |
254 "uimageBuffer"      |
255 
256 "sampler1DArray"    |
257 "sampler1DArrayShadow" |
258 "isampler1D"        |
259 "isampler1DArray"   |
260 "usampler1D"        |
261 "usampler1DArray"   |
262 "isampler2DRect"    |
263 "usampler2DRect"    |
264 "samplerBuffer"     |
265 "isamplerBuffer"    |
266 "usamplerBuffer"    |
267 "sampler2DMSArray"  |
268 "isampler2DMSArray" |
269 "usampler2DMSArray" {
270     if (context->getShaderVersion() < 300) {
271 		yylval->lex.string = NewPoolTString(yytext);
272 	    return check_type(yyscanner);
273 	}
274 	return reserved_word(yyscanner);
275 }
276 
277     /* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */
278 "packed"  {
279     if (context->getShaderVersion() >= 300)
280     {
281         yylval->lex.string = NewPoolTString(yytext);
282         return check_type(yyscanner);
283     }
284 
285     return reserved_word(yyscanner);
286 }
287 
288     /* Reserved keywords */
289 "asm"          |
290 
291 "class"        |
292 "union"        |
293 "enum"         |
294 "typedef"      |
295 "template"     |
296 "this"         |
297 
298 "goto"         |
299 
300 "inline"       |
301 "noinline"     |
302 "public"       |
303 "static"       |
304 "extern"       |
305 "external"     |
306 "interface"    |
307 
308 "long"         |
309 "short"        |
310 "double"       |
311 "half"         |
312 "fixed"        |
313 "unsigned"     |
314 "superp"       |
315 
316 "input"        |
317 "output"       |
318 
319 "hvec2"        |
320 "hvec3"        |
321 "hvec4"        |
322 "dvec2"        |
323 "dvec3"        |
324 "dvec4"        |
325 "fvec2"        |
326 "fvec3"        |
327 "fvec4"        |
328 
329 "sampler1D"    |
330 "sampler1DShadow" |
331 "sampler2DRectShadow" |
332 
333 "sizeof"       |
334 "cast"         |
335 
336 "namespace"    |
337 "using"        { return reserved_word(yyscanner); }
338 
339 {L}({L}|{D})*       {
340    yylval->lex.string = NewPoolTString(yytext);
341    return check_type(yyscanner);
342 }
343 
344 0[xX]{H}+         { return int_constant(context); }
345 0{O}+             { return int_constant(context); }
346 {D}+              { return int_constant(context); }
347 
348 0[xX]{H}+[uU]     { return uint_constant(context); }
349 0{O}+[uU]         { return uint_constant(context); }
350 {D}+[uU]          { return uint_constant(context); }
351 
352 {D}+{E}           { return float_constant(yyscanner); }
353 {D}+"."{D}*({E})? { return float_constant(yyscanner); }
354 "."{D}+({E})?     { return float_constant(yyscanner); }
355 
356 {D}+{E}[fF]           { return floatsuffix_check(context); }
357 {D}+"."{D}*({E})?[fF] { return floatsuffix_check(context); }
358 "."{D}+({E})?[fF]     { return floatsuffix_check(context); }
359 
360 "+="            { return ADD_ASSIGN; }
361 "-="            { return SUB_ASSIGN; }
362 "*="            { return MUL_ASSIGN; }
363 "/="            { return DIV_ASSIGN; }
364 "%="            { return MOD_ASSIGN; }
365 "<<="           { return LEFT_ASSIGN; }
366 ">>="           { return RIGHT_ASSIGN; }
367 "&="            { return AND_ASSIGN; }
368 "^="            { return XOR_ASSIGN; }
369 "|="            { return OR_ASSIGN; }
370 
371 "++"            { return INC_OP; }
372 "--"            { return DEC_OP; }
373 "&&"            { return AND_OP; }
374 "||"            { return OR_OP; }
375 "^^"            { return XOR_OP; }
376 "<="            { return LE_OP; }
377 ">="            { return GE_OP; }
378 "=="            { return EQ_OP; }
379 "!="            { return NE_OP; }
380 "<<"            { return LEFT_OP; }
381 ">>"            { return RIGHT_OP; }
382 ";"             { return SEMICOLON; }
383 ("{"|"<%")      { return LEFT_BRACE; }
384 ("}"|"%>")      { return RIGHT_BRACE; }
385 ","             { return COMMA; }
386 ":"             { return COLON; }
387 "="             { return EQUAL; }
388 "("             { return LEFT_PAREN; }
389 ")"             { return RIGHT_PAREN; }
390 ("["|"<:")      { return LEFT_BRACKET; }
391 ("]"|":>")      { return RIGHT_BRACKET; }
392 "."             { BEGIN(FIELDS); return DOT; }
393 "!"             { return BANG; }
394 "-"             { return DASH; }
395 "~"             { return TILDE; }
396 "+"             { return PLUS; }
397 "*"             { return STAR; }
398 "/"             { return SLASH; }
399 "%"             { return PERCENT; }
400 "<"             { return LEFT_ANGLE; }
401 ">"             { return RIGHT_ANGLE; }
402 "|"             { return VERTICAL_BAR; }
403 "^"             { return CARET; }
404 "&"             { return AMPERSAND; }
405 "?"             { return QUESTION; }
406 
407 <FIELDS>{L}({L}|{D})* {
408     BEGIN(INITIAL);
409     yylval->lex.string = NewPoolTString(yytext);
410     return FIELD_SELECTION;
411 }
412 <FIELDS>[ \t\v\f\r] {}
413 <FIELDS>. {
414     yyextra->error(*yylloc, "Illegal character at fieldname start", yytext);
415     return 0;
416 }
417 
418 [ \t\v\n\f\r] { }
419 <*><<EOF>>    { yyterminate(); }
420 <*>.          { assert(false); return 0; }
421 
422 %%
423 
424 yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
425     pp::Token token;
426     yyget_extra(yyscanner)->getPreprocessor().lex(&token);
427     yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
428     if (len < max_size)
429         memcpy(buf, token.text.c_str(), len);
430     yyset_column(token.location.file, yyscanner);
431     yyset_lineno(token.location.line, yyscanner);
432 
433     if (len >= max_size)
434         YY_FATAL_ERROR("Input buffer overflow");
435     else if (len > 0)
436         buf[len++] = ' ';
437     return len;
438 }
439 
check_type(yyscan_t yyscanner)440 int check_type(yyscan_t yyscanner) {
441     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
442 
443     int token = IDENTIFIER;
444     TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion());
445     if (symbol && symbol->isVariable()) {
446         TVariable* variable = static_cast<TVariable*>(symbol);
447         if (variable->isUserType()) {
448             token = TYPE_NAME;
449         }
450     }
451     yylval->lex.symbol = symbol;
452     return token;
453 }
454 
reserved_word(yyscan_t yyscanner)455 int reserved_word(yyscan_t yyscanner) {
456     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
457 
458     yyextra->error(*yylloc, "Illegal use of reserved word", yytext);
459     return 0;
460 }
461 
ES2_reserved_ES3_keyword(TParseContext * context,int token)462 int ES2_reserved_ES3_keyword(TParseContext *context, int token)
463 {
464     yyscan_t yyscanner = (yyscan_t) context->getScanner();
465 
466     if (context->getShaderVersion() < 300)
467     {
468         return reserved_word(yyscanner);
469     }
470 
471     return token;
472 }
473 
ES2_keyword_ES3_reserved(TParseContext * context,int token)474 int ES2_keyword_ES3_reserved(TParseContext *context, int token)
475 {
476     yyscan_t yyscanner = (yyscan_t) context->getScanner();
477 
478     if (context->getShaderVersion() >= 300)
479     {
480         return reserved_word(yyscanner);
481     }
482 
483     return token;
484 }
485 
ES2_ident_ES3_reserved_ES3_1_keyword(TParseContext * context,int token)486 int ES2_ident_ES3_reserved_ES3_1_keyword(TParseContext *context, int token)
487 {
488     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
489     yyscan_t yyscanner = (yyscan_t) context->getScanner();
490 
491     if (context->getShaderVersion() < 300)
492     {
493         yylval->lex.string = NewPoolTString(yytext);
494         return check_type(yyscanner);
495     }
496     else if (context->getShaderVersion() == 300)
497     {
498         return reserved_word(yyscanner);
499     }
500 
501     return token;
502 }
503 
ES2_ident_ES3_keyword(TParseContext * context,int token)504 int ES2_ident_ES3_keyword(TParseContext *context, int token)
505 {
506     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
507     yyscan_t yyscanner = (yyscan_t) context->getScanner();
508 
509     // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
510     if (context->getShaderVersion() < 300)
511     {
512         yylval->lex.string = NewPoolTString(yytext);
513         return check_type(yyscanner);
514     }
515 
516     return token;
517 }
518 
ES2_ident_ES3_keyword_multiview_keyword(TParseContext * context,int token)519 int ES2_ident_ES3_keyword_multiview_keyword(TParseContext *context, int token)
520 {
521     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
522     yyscan_t yyscanner = (yyscan_t) context->getScanner();
523 
524     // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
525     // except when multiview extension is enabled
526     if (context->getShaderVersion() < 300 && !context->isExtensionEnabled(TExtension::OVR_multiview))
527     {
528         yylval->lex.string = NewPoolTString(yytext);
529         return check_type(yyscanner);
530     }
531 
532     return token;
533 }
534 
ES2_and_ES3_reserved_ES3_1_keyword(TParseContext * context,int token)535 int ES2_and_ES3_reserved_ES3_1_keyword(TParseContext *context, int token)
536 {
537     yyscan_t yyscanner = (yyscan_t) context->getScanner();
538 
539     if (context->getShaderVersion() < 310)
540     {
541         return reserved_word(yyscanner);
542     }
543 
544     return token;
545 }
546 
ES2_and_ES3_ident_ES3_1_keyword(TParseContext * context,int token)547 int ES2_and_ES3_ident_ES3_1_keyword(TParseContext *context, int token)
548 {
549     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
550     yyscan_t yyscanner = (yyscan_t) context->getScanner();
551 
552     // not a reserved word in GLSL ES 1.00 and GLSL ES 3.00, so could be used as an identifier/type name
553     if (context->getShaderVersion() < 310)
554     {
555         yylval->lex.string = NewPoolTString(yytext);
556         return check_type(yyscanner);
557     }
558 
559     return token;
560 }
561 
ES3_extension_keyword_else_ident(TParseContext * context,TExtension extension,int token)562 int ES3_extension_keyword_else_ident(TParseContext *context, TExtension extension, int token)
563 {
564     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
565     yyscan_t yyscanner = (yyscan_t) context->getScanner();
566 
567     // a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an identifier/type name
568     if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(extension))
569     {
570         return token;
571     }
572 
573     yylval->lex.string = NewPoolTString(yytext);
574     return check_type(yyscanner);
575 }
576 
uint_constant(TParseContext * context)577 int uint_constant(TParseContext *context)
578 {
579     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
580 
581     if (context->getShaderVersion() < 300)
582     {
583         context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext);
584         return 0;
585     }
586 
587     if (!atoi_clamp(yytext, &(yylval->lex.u)))
588         yyextra->error(*yylloc, "Integer overflow", yytext);
589 
590     return UINTCONSTANT;
591 }
592 
floatsuffix_check(TParseContext * context)593 int floatsuffix_check(TParseContext* context)
594 {
595     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
596 
597     if (context->getShaderVersion() < 300)
598     {
599         context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext);
600         return 0;
601     }
602 
603     std::string text = yytext;
604     text.resize(text.size() - 1);
605     if (!strtof_clamp(text, &(yylval->lex.f)))
606         yyextra->warning(*yylloc, "Float overflow", yytext);
607 
608     return(FLOATCONSTANT);
609 }
610 
yyerror(YYLTYPE * lloc,TParseContext * context,void * scanner,const char * reason)611 void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* reason) {
612     context->error(*lloc, reason, yyget_text(scanner));
613 }
614 
int_constant(TParseContext * context)615 int int_constant(TParseContext *context) {
616     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
617 
618     unsigned int u;
619     if (!atoi_clamp(yytext, &u))
620     {
621         if (context->getShaderVersion() >= 300)
622             yyextra->error(*yylloc, "Integer overflow", yytext);
623         else
624             yyextra->warning(*yylloc, "Integer overflow", yytext);
625     }
626     yylval->lex.i = static_cast<int>(u);
627     return INTCONSTANT;
628 }
629 
float_constant(yyscan_t yyscanner)630 int float_constant(yyscan_t yyscanner) {
631     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
632 
633     if (!strtof_clamp(yytext, &(yylval->lex.f)))
634         yyextra->warning(*yylloc, "Float overflow", yytext);
635     return FLOATCONSTANT;
636 }
637 
yuvcscstandardext_constant(TParseContext * context)638 int yuvcscstandardext_constant(TParseContext *context)
639 {
640     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
641     yyscan_t yyscanner = (yyscan_t) context->getScanner();
642 
643     // a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an identifier/type name
644     if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(TExtension::EXT_YUV_target))
645     {
646         yylval->lex.string = NewPoolTString(yytext);
647         return YUVCSCSTANDARDEXTCONSTANT;
648     }
649 
650     yylval->lex.string = NewPoolTString(yytext);
651     return check_type(yyscanner);
652 }
653 
glslang_initialize(TParseContext * context)654 int glslang_initialize(TParseContext* context) {
655     yyscan_t scanner = NULL;
656     if (yylex_init_extra(context, &scanner))
657         return 1;
658 
659     context->setScanner(scanner);
660     return 0;
661 }
662 
glslang_finalize(TParseContext * context)663 int glslang_finalize(TParseContext* context) {
664     yyscan_t scanner = context->getScanner();
665     if (scanner == NULL) return 0;
666 
667     context->setScanner(NULL);
668     yylex_destroy(scanner);
669 
670     return 0;
671 }
672 
glslang_scan(size_t count,const char * const string[],const int length[],TParseContext * context)673 int glslang_scan(size_t count, const char* const string[], const int length[],
674                  TParseContext* context) {
675     yyrestart(NULL, context->getScanner());
676     yyset_column(0, context->getScanner());
677     yyset_lineno(1, context->getScanner());
678 
679     // Initialize preprocessor.
680     pp::Preprocessor *preprocessor = &context->getPreprocessor();
681 
682     if (!preprocessor->init(count, string, length))
683         return 1;
684 
685     // Define extension macros.
686     const TExtensionBehavior& extBehavior = context->extensionBehavior();
687     for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
688          iter != extBehavior.end(); ++iter) {
689         preprocessor->predefineMacro(GetExtensionNameString(iter->first), 1);
690     }
691     if (context->getFragmentPrecisionHigh())
692         preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
693 
694     preprocessor->setMaxTokenSize(sh::GetGlobalMaxTokenSize(context->getShaderSpec()));
695 
696     return 0;
697 }
698