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
16This file contains the Lex specification for GLSL ES.
17Based on ANSI C grammar, Lex specification:
18http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
19
20IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh,
21WHICH 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
73static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner);
74static int check_type(yyscan_t yyscanner);
75static int reserved_word(yyscan_t yyscanner);
76static int ES2_reserved_ES3_keyword(TParseContext *context, int token);
77static int ES2_keyword_ES3_reserved(TParseContext *context, int token);
78static int ES2_identifier_ES3_keyword(TParseContext *context, int token);
79static int uint_constant(TParseContext *context);
80static int int_constant(yyscan_t yyscanner);
81static int float_constant(yyscan_t yyscanner);
82static 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
91D           [0-9]
92L           [a-zA-Z_]
93H           [a-fA-F0-9]
94E           [Ee][+-]?{D}+
95O           [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
3390[xX]{H}+         { return int_constant(yyscanner); }
3400{O}+             { return int_constant(yyscanner); }
341{D}+              { return int_constant(yyscanner); }
342
3430[xX]{H}+[uU]     { return uint_constant(context); }
3440{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
415yy_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
431int 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
447int 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
455int 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
467int 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
479int 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
494int 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
512int 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
529int 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
537int 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
545void 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
556int 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
565int 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
575int 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