1 /*
2 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //    http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 This file contains the Lex specification for GLSL ES.
17 Based on ANSI C grammar, Lex specification:
18 http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
19 
20 IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh,
21 WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
22 */
23 
24 %top{
25 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
26 //
27 // Licensed under the Apache License, Version 2.0 (the "License");
28 // you may not use this file except in compliance with the License.
29 // You may obtain a copy of the License at
30 //
31 //    http://www.apache.org/licenses/LICENSE-2.0
32 //
33 // Unless required by applicable law or agreed to in writing, software
34 // distributed under the License is distributed on an "AS IS" BASIS,
35 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36 // See the License for the specific language governing permissions and
37 // limitations under the License.
38 
39 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
40 
41 // Ignore errors in auto-generated code.
42 #if defined(__GNUC__)
43 #pragma GCC diagnostic ignored "-Wunused-function"
44 #pragma GCC diagnostic ignored "-Wunused-variable"
45 #pragma GCC diagnostic ignored "-Wswitch-enum"
46 #elif defined(_MSC_VER)
47 #pragma warning(disable: 4065)
48 #pragma warning(disable: 4189)
49 #pragma warning(disable: 4505)
50 #pragma warning(disable: 4701)
51 #endif
52 }
53 
54 %{
55 #include "glslang.h"
56 #include "ParseHelper.h"
57 #include "preprocessor/Token.h"
58 #include "util.h"
59 #include "glslang_tab.h"
60 
61 /* windows only pragma */
62 #ifdef _MSC_VER
63 #pragma warning(disable : 4102)
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_identifier_ES3_keyword(TParseContext *context, int token);
79 static int uint_constant(TParseContext *context);
80 static int int_constant(yyscan_t yyscanner);
81 static int float_constant(yyscan_t yyscanner);
82 static int floatsuffix_check(TParseContext* context);
83 %}
84 
85 %option noyywrap nounput never-interactive
86 %option yylineno reentrant bison-bridge bison-locations
87 %option extra-type="TParseContext*"
88 %x COMMENT FIELDS
89 
90 D           [0-9]
91 L           [a-zA-Z_]
92 H           [a-fA-F0-9]
93 E           [Ee][+-]?{D}+
94 O           [0-7]
95 
96 %%
97 
98 %{
99     TParseContext* context = yyextra;
100 %}
101 
102 "invariant"    { return(INVARIANT); }
103 "highp"        { return(HIGH_PRECISION); }
104 "mediump"      { return(MEDIUM_PRECISION); }
105 "lowp"         { return(LOW_PRECISION); }
106 "precision"    { return(PRECISION); }
107 
108 "attribute"    { return ES2_keyword_ES3_reserved(context, ATTRIBUTE); }
109 "const"        { return(CONST_QUAL); }
110 "uniform"      { return(UNIFORM); }
111 "varying"      { return ES2_keyword_ES3_reserved(context, VARYING); }
112 
113 "break"        { return(BREAK); }
114 "continue"     { return(CONTINUE); }
115 "do"           { return(DO); }
116 "for"          { return(FOR); }
117 "while"        { return(WHILE); }
118 
119 "if"           { return(IF); }
120 "else"         { return(ELSE); }
121 "switch"       { return ES2_reserved_ES3_keyword(context, SWITCH); }
122 "case"         { return ES2_reserved_ES3_keyword(context, CASE); }
123 "default"      { return ES2_reserved_ES3_keyword(context, DEFAULT); }
124 
125 "centroid"     { return ES2_reserved_ES3_keyword(context, CENTROID); }
126 "flat"         { return ES2_reserved_ES3_keyword(context, FLAT); }
127 "smooth"       { return ES2_reserved_ES3_keyword(context, SMOOTH); }
128 
129 "in"           { return(IN_QUAL); }
130 "out"          { return(OUT_QUAL); }
131 "inout"        { return(INOUT_QUAL); }
132 
133 "float"        { context->lexAfterType = true; return(FLOAT_TYPE); }
134 "int"          { context->lexAfterType = true; return(INT_TYPE); }
135 "uint"         { return ES2_identifier_ES3_keyword(context, UINT_TYPE); }
136 "void"         { context->lexAfterType = true; return(VOID_TYPE); }
137 "bool"         { context->lexAfterType = true; return(BOOL_TYPE); }
138 "true"         { yylval->lex.b = true;  return(BOOLCONSTANT); }
139 "false"        { yylval->lex.b = false; return(BOOLCONSTANT); }
140 
141 "discard"      { return(DISCARD); }
142 "return"       { return(RETURN); }
143 
144 "mat2"         { context->lexAfterType = true; return(MATRIX2); }
145 "mat3"         { context->lexAfterType = true; return(MATRIX3); }
146 "mat4"         { context->lexAfterType = true; return(MATRIX4); }
147 
148 "mat2x2"       { return ES2_identifier_ES3_keyword(context, MATRIX2); }
149 "mat3x3"       { return ES2_identifier_ES3_keyword(context, MATRIX3); }
150 "mat4x4"       { return ES2_identifier_ES3_keyword(context, MATRIX4); }
151 
152 "mat2x3"       { return ES2_identifier_ES3_keyword(context, MATRIX2x3); }
153 "mat3x2"       { return ES2_identifier_ES3_keyword(context, MATRIX3x2); }
154 "mat2x4"       { return ES2_identifier_ES3_keyword(context, MATRIX2x4); }
155 "mat4x2"       { return ES2_identifier_ES3_keyword(context, MATRIX4x2); }
156 "mat3x4"       { return ES2_identifier_ES3_keyword(context, MATRIX3x4); }
157 "mat4x3"       { return ES2_identifier_ES3_keyword(context, MATRIX4x3); }
158 
159 "vec2"         { context->lexAfterType = true; return (VEC2); }
160 "vec3"         { context->lexAfterType = true; return (VEC3); }
161 "vec4"         { context->lexAfterType = true; return (VEC4); }
162 "ivec2"        { context->lexAfterType = true; return (IVEC2); }
163 "ivec3"        { context->lexAfterType = true; return (IVEC3); }
164 "ivec4"        { context->lexAfterType = true; return (IVEC4); }
165 "uvec2"        { return ES2_identifier_ES3_keyword(context, UVEC2); }
166 "uvec3"        { return ES2_identifier_ES3_keyword(context, UVEC3); }
167 "uvec4"        { return ES2_identifier_ES3_keyword(context, UVEC4); }
168 "bvec2"        { context->lexAfterType = true; return (BVEC2); }
169 "bvec3"        { context->lexAfterType = true; return (BVEC3); }
170 "bvec4"        { context->lexAfterType = true; return (BVEC4); }
171 
172 "sampler2D"          { context->lexAfterType = true; return SAMPLER2D; }
173 "samplerCube"        { context->lexAfterType = true; return SAMPLERCUBE; }
174 "sampler2DRect"      { context->lexAfterType = true; return SAMPLER2DRECT; }
175 "samplerExternalOES" { context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; }
176 "sampler3D"          { context->lexAfterType = true; return SAMPLER3D; }
177 "sampler3DRect"      { return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); }
178 "sampler2DArray"     { return  ES2_identifier_ES3_keyword(context, SAMPLER2DARRAY); }
179 "isampler2D"         { return  ES2_identifier_ES3_keyword(context, ISAMPLER2D); }
180 "isampler3D"         { return  ES2_identifier_ES3_keyword(context, ISAMPLER3D); }
181 "isamplerCube"       { return  ES2_identifier_ES3_keyword(context, ISAMPLERCUBE); }
182 "isampler2DArray"    { return  ES2_identifier_ES3_keyword(context, ISAMPLER2DARRAY); }
183 "usampler2D"         { return  ES2_identifier_ES3_keyword(context, USAMPLER2D); }
184 "usampler3D"         { return  ES2_identifier_ES3_keyword(context, USAMPLER3D); }
185 "usamplerCube"       { return  ES2_identifier_ES3_keyword(context, USAMPLERCUBE); }
186 "usampler2DArray"    { return  ES2_identifier_ES3_keyword(context, USAMPLER2DARRAY); }
187 "sampler2DShadow"    { return ES2_reserved_ES3_keyword(context, SAMPLER2DSHADOW); }
188 "samplerCubeShadow"  { return  ES2_identifier_ES3_keyword(context, SAMPLERCUBESHADOW); }
189 "sampler2DArrayShadow" { return  ES2_identifier_ES3_keyword(context, SAMPLER2DARRAYSHADOW); }
190 
191 "struct"       { context->lexAfterType = true; return(STRUCT); }
192 
193 "layout"  { return ES2_identifier_ES3_keyword(context, LAYOUT); }
194 
195     /* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */
196 "coherent"          |
197 "restrict"          |
198 "readonly"          |
199 "writeonly"         |
200 "resource"          |
201 "atomic_uint"       |
202 "noperspective"     |
203 "patch"             |
204 "sample"            |
205 "subroutine"        |
206 "common"            |
207 "partition"         |
208 "active"            |
209 
210 "filter"            |
211 "image1D"           |
212 "image2D"           |
213 "image3D"           |
214 "imageCube"	        |
215 "iimage1D"          |
216 "iimage2D"          |
217 "iimage3D"          |
218 "iimageCube"        |
219 "uimage1D"          |
220 "uimage2D"          |
221 "uimage3D"          |
222 "uimageCube"        |
223 "image1DArray"      |
224 "image2DArray"      |
225 "iimage1DArray"     |
226 "iimage2DArray"     |
227 "uimage1DArray"     |
228 "uimage2DArray"     |
229 "image1DShadow"     |
230 "image2DShadow"     |
231 "image1DArrayShadow" |
232 "image2DArrayShadow" |
233 "imageBuffer"       |
234 "iimageBuffer"      |
235 "uimageBuffer"      |
236 
237 "sampler1DArray"    |
238 "sampler1DArrayShadow" |
239 "isampler1D"        |
240 "isampler1DArray"   |
241 "usampler1D"        |
242 "usampler1DArray"   |
243 "isampler2DRect"    |
244 "usampler2DRect"    |
245 "samplerBuffer"     |
246 "isamplerBuffer"    |
247 "usamplerBuffer"    |
248 "sampler2DMS"       |
249 "isampler2DMS"      |
250 "usampler2DMS"      |
251 "sampler2DMSArray"  |
252 "isampler2DMSArray" |
253 "usampler2DMSArray" {
254     if (context->getShaderVersion() < 300) {
255 		yylval->lex.string = NewPoolTString(yytext);
256 	    return check_type(yyscanner);
257 	}
258 	return reserved_word(yyscanner);
259 }
260 
261     /* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */
262 "packed"  {
263     if (context->getShaderVersion() >= 300)
264     {
265         yylval->lex.string = NewPoolTString(yytext);
266         return check_type(yyscanner);
267     }
268 
269     return reserved_word(yyscanner);
270 }
271 
272     /* Reserved keywords */
273 "asm"          |
274 
275 "class"        |
276 "union"        |
277 "enum"         |
278 "typedef"      |
279 "template"     |
280 "this"         |
281 
282 "goto"         |
283 
284 "inline"       |
285 "noinline"     |
286 "volatile"     |
287 "public"       |
288 "static"       |
289 "extern"       |
290 "external"     |
291 "interface"    |
292 
293 "long"         |
294 "short"        |
295 "double"       |
296 "half"         |
297 "fixed"        |
298 "unsigned"     |
299 "superp"       |
300 
301 "input"        |
302 "output"       |
303 
304 "hvec2"        |
305 "hvec3"        |
306 "hvec4"        |
307 "dvec2"        |
308 "dvec3"        |
309 "dvec4"        |
310 "fvec2"        |
311 "fvec3"        |
312 "fvec4"        |
313 
314 "sampler1D"    |
315 "sampler1DShadow" |
316 "sampler2DRectShadow" |
317 
318 "sizeof"       |
319 "cast"         |
320 
321 "namespace"    |
322 "using"        { return reserved_word(yyscanner); }
323 
324 {L}({L}|{D})*       {
325    yylval->lex.string = NewPoolTString(yytext);
326    return check_type(yyscanner);
327 }
328 
329 0[xX]{H}+         { return int_constant(yyscanner); }
330 0{O}+             { return int_constant(yyscanner); }
331 {D}+              { return int_constant(yyscanner); }
332 
333 0[xX]{H}+[uU]     { return uint_constant(context); }
334 0{O}+[uU]         { return uint_constant(context); }
335 {D}+[uU]          { return uint_constant(context); }
336 
337 {D}+{E}           { return float_constant(yyscanner); }
338 {D}+"."{D}*({E})? { return float_constant(yyscanner); }
339 "."{D}+({E})?     { return float_constant(yyscanner); }
340 
341 {D}+{E}[fF]           { return floatsuffix_check(context); }
342 {D}+"."{D}*({E})?[fF] { return floatsuffix_check(context); }
343 "."{D}+({E})?[fF]     { return floatsuffix_check(context); }
344 
345 "+="            {  return(ADD_ASSIGN); }
346 "-="            {  return(SUB_ASSIGN); }
347 "*="            {  return(MUL_ASSIGN); }
348 "/="            {  return(DIV_ASSIGN); }
349 "%="            {  return(MOD_ASSIGN); }
350 "<<="           {  return(LEFT_ASSIGN); }
351 ">>="           {  return(RIGHT_ASSIGN); }
352 "&="            {  return(AND_ASSIGN); }
353 "^="            {  return(XOR_ASSIGN); }
354 "|="            {  return(OR_ASSIGN); }
355 
356 "++"            {  return(INC_OP); }
357 "--"            {  return(DEC_OP); }
358 "&&"            {  return(AND_OP); }
359 "||"            {  return(OR_OP); }
360 "^^"            {  return(XOR_OP); }
361 "<="            {  return(LE_OP); }
362 ">="            {  return(GE_OP); }
363 "=="            {  return(EQ_OP); }
364 "!="            {  return(NE_OP); }
365 "<<"            {  return(LEFT_OP); }
366 ">>"            {  return(RIGHT_OP); }
367 ";"             { context->lexAfterType = false; return(SEMICOLON); }
368 ("{"|"<%")      { context->lexAfterType = false; return(LEFT_BRACE); }
369 ("}"|"%>")      { return(RIGHT_BRACE); }
370 ","             { if (context->inTypeParen) context->lexAfterType = false; return(COMMA); }
371 ":"             { return(COLON); }
372 "="             { context->lexAfterType = false; return(EQUAL); }
373 "("             { context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); }
374 ")"             { context->inTypeParen = false; return(RIGHT_PAREN); }
375 ("["|"<:")      { return(LEFT_BRACKET); }
376 ("]"|":>")      { return(RIGHT_BRACKET); }
377 "."             { BEGIN(FIELDS);  return(DOT); }
378 "!"             { return(BANG); }
379 "-"             { return(DASH); }
380 "~"             { return(TILDE); }
381 "+"             { return(PLUS); }
382 "*"             { return(STAR); }
383 "/"             { return(SLASH); }
384 "%"             { return(PERCENT); }
385 "<"             { return(LEFT_ANGLE); }
386 ">"             { return(RIGHT_ANGLE); }
387 "|"             { return(VERTICAL_BAR); }
388 "^"             { return(CARET); }
389 "&"             { return(AMPERSAND); }
390 "?"             { return(QUESTION); }
391 
392 <FIELDS>{L}({L}|{D})* {
393     BEGIN(INITIAL);
394     yylval->lex.string = NewPoolTString(yytext);
395     return FIELD_SELECTION;
396 }
397 <FIELDS>[ \t\v\f\r] {}
398 
399 [ \t\v\n\f\r]   {  }
400 <*><<EOF>>      { context->AfterEOF = true; yyterminate(); }
401 <*>.            { context->warning(*yylloc, "Unknown char", yytext, ""); return 0; }
402 
403 %%
404 
405 yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
406     pp::Token token;
407     yyget_extra(yyscanner)->getPreprocessor().lex(&token);
408     yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
409     if (len < max_size)
410         memcpy(buf, token.text.c_str(), len);
411     yyset_column(token.location.file, yyscanner);
412     yyset_lineno(token.location.line, yyscanner);
413 
414     if (len >= max_size)
415         YY_FATAL_ERROR("Input buffer overflow");
416     else if (len > 0)
417         buf[len++] = ' ';
418     return len;
419 }
420 
check_type(yyscan_t yyscanner)421 int check_type(yyscan_t yyscanner) {
422     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
423 
424     int token = IDENTIFIER;
425     TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion());
426     if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) {
427         TVariable* variable = static_cast<TVariable*>(symbol);
428         if (variable->isUserType()) {
429             yyextra->lexAfterType = true;
430             token = TYPE_NAME;
431         }
432     }
433     yylval->lex.symbol = symbol;
434     return token;
435 }
436 
reserved_word(yyscan_t yyscanner)437 int reserved_word(yyscan_t yyscanner) {
438     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
439 
440     yyextra->error(*yylloc, "Illegal use of reserved word", yytext, "");
441     yyextra->recover();
442     return 0;
443 }
444 
ES2_reserved_ES3_keyword(TParseContext * context,int token)445 int ES2_reserved_ES3_keyword(TParseContext *context, int token)
446 {
447     yyscan_t yyscanner = (yyscan_t) context->getScanner();
448 
449     if (context->getShaderVersion() < 300)
450     {
451         return reserved_word(yyscanner);
452     }
453 
454     return token;
455 }
456 
ES2_keyword_ES3_reserved(TParseContext * context,int token)457 int ES2_keyword_ES3_reserved(TParseContext *context, int token)
458 {
459     yyscan_t yyscanner = (yyscan_t) context->getScanner();
460 
461     if (context->getShaderVersion() >= 300)
462     {
463         return reserved_word(yyscanner);
464     }
465 
466     return token;
467 }
468 
ES2_identifier_ES3_keyword(TParseContext * context,int token)469 int ES2_identifier_ES3_keyword(TParseContext *context, int token)
470 {
471     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
472     yyscan_t yyscanner = (yyscan_t) context->getScanner();
473 
474     // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
475     if (context->getShaderVersion() < 300)
476     {
477         yylval->lex.string = NewPoolTString(yytext);
478         return check_type(yyscanner);
479     }
480 
481     return token;
482 }
483 
uint_constant(TParseContext * context)484 int uint_constant(TParseContext *context)
485 {
486     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
487 
488     if (context->getShaderVersion() < 300)
489     {
490         context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, "");
491         context->recover();
492         return 0;
493     }
494 
495     if (!atou_clamp(yytext, &(yylval->lex.u)))
496         yyextra->warning(*yylloc, "Integer overflow", yytext, "");
497 
498     return UINTCONSTANT;
499 }
500 
floatsuffix_check(TParseContext * context)501 int floatsuffix_check(TParseContext* context)
502 {
503     struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
504 
505     if (context->getShaderVersion() < 300)
506     {
507         context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext);
508         context->recover();
509         return 0;
510     }
511 
512     if (!atof_clamp(yytext, &(yylval->lex.f)))
513         yyextra->warning(*yylloc, "Float overflow", yytext, "");
514 
515     return(FLOATCONSTANT);
516 }
517 
int_constant(yyscan_t yyscanner)518 int int_constant(yyscan_t yyscanner) {
519     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
520 
521     if (!atoi_clamp(yytext, &(yylval->lex.i)))
522         yyextra->warning(*yylloc, "Integer overflow", yytext, "");
523     return INTCONSTANT;
524 }
525 
float_constant(yyscan_t yyscanner)526 int float_constant(yyscan_t yyscanner) {
527     struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
528 
529     if (!atof_clamp(yytext, &(yylval->lex.f)))
530         yyextra->warning(*yylloc, "Float overflow", yytext, "");
531     return FLOATCONSTANT;
532 }
533 
yyerror(YYLTYPE * lloc,TParseContext * context,void * scanner,const char * reason)534 void yyerror(YYLTYPE* lloc, TParseContext* context, void* scanner, const char* reason) {
535     struct yyguts_t* yyg = (struct yyguts_t*) scanner;
536 
537     if (context->AfterEOF) {
538         context->error(*lloc, reason, "unexpected EOF");
539     } else {
540         context->error(*lloc, reason, yytext);
541     }
542     context->recover();
543 }
544 
glslang_initialize(TParseContext * context)545 int glslang_initialize(TParseContext* context) {
546     yyscan_t scanner = NULL;
547     if (yylex_init_extra(context, &scanner))
548         return 1;
549 
550     context->setScanner(scanner);
551     return 0;
552 }
553 
glslang_finalize(TParseContext * context)554 int glslang_finalize(TParseContext* context) {
555     yyscan_t scanner = context->getScanner();
556     if (scanner == NULL) return 0;
557 
558     context->setScanner(NULL);
559     yylex_destroy(scanner);
560 
561     return 0;
562 }
563 
glslang_scan(size_t count,const char * const string[],const int length[],TParseContext * context)564 int glslang_scan(size_t count, const char* const string[], const int length[],
565                  TParseContext* context) {
566     yyrestart(NULL, context->getScanner());
567     yyset_column(0, context->getScanner());
568     yyset_lineno(1, context->getScanner());
569     context->AfterEOF = false;
570 
571     // Initialize preprocessor.
572     if (!context->getPreprocessor().init(count, string, length))
573         return 1;
574 
575     // Define extension macros.
576     const TExtensionBehavior& extBehavior = context->extensionBehavior();
577     for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
578          iter != extBehavior.end(); ++iter)
579     {
580         context->getPreprocessor().predefineMacro(iter->first.c_str(), 1);
581     }
582 
583     context->getPreprocessor().predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
584 
585     return 0;
586 }
587 
588