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