|
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/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 |
|
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 %} |
|
61 |
|
62 %option noyywrap nounput never-interactive |
|
63 %option yylineno reentrant bison-bridge bison-locations |
|
64 %option extra-type="TParseContext*" |
|
65 |
|
66 D [0-9] |
|
67 L [a-zA-Z_] |
|
68 H [a-fA-F0-9] |
|
69 E [Ee][+-]?{D}+ |
|
70 O [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 |
|
192 0[xX]{H}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return INTCONSTANT; } |
|
193 0{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 |
|
253 yy_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 |
|
269 int 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 |
|
283 int 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 |
|
291 int 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 |
|
300 int 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 |
|
310 int 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 |