daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 1 | /* |
| 2 | // |
| 3 | // Copyright (c) 2002-2010 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 | // |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 7 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 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 |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 11 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 12 | IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glslang_lexer.sh, |
| 13 | WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 14 | */ |
| 15 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 16 | %top{ |
| 17 | // |
| 18 | // Copyright (c) 2010 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 | // |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 22 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 23 | // This file is auto-generated by generate_glslang_lexer.sh. DO NOT EDIT! |
| 24 | } |
| 25 | |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 26 | %{ |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 27 | #include "compiler/glslang.h" |
daniel@transgaming.com | e684229 | 2010-04-20 18:52:50 +0000 | [diff] [blame] | 28 | #include "compiler/ParseHelper.h" |
daniel@transgaming.com | 91ed149 | 2010-10-29 03:11:43 +0000 | [diff] [blame] | 29 | #include "compiler/util.h" |
alokp@chromium.org | eab1ef1 | 2010-04-23 17:33:49 +0000 | [diff] [blame] | 30 | #include "glslang_tab.h" |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 31 | |
| 32 | /* windows only pragma */ |
| 33 | #ifdef _MSC_VER |
| 34 | #pragma warning(disable : 4102) |
| 35 | #endif |
| 36 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 37 | #define YY_USER_ACTION yylval->lex.line = yylineno; |
| 38 | #define YY_INPUT(buf, result, max_size) \ |
| 39 | result = string_input(buf, max_size, yyscanner); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 40 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 41 | static int string_input(char* buf, int max_size, yyscan_t yyscanner); |
| 42 | static int check_type(yyscan_t yyscanner); |
| 43 | static int reserved_word(yyscan_t yyscanner); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 44 | %} |
| 45 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 46 | %option noyywrap nounput never-interactive |
| 47 | %option yylineno reentrant bison-bridge |
| 48 | %option stack |
| 49 | %option extra-type="TParseContext*" |
| 50 | %x COMMENT FIELDS |
alokp@chromium.org | 29d56fb | 2010-04-06 15:42:22 +0000 | [diff] [blame] | 51 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 52 | D [0-9] |
| 53 | L [a-zA-Z_] |
| 54 | H [a-fA-F0-9] |
| 55 | E [Ee][+-]?{D}+ |
| 56 | O [0-7] |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 57 | |
| 58 | %% |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 59 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 60 | %{ |
| 61 | TParseContext* context = yyextra; |
| 62 | %} |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 63 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 64 | /* Single-line comments */ |
| 65 | "//"[^\n]* ; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 66 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 67 | /* Multi-line comments */ |
| 68 | "/*" { yy_push_state(COMMENT, yyscanner); } |
| 69 | <COMMENT>. | |
| 70 | <COMMENT>\n ; |
| 71 | <COMMENT>"*/" { yy_pop_state(yyscanner); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 72 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 73 | "invariant" { return(INVARIANT); } |
| 74 | "highp" { return(HIGH_PRECISION); } |
| 75 | "mediump" { return(MEDIUM_PRECISION); } |
| 76 | "lowp" { return(LOW_PRECISION); } |
| 77 | "precision" { return(PRECISION); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 78 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 79 | "attribute" { return(ATTRIBUTE); } |
| 80 | "const" { return(CONST_QUAL); } |
| 81 | "uniform" { return(UNIFORM); } |
| 82 | "varying" { return(VARYING); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 83 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 84 | "break" { return(BREAK); } |
| 85 | "continue" { return(CONTINUE); } |
| 86 | "do" { return(DO); } |
| 87 | "for" { return(FOR); } |
| 88 | "while" { return(WHILE); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 89 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 90 | "if" { return(IF); } |
| 91 | "else" { return(ELSE); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 92 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 93 | "in" { return(IN_QUAL); } |
| 94 | "out" { return(OUT_QUAL); } |
| 95 | "inout" { return(INOUT_QUAL); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 96 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 97 | "float" { context->lexAfterType = true; return(FLOAT_TYPE); } |
| 98 | "int" { context->lexAfterType = true; return(INT_TYPE); } |
| 99 | "void" { context->lexAfterType = true; return(VOID_TYPE); } |
| 100 | "bool" { context->lexAfterType = true; return(BOOL_TYPE); } |
| 101 | "true" { yylval->lex.b = true; return(BOOLCONSTANT); } |
| 102 | "false" { yylval->lex.b = false; return(BOOLCONSTANT); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 103 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 104 | "discard" { return(DISCARD); } |
| 105 | "return" { return(RETURN); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 106 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 107 | "mat2" { context->lexAfterType = true; return(MATRIX2); } |
| 108 | "mat3" { context->lexAfterType = true; return(MATRIX3); } |
| 109 | "mat4" { context->lexAfterType = true; return(MATRIX4); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 110 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 111 | "vec2" { context->lexAfterType = true; return (VEC2); } |
| 112 | "vec3" { context->lexAfterType = true; return (VEC3); } |
| 113 | "vec4" { context->lexAfterType = true; return (VEC4); } |
| 114 | "ivec2" { context->lexAfterType = true; return (IVEC2); } |
| 115 | "ivec3" { context->lexAfterType = true; return (IVEC3); } |
| 116 | "ivec4" { context->lexAfterType = true; return (IVEC4); } |
| 117 | "bvec2" { context->lexAfterType = true; return (BVEC2); } |
| 118 | "bvec3" { context->lexAfterType = true; return (BVEC3); } |
| 119 | "bvec4" { context->lexAfterType = true; return (BVEC4); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 120 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 121 | "sampler2D" { context->lexAfterType = true; return SAMPLER2D; } |
| 122 | "samplerCube" { context->lexAfterType = true; return SAMPLERCUBE; } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 123 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 124 | "struct" { context->lexAfterType = true; return(STRUCT); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 125 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 126 | "asm" { return reserved_word(yyscanner); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 127 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 128 | "class" { return reserved_word(yyscanner); } |
| 129 | "union" { return reserved_word(yyscanner); } |
| 130 | "enum" { return reserved_word(yyscanner); } |
| 131 | "typedef" { return reserved_word(yyscanner); } |
| 132 | "template" { return reserved_word(yyscanner); } |
| 133 | "this" { return reserved_word(yyscanner); } |
| 134 | "packed" { return reserved_word(yyscanner); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 135 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 136 | "goto" { return reserved_word(yyscanner); } |
| 137 | "switch" { return reserved_word(yyscanner); } |
| 138 | "default" { return reserved_word(yyscanner); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 139 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 140 | "inline" { return reserved_word(yyscanner); } |
| 141 | "noinline" { return reserved_word(yyscanner); } |
| 142 | "volatile" { return reserved_word(yyscanner); } |
| 143 | "public" { return reserved_word(yyscanner); } |
| 144 | "static" { return reserved_word(yyscanner); } |
| 145 | "extern" { return reserved_word(yyscanner); } |
| 146 | "external" { return reserved_word(yyscanner); } |
| 147 | "interface" { return reserved_word(yyscanner); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 148 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 149 | "long" { return reserved_word(yyscanner); } |
| 150 | "short" { return reserved_word(yyscanner); } |
| 151 | "double" { return reserved_word(yyscanner); } |
| 152 | "half" { return reserved_word(yyscanner); } |
| 153 | "fixed" { return reserved_word(yyscanner); } |
| 154 | "unsigned" { return reserved_word(yyscanner); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 155 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 156 | "input" { return reserved_word(yyscanner); } |
| 157 | "output" { return reserved_word(yyscanner); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 158 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 159 | "hvec2" { return reserved_word(yyscanner); } |
| 160 | "hvec3" { return reserved_word(yyscanner); } |
| 161 | "hvec4" { return reserved_word(yyscanner); } |
| 162 | "fvec2" { return reserved_word(yyscanner); } |
| 163 | "fvec3" { return reserved_word(yyscanner); } |
| 164 | "fvec4" { return reserved_word(yyscanner); } |
| 165 | "dvec2" { return reserved_word(yyscanner); } |
| 166 | "dvec3" { return reserved_word(yyscanner); } |
| 167 | "dvec4" { return reserved_word(yyscanner); } |
| 168 | |
| 169 | "sizeof" { return reserved_word(yyscanner); } |
| 170 | "cast" { return reserved_word(yyscanner); } |
| 171 | |
| 172 | "namespace" { return reserved_word(yyscanner); } |
| 173 | "using" { return reserved_word(yyscanner); } |
| 174 | |
| 175 | {L}({L}|{D})* { |
| 176 | yylval->lex.string = NewPoolTString(yytext); |
| 177 | return check_type(yyscanner); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 178 | } |
| 179 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 180 | 0[xX]{H}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } |
| 181 | 0{O}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } |
| 182 | 0{D}+ { context->error(yylineno, "Invalid Octal number.", yytext, "", ""); context->recover(); return 0;} |
| 183 | {D}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 184 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 185 | {D}+{E} { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); } |
| 186 | {D}+"."{D}*({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); } |
| 187 | "."{D}+({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 188 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 189 | "+=" { return(ADD_ASSIGN); } |
| 190 | "-=" { return(SUB_ASSIGN); } |
| 191 | "*=" { return(MUL_ASSIGN); } |
| 192 | "/=" { return(DIV_ASSIGN); } |
| 193 | "%=" { return(MOD_ASSIGN); } |
| 194 | "<<=" { return(LEFT_ASSIGN); } |
| 195 | ">>=" { return(RIGHT_ASSIGN); } |
| 196 | "&=" { return(AND_ASSIGN); } |
| 197 | "^=" { return(XOR_ASSIGN); } |
| 198 | "|=" { return(OR_ASSIGN); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 199 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 200 | "++" { return(INC_OP); } |
| 201 | "--" { return(DEC_OP); } |
| 202 | "&&" { return(AND_OP); } |
| 203 | "||" { return(OR_OP); } |
| 204 | "^^" { return(XOR_OP); } |
| 205 | "<=" { return(LE_OP); } |
| 206 | ">=" { return(GE_OP); } |
| 207 | "==" { return(EQ_OP); } |
| 208 | "!=" { return(NE_OP); } |
| 209 | "<<" { return(LEFT_OP); } |
| 210 | ">>" { return(RIGHT_OP); } |
| 211 | ";" { context->lexAfterType = false; return(SEMICOLON); } |
| 212 | ("{"|"<%") { context->lexAfterType = false; return(LEFT_BRACE); } |
| 213 | ("}"|"%>") { return(RIGHT_BRACE); } |
| 214 | "," { if (context->inTypeParen) context->lexAfterType = false; return(COMMA); } |
| 215 | ":" { return(COLON); } |
| 216 | "=" { context->lexAfterType = false; return(EQUAL); } |
| 217 | "(" { context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); } |
| 218 | ")" { context->inTypeParen = false; return(RIGHT_PAREN); } |
| 219 | ("["|"<:") { return(LEFT_BRACKET); } |
| 220 | ("]"|":>") { return(RIGHT_BRACKET); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 221 | "." { BEGIN(FIELDS); return(DOT); } |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 222 | "!" { return(BANG); } |
| 223 | "-" { return(DASH); } |
| 224 | "~" { return(TILDE); } |
| 225 | "+" { return(PLUS); } |
| 226 | "*" { return(STAR); } |
| 227 | "/" { return(SLASH); } |
| 228 | "%" { return(PERCENT); } |
| 229 | "<" { return(LEFT_ANGLE); } |
| 230 | ">" { return(RIGHT_ANGLE); } |
| 231 | "|" { return(VERTICAL_BAR); } |
| 232 | "^" { return(CARET); } |
| 233 | "&" { return(AMPERSAND); } |
| 234 | "?" { return(QUESTION); } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 235 | |
| 236 | <FIELDS>{L}({L}|{D})* { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 237 | BEGIN(INITIAL); |
| 238 | yylval->lex.string = NewPoolTString(yytext); |
| 239 | return FIELD_SELECTION; |
| 240 | } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 241 | <FIELDS>[ \t\v\f\r] {} |
| 242 | |
| 243 | [ \t\v\n\f\r] { } |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 244 | <*><<EOF>> { context->AfterEOF = true; yyterminate(); } |
| 245 | <*>. { context->warning(yylineno, "Unknown char", yytext, ""); return 0; } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 246 | |
| 247 | %% |
| 248 | |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 249 | extern "C" { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 250 | // Preprocessor interface. |
| 251 | #include "compiler/preprocessor/preprocess.h" |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 252 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 253 | #define SETUP_CONTEXT(pp) \ |
| 254 | TParseContext* context = (TParseContext*) pp->pC; \ |
| 255 | struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 256 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 257 | // Preprocessor callbacks. |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 258 | void CPPDebugLogMsg(const char *msg) |
| 259 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 260 | SETUP_CONTEXT(cpp); |
| 261 | context->infoSink.debug.message(EPrefixNone, msg); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 262 | } |
| 263 | |
| 264 | void CPPWarningToInfoLog(const char *msg) |
| 265 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 266 | SETUP_CONTEXT(cpp); |
| 267 | context->warning(yylineno, msg, "", ""); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 268 | } |
| 269 | |
| 270 | void CPPShInfoLogMsg(const char *msg) |
| 271 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 272 | SETUP_CONTEXT(cpp); |
| 273 | context->error(yylineno, msg, "", ""); |
| 274 | context->recover(); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 275 | } |
| 276 | |
| 277 | void CPPErrorToInfoLog(char *msg) |
| 278 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 279 | SETUP_CONTEXT(cpp); |
| 280 | context->error(yylineno, msg, "", ""); |
| 281 | context->recover(); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 282 | } |
| 283 | |
| 284 | void SetLineNumber(int line) |
| 285 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 286 | SETUP_CONTEXT(cpp); |
| 287 | int string = 0; |
| 288 | DecodeSourceLoc(yylineno, &string, NULL); |
| 289 | yylineno = EncodeSourceLoc(string, line); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 290 | } |
| 291 | |
| 292 | void SetStringNumber(int string) |
| 293 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 294 | SETUP_CONTEXT(cpp); |
| 295 | int line = 0; |
| 296 | DecodeSourceLoc(yylineno, NULL, &line); |
| 297 | yylineno = EncodeSourceLoc(string, line); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 298 | } |
| 299 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 300 | int GetStringNumber() |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 301 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 302 | SETUP_CONTEXT(cpp); |
| 303 | int string = 0; |
| 304 | DecodeSourceLoc(yylineno, &string, NULL); |
| 305 | return string; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 306 | } |
| 307 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 308 | int GetLineNumber() |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 309 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 310 | SETUP_CONTEXT(cpp); |
| 311 | int line = 0; |
| 312 | DecodeSourceLoc(yylineno, NULL, &line); |
| 313 | return line; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 314 | } |
| 315 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 316 | void IncLineNumber() |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 317 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 318 | SETUP_CONTEXT(cpp); |
| 319 | int string = 0, line = 0; |
| 320 | DecodeSourceLoc(yylineno, &string, &line); |
| 321 | yylineno = EncodeSourceLoc(string, ++line); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 322 | } |
| 323 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 324 | void DecLineNumber() |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 325 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 326 | SETUP_CONTEXT(cpp); |
| 327 | int string = 0, line = 0; |
| 328 | DecodeSourceLoc(yylineno, &string, &line); |
| 329 | yylineno = EncodeSourceLoc(string, --line); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 330 | } |
| 331 | |
| 332 | void HandlePragma(const char **tokens, int numTokens) |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 333 | { |
| 334 | SETUP_CONTEXT(cpp); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 335 | if (!strcmp(tokens[0], "optimize")) { |
| 336 | if (numTokens != 4) { |
| 337 | CPPShInfoLogMsg("optimize pragma syntax is incorrect"); |
| 338 | return; |
| 339 | } |
| 340 | |
| 341 | if (strcmp(tokens[1], "(")) { |
| 342 | CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword"); |
| 343 | return; |
| 344 | } |
| 345 | |
| 346 | if (!strcmp(tokens[2], "on")) |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 347 | context->contextPragma.optimize = true; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 348 | else if (!strcmp(tokens[2], "off")) |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 349 | context->contextPragma.optimize = false; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 350 | else { |
| 351 | CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma"); |
| 352 | return; |
| 353 | } |
| 354 | |
| 355 | if (strcmp(tokens[3], ")")) { |
| 356 | CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma"); |
| 357 | return; |
| 358 | } |
| 359 | } else if (!strcmp(tokens[0], "debug")) { |
| 360 | if (numTokens != 4) { |
| 361 | CPPShInfoLogMsg("debug pragma syntax is incorrect"); |
| 362 | return; |
| 363 | } |
| 364 | |
| 365 | if (strcmp(tokens[1], "(")) { |
| 366 | CPPShInfoLogMsg("\"(\" expected after 'debug' keyword"); |
| 367 | return; |
| 368 | } |
| 369 | |
| 370 | if (!strcmp(tokens[2], "on")) |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 371 | context->contextPragma.debug = true; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 372 | else if (!strcmp(tokens[2], "off")) |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 373 | context->contextPragma.debug = false; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 374 | else { |
| 375 | CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma"); |
| 376 | return; |
| 377 | } |
| 378 | |
| 379 | if (strcmp(tokens[3], ")")) { |
| 380 | CPPShInfoLogMsg("\")\" expected to end 'debug' pragma"); |
| 381 | return; |
| 382 | } |
| 383 | } else { |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 384 | #ifdef PRAGMA_TABLE |
| 385 | // |
| 386 | // implementation specific pragma |
| 387 | // use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma |
| 388 | // For now, just ignore the pragma that the implementation cannot recognize |
| 389 | // An Example of one such implementation for a pragma that has a syntax like |
| 390 | // #pragma pragmaname(pragmavalue) |
| 391 | // This implementation stores the current pragmavalue against the pragma name in pragmaTable. |
| 392 | // |
| 393 | if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) { |
| 394 | TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable; |
| 395 | TPragmaTable::iterator iter; |
| 396 | iter = pragmaTable.find(TString(tokens[0])); |
| 397 | if (iter != pragmaTable.end()) { |
| 398 | iter->second = tokens[2]; |
| 399 | } else { |
alokp@chromium.org | 7e0ed77 | 2010-05-12 21:16:46 +0000 | [diff] [blame] | 400 | pragmaTable[ tokens[0] ] = tokens[2]; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 401 | } |
| 402 | } else if (numTokens >= 2) { |
| 403 | TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable; |
| 404 | TPragmaTable::iterator iter; |
| 405 | iter = pragmaTable.find(TString(tokens[0])); |
| 406 | if (iter != pragmaTable.end()) { |
| 407 | iter->second = tokens[1]; |
| 408 | } else { |
alokp@chromium.org | 7e0ed77 | 2010-05-12 21:16:46 +0000 | [diff] [blame] | 409 | pragmaTable[ tokens[0] ] = tokens[1]; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 410 | } |
| 411 | } |
| 412 | #endif // PRAGMA_TABLE |
| 413 | } |
| 414 | } |
| 415 | |
| 416 | void StoreStr(char *string) |
| 417 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 418 | SETUP_CONTEXT(cpp); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 419 | TString strSrc; |
| 420 | strSrc = TString(string); |
| 421 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 422 | context->HashErrMsg = context->HashErrMsg + " " + strSrc; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 423 | } |
| 424 | |
| 425 | const char* GetStrfromTStr(void) |
| 426 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 427 | SETUP_CONTEXT(cpp); |
| 428 | cpp->ErrMsg = context->HashErrMsg.c_str(); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 429 | return cpp->ErrMsg; |
| 430 | } |
| 431 | |
| 432 | void ResetTString(void) |
| 433 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 434 | SETUP_CONTEXT(cpp); |
| 435 | context->HashErrMsg = ""; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 436 | } |
| 437 | |
| 438 | TBehavior GetBehavior(const char* behavior) |
| 439 | { |
| 440 | if (!strcmp("require", behavior)) |
| 441 | return EBhRequire; |
| 442 | else if (!strcmp("enable", behavior)) |
| 443 | return EBhEnable; |
| 444 | else if (!strcmp("disable", behavior)) |
| 445 | return EBhDisable; |
| 446 | else if (!strcmp("warn", behavior)) |
| 447 | return EBhWarn; |
| 448 | else { |
| 449 | CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str()); |
| 450 | return EBhDisable; |
| 451 | } |
| 452 | } |
| 453 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 454 | void updateExtensionBehavior(const char* extName, const char* behavior) |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 455 | { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 456 | SETUP_CONTEXT(cpp); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 457 | TBehavior behaviorVal = GetBehavior(behavior); |
| 458 | TMap<TString, TBehavior>:: iterator iter; |
| 459 | TString msg; |
| 460 | |
| 461 | // special cased for all extension |
| 462 | if (!strcmp(extName, "all")) { |
| 463 | if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) { |
| 464 | CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior"); |
| 465 | return; |
| 466 | } else { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 467 | for (iter = context->extensionBehavior.begin(); iter != context->extensionBehavior.end(); ++iter) |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 468 | iter->second = behaviorVal; |
| 469 | } |
| 470 | } else { |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 471 | iter = context->extensionBehavior.find(TString(extName)); |
| 472 | if (iter == context->extensionBehavior.end()) { |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 473 | switch (behaviorVal) { |
| 474 | case EBhRequire: |
| 475 | CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str()); |
| 476 | break; |
| 477 | case EBhEnable: |
| 478 | case EBhWarn: |
| 479 | case EBhDisable: |
| 480 | msg = TString("extension '") + extName + "' is not supported"; |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 481 | context->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno); |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 482 | break; |
| 483 | } |
| 484 | return; |
| 485 | } else |
| 486 | iter->second = behaviorVal; |
| 487 | } |
| 488 | } |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 489 | } // extern "C" |
| 490 | |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 491 | int string_input(char* buf, int max_size, yyscan_t yyscanner) { |
| 492 | int len; |
| 493 | |
| 494 | if ((len = yylex_CPP(buf, max_size)) == 0) |
| 495 | return 0; |
| 496 | if (len >= max_size) |
| 497 | YY_FATAL_ERROR("input buffer overflow, can't enlarge buffer because scanner uses REJECT"); |
| 498 | |
| 499 | buf[len] = ' '; |
| 500 | return len+1; |
daniel@transgaming.com | 4f39fd9 | 2010-03-08 20:26:45 +0000 | [diff] [blame] | 501 | } |
alokp@chromium.org | 044a5cf | 2010-11-12 15:42:16 +0000 | [diff] [blame^] | 502 | |
| 503 | int check_type(yyscan_t yyscanner) { |
| 504 | struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; |
| 505 | |
| 506 | int token = IDENTIFIER; |
| 507 | TSymbol* symbol = yyextra->symbolTable.find(yytext); |
| 508 | if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) { |
| 509 | TVariable* variable = static_cast<TVariable*>(symbol); |
| 510 | if (variable->isUserType()) { |
| 511 | yyextra->lexAfterType = true; |
| 512 | token = TYPE_NAME; |
| 513 | } |
| 514 | } |
| 515 | yylval->lex.symbol = symbol; |
| 516 | return token; |
| 517 | } |
| 518 | |
| 519 | int reserved_word(yyscan_t yyscanner) { |
| 520 | struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; |
| 521 | |
| 522 | yyextra->error(yylineno, "Illegal use of reserved word", yytext, ""); |
| 523 | yyextra->recover(); |
| 524 | return 0; |
| 525 | } |
| 526 | |
| 527 | void yyerror(TParseContext* context, const char* reason) { |
| 528 | struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; |
| 529 | |
| 530 | if (context->AfterEOF) { |
| 531 | context->error(yylineno, reason, "unexpected EOF", ""); |
| 532 | } else { |
| 533 | context->error(yylineno, reason, yytext, ""); |
| 534 | } |
| 535 | context->recover(); |
| 536 | } |
| 537 | |
| 538 | int glslang_initialize(TParseContext* context) { |
| 539 | yyscan_t scanner = NULL; |
| 540 | if (yylex_init_extra(context, &scanner)) |
| 541 | return 1; |
| 542 | |
| 543 | context->scanner = scanner; |
| 544 | return 0; |
| 545 | } |
| 546 | |
| 547 | int glslang_finalize(TParseContext* context) { |
| 548 | yyscan_t scanner = context->scanner; |
| 549 | if (scanner == NULL) return 0; |
| 550 | |
| 551 | context->scanner = NULL; |
| 552 | return yylex_destroy(scanner); |
| 553 | } |
| 554 | |
| 555 | void glslang_scan(int count, const char* const string[], const int length[], |
| 556 | TParseContext* context) { |
| 557 | yyrestart(NULL, context->scanner); |
| 558 | yyset_lineno(EncodeSourceLoc(0, 1), context->scanner); |
| 559 | context->AfterEOF = false; |
| 560 | |
| 561 | // Init preprocessor. |
| 562 | cpp->pC = context; |
| 563 | cpp->PaWhichStr = 0; |
| 564 | cpp->PaArgv = string; |
| 565 | cpp->PaArgc = count; |
| 566 | cpp->PaStrLen = length; |
| 567 | cpp->pastFirstStatement = 0; |
| 568 | ScanFromString(string[0]); |
| 569 | } |
| 570 | |