2010-02-22 13:19:34 -08:00
|
|
|
%{
|
|
|
|
/*
|
|
|
|
* Copyright © 2008, 2009 Intel Corporation
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
* Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
2010-04-26 14:19:49 -07:00
|
|
|
#include <ctype.h>
|
2010-02-22 13:19:34 -08:00
|
|
|
#include "ast.h"
|
|
|
|
#include "glsl_parser_extras.h"
|
2010-02-25 17:17:23 -08:00
|
|
|
#include "glsl_parser.h"
|
2010-02-22 13:19:34 -08:00
|
|
|
|
|
|
|
#define YY_USER_ACTION \
|
|
|
|
do { \
|
|
|
|
yylloc->source = 0; \
|
|
|
|
yylloc->first_column = yycolumn + 1; \
|
|
|
|
yylloc->first_line = yylineno + 1; \
|
|
|
|
yycolumn += yyleng; \
|
|
|
|
} while(0);
|
|
|
|
|
2010-07-07 11:40:51 -07:00
|
|
|
#define YY_USER_INIT yylineno = 0; yycolumn = 0;
|
|
|
|
|
2010-08-01 18:44:21 -07:00
|
|
|
#define TOKEN_OR_IDENTIFIER(version, token) \
|
|
|
|
do { \
|
|
|
|
if (yyextra->language_version >= version) { \
|
|
|
|
return token; \
|
|
|
|
} else { \
|
|
|
|
yylval->identifier = strdup(yytext); \
|
|
|
|
return IDENTIFIER; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2010-08-11 17:01:31 -07:00
|
|
|
#define RESERVED_WORD(version, token) \
|
|
|
|
do { \
|
|
|
|
if (yyextra->language_version >= version) { \
|
|
|
|
return token; \
|
|
|
|
} else { \
|
|
|
|
_mesa_glsl_error(yylloc, yyextra, \
|
|
|
|
"Illegal use of reserved word `%s'", yytext); \
|
|
|
|
return ERROR_TOK; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
2010-02-22 13:19:34 -08:00
|
|
|
%}
|
|
|
|
|
|
|
|
%option bison-bridge bison-locations reentrant noyywrap
|
2010-04-29 17:53:26 -07:00
|
|
|
%option nounput noyy_top_state
|
2010-02-22 13:19:34 -08:00
|
|
|
%option never-interactive
|
|
|
|
%option prefix="_mesa_glsl_"
|
|
|
|
%option extra-type="struct _mesa_glsl_parse_state *"
|
|
|
|
|
2010-06-21 15:12:34 -07:00
|
|
|
%x PP
|
2010-02-22 13:19:34 -08:00
|
|
|
|
2010-04-26 14:19:49 -07:00
|
|
|
DEC_INT [1-9][0-9]*
|
|
|
|
HEX_INT 0[xX][0-9a-fA-F]+
|
|
|
|
OCT_INT 0[0-7]*
|
|
|
|
INT ({DEC_INT}|{HEX_INT}|{OCT_INT})
|
|
|
|
SPC [ \t]*
|
|
|
|
SPCP [ \t]+
|
|
|
|
HASH ^{SPC}#{SPC}
|
2010-02-22 13:19:34 -08:00
|
|
|
%%
|
|
|
|
|
|
|
|
[ \r\t]+ ;
|
|
|
|
|
|
|
|
/* Preprocessor tokens. */
|
|
|
|
^[ \t]*#[ \t]*$ ;
|
|
|
|
^[ \t]*#[ \t]*version { BEGIN PP; return VERSION; }
|
|
|
|
^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; }
|
2010-04-26 14:19:49 -07:00
|
|
|
{HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ {
|
|
|
|
/* Eat characters until the first digit is
|
|
|
|
* encountered
|
|
|
|
*/
|
|
|
|
char *ptr = yytext;
|
|
|
|
while (!isdigit(*ptr))
|
|
|
|
ptr++;
|
|
|
|
|
|
|
|
/* Subtract one from the line number because
|
|
|
|
* yylineno is zero-based instead of
|
|
|
|
* one-based.
|
|
|
|
*/
|
|
|
|
yylineno = strtol(ptr, &ptr, 0) - 1;
|
|
|
|
yylloc->source = strtol(ptr, NULL, 0);
|
|
|
|
}
|
|
|
|
{HASH}line{SPCP}{INT}{SPC}$ {
|
|
|
|
/* Eat characters until the first digit is
|
|
|
|
* encountered
|
|
|
|
*/
|
|
|
|
char *ptr = yytext;
|
|
|
|
while (!isdigit(*ptr))
|
|
|
|
ptr++;
|
|
|
|
|
|
|
|
/* Subtract one from the line number because
|
|
|
|
* yylineno is zero-based instead of
|
|
|
|
* one-based.
|
|
|
|
*/
|
|
|
|
yylineno = strtol(ptr, &ptr, 0) - 1;
|
|
|
|
}
|
2010-02-22 13:19:34 -08:00
|
|
|
^[ \t]*#[ \t]*pragma { BEGIN PP; return PRAGMA; }
|
2010-04-07 13:43:52 -07:00
|
|
|
<PP>\/\/[^\n]* { }
|
2010-04-07 14:49:59 -07:00
|
|
|
<PP>[ \t\r]* { }
|
2010-02-22 13:19:34 -08:00
|
|
|
<PP>: return COLON;
|
|
|
|
<PP>[_a-zA-Z][_a-zA-Z0-9]* {
|
|
|
|
yylval->identifier = strdup(yytext);
|
|
|
|
return IDENTIFIER;
|
|
|
|
}
|
|
|
|
<PP>[1-9][0-9]* {
|
|
|
|
yylval->n = strtol(yytext, NULL, 10);
|
|
|
|
return INTCONSTANT;
|
|
|
|
}
|
|
|
|
<PP>\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; }
|
|
|
|
|
|
|
|
\n { yylineno++; yycolumn = 0; }
|
|
|
|
|
|
|
|
attribute return ATTRIBUTE;
|
2010-06-30 16:40:47 -07:00
|
|
|
const return CONST_TOK;
|
2010-02-22 13:19:34 -08:00
|
|
|
bool return BOOL;
|
|
|
|
float return FLOAT;
|
|
|
|
int return INT;
|
|
|
|
|
|
|
|
break return BREAK;
|
|
|
|
continue return CONTINUE;
|
|
|
|
do return DO;
|
|
|
|
while return WHILE;
|
|
|
|
else return ELSE;
|
|
|
|
for return FOR;
|
|
|
|
if return IF;
|
|
|
|
discard return DISCARD;
|
|
|
|
return return RETURN;
|
|
|
|
|
|
|
|
bvec2 return BVEC2;
|
|
|
|
bvec3 return BVEC3;
|
|
|
|
bvec4 return BVEC4;
|
|
|
|
ivec2 return IVEC2;
|
|
|
|
ivec3 return IVEC3;
|
|
|
|
ivec4 return IVEC4;
|
|
|
|
vec2 return VEC2;
|
|
|
|
vec3 return VEC3;
|
|
|
|
vec4 return VEC4;
|
|
|
|
mat2 return MAT2;
|
|
|
|
mat3 return MAT3;
|
|
|
|
mat4 return MAT4;
|
2010-08-01 18:44:21 -07:00
|
|
|
mat2x2 TOKEN_OR_IDENTIFIER(120, MAT2X2);
|
|
|
|
mat2x3 TOKEN_OR_IDENTIFIER(120, MAT2X3);
|
|
|
|
mat2x4 TOKEN_OR_IDENTIFIER(120, MAT2X4);
|
|
|
|
mat3x2 TOKEN_OR_IDENTIFIER(120, MAT3X2);
|
|
|
|
mat3x3 TOKEN_OR_IDENTIFIER(120, MAT3X3);
|
|
|
|
mat3x4 TOKEN_OR_IDENTIFIER(120, MAT3X4);
|
|
|
|
mat4x2 TOKEN_OR_IDENTIFIER(120, MAT4X2);
|
|
|
|
mat4x3 TOKEN_OR_IDENTIFIER(120, MAT4X3);
|
|
|
|
mat4x4 TOKEN_OR_IDENTIFIER(120, MAT4X4);
|
2010-02-22 13:19:34 -08:00
|
|
|
|
|
|
|
in return IN;
|
|
|
|
out return OUT;
|
|
|
|
inout return INOUT;
|
|
|
|
uniform return UNIFORM;
|
|
|
|
varying return VARYING;
|
2010-08-01 18:44:21 -07:00
|
|
|
centroid TOKEN_OR_IDENTIFIER(120, CENTROID);
|
|
|
|
invariant TOKEN_OR_IDENTIFIER(120, INVARIANT);
|
2010-02-22 13:19:34 -08:00
|
|
|
|
2010-08-01 18:44:21 -07:00
|
|
|
flat TOKEN_OR_IDENTIFIER(130, FLAT);
|
|
|
|
smooth TOKEN_OR_IDENTIFIER(130, SMOOTH);
|
|
|
|
noperspective TOKEN_OR_IDENTIFIER(130, NOPERSPECTIVE);
|
2010-06-18 18:36:51 -07:00
|
|
|
|
2010-02-22 13:19:34 -08:00
|
|
|
sampler1D return SAMPLER1D;
|
|
|
|
sampler2D return SAMPLER2D;
|
|
|
|
sampler3D return SAMPLER3D;
|
|
|
|
samplerCube return SAMPLERCUBE;
|
|
|
|
sampler1DShadow return SAMPLER1DSHADOW;
|
|
|
|
sampler2DShadow return SAMPLER2DSHADOW;
|
|
|
|
|
|
|
|
struct return STRUCT;
|
|
|
|
void return VOID;
|
|
|
|
|
2010-06-30 17:30:03 -07:00
|
|
|
layout {
|
|
|
|
if ((yyextra->language_version >= 140)
|
|
|
|
|| (yyextra->ARB_fragment_coord_conventions_enable)){
|
|
|
|
return LAYOUT_TOK;
|
|
|
|
} else {
|
|
|
|
yylval->identifier = strdup(yytext);
|
|
|
|
return IDENTIFIER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-22 13:19:34 -08:00
|
|
|
\+\+ return INC_OP;
|
|
|
|
-- return DEC_OP;
|
|
|
|
\<= return LE_OP;
|
|
|
|
>= return GE_OP;
|
|
|
|
== return EQ_OP;
|
|
|
|
!= return NE_OP;
|
|
|
|
&& return AND_OP;
|
|
|
|
\|\| return OR_OP;
|
|
|
|
"^^" return XOR_OP;
|
|
|
|
|
|
|
|
\*= return MUL_ASSIGN;
|
|
|
|
\/= return DIV_ASSIGN;
|
|
|
|
\+= return ADD_ASSIGN;
|
|
|
|
\%= return MOD_ASSIGN;
|
|
|
|
\<\<= return LEFT_ASSIGN;
|
|
|
|
>>= return RIGHT_ASSIGN;
|
|
|
|
&= return AND_ASSIGN;
|
|
|
|
^= return XOR_ASSIGN;
|
|
|
|
\|= return OR_ASSIGN;
|
|
|
|
-= return SUB_ASSIGN;
|
|
|
|
|
|
|
|
[1-9][0-9]* {
|
|
|
|
yylval->n = strtol(yytext, NULL, 10);
|
|
|
|
return INTCONSTANT;
|
|
|
|
}
|
|
|
|
0[xX][0-9a-fA-F]+ {
|
|
|
|
yylval->n = strtol(yytext + 2, NULL, 16);
|
|
|
|
return INTCONSTANT;
|
|
|
|
}
|
|
|
|
0[0-7]* {
|
2010-07-19 11:52:54 -07:00
|
|
|
yylval->n = strtol(yytext, NULL, 8);
|
2010-02-22 13:19:34 -08:00
|
|
|
return INTCONSTANT;
|
|
|
|
}
|
|
|
|
|
|
|
|
[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
|
|
|
|
yylval->real = strtod(yytext, NULL);
|
|
|
|
return FLOATCONSTANT;
|
|
|
|
}
|
|
|
|
\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
|
|
|
|
yylval->real = strtod(yytext, NULL);
|
|
|
|
return FLOATCONSTANT;
|
|
|
|
}
|
|
|
|
[0-9]+\.([eE][+-]?[0-9]+)?[fF]? {
|
|
|
|
yylval->real = strtod(yytext, NULL);
|
|
|
|
return FLOATCONSTANT;
|
|
|
|
}
|
|
|
|
[0-9]+[eE][+-]?[0-9]+[fF]? {
|
|
|
|
yylval->real = strtod(yytext, NULL);
|
|
|
|
return FLOATCONSTANT;
|
|
|
|
}
|
2010-08-02 11:26:43 -07:00
|
|
|
[0-9]+[fF] {
|
|
|
|
yylval->real = strtod(yytext, NULL);
|
|
|
|
return FLOATCONSTANT;
|
|
|
|
}
|
2010-02-22 13:19:34 -08:00
|
|
|
|
|
|
|
true {
|
|
|
|
yylval->n = 1;
|
|
|
|
return BOOLCONSTANT;
|
|
|
|
}
|
|
|
|
false {
|
|
|
|
yylval->n = 0;
|
|
|
|
return BOOLCONSTANT;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Reserved words in GLSL 1.10. */
|
2010-08-11 17:01:31 -07:00
|
|
|
asm RESERVED_WORD(999, ASM);
|
|
|
|
class RESERVED_WORD(999, CLASS);
|
|
|
|
union RESERVED_WORD(999, UNION);
|
|
|
|
enum RESERVED_WORD(999, ENUM);
|
|
|
|
typedef RESERVED_WORD(999, TYPEDEF);
|
|
|
|
template RESERVED_WORD(999, TEMPLATE);
|
|
|
|
this RESERVED_WORD(999, THIS);
|
|
|
|
packed RESERVED_WORD(999, PACKED);
|
|
|
|
goto RESERVED_WORD(999, GOTO);
|
|
|
|
switch RESERVED_WORD(130, SWITCH);
|
|
|
|
default RESERVED_WORD(130, DEFAULT);
|
|
|
|
inline RESERVED_WORD(999, INLINE_TOK);
|
|
|
|
noinline RESERVED_WORD(999, NOINLINE);
|
|
|
|
volatile RESERVED_WORD(999, VOLATILE);
|
|
|
|
public RESERVED_WORD(999, PUBLIC_TOK);
|
|
|
|
static RESERVED_WORD(999, STATIC);
|
|
|
|
extern RESERVED_WORD(999, EXTERN);
|
|
|
|
external RESERVED_WORD(999, EXTERNAL);
|
|
|
|
interface RESERVED_WORD(999, INTERFACE);
|
|
|
|
long RESERVED_WORD(999, LONG);
|
|
|
|
short RESERVED_WORD(999, SHORT);
|
|
|
|
double RESERVED_WORD(999, DOUBLE);
|
|
|
|
half RESERVED_WORD(999, HALF);
|
|
|
|
fixed RESERVED_WORD(999, FIXED);
|
|
|
|
unsigned RESERVED_WORD(999, UNSIGNED);
|
|
|
|
input RESERVED_WORD(999, INPUT);
|
|
|
|
output RESERVED_WORD(999, OUTPUT);
|
|
|
|
hvec2 RESERVED_WORD(999, HVEC2);
|
|
|
|
hvec3 RESERVED_WORD(999, HVEC3);
|
|
|
|
hvec4 RESERVED_WORD(999, HVEC4);
|
|
|
|
dvec2 RESERVED_WORD(999, DVEC2);
|
|
|
|
dvec3 RESERVED_WORD(999, DVEC3);
|
|
|
|
dvec4 RESERVED_WORD(999, DVEC4);
|
|
|
|
fvec2 RESERVED_WORD(999, FVEC2);
|
|
|
|
fvec3 RESERVED_WORD(999, FVEC3);
|
|
|
|
fvec4 RESERVED_WORD(999, FVEC4);
|
2010-02-22 13:19:34 -08:00
|
|
|
sampler2DRect return SAMPLER2DRECT;
|
2010-08-11 17:01:31 -07:00
|
|
|
sampler3DRect RESERVED_WORD(999, SAMPLER3DRECT);
|
2010-02-22 13:19:34 -08:00
|
|
|
sampler2DRectShadow return SAMPLER2DRECTSHADOW;
|
2010-08-11 17:01:31 -07:00
|
|
|
sizeof RESERVED_WORD(999, SIZEOF);
|
|
|
|
cast RESERVED_WORD(999, CAST);
|
|
|
|
namespace RESERVED_WORD(999, NAMESPACE);
|
|
|
|
using RESERVED_WORD(999, USING);
|
2010-02-22 13:19:34 -08:00
|
|
|
|
|
|
|
/* Additional reserved words in GLSL 1.20. */
|
2010-08-01 18:44:21 -07:00
|
|
|
lowp TOKEN_OR_IDENTIFIER(120, LOWP);
|
|
|
|
mediump TOKEN_OR_IDENTIFIER(120, MEDIUMP);
|
|
|
|
highp TOKEN_OR_IDENTIFIER(120, HIGHP);
|
|
|
|
precision TOKEN_OR_IDENTIFIER(120, PRECISION);
|
2010-02-22 13:19:34 -08:00
|
|
|
|
2010-08-07 00:50:08 -07:00
|
|
|
/* Additional reserved words in GLSL 1.30. */
|
|
|
|
common TOKEN_OR_IDENTIFIER(130, COMMON);
|
|
|
|
partition TOKEN_OR_IDENTIFIER(130, PARTITION);
|
|
|
|
active TOKEN_OR_IDENTIFIER(130, ACTIVE);
|
|
|
|
superp TOKEN_OR_IDENTIFIER(130, SUPERP);
|
|
|
|
samplerBuffer TOKEN_OR_IDENTIFIER(130, SAMPLERBUFFER);
|
|
|
|
filter TOKEN_OR_IDENTIFIER(130, FILTER);
|
|
|
|
image1D TOKEN_OR_IDENTIFIER(130, IMAGE1D);
|
|
|
|
image2D TOKEN_OR_IDENTIFIER(130, IMAGE2D);
|
|
|
|
image3D TOKEN_OR_IDENTIFIER(130, IMAGE3D);
|
|
|
|
imageCube TOKEN_OR_IDENTIFIER(130, IMAGECUBE);
|
|
|
|
iimage1D TOKEN_OR_IDENTIFIER(130, IIMAGE1D);
|
|
|
|
iimage2D TOKEN_OR_IDENTIFIER(130, IIMAGE2D);
|
|
|
|
iimage3D TOKEN_OR_IDENTIFIER(130, IIMAGE3D);
|
|
|
|
iimageCube TOKEN_OR_IDENTIFIER(130, IIMAGECUBE);
|
|
|
|
uimage1D TOKEN_OR_IDENTIFIER(130, UIMAGE1D);
|
|
|
|
uimage2D TOKEN_OR_IDENTIFIER(130, UIMAGE2D);
|
|
|
|
uimage3D TOKEN_OR_IDENTIFIER(130, UIMAGE3D);
|
|
|
|
uimageCube TOKEN_OR_IDENTIFIER(130, UIMAGECUBE);
|
|
|
|
image1DArray TOKEN_OR_IDENTIFIER(130, IMAGE1DARRAY);
|
|
|
|
image2DArray TOKEN_OR_IDENTIFIER(130, IMAGE2DARRAY);
|
|
|
|
iimage1DArray TOKEN_OR_IDENTIFIER(130, IIMAGE1DARRAY);
|
|
|
|
iimage2DArray TOKEN_OR_IDENTIFIER(130, IIMAGE2DARRAY);
|
|
|
|
uimage1DArray TOKEN_OR_IDENTIFIER(130, UIMAGE1DARRAY);
|
|
|
|
uimage2DArray TOKEN_OR_IDENTIFIER(130, UIMAGE2DARRAY);
|
|
|
|
image1DShadow TOKEN_OR_IDENTIFIER(130, IMAGE1DSHADOW);
|
|
|
|
image2DShadow TOKEN_OR_IDENTIFIER(130, IMAGE2DSHADOW);
|
|
|
|
imageBuffer TOKEN_OR_IDENTIFIER(130, IMAGEBUFFER);
|
|
|
|
iimageBuffer TOKEN_OR_IDENTIFIER(130, IIMAGEBUFFER);
|
|
|
|
uimageBuffer TOKEN_OR_IDENTIFIER(130, UIMAGEBUFFER);
|
|
|
|
row_major TOKEN_OR_IDENTIFIER(130, ROW_MAJOR);
|
|
|
|
|
2010-02-22 13:19:34 -08:00
|
|
|
[_a-zA-Z][_a-zA-Z0-9]* {
|
2010-06-18 17:43:40 -07:00
|
|
|
struct _mesa_glsl_parse_state *state = yyextra;
|
2010-06-25 13:14:37 -07:00
|
|
|
void *ctx = state;
|
2010-06-18 17:43:40 -07:00
|
|
|
yylval->identifier = talloc_strdup(ctx, yytext);
|
2010-03-19 11:12:33 -07:00
|
|
|
return IDENTIFIER;
|
2010-02-22 13:19:34 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
. { return yytext[0]; }
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
void
|
2010-06-21 11:43:42 -07:00
|
|
|
_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string)
|
2010-02-22 13:19:34 -08:00
|
|
|
{
|
|
|
|
yylex_init_extra(state, & state->scanner);
|
2010-06-21 11:43:42 -07:00
|
|
|
yy_scan_string(string, state->scanner);
|
2010-02-22 13:19:34 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state)
|
|
|
|
{
|
|
|
|
yylex_destroy(state->scanner);
|
|
|
|
}
|