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