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