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