1/*
2//
3// Copyright (c) 2002-2012 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 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/glslang.h"
40#include "compiler/ParseHelper.h"
41#include "compiler/preprocessor/Token.h"
42#include "compiler/util.h"
43#include "glslang_tab.h"
44
45/* windows only pragma */
46#ifdef _MSC_VER
47#pragma warning(disable : 4102)
48#endif
49
50#define YY_USER_ACTION                                 \
51    yylloc->first_file = yylloc->last_file = yycolumn; \
52    yylloc->first_line = yylloc->last_line = yylineno;
53
54#define YY_INPUT(buf, result, max_size) \
55    result = string_input(buf, max_size, yyscanner);
56
57static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner);
58static int check_type(yyscan_t yyscanner);
59static int reserved_word(yyscan_t yyscanner);
60%}
61
62%option noyywrap nounput never-interactive
63%option yylineno reentrant bison-bridge bison-locations
64%option extra-type="TParseContext*"
65
66D           [0-9]
67L           [a-zA-Z_]
68H           [a-fA-F0-9]
69E           [Ee][+-]?{D}+
70O           [0-7]
71
72%%
73
74"invariant"    { return INVARIANT; }
75"highp"        { return HIGH_PRECISION; }
76"mediump"      { return MEDIUM_PRECISION; }
77"lowp"         { return LOW_PRECISION; }
78"precision"    { return PRECISION; }
79
80"attribute"    { return ATTRIBUTE; }
81"const"        { return CONST_QUAL; }
82"uniform"      { return UNIFORM; }
83"varying"      { return VARYING; }
84
85"break"        { return BREAK; }
86"continue"     { return CONTINUE; }
87"do"           { return DO; }
88"for"          { return FOR; }
89"while"        { return WHILE; }
90
91"if"           { return IF; }
92"else"         { return ELSE; }
93
94"in"           { return IN_QUAL; }
95"out"          { return OUT_QUAL; }
96"inout"        { return INOUT_QUAL; }
97
98"float"        { return FLOAT_TYPE; }
99"int"          { return INT_TYPE; }
100"void"         { return VOID_TYPE; }
101"bool"         { return BOOL_TYPE; }
102"true"         { yylval->lex.b = true;  return BOOLCONSTANT; }
103"false"        { yylval->lex.b = false; return BOOLCONSTANT; }
104
105"discard"      { return DISCARD; }
106"return"       { return RETURN; }
107
108"mat2"         { return MATRIX2; }
109"mat3"         { return MATRIX3; }
110"mat4"         { return MATRIX4; }
111
112"vec2"         { return VEC2; }
113"vec3"         { return VEC3; }
114"vec4"         { return VEC4; }
115"ivec2"        { return IVEC2; }
116"ivec3"        { return IVEC3; }
117"ivec4"        { return IVEC4; }
118"bvec2"        { return BVEC2; }
119"bvec3"        { return BVEC3; }
120"bvec4"        { return BVEC4; }
121
122"sampler2D"          { return SAMPLER2D; }
123"samplerCube"        { return SAMPLERCUBE; }
124"samplerExternalOES" { return SAMPLER_EXTERNAL_OES; }
125"sampler2DRect"      { return SAMPLER2DRECT; }
126
127"struct"       { return STRUCT; }
128
129"asm"          { return reserved_word(yyscanner); }
130
131"class"        { return reserved_word(yyscanner); }
132"union"        { return reserved_word(yyscanner); }
133"enum"         { return reserved_word(yyscanner); }
134"typedef"      { return reserved_word(yyscanner); }
135"template"     { return reserved_word(yyscanner); }
136"this"         { return reserved_word(yyscanner); }
137"packed"       { return reserved_word(yyscanner); }
138
139"goto"         { return reserved_word(yyscanner); }
140"switch"       { return reserved_word(yyscanner); }
141"default"      { return reserved_word(yyscanner); }
142
143"inline"       { return reserved_word(yyscanner); }
144"noinline"     { return reserved_word(yyscanner); }
145"volatile"     { return reserved_word(yyscanner); }
146"public"       { return reserved_word(yyscanner); }
147"static"       { return reserved_word(yyscanner); }
148"extern"       { return reserved_word(yyscanner); }
149"external"     { return reserved_word(yyscanner); }
150"interface"    { return reserved_word(yyscanner); }
151"flat"         { return reserved_word(yyscanner); }
152
153"long"         { return reserved_word(yyscanner); }
154"short"        { return reserved_word(yyscanner); }
155"double"       { return reserved_word(yyscanner); }
156"half"         { return reserved_word(yyscanner); }
157"fixed"        { return reserved_word(yyscanner); }
158"unsigned"     { return reserved_word(yyscanner); }
159"superp"       { return reserved_word(yyscanner); }
160
161"input"        { return reserved_word(yyscanner); }
162"output"       { return reserved_word(yyscanner); }
163
164"hvec2"        { return reserved_word(yyscanner); }
165"hvec3"        { return reserved_word(yyscanner); }
166"hvec4"        { return reserved_word(yyscanner); }
167"dvec2"        { return reserved_word(yyscanner); }
168"dvec3"        { return reserved_word(yyscanner); }
169"dvec4"        { return reserved_word(yyscanner); }
170"fvec2"        { return reserved_word(yyscanner); }
171"fvec3"        { return reserved_word(yyscanner); }
172"fvec4"        { return reserved_word(yyscanner); }
173
174"sampler1D"           { return reserved_word(yyscanner); }
175"sampler3D"           { return reserved_word(yyscanner); }
176"sampler1DShadow"     { return reserved_word(yyscanner); }
177"sampler2DShadow"     { return reserved_word(yyscanner); }
178"sampler3DRect"       { return reserved_word(yyscanner); }
179"sampler2DRectShadow" { return reserved_word(yyscanner); }
180
181"sizeof"       { return reserved_word(yyscanner); }
182"cast"         { return reserved_word(yyscanner); }
183
184"namespace"    { return reserved_word(yyscanner); }
185"using"        { return reserved_word(yyscanner); }
186
187{L}({L}|{D})*       {
188   yylval->lex.string = NewPoolTString(yytext);
189   return check_type(yyscanner);
190}
191
1920[xX]{H}+         { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return INTCONSTANT; }
1930{O}+             { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return INTCONSTANT; }
194{D}+              { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return INTCONSTANT; }
195
196{D}+{E}           { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return FLOATCONSTANT; }
197{D}+"."{D}*({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return FLOATCONSTANT; }
198"."{D}+({E})?     { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return FLOATCONSTANT; }
199
200"+="            { return ADD_ASSIGN; }
201"-="            { return SUB_ASSIGN; }
202"*="            { return MUL_ASSIGN; }
203"/="            { return DIV_ASSIGN; }
204"%="            { return MOD_ASSIGN; }
205"<<="           { return LEFT_ASSIGN; }
206">>="           { return RIGHT_ASSIGN; }
207"&="            { return AND_ASSIGN; }
208"^="            { return XOR_ASSIGN; }
209"|="            { return OR_ASSIGN; }
210
211"++"            { return INC_OP; }
212"--"            { return DEC_OP; }
213"&&"            { return AND_OP; }
214"||"            { return OR_OP; }
215"^^"            { return XOR_OP; }
216"<="            { return LE_OP; }
217">="            { return GE_OP; }
218"=="            { return EQ_OP; }
219"!="            { return NE_OP; }
220"<<"            { return LEFT_OP; }
221">>"            { return RIGHT_OP; }
222";"             { return SEMICOLON; }
223("{"|"<%")      { return LEFT_BRACE; }
224("}"|"%>")      { return RIGHT_BRACE; }
225","         { return COMMA; }
226":"         { return COLON; }
227"="         { return EQUAL; }
228"("         { return LEFT_PAREN; }
229")"         { return RIGHT_PAREN; }
230("["|"<:")  { return LEFT_BRACKET; }
231("]"|":>")  { return RIGHT_BRACKET; }
232"."         { return DOT; }
233"!"         { return BANG; }
234"-"         { return DASH; }
235"~"         { return TILDE; }
236"+"         { return PLUS; }
237"*"         { return STAR; }
238"/"         { return SLASH; }
239"%"         { return PERCENT; }
240"<"         { return LEFT_ANGLE; }
241">"         { return RIGHT_ANGLE; }
242"|"         { return VERTICAL_BAR; }
243"^"         { return CARET; }
244"&"         { return AMPERSAND; }
245"?"         { return QUESTION; }
246
247[ \t\v\n\f\r] { }
248<<EOF>>    { yyterminate(); }
249.          { assert(false); return 0; }
250
251%%
252
253yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
254    pp::Token token;
255    yyget_extra(yyscanner)->preprocessor.lex(&token);
256    yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
257    if (len < max_size)
258        memcpy(buf, token.text.c_str(), len);
259    yyset_column(token.location.file, yyscanner);
260    yyset_lineno(token.location.line, yyscanner);
261
262    if (len >= max_size)
263        YY_FATAL_ERROR("Input buffer overflow");
264    else if (len > 0)
265        buf[len++] = ' ';
266    return len;
267}
268
269int check_type(yyscan_t yyscanner) {
270    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
271
272    int token = IDENTIFIER;
273    TSymbol* symbol = yyextra->symbolTable.find(yytext);
274    if (symbol && symbol->isVariable()) {
275        TVariable* variable = static_cast<TVariable*>(symbol);
276        if (variable->isUserType())
277            token = TYPE_NAME;
278    }
279    yylval->lex.symbol = symbol;
280    return token;
281}
282
283int reserved_word(yyscan_t yyscanner) {
284    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
285
286    yyextra->error(*yylloc, "Illegal use of reserved word", yytext, "");
287    yyextra->recover();
288    return 0;
289}
290
291int glslang_initialize(TParseContext* context) {
292    yyscan_t scanner = NULL;
293    if (yylex_init_extra(context, &scanner))
294        return 1;
295
296    context->scanner = scanner;
297    return 0;
298}
299
300int glslang_finalize(TParseContext* context) {
301    yyscan_t scanner = context->scanner;
302    if (scanner == NULL) return 0;
303
304    context->scanner = NULL;
305    yylex_destroy(scanner);
306
307    return 0;
308}
309
310int glslang_scan(size_t count, const char* const string[], const int length[],
311                 TParseContext* context) {
312    yyrestart(NULL, context->scanner);
313    yyset_column(0, context->scanner);
314    yyset_lineno(1, context->scanner);
315
316    // Initialize preprocessor.
317    if (!context->preprocessor.init(count, string, length))
318        return 1;
319
320    // Define extension macros.
321    const TExtensionBehavior& extBehavior = context->extensionBehavior();
322    for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
323         iter != extBehavior.end(); ++iter) {
324        context->preprocessor.predefineMacro(iter->first.c_str(), 1);
325    }
326    if (context->fragmentPrecisionHigh)
327        context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
328
329    return 0;
330}
331
332