From: Ian Romanick Date: Fri, 26 Feb 2010 01:17:23 +0000 (-0800) Subject: autoconf for the ... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d59673c9de9f14e6aefcdb0b06751d935385c4aa;p=mesa.git autoconf for the ... --- diff --git a/.gitignore b/.gitignore index 4c678686229..e098bdb965a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,22 @@ +.deps +COPYING +INSTALL +Makefile.in +aclocal.m4 +autom4te.cache +config.* +configure +depcomp +ylwrap +install-sh +missing +stamp-h1 +Makefile *.o *~ builtin_types.h glsl_lexer.cpp glsl_parser.output -glsl_parser.tab.cpp -glsl_parser.tab.h -glsl_parser.tab.hpp +glsl_parser.cpp +glsl_parser.h glsl diff --git a/Makefile b/Makefile deleted file mode 100644 index 7b1f3f1f93f..00000000000 --- a/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -CSRCS = symbol_table.c hash_table.c glsl_types.c -CCSRCS = glsl_parser.tab.cpp glsl_lexer.cpp glsl_parser_extras.cpp \ - ast_expr.cpp -# ast_to_hir.cpp ir.cpp hir_field_selection.cpp -OBJS = $(CSRCS:.c=.o) $(CCSRCS:.cpp=.o) - -CC = gcc -CXX = g++ -WARN = -Wall -Wextra -Wunsafe-loop-optimizations -Wstack-protector \ - -Wunreachable-code -CPPFLAGS = -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -CFLAGS = -O0 -ggdb3 -fstack-protector $(CPPFLAGS) $(WARN) -std=c89 -ansi -pedantic -CXXFLAGS = -O0 -ggdb3 -fstack-protector $(CPPFLAGS) $(WARN) -LDLAGS = -ggdb3 - -glsl: $(OBJS) - $(CXX) $(LDLAGS) $(OBJS) -o glsl - -glsl_parser.tab.cpp glsl_parser.tab.h: glsl_parser.y - bison --report-file=glsl_parser.output -v -d \ - --output=glsl_parser.tab.cpp \ - --name-prefix=_mesa_glsl_ $< && \ - mv glsl_parser.tab.hpp glsl_parser.tab.h - -glsl_lexer.cpp: glsl_lexer.l - flex --outfile="glsl_lexer.cpp" $< - -glsl_parser_tab.o: glsl_parser.tab.cpp -glsl_types.o: glsl_types.c glsl_types.h builtin_types.h -glsl_lexer.o: glsl_lexer.cpp glsl_parser.tab.h glsl_parser_extras.h ast.h -glsl_parser.o: glsl_parser_extras.h ast.h -ast_to_hir.o: ast_to_hir.cpp symbol_table.h glsl_parser_extras.h ast.h glsl_types.h ir.h - -builtin_types.h: builtin_types.sh - ./builtin_types.sh > builtin_types.h - -clean: - rm -f $(OBJS) glsl - rm -f glsl_lexer.cpp glsl_parser.tab.{cpp,h,hpp} glsl_parser.output - rm -f builtin_types.h - rm -f *~ \ No newline at end of file diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000000..28d9c3c7a1d --- /dev/null +++ b/Makefile.am @@ -0,0 +1,39 @@ +# Copyright © 2010 Intel Corporation +# All Rights Reserved. +# +# 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 +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL +# AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS 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. + +AUTOMAKE_OPTIONS = foreign + +bin_PROGRAMS = glsl +glsl_SOURCES = symbol_table.c hash_table.c glsl_types.c \ + glsl_parser.ypp glsl_lexer.lpp glsl_parser_extras.cpp \ + ast_expr.cpp +# ast_to_hir.cpp ir.cpp hir_field_selection.cpp + +BUILT_SOURCES = glsl_parser.h builtin_types.h + +glsl_parser.h: glsl_parser.ypp + +.lpp.cpp: + $(LEXCOMPILE) --outfile="$@" $< + +builtin_types.h: builtin_types.sh + sh ./builtin_types.sh > builtin_types.h diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 00000000000..904cd6746c8 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir + +autoreconf -v --install || exit 1 +cd $ORIGDIR || exit $? + +$srcdir/configure --enable-maintainer-mode "$@" diff --git a/configure.ac b/configure.ac new file mode 100644 index 00000000000..b97feb94407 --- /dev/null +++ b/configure.ac @@ -0,0 +1,71 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.61) +AC_INIT(glsl, XXXXX, idr@freedesktop.org, glsl) +AC_CONFIG_SRCDIR([Makefile.am]) +AM_CONFIG_HEADER([config.h]) + +AM_INIT_AUTOMAKE + +AM_MAINTAINER_MODE + +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC +AC_PROG_MAKE_SET +AC_PROG_YACC +AC_PROG_LEX + +# Checks for libraries. + +# Checks for header files. + +# Checks for typedefs, structures, and compiler characteristics. + +# Checks for library functions. +AC_HEADER_STDC + + +AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug], + [use debug compiler flags and macros @<:@default=disabled@:>@])], + [enable_debug="$enableval"], + [enable_debug=no] +) +if test "x$enable_debug" = xyes; then + DEFINES="$DEFINES -DDEBUG" + if test "x$GCC" = xyes; then + # Remove any -g or -O flags from the command line + CFLAGS=[`echo $CFLAGS | sed 's/-g[^ \t]*[ \t]*//g;s/-O[^ \t]*[ \t]*//g'`] + CFLAGS="$CFLAGS -O0 -ggdb3 -fstack-protector -D_FORTIFY_SOURCE=2" + fi + if test "x$GXX" = xyes; then + # Remove any -g flags from the command line + CXXFLAGS=[`echo $CXXFLAGS | sed 's/-g[^ \t]*[ \t]*//g;s/-O[^ \t]*[ \t]*//g'`] + CXXFLAGS="$CXXFLAGS -O0 -ggdb3 -fstack-protector -D_FORTIFY_SOURCE=2" + fi +fi + + +if test "x$GCC" = xyes ; then + WARN="-Wall -Wextra -Wunsafe-loop-optimizations -Wstack-protector -Wunreadchable-code" +else + WARN="" +fi + +if test "x$GXX" = xyes ; then + WARN="-Wall -Wextra -Wunsafe-loop-optimizations -Wstack-protector" +else + WARN="" +fi + +if test "x$GCC" = xyes ; then + CFLAGS="$CFLAGS -std=c89 -ansi -pedantic" +fi + +CFLAGS="$CFLAGS $WARN" +CXXFLAGS="$CXXFLAGS $WARN" +YFLAGS="-d -v" + +AC_OUTPUT([Makefile]) diff --git a/glsl_lexer.l b/glsl_lexer.l deleted file mode 100644 index 201d4616834..00000000000 --- a/glsl_lexer.l +++ /dev/null @@ -1,273 +0,0 @@ -%{ -/* - * 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. - */ -#include "ast.h" -#include "glsl_parser_extras.h" -#include "glsl_parser.tab.h" -#include "symbol_table.h" - -#define YY_USER_ACTION \ - do { \ - yylloc->source = 0; \ - yylloc->first_column = yycolumn + 1; \ - yylloc->first_line = yylineno + 1; \ - yycolumn += yyleng; \ - } while(0); - -%} - -%option bison-bridge bison-locations reentrant noyywrap -%option never-interactive -%option prefix="_mesa_glsl_" -%option extra-type="struct _mesa_glsl_parse_state *" -%option stack - -%x PP COMMENT - -%% - -"/*" { yy_push_state(COMMENT, yyscanner); } -[^*\n]* -[^*\n]*\n { yylineno++; yycolumn = 0; } -"*"+[^*/\n]* -"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; } -"*"+"/" { yy_pop_state(yyscanner); } - -\/\/.*\n { yylineno++; yycolumn = 0; } -[ \r\t]+ ; - - /* Preprocessor tokens. */ -^[ \t]*#[ \t]*$ ; -^[ \t]*#[ \t]*version { BEGIN PP; return VERSION; } -^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; } -^[ \t]*#[ \t]*line { BEGIN PP; return LINE; } -^[ \t]*#[ \t]*pragma { BEGIN PP; return PRAGMA; } -: return COLON; -[_a-zA-Z][_a-zA-Z0-9]* { - yylval->identifier = strdup(yytext); - return IDENTIFIER; - } -[1-9][0-9]* { - yylval->n = strtol(yytext, NULL, 10); - return INTCONSTANT; - } -\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; } - -\n { yylineno++; yycolumn = 0; } - -attribute return ATTRIBUTE; -const return CONST; -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; -mat2x2 return MAT2X2; -mat2x3 return MAT2X3; -mat2x4 return MAT2X4; -mat3x2 return MAT3X2; -mat3x3 return MAT3X3; -mat3x4 return MAT3X4; -mat4x2 return MAT4X2; -mat4x3 return MAT4X3; -mat4x4 return MAT4X4; - -in return IN; -out return OUT; -inout return INOUT; -uniform return UNIFORM; -varying return VARYING; -centroid return CENTROID; -invariant return INVARIANT; - -sampler1D return SAMPLER1D; -sampler2D return SAMPLER2D; -sampler3D return SAMPLER3D; -samplerCube return SAMPLERCUBE; -sampler1DShadow return SAMPLER1DSHADOW; -sampler2DShadow return SAMPLER2DSHADOW; - -struct return STRUCT; -void return VOID; - -\+\+ 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]* { - yylval->n = strtol(yytext + 2, NULL, 8); - 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; - } - -true { - yylval->n = 1; - return BOOLCONSTANT; - } -false { - yylval->n = 0; - return BOOLCONSTANT; - } - - - /* Reserved words in GLSL 1.10. */ -asm return ASM; -class return CLASS; -union return UNION; -enum return ENUM; -typedef return TYPEDEF; -template return TEMPLATE; -this return THIS; -packed return PACKED; -goto return GOTO; -switch return SWITCH; -default return DEFAULT; -inline return INLINE; -noinline return NOINLINE; -volatile return VOLATILE; -public return PUBLIC; -static return STATIC; -extern return EXTERN; -external return EXTERNAL; -interface return INTERFACE; -long return LONG; -short return SHORT; -double return DOUBLE; -half return HALF; -fixed return FIXED; -unsigned return UNSIGNED; -input return INPUT; -output return OUTPUT; -hvec2 return HVEC2; -hvec3 return HVEC3; -hvec4 return HVEC4; -dvec2 return DVEC2; -dvec3 return DVEC3; -dvec4 return DVEC4; -fvec2 return FVEC2; -fvec3 return FVEC3; -fvec4 return FVEC4; -sampler2DRect return SAMPLER2DRECT; -sampler3DRect return SAMPLER3DRECT; -sampler2DRectShadow return SAMPLER2DRECTSHADOW; -sizeof return SIZEOF; -cast return CAST; -namespace return NAMESPACE; -using return USING; - - /* Additional reserved words in GLSL 1.20. */ -lowp return LOWP; -mediump return MEDIUMP; -highp return HIGHP; -precision return PRECISION; - -[_a-zA-Z][_a-zA-Z0-9]* { - yylval->identifier = strdup(yytext); - - if (_mesa_symbol_table_find_symbol(yyextra->symbols, - 0, - yylval->identifier)) - return TYPE_NAME; - else - return IDENTIFIER; - } - -. { return yytext[0]; } - -%% - -void -_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, - const char *string, size_t len) -{ - yylex_init_extra(state, & state->scanner); - yy_scan_bytes(string, len, state->scanner); -} - -void -_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state) -{ - yylex_destroy(state->scanner); -} diff --git a/glsl_lexer.lpp b/glsl_lexer.lpp new file mode 100644 index 00000000000..9c7e3064e4a --- /dev/null +++ b/glsl_lexer.lpp @@ -0,0 +1,273 @@ +%{ +/* + * 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. + */ +#include "ast.h" +#include "glsl_parser_extras.h" +#include "glsl_parser.h" +#include "symbol_table.h" + +#define YY_USER_ACTION \ + do { \ + yylloc->source = 0; \ + yylloc->first_column = yycolumn + 1; \ + yylloc->first_line = yylineno + 1; \ + yycolumn += yyleng; \ + } while(0); + +%} + +%option bison-bridge bison-locations reentrant noyywrap +%option never-interactive +%option prefix="_mesa_glsl_" +%option extra-type="struct _mesa_glsl_parse_state *" +%option stack + +%x PP COMMENT + +%% + +"/*" { yy_push_state(COMMENT, yyscanner); } +[^*\n]* +[^*\n]*\n { yylineno++; yycolumn = 0; } +"*"+[^*/\n]* +"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; } +"*"+"/" { yy_pop_state(yyscanner); } + +\/\/.*\n { yylineno++; yycolumn = 0; } +[ \r\t]+ ; + + /* Preprocessor tokens. */ +^[ \t]*#[ \t]*$ ; +^[ \t]*#[ \t]*version { BEGIN PP; return VERSION; } +^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; } +^[ \t]*#[ \t]*line { BEGIN PP; return LINE; } +^[ \t]*#[ \t]*pragma { BEGIN PP; return PRAGMA; } +: return COLON; +[_a-zA-Z][_a-zA-Z0-9]* { + yylval->identifier = strdup(yytext); + return IDENTIFIER; + } +[1-9][0-9]* { + yylval->n = strtol(yytext, NULL, 10); + return INTCONSTANT; + } +\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; } + +\n { yylineno++; yycolumn = 0; } + +attribute return ATTRIBUTE; +const return CONST; +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; +mat2x2 return MAT2X2; +mat2x3 return MAT2X3; +mat2x4 return MAT2X4; +mat3x2 return MAT3X2; +mat3x3 return MAT3X3; +mat3x4 return MAT3X4; +mat4x2 return MAT4X2; +mat4x3 return MAT4X3; +mat4x4 return MAT4X4; + +in return IN; +out return OUT; +inout return INOUT; +uniform return UNIFORM; +varying return VARYING; +centroid return CENTROID; +invariant return INVARIANT; + +sampler1D return SAMPLER1D; +sampler2D return SAMPLER2D; +sampler3D return SAMPLER3D; +samplerCube return SAMPLERCUBE; +sampler1DShadow return SAMPLER1DSHADOW; +sampler2DShadow return SAMPLER2DSHADOW; + +struct return STRUCT; +void return VOID; + +\+\+ 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]* { + yylval->n = strtol(yytext + 2, NULL, 8); + 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; + } + +true { + yylval->n = 1; + return BOOLCONSTANT; + } +false { + yylval->n = 0; + return BOOLCONSTANT; + } + + + /* Reserved words in GLSL 1.10. */ +asm return ASM; +class return CLASS; +union return UNION; +enum return ENUM; +typedef return TYPEDEF; +template return TEMPLATE; +this return THIS; +packed return PACKED; +goto return GOTO; +switch return SWITCH; +default return DEFAULT; +inline return INLINE; +noinline return NOINLINE; +volatile return VOLATILE; +public return PUBLIC; +static return STATIC; +extern return EXTERN; +external return EXTERNAL; +interface return INTERFACE; +long return LONG; +short return SHORT; +double return DOUBLE; +half return HALF; +fixed return FIXED; +unsigned return UNSIGNED; +input return INPUT; +output return OUTPUT; +hvec2 return HVEC2; +hvec3 return HVEC3; +hvec4 return HVEC4; +dvec2 return DVEC2; +dvec3 return DVEC3; +dvec4 return DVEC4; +fvec2 return FVEC2; +fvec3 return FVEC3; +fvec4 return FVEC4; +sampler2DRect return SAMPLER2DRECT; +sampler3DRect return SAMPLER3DRECT; +sampler2DRectShadow return SAMPLER2DRECTSHADOW; +sizeof return SIZEOF; +cast return CAST; +namespace return NAMESPACE; +using return USING; + + /* Additional reserved words in GLSL 1.20. */ +lowp return LOWP; +mediump return MEDIUMP; +highp return HIGHP; +precision return PRECISION; + +[_a-zA-Z][_a-zA-Z0-9]* { + yylval->identifier = strdup(yytext); + + if (_mesa_symbol_table_find_symbol(yyextra->symbols, + 0, + yylval->identifier)) + return TYPE_NAME; + else + return IDENTIFIER; + } + +. { return yytext[0]; } + +%% + +void +_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, + const char *string, size_t len) +{ + yylex_init_extra(state, & state->scanner); + yy_scan_bytes(string, len, state->scanner); +} + +void +_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state) +{ + yylex_destroy(state->scanner); +} diff --git a/glsl_parser.y b/glsl_parser.y deleted file mode 100644 index f4105652b8e..00000000000 --- a/glsl_parser.y +++ /dev/null @@ -1,1228 +0,0 @@ -%{ -/* - * 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. - */ -#include -#include -#include -#include - -#include "ast.h" -#include "glsl_parser_extras.h" -#include "symbol_table.h" -#include "glsl_types.h" - -#define YYLEX_PARAM state->scanner - -%} - -%pure-parser -%locations -%error-verbose - -%lex-param {void *scanner} -%parse-param {struct _mesa_glsl_parse_state *state} - -%union { - int n; - float real; - char *identifier; - - union { - struct ast_type_qualifier q; - unsigned i; - } type_qualifier; - - struct ast_node *node; - struct ast_type_specifier *type_specifier; - struct ast_fully_specified_type *fully_specified_type; - struct ast_function *function; - struct ast_parameter_declarator *parameter_declarator; - struct ast_function_definition *function_definition; - struct ast_compound_statement *compound_statement; - struct ast_expression *expression; - struct ast_declarator_list *declarator_list; - struct ast_struct_specifier *struct_specifier; - struct ast_declaration *declaration; - - struct { - struct ast_node *cond; - struct ast_expression *rest; - } for_rest_statement; -} - -%token ATTRIBUTE CONST BOOL FLOAT INT UINT -%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT -%token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4 -%token MAT2 MAT3 MAT4 CENTROID IN OUT INOUT UNIFORM VARYING -%token NOPERSPECTIVE FLAT SMOOTH -%token MAT2X2 MAT2X3 MAT2X4 -%token MAT3X2 MAT3X3 MAT3X4 -%token MAT4X2 MAT4X3 MAT4X4 -%token SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW -%token SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW -%token SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE -%token ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D -%token USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY -%token STRUCT VOID WHILE -%token IDENTIFIER TYPE_NAME -%token FLOATCONSTANT -%token INTCONSTANT UINTCONSTANT BOOLCONSTANT -%token FIELD_SELECTION -%token LEFT_OP RIGHT_OP -%token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP -%token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN -%token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN -%token SUB_ASSIGN -%token INVARIANT -%token HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION - -%token VERSION EXTENSION LINE PRAGMA COLON EOL INTERFACE OUTPUT - - /* Reserved words that are not actually used in the grammar. - */ -%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED GOTO -%token INLINE NOINLINE VOLATILE PUBLIC STATIC EXTERN EXTERNAL -%token LONG SHORT DOUBLE HALF FIXED UNSIGNED INPUT OUPTUT -%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4 -%token SAMPLER2DRECT SAMPLER3DRECT SAMPLER2DRECTSHADOW -%token SIZEOF CAST NAMESPACE USING LOWP MEDIUMP HIGHP - -%type variable_identifier -%type statement -%type statement_list -%type simple_statement -%type statement_matched -%type statement_unmatched -%type precision_qualifier -%type type_qualifier -%type storage_qualifier -%type interpolation_qualifier -%type type_specifier -%type type_specifier_no_prec -%type type_specifier_nonarray -%type basic_type_specifier_nonarray -%type fully_specified_type -%type function_prototype -%type function_header -%type function_header_with_parameters -%type function_declarator -%type parameter_declarator -%type parameter_declaration -%type parameter_qualifier -%type parameter_type_qualifier -%type parameter_type_specifier -%type function_definition -%type compound_statement_no_new_scope -%type compound_statement -%type statement_no_new_scope -%type expression_statement -%type expression -%type primary_expression -%type assignment_expression -%type conditional_expression -%type logical_or_expression -%type logical_xor_expression -%type logical_and_expression -%type inclusive_or_expression -%type exclusive_or_expression -%type and_expression -%type equality_expression -%type relational_expression -%type shift_expression -%type additive_expression -%type multiplicative_expression -%type unary_expression -%type constant_expression -%type integer_expression -%type postfix_expression -%type function_call_header_with_parameters -%type function_call_header_no_parameters -%type function_call_header -%type function_call_generic -%type function_call_or_method -%type function_call -%type assignment_operator -%type unary_operator -%type function_identifier -%type external_declaration -%type init_declarator_list -%type single_declaration -%type initializer -%type declaration -%type declaration_statement -%type jump_statement -%type struct_specifier -%type struct_declaration_list -%type struct_declaration -%type struct_declarator -%type struct_declarator_list -%type selection_statement_matched -%type selection_statement_unmatched -%type iteration_statement -%type condition -%type conditionopt -%type for_init_statement -%type for_rest_statement -%% - -translation_unit: - version_statement - { - _mesa_glsl_initialize_types(state); - } - external_declaration_list - | - { - state->language_version = 110; - _mesa_glsl_initialize_types(state); - } - external_declaration_list - ; - -version_statement: - VERSION INTCONSTANT EOL - { - switch ($2) { - case 110: - case 120: - case 130: - /* FINISHME: Check against implementation support versions. */ - state->language_version = $2; - break; - default: - _mesa_glsl_error(& @2, state, "Shading language version" - "%u is not supported\n", $2); - break; - } - } - ; - -external_declaration_list: - external_declaration - { - insert_at_tail(& state->translation_unit, - (struct simple_node *) $1); - } - | external_declaration_list external_declaration - { - insert_at_tail(& state->translation_unit, - (struct simple_node *) $2); - } - ; - -variable_identifier: - IDENTIFIER - ; - -primary_expression: - variable_identifier - { - $$ = new ast_expression(ast_identifier, NULL, NULL, NULL); - $$->primary_expression.identifier = $1; - } - | INTCONSTANT - { - $$ = new ast_expression(ast_int_constant, NULL, NULL, NULL); - $$->primary_expression.int_constant = $1; - } - | UINTCONSTANT - { - $$ = new ast_expression(ast_uint_constant, NULL, NULL, NULL); - $$->primary_expression.uint_constant = $1; - } - | FLOATCONSTANT - { - $$ = new ast_expression(ast_float_constant, NULL, NULL, NULL); - $$->primary_expression.float_constant = $1; - } - | BOOLCONSTANT - { - $$ = new ast_expression(ast_bool_constant, NULL, NULL, NULL); - $$->primary_expression.bool_constant = $1; - } - | '(' expression ')' - { - $$ = $2; - } - ; - -postfix_expression: - primary_expression - | postfix_expression '[' integer_expression ']' - { - $$ = new ast_expression(ast_array_index, $1, $3, NULL); - } - | function_call - { - $$ = $1; - } - | postfix_expression '.' IDENTIFIER - { - $$ = new ast_expression(ast_field_selection, $1, NULL, NULL); - $$->primary_expression.identifier = $3; - } - | postfix_expression INC_OP - { - $$ = new ast_expression(ast_post_inc, $1, NULL, NULL); - } - | postfix_expression DEC_OP - { - $$ = new ast_expression(ast_post_dec, $1, NULL, NULL); - } - ; - -integer_expression: - expression - ; - -function_call: - function_call_or_method - ; - -function_call_or_method: - function_call_generic - | postfix_expression '.' function_call_generic - { - $$ = new ast_expression(ast_field_selection, $1, $3, NULL); - } - ; - -function_call_generic: - function_call_header_with_parameters ')' - | function_call_header_no_parameters ')' - ; - -function_call_header_no_parameters: - function_call_header VOID - | function_call_header - ; - -function_call_header_with_parameters: - function_call_header assignment_expression - { - $$ = $1; - $$->subexpressions[1] = $2; - } - | function_call_header_with_parameters ',' assignment_expression - { - $$ = $1; - insert_at_tail((struct simple_node *) $$->subexpressions[1], - (struct simple_node *) $3); - } - ; - - // Grammar Note: Constructors look like functions, but lexical - // analysis recognized most of them as keywords. They are now - // recognized through "type_specifier". -function_call_header: - function_identifier '(' - { - $$ = new ast_expression(ast_function_call, - (struct ast_expression *) $1, - NULL, NULL); - } - ; - -function_identifier: - type_specifier - { - $$ = (struct ast_node *) $1; - } - | IDENTIFIER - { - ast_expression *expr = - new ast_expression(ast_identifier, NULL, NULL, NULL); - expr->primary_expression.identifier = $1; - - $$ = (struct ast_node *) expr; - } - | FIELD_SELECTION - { - ast_expression *expr = - new ast_expression(ast_identifier, NULL, NULL, NULL); - expr->primary_expression.identifier = $1; - - $$ = (struct ast_node *) expr; - } - ; - - // Grammar Note: No traditional style type casts. -unary_expression: - postfix_expression - | INC_OP unary_expression - { - $$ = new ast_expression(ast_pre_inc, $2, NULL, NULL); - } - | DEC_OP unary_expression - { - $$ = new ast_expression(ast_pre_dec, $2, NULL, NULL); - } - | unary_operator unary_expression - { - $$ = new ast_expression($1, $2, NULL, NULL); - } - ; - - // Grammar Note: No '*' or '&' unary ops. Pointers are not supported. -unary_operator: - '+' { $$ = ast_plus; } - | '-' { $$ = ast_neg; } - | '!' { $$ = ast_logic_not; } - | '~' { $$ = ast_bit_not; } - ; - -multiplicative_expression: - unary_expression - | multiplicative_expression '*' unary_expression - { - $$ = new ast_expression_bin(ast_mul, $1, $3); - } - | multiplicative_expression '/' unary_expression - { - $$ = new ast_expression_bin(ast_div, $1, $3); - } - | multiplicative_expression '%' unary_expression - { - $$ = new ast_expression_bin(ast_mod, $1, $3); - } - ; - -additive_expression: - multiplicative_expression - | additive_expression '+' multiplicative_expression - { - $$ = new ast_expression_bin(ast_add, $1, $3); - } - | additive_expression '-' multiplicative_expression - { - $$ = new ast_expression_bin(ast_sub, $1, $3); - } - ; - -shift_expression: - additive_expression - | shift_expression LEFT_OP additive_expression - { - $$ = new ast_expression_bin(ast_lshift, $1, $3); - } - | shift_expression RIGHT_OP additive_expression - { - $$ = new ast_expression_bin(ast_rshift, $1, $3); - } - ; - -relational_expression: - shift_expression - | relational_expression '<' shift_expression - { - $$ = new ast_expression_bin(ast_less, $1, $3); - } - | relational_expression '>' shift_expression - { - $$ = new ast_expression_bin(ast_greater, $1, $3); - } - | relational_expression LE_OP shift_expression - { - $$ = new ast_expression_bin(ast_lequal, $1, $3); - } - | relational_expression GE_OP shift_expression - { - $$ = new ast_expression_bin(ast_gequal, $1, $3); - } - ; - -equality_expression: - relational_expression - | equality_expression EQ_OP relational_expression - { - $$ = new ast_expression_bin(ast_equal, $1, $3); - } - | equality_expression NE_OP relational_expression - { - $$ = new ast_expression_bin(ast_nequal, $1, $3); - } - ; - -and_expression: - equality_expression - | and_expression '&' equality_expression - { - $$ = new ast_expression_bin(ast_bit_or, $1, $3); - } - ; - -exclusive_or_expression: - and_expression - | exclusive_or_expression '^' and_expression - { - $$ = new ast_expression_bin(ast_bit_xor, $1, $3); - } - ; - -inclusive_or_expression: - exclusive_or_expression - | inclusive_or_expression '|' exclusive_or_expression - { - $$ = new ast_expression_bin(ast_bit_or, $1, $3); - } - ; - -logical_and_expression: - inclusive_or_expression - | logical_and_expression AND_OP inclusive_or_expression - { - $$ = new ast_expression_bin(ast_logic_and, $1, $3); - } - ; - -logical_xor_expression: - logical_and_expression - | logical_xor_expression XOR_OP logical_and_expression - { - $$ = new ast_expression_bin(ast_logic_xor, $1, $3); - } - ; - -logical_or_expression: - logical_xor_expression - | logical_or_expression OR_OP logical_xor_expression - { - $$ = new ast_expression_bin(ast_logic_or, $1, $3); - } - ; - -conditional_expression: - logical_or_expression - | logical_or_expression '?' expression ':' assignment_expression - { - $$ = new ast_expression(ast_conditional, $1, $3, $5); - } - ; - -assignment_expression: - conditional_expression - | unary_expression assignment_operator assignment_expression - { - $$ = new ast_expression($2, $1, $3, NULL); - } - ; - -assignment_operator: - '=' { $$ = ast_assign; } - | MUL_ASSIGN { $$ = ast_mul_assign; } - | DIV_ASSIGN { $$ = ast_div_assign; } - | MOD_ASSIGN { $$ = ast_mod_assign; } - | ADD_ASSIGN { $$ = ast_add_assign; } - | SUB_ASSIGN { $$ = ast_sub_assign; } - | LEFT_ASSIGN { $$ = ast_ls_assign; } - | RIGHT_ASSIGN { $$ = ast_rs_assign; } - | AND_ASSIGN { $$ = ast_and_assign; } - | XOR_ASSIGN { $$ = ast_xor_assign; } - | OR_ASSIGN { $$ = ast_or_assign; } - ; - -expression: - assignment_expression - { - $$ = $1; - } - | expression ',' assignment_expression - { - if ($1->oper != ast_sequence) { - $$ = new ast_expression(ast_sequence, NULL, NULL, NULL); - insert_at_tail(& $$->expressions, $1); - } else { - $$ = $1; - } - - insert_at_tail(& $$->expressions, $3); - } - ; - -constant_expression: - conditional_expression - ; - -declaration: - function_prototype ';' - { - $$ = $1; - } - | init_declarator_list ';' - { - $$ = $1; - } - | PRECISION precision_qualifier type_specifier_no_prec ';' - { - $$ = NULL; /* FINISHME */ - } - ; - -function_prototype: - function_declarator ')' - ; - -function_declarator: - function_header - | function_header_with_parameters - ; - -function_header_with_parameters: - function_header parameter_declaration - { - $$ = $1; - insert_at_head(& $$->parameters, - (struct simple_node *) $2); - } - | function_header_with_parameters ',' parameter_declaration - { - $$ = $1; - insert_at_head(& $$->parameters, - (struct simple_node *) $3); - } - ; - -function_header: - fully_specified_type IDENTIFIER '(' - { - $$ = new ast_function(); - $$->return_type = $1; - $$->identifier = $2; - } - ; - -parameter_declarator: - type_specifier IDENTIFIER - { - $$ = new ast_parameter_declarator(); - $$->type = new ast_fully_specified_type(); - $$->type->specifier = $1; - $$->identifier = $2; - } - | type_specifier IDENTIFIER '[' constant_expression ']' - { - $$ = new ast_parameter_declarator(); - $$->type = new ast_fully_specified_type(); - $$->type->specifier = $1; - $$->identifier = $2; - $$->is_array = true; - $$->array_size = $4; - } - ; - -parameter_declaration: - parameter_type_qualifier parameter_qualifier parameter_declarator - { - $1.i |= $2.i; - - $$ = $3; - $$->type->qualifier = $1.q; - } - | parameter_qualifier parameter_declarator - { - $$ = $2; - $$->type->qualifier = $1.q; - } - | parameter_type_qualifier parameter_qualifier parameter_type_specifier - { - $1.i |= $2.i; - - $$ = new ast_parameter_declarator(); - $$->type = new ast_fully_specified_type(); - $$->type->qualifier = $1.q; - $$->type->specifier = $3; - } - | parameter_qualifier parameter_type_specifier - { - $$ = new ast_parameter_declarator(); - $$->type = new ast_fully_specified_type(); - $$->type->qualifier = $1.q; - $$->type->specifier = $2; - } - ; - -parameter_qualifier: - /* empty */ { $$.i = 0; } - | IN { $$.i = 0; $$.q.in = 1; } - | OUT { $$.i = 0; $$.q.out = 1; } - | INOUT { $$.i = 0; $$.q.in = 1; $$.q.out = 1; } - ; - -parameter_type_specifier: - type_specifier - ; - -init_declarator_list: - single_declaration - | init_declarator_list ',' IDENTIFIER - { - ast_declaration *decl = new ast_declaration($3, false, NULL, NULL); - - $$ = $1; - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - | init_declarator_list ',' IDENTIFIER '[' ']' - { - ast_declaration *decl = new ast_declaration($3, true, NULL, NULL); - - $$ = $1; - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' - { - ast_declaration *decl = new ast_declaration($3, true, $5, NULL); - - $$ = $1; - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - | init_declarator_list ',' IDENTIFIER '[' ']' '=' initializer - { - ast_declaration *decl = new ast_declaration($3, true, NULL, $7); - - $$ = $1; - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' '=' initializer - { - ast_declaration *decl = new ast_declaration($3, true, $5, $8); - - $$ = $1; - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - | init_declarator_list ',' IDENTIFIER '=' initializer - { - ast_declaration *decl = new ast_declaration($3, false, NULL, $5); - - $$ = $1; - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - ; - - // Grammar Note: No 'enum', or 'typedef'. -single_declaration: - fully_specified_type - { - $$ = new ast_declarator_list($1); - } - | fully_specified_type IDENTIFIER - { - ast_declaration *decl = new ast_declaration($2, false, NULL, NULL); - - $$ = new ast_declarator_list($1); - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - | fully_specified_type IDENTIFIER '[' ']' - { - ast_declaration *decl = new ast_declaration($2, true, NULL, NULL); - - $$ = new ast_declarator_list($1); - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - | fully_specified_type IDENTIFIER '[' constant_expression ']' - { - ast_declaration *decl = new ast_declaration($2, true, $4, NULL); - - $$ = new ast_declarator_list($1); - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - | fully_specified_type IDENTIFIER '[' ']' '=' initializer - { - ast_declaration *decl = new ast_declaration($2, true, NULL, $6); - - $$ = new ast_declarator_list($1); - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - | fully_specified_type IDENTIFIER '[' constant_expression ']' '=' initializer - { - ast_declaration *decl = new ast_declaration($2, true, $4, $7); - - $$ = new ast_declarator_list($1); - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - | fully_specified_type IDENTIFIER '=' initializer - { - ast_declaration *decl = new ast_declaration($2, false, NULL, $4); - - $$ = new ast_declarator_list($1); - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - | INVARIANT IDENTIFIER // Vertex only. - { - ast_declaration *decl = new ast_declaration($2, false, NULL, NULL); - - $$ = new ast_declarator_list(NULL); - $$->invariant = true; - - insert_at_tail(& $$->declarations, - (struct simple_node *) decl); - } - ; - -fully_specified_type: - type_specifier - { - $$ = new ast_fully_specified_type(); - $$->specifier = $1; - } - | type_qualifier type_specifier - { - $$ = new ast_fully_specified_type(); - $$->qualifier = $1.q; - $$->specifier = $2; - } - ; - -interpolation_qualifier: - SMOOTH { $$.i = 0; $$.q.smooth = 1; } - | FLAT { $$.i = 0; $$.q.flat = 1; } - | NOPERSPECTIVE { $$.i = 0; $$.q.noperspective = 1; } - ; - -parameter_type_qualifier: - CONST { $$.i = 0; $$.q.constant = 1; } - ; - -type_qualifier: - storage_qualifier - | interpolation_qualifier type_qualifier - { - $$.i = $1.i | $2.i; - } - | INVARIANT type_qualifier - { - $$ = $2; - $$.q.invariant = 1; - } - ; - -storage_qualifier: - CONST { $$.i = 0; $$.q.constant = 1; } - | ATTRIBUTE { $$.i = 0; $$.q.attribute = 1; } - | VARYING { $$.i = 0; $$.q.varying = 1; } - | CENTROID VARYING { $$.i = 0; $$.q.centroid = 1; $$.q.varying = 1; } - | IN { $$.i = 0; $$.q.in = 1; } - | OUT { $$.i = 0; $$.q.out = 1; } - | CENTROID IN { $$.i = 0; $$.q.centroid = 1; $$.q.in = 1; } - | CENTROID OUT { $$.i = 0; $$.q.centroid = 1; $$.q.out = 1; } - | UNIFORM { $$.i = 0; $$.q.uniform = 1; } - ; - -type_specifier: - type_specifier_no_prec - | precision_qualifier type_specifier_no_prec - { - $$ = $2; - $$->precision = $1; - } - ; - -type_specifier_no_prec: - type_specifier_nonarray - | type_specifier_nonarray '[' ']' - { - $$ = $1; - $$->is_array = true; - $$->array_size = NULL; - } - | type_specifier_nonarray '[' constant_expression ']' - { - $$ = $1; - $$->is_array = true; - $$->array_size = $3; - } - ; - -type_specifier_nonarray: - basic_type_specifier_nonarray - { - $$ = new ast_type_specifier($1); - } - | struct_specifier - { - $$ = new ast_type_specifier(ast_struct); - $$->structure = $1; - } - | TYPE_NAME - { - $$ = new ast_type_specifier(ast_type_name); - $$->type_name = $1; - } - ; - -basic_type_specifier_nonarray: - VOID { $$ = ast_void; } - | FLOAT { $$ = ast_float; } - | INT { $$ = ast_int; } - | UINT { $$ = ast_uint; } - | BOOL { $$ = ast_bool; } - | VEC2 { $$ = ast_vec2; } - | VEC3 { $$ = ast_vec3; } - | VEC4 { $$ = ast_vec4; } - | BVEC2 { $$ = ast_bvec2; } - | BVEC3 { $$ = ast_bvec3; } - | BVEC4 { $$ = ast_bvec4; } - | IVEC2 { $$ = ast_ivec2; } - | IVEC3 { $$ = ast_ivec3; } - | IVEC4 { $$ = ast_ivec4; } - | UVEC2 { $$ = ast_uvec2; } - | UVEC3 { $$ = ast_uvec3; } - | UVEC4 { $$ = ast_uvec4; } - | MAT2 { $$ = ast_mat2; } - | MAT3 { $$ = ast_mat3; } - | MAT4 { $$ = ast_mat4; } - | MAT2X2 { $$ = ast_mat2; } - | MAT2X3 { $$ = ast_mat2x3; } - | MAT2X4 { $$ = ast_mat2x4; } - | MAT3X2 { $$ = ast_mat3x2; } - | MAT3X3 { $$ = ast_mat3; } - | MAT3X4 { $$ = ast_mat3x4; } - | MAT4X2 { $$ = ast_mat4x2; } - | MAT4X3 { $$ = ast_mat4x3; } - | MAT4X4 { $$ = ast_mat4; } - | SAMPLER1D { $$ = ast_sampler1d; } - | SAMPLER2D { $$ = ast_sampler2d; } - | SAMPLER3D { $$ = ast_sampler3d; } - | SAMPLERCUBE { $$ = ast_samplercube; } - | SAMPLER1DSHADOW { $$ = ast_sampler1dshadow; } - | SAMPLER2DSHADOW { $$ = ast_sampler2dshadow; } - | SAMPLERCUBESHADOW { $$ = ast_samplercubeshadow; } - | SAMPLER1DARRAY { $$ = ast_sampler1darray; } - | SAMPLER2DARRAY { $$ = ast_sampler2darray; } - | SAMPLER1DARRAYSHADOW { $$ = ast_sampler1darrayshadow; } - | SAMPLER2DARRAYSHADOW { $$ = ast_sampler2darrayshadow; } - | ISAMPLER1D { $$ = ast_isampler1d; } - | ISAMPLER2D { $$ = ast_isampler2d; } - | ISAMPLER3D { $$ = ast_isampler3d; } - | ISAMPLERCUBE { $$ = ast_isamplercube; } - | ISAMPLER1DARRAY { $$ = ast_isampler1darray; } - | ISAMPLER2DARRAY { $$ = ast_isampler2darray; } - | USAMPLER1D { $$ = ast_usampler1d; } - | USAMPLER2D { $$ = ast_usampler2d; } - | USAMPLER3D { $$ = ast_usampler3d; } - | USAMPLERCUBE { $$ = ast_usamplercube; } - | USAMPLER1DARRAY { $$ = ast_usampler1darray; } - | USAMPLER2DARRAY { $$ = ast_usampler2darray; } - ; - -precision_qualifier: - HIGH_PRECISION { $$ = ast_precision_high; } - | MEDIUM_PRECISION { $$ = ast_precision_medium; } - | LOW_PRECISION { $$ = ast_precision_low; } - ; - -struct_specifier: - STRUCT IDENTIFIER '{' struct_declaration_list '}' - { - $$ = new ast_struct_specifier($2, $4); - - _mesa_symbol_table_add_symbol(state->symbols, 0, $2, $$); - } - | STRUCT '{' struct_declaration_list '}' - { - $$ = new ast_struct_specifier(NULL, $3); - } - ; - -struct_declaration_list: - struct_declaration - { - $$ = (struct ast_node *) $1; - } - | struct_declaration_list struct_declaration - { - $$ = (struct ast_node *) $1; - insert_at_tail((struct simple_node *) $$, - (struct simple_node *) $2); - } - ; - -struct_declaration: - type_specifier struct_declarator_list ';' - { - ast_fully_specified_type *type = new ast_fully_specified_type(); - - type->specifier = $1; - $$ = new ast_declarator_list(type); - - insert_at_tail((struct simple_node *) $2, - & $$->declarations); - } - ; - -struct_declarator_list: - struct_declarator - | struct_declarator_list ',' struct_declarator - { - $$ = $1; - insert_at_tail((struct simple_node *) $$, - (struct simple_node *) $3); - } - ; - -struct_declarator: - IDENTIFIER - { - $$ = new ast_declaration($1, false, NULL, NULL); - } - | IDENTIFIER '[' constant_expression ']' - { - $$ = new ast_declaration($1, true, $3, NULL); - } - ; - -initializer: - assignment_expression - ; - -declaration_statement: - declaration - ; - - // Grammar Note: labeled statements for SWITCH only; 'goto' is not - // supported. -statement: - statement_matched - | statement_unmatched - ; - -statement_matched: - compound_statement { $$ = (struct ast_node *) $1; } - | simple_statement - ; - -statement_unmatched: - selection_statement_unmatched - ; - -simple_statement: - declaration_statement - | expression_statement - | selection_statement_matched - | switch_statement { $$ = NULL; } - | case_label { $$ = NULL; } - | iteration_statement - | jump_statement - ; - -compound_statement: - '{' '}' - { - $$ = new ast_compound_statement(true, NULL); - } - | '{' statement_list '}' - { - $$ = new ast_compound_statement(true, $2); - } - ; - -statement_no_new_scope: - compound_statement_no_new_scope { $$ = (struct ast_node *) $1; } - | simple_statement - ; - -compound_statement_no_new_scope: - '{' '}' - { - $$ = new ast_compound_statement(false, NULL); - } - | '{' statement_list '}' - { - $$ = new ast_compound_statement(false, $2); - } - ; - -statement_list: - statement - { - if ($1 == NULL) { - _mesa_glsl_error(& @1, state, " statement\n"); - assert($1 != NULL); - } - - $$ = $1; - make_empty_list((struct simple_node *) $$); - } - | statement_list statement - { - if ($2 == NULL) { - _mesa_glsl_error(& @2, state, " statement\n"); - assert($2 != NULL); - } - $$ = $1; - insert_at_tail((struct simple_node *) $$, - (struct simple_node *) $2); - } - ; - -expression_statement: - ';' - { - $$ = new ast_expression_statement(NULL); - } - | expression ';' - { - $$ = new ast_expression_statement($1); - } - ; - -selection_statement_matched: - IF '(' expression ')' statement_matched ELSE statement_matched - { - $$ = new ast_selection_statement($3, $5, $7); - } - ; - -selection_statement_unmatched: - IF '(' expression ')' statement_matched - { - $$ = new ast_selection_statement($3, $5, NULL); - } - | IF '(' expression ')' statement_unmatched - { - $$ = new ast_selection_statement($3, $5, NULL); - } - | IF '(' expression ')' statement_matched ELSE statement_unmatched - { - $$ = new ast_selection_statement($3, $5, $7); - } - ; - -condition: - expression - { - $$ = (struct ast_node *) $1; - } - | fully_specified_type IDENTIFIER '=' initializer - { - ast_declaration *decl = new ast_declaration($2, false, NULL, $4); - ast_declarator_list *declarator = new ast_declarator_list($1); - - insert_at_tail(& declarator->declarations, - (struct simple_node *) decl); - - $$ = declarator; - } - ; - -switch_statement: - SWITCH '(' expression ')' compound_statement - ; - -case_label: - CASE expression ':' - | DEFAULT ':' - ; - -iteration_statement: - WHILE '(' condition ')' statement_no_new_scope - { - $$ = new ast_iteration_statement(ast_iteration_statement::ast_while, - NULL, $3, NULL, $5); - } - | DO statement WHILE '(' expression ')' ';' - { - $$ = new ast_iteration_statement(ast_iteration_statement::ast_do_while, - NULL, $5, NULL, $2); - } - | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope - { - $$ = new ast_iteration_statement(ast_iteration_statement::ast_for, - $3, $4.cond, $4.rest, $6); - } - ; - -for_init_statement: - expression_statement - | declaration_statement - ; - -conditionopt: - condition - | /* empty */ - { - $$ = NULL; - } - ; - -for_rest_statement: - conditionopt ';' - { - $$.cond = $1; - $$.rest = NULL; - } - | conditionopt ';' expression - { - $$.cond = $1; - $$.rest = $3; - } - ; - - // Grammar Note: No 'goto'. Gotos are not supported. -jump_statement: - CONTINUE ';' - { - $$ = new ast_jump_statement(ast_jump_statement::ast_continue, NULL); - } - | BREAK ';' - { - $$ = new ast_jump_statement(ast_jump_statement::ast_break, NULL); - } - | RETURN ';' - { - $$ = new ast_jump_statement(ast_jump_statement::ast_return, NULL); - } - | RETURN expression ';' - { - $$ = new ast_jump_statement(ast_jump_statement::ast_return, $2); - } - | DISCARD ';' // Fragment shader only. - { - $$ = new ast_jump_statement(ast_jump_statement::ast_discard, NULL); - } - ; - -external_declaration: - function_definition { $$ = $1; } - | declaration { $$ = $1; } - ; - -function_definition: - function_prototype compound_statement_no_new_scope - { - $$ = new ast_function_definition(); - $$->prototype = $1; - $$->body = $2; - } - ; diff --git a/glsl_parser.ypp b/glsl_parser.ypp new file mode 100644 index 00000000000..c7557254581 --- /dev/null +++ b/glsl_parser.ypp @@ -0,0 +1,1229 @@ +%{ +/* + * 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. + */ +#include +#include +#include +#include + +#include "ast.h" +#include "glsl_parser_extras.h" +#include "symbol_table.h" +#include "glsl_types.h" + +#define YYLEX_PARAM state->scanner + +%} + +%pure-parser +%locations +%error-verbose + +%lex-param {void *scanner} +%parse-param {struct _mesa_glsl_parse_state *state} +%name-prefix "_mesa_glsl_" + +%union { + int n; + float real; + char *identifier; + + union { + struct ast_type_qualifier q; + unsigned i; + } type_qualifier; + + struct ast_node *node; + struct ast_type_specifier *type_specifier; + struct ast_fully_specified_type *fully_specified_type; + struct ast_function *function; + struct ast_parameter_declarator *parameter_declarator; + struct ast_function_definition *function_definition; + struct ast_compound_statement *compound_statement; + struct ast_expression *expression; + struct ast_declarator_list *declarator_list; + struct ast_struct_specifier *struct_specifier; + struct ast_declaration *declaration; + + struct { + struct ast_node *cond; + struct ast_expression *rest; + } for_rest_statement; +} + +%token ATTRIBUTE CONST BOOL FLOAT INT UINT +%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT +%token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4 +%token MAT2 MAT3 MAT4 CENTROID IN OUT INOUT UNIFORM VARYING +%token NOPERSPECTIVE FLAT SMOOTH +%token MAT2X2 MAT2X3 MAT2X4 +%token MAT3X2 MAT3X3 MAT3X4 +%token MAT4X2 MAT4X3 MAT4X4 +%token SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW +%token SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW +%token SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE +%token ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D +%token USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY +%token STRUCT VOID WHILE +%token IDENTIFIER TYPE_NAME +%token FLOATCONSTANT +%token INTCONSTANT UINTCONSTANT BOOLCONSTANT +%token FIELD_SELECTION +%token LEFT_OP RIGHT_OP +%token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP +%token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN +%token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN +%token SUB_ASSIGN +%token INVARIANT +%token HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION + +%token VERSION EXTENSION LINE PRAGMA COLON EOL INTERFACE OUTPUT + + /* Reserved words that are not actually used in the grammar. + */ +%token ASM CLASS UNION ENUM TYPEDEF TEMPLATE THIS PACKED GOTO +%token INLINE NOINLINE VOLATILE PUBLIC STATIC EXTERN EXTERNAL +%token LONG SHORT DOUBLE HALF FIXED UNSIGNED INPUT OUPTUT +%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4 +%token SAMPLER2DRECT SAMPLER3DRECT SAMPLER2DRECTSHADOW +%token SIZEOF CAST NAMESPACE USING LOWP MEDIUMP HIGHP + +%type variable_identifier +%type statement +%type statement_list +%type simple_statement +%type statement_matched +%type statement_unmatched +%type precision_qualifier +%type type_qualifier +%type storage_qualifier +%type interpolation_qualifier +%type type_specifier +%type type_specifier_no_prec +%type type_specifier_nonarray +%type basic_type_specifier_nonarray +%type fully_specified_type +%type function_prototype +%type function_header +%type function_header_with_parameters +%type function_declarator +%type parameter_declarator +%type parameter_declaration +%type parameter_qualifier +%type parameter_type_qualifier +%type parameter_type_specifier +%type function_definition +%type compound_statement_no_new_scope +%type compound_statement +%type statement_no_new_scope +%type expression_statement +%type expression +%type primary_expression +%type assignment_expression +%type conditional_expression +%type logical_or_expression +%type logical_xor_expression +%type logical_and_expression +%type inclusive_or_expression +%type exclusive_or_expression +%type and_expression +%type equality_expression +%type relational_expression +%type shift_expression +%type additive_expression +%type multiplicative_expression +%type unary_expression +%type constant_expression +%type integer_expression +%type postfix_expression +%type function_call_header_with_parameters +%type function_call_header_no_parameters +%type function_call_header +%type function_call_generic +%type function_call_or_method +%type function_call +%type assignment_operator +%type unary_operator +%type function_identifier +%type external_declaration +%type init_declarator_list +%type single_declaration +%type initializer +%type declaration +%type declaration_statement +%type jump_statement +%type struct_specifier +%type struct_declaration_list +%type struct_declaration +%type struct_declarator +%type struct_declarator_list +%type selection_statement_matched +%type selection_statement_unmatched +%type iteration_statement +%type condition +%type conditionopt +%type for_init_statement +%type for_rest_statement +%% + +translation_unit: + version_statement + { + _mesa_glsl_initialize_types(state); + } + external_declaration_list + | + { + state->language_version = 110; + _mesa_glsl_initialize_types(state); + } + external_declaration_list + ; + +version_statement: + VERSION INTCONSTANT EOL + { + switch ($2) { + case 110: + case 120: + case 130: + /* FINISHME: Check against implementation support versions. */ + state->language_version = $2; + break; + default: + _mesa_glsl_error(& @2, state, "Shading language version" + "%u is not supported\n", $2); + break; + } + } + ; + +external_declaration_list: + external_declaration + { + insert_at_tail(& state->translation_unit, + (struct simple_node *) $1); + } + | external_declaration_list external_declaration + { + insert_at_tail(& state->translation_unit, + (struct simple_node *) $2); + } + ; + +variable_identifier: + IDENTIFIER + ; + +primary_expression: + variable_identifier + { + $$ = new ast_expression(ast_identifier, NULL, NULL, NULL); + $$->primary_expression.identifier = $1; + } + | INTCONSTANT + { + $$ = new ast_expression(ast_int_constant, NULL, NULL, NULL); + $$->primary_expression.int_constant = $1; + } + | UINTCONSTANT + { + $$ = new ast_expression(ast_uint_constant, NULL, NULL, NULL); + $$->primary_expression.uint_constant = $1; + } + | FLOATCONSTANT + { + $$ = new ast_expression(ast_float_constant, NULL, NULL, NULL); + $$->primary_expression.float_constant = $1; + } + | BOOLCONSTANT + { + $$ = new ast_expression(ast_bool_constant, NULL, NULL, NULL); + $$->primary_expression.bool_constant = $1; + } + | '(' expression ')' + { + $$ = $2; + } + ; + +postfix_expression: + primary_expression + | postfix_expression '[' integer_expression ']' + { + $$ = new ast_expression(ast_array_index, $1, $3, NULL); + } + | function_call + { + $$ = $1; + } + | postfix_expression '.' IDENTIFIER + { + $$ = new ast_expression(ast_field_selection, $1, NULL, NULL); + $$->primary_expression.identifier = $3; + } + | postfix_expression INC_OP + { + $$ = new ast_expression(ast_post_inc, $1, NULL, NULL); + } + | postfix_expression DEC_OP + { + $$ = new ast_expression(ast_post_dec, $1, NULL, NULL); + } + ; + +integer_expression: + expression + ; + +function_call: + function_call_or_method + ; + +function_call_or_method: + function_call_generic + | postfix_expression '.' function_call_generic + { + $$ = new ast_expression(ast_field_selection, $1, $3, NULL); + } + ; + +function_call_generic: + function_call_header_with_parameters ')' + | function_call_header_no_parameters ')' + ; + +function_call_header_no_parameters: + function_call_header VOID + | function_call_header + ; + +function_call_header_with_parameters: + function_call_header assignment_expression + { + $$ = $1; + $$->subexpressions[1] = $2; + } + | function_call_header_with_parameters ',' assignment_expression + { + $$ = $1; + insert_at_tail((struct simple_node *) $$->subexpressions[1], + (struct simple_node *) $3); + } + ; + + // Grammar Note: Constructors look like functions, but lexical + // analysis recognized most of them as keywords. They are now + // recognized through "type_specifier". +function_call_header: + function_identifier '(' + { + $$ = new ast_expression(ast_function_call, + (struct ast_expression *) $1, + NULL, NULL); + } + ; + +function_identifier: + type_specifier + { + $$ = (struct ast_node *) $1; + } + | IDENTIFIER + { + ast_expression *expr = + new ast_expression(ast_identifier, NULL, NULL, NULL); + expr->primary_expression.identifier = $1; + + $$ = (struct ast_node *) expr; + } + | FIELD_SELECTION + { + ast_expression *expr = + new ast_expression(ast_identifier, NULL, NULL, NULL); + expr->primary_expression.identifier = $1; + + $$ = (struct ast_node *) expr; + } + ; + + // Grammar Note: No traditional style type casts. +unary_expression: + postfix_expression + | INC_OP unary_expression + { + $$ = new ast_expression(ast_pre_inc, $2, NULL, NULL); + } + | DEC_OP unary_expression + { + $$ = new ast_expression(ast_pre_dec, $2, NULL, NULL); + } + | unary_operator unary_expression + { + $$ = new ast_expression($1, $2, NULL, NULL); + } + ; + + // Grammar Note: No '*' or '&' unary ops. Pointers are not supported. +unary_operator: + '+' { $$ = ast_plus; } + | '-' { $$ = ast_neg; } + | '!' { $$ = ast_logic_not; } + | '~' { $$ = ast_bit_not; } + ; + +multiplicative_expression: + unary_expression + | multiplicative_expression '*' unary_expression + { + $$ = new ast_expression_bin(ast_mul, $1, $3); + } + | multiplicative_expression '/' unary_expression + { + $$ = new ast_expression_bin(ast_div, $1, $3); + } + | multiplicative_expression '%' unary_expression + { + $$ = new ast_expression_bin(ast_mod, $1, $3); + } + ; + +additive_expression: + multiplicative_expression + | additive_expression '+' multiplicative_expression + { + $$ = new ast_expression_bin(ast_add, $1, $3); + } + | additive_expression '-' multiplicative_expression + { + $$ = new ast_expression_bin(ast_sub, $1, $3); + } + ; + +shift_expression: + additive_expression + | shift_expression LEFT_OP additive_expression + { + $$ = new ast_expression_bin(ast_lshift, $1, $3); + } + | shift_expression RIGHT_OP additive_expression + { + $$ = new ast_expression_bin(ast_rshift, $1, $3); + } + ; + +relational_expression: + shift_expression + | relational_expression '<' shift_expression + { + $$ = new ast_expression_bin(ast_less, $1, $3); + } + | relational_expression '>' shift_expression + { + $$ = new ast_expression_bin(ast_greater, $1, $3); + } + | relational_expression LE_OP shift_expression + { + $$ = new ast_expression_bin(ast_lequal, $1, $3); + } + | relational_expression GE_OP shift_expression + { + $$ = new ast_expression_bin(ast_gequal, $1, $3); + } + ; + +equality_expression: + relational_expression + | equality_expression EQ_OP relational_expression + { + $$ = new ast_expression_bin(ast_equal, $1, $3); + } + | equality_expression NE_OP relational_expression + { + $$ = new ast_expression_bin(ast_nequal, $1, $3); + } + ; + +and_expression: + equality_expression + | and_expression '&' equality_expression + { + $$ = new ast_expression_bin(ast_bit_or, $1, $3); + } + ; + +exclusive_or_expression: + and_expression + | exclusive_or_expression '^' and_expression + { + $$ = new ast_expression_bin(ast_bit_xor, $1, $3); + } + ; + +inclusive_or_expression: + exclusive_or_expression + | inclusive_or_expression '|' exclusive_or_expression + { + $$ = new ast_expression_bin(ast_bit_or, $1, $3); + } + ; + +logical_and_expression: + inclusive_or_expression + | logical_and_expression AND_OP inclusive_or_expression + { + $$ = new ast_expression_bin(ast_logic_and, $1, $3); + } + ; + +logical_xor_expression: + logical_and_expression + | logical_xor_expression XOR_OP logical_and_expression + { + $$ = new ast_expression_bin(ast_logic_xor, $1, $3); + } + ; + +logical_or_expression: + logical_xor_expression + | logical_or_expression OR_OP logical_xor_expression + { + $$ = new ast_expression_bin(ast_logic_or, $1, $3); + } + ; + +conditional_expression: + logical_or_expression + | logical_or_expression '?' expression ':' assignment_expression + { + $$ = new ast_expression(ast_conditional, $1, $3, $5); + } + ; + +assignment_expression: + conditional_expression + | unary_expression assignment_operator assignment_expression + { + $$ = new ast_expression($2, $1, $3, NULL); + } + ; + +assignment_operator: + '=' { $$ = ast_assign; } + | MUL_ASSIGN { $$ = ast_mul_assign; } + | DIV_ASSIGN { $$ = ast_div_assign; } + | MOD_ASSIGN { $$ = ast_mod_assign; } + | ADD_ASSIGN { $$ = ast_add_assign; } + | SUB_ASSIGN { $$ = ast_sub_assign; } + | LEFT_ASSIGN { $$ = ast_ls_assign; } + | RIGHT_ASSIGN { $$ = ast_rs_assign; } + | AND_ASSIGN { $$ = ast_and_assign; } + | XOR_ASSIGN { $$ = ast_xor_assign; } + | OR_ASSIGN { $$ = ast_or_assign; } + ; + +expression: + assignment_expression + { + $$ = $1; + } + | expression ',' assignment_expression + { + if ($1->oper != ast_sequence) { + $$ = new ast_expression(ast_sequence, NULL, NULL, NULL); + insert_at_tail(& $$->expressions, $1); + } else { + $$ = $1; + } + + insert_at_tail(& $$->expressions, $3); + } + ; + +constant_expression: + conditional_expression + ; + +declaration: + function_prototype ';' + { + $$ = $1; + } + | init_declarator_list ';' + { + $$ = $1; + } + | PRECISION precision_qualifier type_specifier_no_prec ';' + { + $$ = NULL; /* FINISHME */ + } + ; + +function_prototype: + function_declarator ')' + ; + +function_declarator: + function_header + | function_header_with_parameters + ; + +function_header_with_parameters: + function_header parameter_declaration + { + $$ = $1; + insert_at_head(& $$->parameters, + (struct simple_node *) $2); + } + | function_header_with_parameters ',' parameter_declaration + { + $$ = $1; + insert_at_head(& $$->parameters, + (struct simple_node *) $3); + } + ; + +function_header: + fully_specified_type IDENTIFIER '(' + { + $$ = new ast_function(); + $$->return_type = $1; + $$->identifier = $2; + } + ; + +parameter_declarator: + type_specifier IDENTIFIER + { + $$ = new ast_parameter_declarator(); + $$->type = new ast_fully_specified_type(); + $$->type->specifier = $1; + $$->identifier = $2; + } + | type_specifier IDENTIFIER '[' constant_expression ']' + { + $$ = new ast_parameter_declarator(); + $$->type = new ast_fully_specified_type(); + $$->type->specifier = $1; + $$->identifier = $2; + $$->is_array = true; + $$->array_size = $4; + } + ; + +parameter_declaration: + parameter_type_qualifier parameter_qualifier parameter_declarator + { + $1.i |= $2.i; + + $$ = $3; + $$->type->qualifier = $1.q; + } + | parameter_qualifier parameter_declarator + { + $$ = $2; + $$->type->qualifier = $1.q; + } + | parameter_type_qualifier parameter_qualifier parameter_type_specifier + { + $1.i |= $2.i; + + $$ = new ast_parameter_declarator(); + $$->type = new ast_fully_specified_type(); + $$->type->qualifier = $1.q; + $$->type->specifier = $3; + } + | parameter_qualifier parameter_type_specifier + { + $$ = new ast_parameter_declarator(); + $$->type = new ast_fully_specified_type(); + $$->type->qualifier = $1.q; + $$->type->specifier = $2; + } + ; + +parameter_qualifier: + /* empty */ { $$.i = 0; } + | IN { $$.i = 0; $$.q.in = 1; } + | OUT { $$.i = 0; $$.q.out = 1; } + | INOUT { $$.i = 0; $$.q.in = 1; $$.q.out = 1; } + ; + +parameter_type_specifier: + type_specifier + ; + +init_declarator_list: + single_declaration + | init_declarator_list ',' IDENTIFIER + { + ast_declaration *decl = new ast_declaration($3, false, NULL, NULL); + + $$ = $1; + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + | init_declarator_list ',' IDENTIFIER '[' ']' + { + ast_declaration *decl = new ast_declaration($3, true, NULL, NULL); + + $$ = $1; + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' + { + ast_declaration *decl = new ast_declaration($3, true, $5, NULL); + + $$ = $1; + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + | init_declarator_list ',' IDENTIFIER '[' ']' '=' initializer + { + ast_declaration *decl = new ast_declaration($3, true, NULL, $7); + + $$ = $1; + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' '=' initializer + { + ast_declaration *decl = new ast_declaration($3, true, $5, $8); + + $$ = $1; + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + | init_declarator_list ',' IDENTIFIER '=' initializer + { + ast_declaration *decl = new ast_declaration($3, false, NULL, $5); + + $$ = $1; + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + ; + + // Grammar Note: No 'enum', or 'typedef'. +single_declaration: + fully_specified_type + { + $$ = new ast_declarator_list($1); + } + | fully_specified_type IDENTIFIER + { + ast_declaration *decl = new ast_declaration($2, false, NULL, NULL); + + $$ = new ast_declarator_list($1); + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + | fully_specified_type IDENTIFIER '[' ']' + { + ast_declaration *decl = new ast_declaration($2, true, NULL, NULL); + + $$ = new ast_declarator_list($1); + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + | fully_specified_type IDENTIFIER '[' constant_expression ']' + { + ast_declaration *decl = new ast_declaration($2, true, $4, NULL); + + $$ = new ast_declarator_list($1); + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + | fully_specified_type IDENTIFIER '[' ']' '=' initializer + { + ast_declaration *decl = new ast_declaration($2, true, NULL, $6); + + $$ = new ast_declarator_list($1); + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + | fully_specified_type IDENTIFIER '[' constant_expression ']' '=' initializer + { + ast_declaration *decl = new ast_declaration($2, true, $4, $7); + + $$ = new ast_declarator_list($1); + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + | fully_specified_type IDENTIFIER '=' initializer + { + ast_declaration *decl = new ast_declaration($2, false, NULL, $4); + + $$ = new ast_declarator_list($1); + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + | INVARIANT IDENTIFIER // Vertex only. + { + ast_declaration *decl = new ast_declaration($2, false, NULL, NULL); + + $$ = new ast_declarator_list(NULL); + $$->invariant = true; + + insert_at_tail(& $$->declarations, + (struct simple_node *) decl); + } + ; + +fully_specified_type: + type_specifier + { + $$ = new ast_fully_specified_type(); + $$->specifier = $1; + } + | type_qualifier type_specifier + { + $$ = new ast_fully_specified_type(); + $$->qualifier = $1.q; + $$->specifier = $2; + } + ; + +interpolation_qualifier: + SMOOTH { $$.i = 0; $$.q.smooth = 1; } + | FLAT { $$.i = 0; $$.q.flat = 1; } + | NOPERSPECTIVE { $$.i = 0; $$.q.noperspective = 1; } + ; + +parameter_type_qualifier: + CONST { $$.i = 0; $$.q.constant = 1; } + ; + +type_qualifier: + storage_qualifier + | interpolation_qualifier type_qualifier + { + $$.i = $1.i | $2.i; + } + | INVARIANT type_qualifier + { + $$ = $2; + $$.q.invariant = 1; + } + ; + +storage_qualifier: + CONST { $$.i = 0; $$.q.constant = 1; } + | ATTRIBUTE { $$.i = 0; $$.q.attribute = 1; } + | VARYING { $$.i = 0; $$.q.varying = 1; } + | CENTROID VARYING { $$.i = 0; $$.q.centroid = 1; $$.q.varying = 1; } + | IN { $$.i = 0; $$.q.in = 1; } + | OUT { $$.i = 0; $$.q.out = 1; } + | CENTROID IN { $$.i = 0; $$.q.centroid = 1; $$.q.in = 1; } + | CENTROID OUT { $$.i = 0; $$.q.centroid = 1; $$.q.out = 1; } + | UNIFORM { $$.i = 0; $$.q.uniform = 1; } + ; + +type_specifier: + type_specifier_no_prec + | precision_qualifier type_specifier_no_prec + { + $$ = $2; + $$->precision = $1; + } + ; + +type_specifier_no_prec: + type_specifier_nonarray + | type_specifier_nonarray '[' ']' + { + $$ = $1; + $$->is_array = true; + $$->array_size = NULL; + } + | type_specifier_nonarray '[' constant_expression ']' + { + $$ = $1; + $$->is_array = true; + $$->array_size = $3; + } + ; + +type_specifier_nonarray: + basic_type_specifier_nonarray + { + $$ = new ast_type_specifier($1); + } + | struct_specifier + { + $$ = new ast_type_specifier(ast_struct); + $$->structure = $1; + } + | TYPE_NAME + { + $$ = new ast_type_specifier(ast_type_name); + $$->type_name = $1; + } + ; + +basic_type_specifier_nonarray: + VOID { $$ = ast_void; } + | FLOAT { $$ = ast_float; } + | INT { $$ = ast_int; } + | UINT { $$ = ast_uint; } + | BOOL { $$ = ast_bool; } + | VEC2 { $$ = ast_vec2; } + | VEC3 { $$ = ast_vec3; } + | VEC4 { $$ = ast_vec4; } + | BVEC2 { $$ = ast_bvec2; } + | BVEC3 { $$ = ast_bvec3; } + | BVEC4 { $$ = ast_bvec4; } + | IVEC2 { $$ = ast_ivec2; } + | IVEC3 { $$ = ast_ivec3; } + | IVEC4 { $$ = ast_ivec4; } + | UVEC2 { $$ = ast_uvec2; } + | UVEC3 { $$ = ast_uvec3; } + | UVEC4 { $$ = ast_uvec4; } + | MAT2 { $$ = ast_mat2; } + | MAT3 { $$ = ast_mat3; } + | MAT4 { $$ = ast_mat4; } + | MAT2X2 { $$ = ast_mat2; } + | MAT2X3 { $$ = ast_mat2x3; } + | MAT2X4 { $$ = ast_mat2x4; } + | MAT3X2 { $$ = ast_mat3x2; } + | MAT3X3 { $$ = ast_mat3; } + | MAT3X4 { $$ = ast_mat3x4; } + | MAT4X2 { $$ = ast_mat4x2; } + | MAT4X3 { $$ = ast_mat4x3; } + | MAT4X4 { $$ = ast_mat4; } + | SAMPLER1D { $$ = ast_sampler1d; } + | SAMPLER2D { $$ = ast_sampler2d; } + | SAMPLER3D { $$ = ast_sampler3d; } + | SAMPLERCUBE { $$ = ast_samplercube; } + | SAMPLER1DSHADOW { $$ = ast_sampler1dshadow; } + | SAMPLER2DSHADOW { $$ = ast_sampler2dshadow; } + | SAMPLERCUBESHADOW { $$ = ast_samplercubeshadow; } + | SAMPLER1DARRAY { $$ = ast_sampler1darray; } + | SAMPLER2DARRAY { $$ = ast_sampler2darray; } + | SAMPLER1DARRAYSHADOW { $$ = ast_sampler1darrayshadow; } + | SAMPLER2DARRAYSHADOW { $$ = ast_sampler2darrayshadow; } + | ISAMPLER1D { $$ = ast_isampler1d; } + | ISAMPLER2D { $$ = ast_isampler2d; } + | ISAMPLER3D { $$ = ast_isampler3d; } + | ISAMPLERCUBE { $$ = ast_isamplercube; } + | ISAMPLER1DARRAY { $$ = ast_isampler1darray; } + | ISAMPLER2DARRAY { $$ = ast_isampler2darray; } + | USAMPLER1D { $$ = ast_usampler1d; } + | USAMPLER2D { $$ = ast_usampler2d; } + | USAMPLER3D { $$ = ast_usampler3d; } + | USAMPLERCUBE { $$ = ast_usamplercube; } + | USAMPLER1DARRAY { $$ = ast_usampler1darray; } + | USAMPLER2DARRAY { $$ = ast_usampler2darray; } + ; + +precision_qualifier: + HIGH_PRECISION { $$ = ast_precision_high; } + | MEDIUM_PRECISION { $$ = ast_precision_medium; } + | LOW_PRECISION { $$ = ast_precision_low; } + ; + +struct_specifier: + STRUCT IDENTIFIER '{' struct_declaration_list '}' + { + $$ = new ast_struct_specifier($2, $4); + + _mesa_symbol_table_add_symbol(state->symbols, 0, $2, $$); + } + | STRUCT '{' struct_declaration_list '}' + { + $$ = new ast_struct_specifier(NULL, $3); + } + ; + +struct_declaration_list: + struct_declaration + { + $$ = (struct ast_node *) $1; + } + | struct_declaration_list struct_declaration + { + $$ = (struct ast_node *) $1; + insert_at_tail((struct simple_node *) $$, + (struct simple_node *) $2); + } + ; + +struct_declaration: + type_specifier struct_declarator_list ';' + { + ast_fully_specified_type *type = new ast_fully_specified_type(); + + type->specifier = $1; + $$ = new ast_declarator_list(type); + + insert_at_tail((struct simple_node *) $2, + & $$->declarations); + } + ; + +struct_declarator_list: + struct_declarator + | struct_declarator_list ',' struct_declarator + { + $$ = $1; + insert_at_tail((struct simple_node *) $$, + (struct simple_node *) $3); + } + ; + +struct_declarator: + IDENTIFIER + { + $$ = new ast_declaration($1, false, NULL, NULL); + } + | IDENTIFIER '[' constant_expression ']' + { + $$ = new ast_declaration($1, true, $3, NULL); + } + ; + +initializer: + assignment_expression + ; + +declaration_statement: + declaration + ; + + // Grammar Note: labeled statements for SWITCH only; 'goto' is not + // supported. +statement: + statement_matched + | statement_unmatched + ; + +statement_matched: + compound_statement { $$ = (struct ast_node *) $1; } + | simple_statement + ; + +statement_unmatched: + selection_statement_unmatched + ; + +simple_statement: + declaration_statement + | expression_statement + | selection_statement_matched + | switch_statement { $$ = NULL; } + | case_label { $$ = NULL; } + | iteration_statement + | jump_statement + ; + +compound_statement: + '{' '}' + { + $$ = new ast_compound_statement(true, NULL); + } + | '{' statement_list '}' + { + $$ = new ast_compound_statement(true, $2); + } + ; + +statement_no_new_scope: + compound_statement_no_new_scope { $$ = (struct ast_node *) $1; } + | simple_statement + ; + +compound_statement_no_new_scope: + '{' '}' + { + $$ = new ast_compound_statement(false, NULL); + } + | '{' statement_list '}' + { + $$ = new ast_compound_statement(false, $2); + } + ; + +statement_list: + statement + { + if ($1 == NULL) { + _mesa_glsl_error(& @1, state, " statement\n"); + assert($1 != NULL); + } + + $$ = $1; + make_empty_list((struct simple_node *) $$); + } + | statement_list statement + { + if ($2 == NULL) { + _mesa_glsl_error(& @2, state, " statement\n"); + assert($2 != NULL); + } + $$ = $1; + insert_at_tail((struct simple_node *) $$, + (struct simple_node *) $2); + } + ; + +expression_statement: + ';' + { + $$ = new ast_expression_statement(NULL); + } + | expression ';' + { + $$ = new ast_expression_statement($1); + } + ; + +selection_statement_matched: + IF '(' expression ')' statement_matched ELSE statement_matched + { + $$ = new ast_selection_statement($3, $5, $7); + } + ; + +selection_statement_unmatched: + IF '(' expression ')' statement_matched + { + $$ = new ast_selection_statement($3, $5, NULL); + } + | IF '(' expression ')' statement_unmatched + { + $$ = new ast_selection_statement($3, $5, NULL); + } + | IF '(' expression ')' statement_matched ELSE statement_unmatched + { + $$ = new ast_selection_statement($3, $5, $7); + } + ; + +condition: + expression + { + $$ = (struct ast_node *) $1; + } + | fully_specified_type IDENTIFIER '=' initializer + { + ast_declaration *decl = new ast_declaration($2, false, NULL, $4); + ast_declarator_list *declarator = new ast_declarator_list($1); + + insert_at_tail(& declarator->declarations, + (struct simple_node *) decl); + + $$ = declarator; + } + ; + +switch_statement: + SWITCH '(' expression ')' compound_statement + ; + +case_label: + CASE expression ':' + | DEFAULT ':' + ; + +iteration_statement: + WHILE '(' condition ')' statement_no_new_scope + { + $$ = new ast_iteration_statement(ast_iteration_statement::ast_while, + NULL, $3, NULL, $5); + } + | DO statement WHILE '(' expression ')' ';' + { + $$ = new ast_iteration_statement(ast_iteration_statement::ast_do_while, + NULL, $5, NULL, $2); + } + | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope + { + $$ = new ast_iteration_statement(ast_iteration_statement::ast_for, + $3, $4.cond, $4.rest, $6); + } + ; + +for_init_statement: + expression_statement + | declaration_statement + ; + +conditionopt: + condition + | /* empty */ + { + $$ = NULL; + } + ; + +for_rest_statement: + conditionopt ';' + { + $$.cond = $1; + $$.rest = NULL; + } + | conditionopt ';' expression + { + $$.cond = $1; + $$.rest = $3; + } + ; + + // Grammar Note: No 'goto'. Gotos are not supported. +jump_statement: + CONTINUE ';' + { + $$ = new ast_jump_statement(ast_jump_statement::ast_continue, NULL); + } + | BREAK ';' + { + $$ = new ast_jump_statement(ast_jump_statement::ast_break, NULL); + } + | RETURN ';' + { + $$ = new ast_jump_statement(ast_jump_statement::ast_return, NULL); + } + | RETURN expression ';' + { + $$ = new ast_jump_statement(ast_jump_statement::ast_return, $2); + } + | DISCARD ';' // Fragment shader only. + { + $$ = new ast_jump_statement(ast_jump_statement::ast_discard, NULL); + } + ; + +external_declaration: + function_definition { $$ = $1; } + | declaration { $$ = $1; } + ; + +function_definition: + function_prototype compound_statement_no_new_scope + { + $$ = new ast_function_definition(); + $$->prototype = $1; + $$->body = $2; + } + ; diff --git a/glsl_parser_extras.cpp b/glsl_parser_extras.cpp index 54d510c1a19..f30b7d8eb6c 100644 --- a/glsl_parser_extras.cpp +++ b/glsl_parser_extras.cpp @@ -33,7 +33,7 @@ #include "ast.h" #include "glsl_parser_extras.h" -#include "glsl_parser.tab.h" +#include "glsl_parser.h" #include "symbol_table.h" void