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