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