[Mesa-dev] [PATCH 08/26] glsl: Rework lexer keyword handling in preparation for GLSL 3.00 ES.

Ian Romanick idr at freedesktop.org
Fri Nov 30 10:07:23 PST 2012


From: Paul Berry <stereotype441 at gmail.com>

This patch expands the lexer KEYWORD macro to take two additional
arguments: the GLSL ES versions in which the given keyword was first
reserved, and supported, respectively.  This will allow us to
trivially add support for GLSL 3.00 ES keywords, even though the set
of GLSL 3.00 ES keywords is neither a subset or a superset of the
keywords corresponding to any desktop GLSL version.

The new KEYWORD macro makes use of the
_mesa_glsl_parse_state::is_version() function, so it accepts 0 as
meaning "unsupported" (rather than 999, which we used previously).

Note that a few keywords ("packed" and "row_major") are supported
*either* when GLSL 1.40 is in use or when ARB_uniform_buffer_obj
support is enabled.  Previously, we handled these by cleverly taking
advantage of the fact that the KEYWORD macro didn't parenthesize its
arguments in the usual way.  Now they are handled more
straightforwardly, with a new macro, KEYWORD_WITH_ALT.

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
---
 src/glsl/glsl_lexer.ll | 268 +++++++++++++++++++++++++------------------------
 1 file changed, 136 insertions(+), 132 deletions(-)

diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll
index d2c8c31..ef1402b 100644
--- a/src/glsl/glsl_lexer.ll
+++ b/src/glsl/glsl_lexer.ll
@@ -48,20 +48,34 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
  *
  * Certain words start out as identifiers, become reserved words in
  * later language revisions, and finally become language keywords.
+ * This may happen at different times in desktop GLSL and GLSL ES.
  *
  * For example, consider the following lexer rule:
- * samplerBuffer       KEYWORD(130, 140, SAMPLERBUFFER)
+ * samplerBuffer       KEYWORD(130, 0, 140, 0, SAMPLERBUFFER)
  *
  * This means that "samplerBuffer" will be treated as:
  * - a keyword (SAMPLERBUFFER token)         ...in GLSL >= 1.40
  * - a reserved word - error                 ...in GLSL >= 1.30
- * - an identifier                           ...in GLSL <  1.30
+ * - an identifier                           ...in GLSL <  1.30 or GLSL ES
  */
-#define KEYWORD(reserved_version, allowed_version, token)		\
+#define KEYWORD(reserved_glsl, reserved_glsl_es,			\
+                allowed_glsl, allowed_glsl_es, token)			\
+   KEYWORD_WITH_ALT(reserved_glsl, reserved_glsl_es,			\
+                    allowed_glsl, allowed_glsl_es, false, token)
+
+/**
+ * Like the KEYWORD macro, but the word is also treated as a keyword
+ * if the given boolean expression is true.
+ */
+#define KEYWORD_WITH_ALT(reserved_glsl, reserved_glsl_es,		\
+                         allowed_glsl, allowed_glsl_es,			\
+                         alt_expr, token)				\
    do {									\
-      if (yyextra->language_version >= allowed_version) {		\
+      if (yyextra->is_version(allowed_glsl, allowed_glsl_es)		\
+          || alt_expr) {						\
 	 return token;							\
-      } else if (yyextra->language_version >= reserved_version) {	\
+      } else if (yyextra->is_version(reserved_glsl,			\
+                                     reserved_glsl_es)) {		\
 	 _mesa_glsl_error(yylloc, yyextra,				\
 			  "Illegal use of reserved word `%s'", yytext);	\
 	 return ERROR_TOK;						\
@@ -71,16 +85,6 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
       }									\
    } while (0)
 
-/* The ES macro can be used in KEYWORD checks:
- *
- *    word      KEYWORD(110 || ES, 400, TOKEN)
- * ...means the word is reserved in GLSL ES 1.00, while
- *
- *    word      KEYWORD(110, 130 || ES, TOKEN)
- * ...means the word is a legal keyword in GLSL ES 1.00.
- */
-#define ES yyextra->es_shader
-
 static int
 literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state,
 		YYSTYPE *lval, YYLTYPE *lloc, int base)
@@ -224,7 +228,7 @@ const		return CONST_TOK;
 bool		return BOOL_TOK;
 float		return FLOAT_TOK;
 int		return INT_TOK;
-uint		KEYWORD(130, 130, UINT_TOK);
+uint		KEYWORD(130, 0, 130, 0, UINT_TOK);
 
 break		return BREAK;
 continue	return CONTINUE;
@@ -242,59 +246,59 @@ bvec4		return BVEC4;
 ivec2		return IVEC2;
 ivec3		return IVEC3;
 ivec4		return IVEC4;
-uvec2		KEYWORD(130, 130, UVEC2);
-uvec3		KEYWORD(130, 130, UVEC3);
-uvec4		KEYWORD(130, 130, UVEC4);
+uvec2		KEYWORD(130, 0, 130, 0, UVEC2);
+uvec3		KEYWORD(130, 0, 130, 0, UVEC3);
+uvec4		KEYWORD(130, 0, 130, 0, UVEC4);
 vec2		return VEC2;
 vec3		return VEC3;
 vec4		return VEC4;
 mat2		return MAT2X2;
 mat3		return MAT3X3;
 mat4		return MAT4X4;
-mat2x2		KEYWORD(120, 120, MAT2X2);
-mat2x3		KEYWORD(120, 120, MAT2X3);
-mat2x4		KEYWORD(120, 120, MAT2X4);
-mat3x2		KEYWORD(120, 120, MAT3X2);
-mat3x3		KEYWORD(120, 120, MAT3X3);
-mat3x4		KEYWORD(120, 120, MAT3X4);
-mat4x2		KEYWORD(120, 120, MAT4X2);
-mat4x3		KEYWORD(120, 120, MAT4X3);
-mat4x4		KEYWORD(120, 120, MAT4X4);
+mat2x2		KEYWORD(120, 0, 120, 0, MAT2X2);
+mat2x3		KEYWORD(120, 0, 120, 0, MAT2X3);
+mat2x4		KEYWORD(120, 0, 120, 0, MAT2X4);
+mat3x2		KEYWORD(120, 0, 120, 0, MAT3X2);
+mat3x3		KEYWORD(120, 0, 120, 0, MAT3X3);
+mat3x4		KEYWORD(120, 0, 120, 0, MAT3X4);
+mat4x2		KEYWORD(120, 0, 120, 0, MAT4X2);
+mat4x3		KEYWORD(120, 0, 120, 0, MAT4X3);
+mat4x4		KEYWORD(120, 0, 120, 0, MAT4X4);
 
 in		return IN_TOK;
 out		return OUT_TOK;
 inout		return INOUT_TOK;
 uniform		return UNIFORM;
 varying		return VARYING;
-centroid	KEYWORD(120, 120, CENTROID);
-invariant	KEYWORD(120 || ES, 120 || ES, INVARIANT);
-flat		KEYWORD(130 || ES, 130, FLAT);
-smooth		KEYWORD(130, 130, SMOOTH);
-noperspective	KEYWORD(130, 130, NOPERSPECTIVE);
+centroid	KEYWORD(120, 0, 120, 0, CENTROID);
+invariant	KEYWORD(120, 100, 120, 100, INVARIANT);
+flat		KEYWORD(130, 100, 130, 0, FLAT);
+smooth		KEYWORD(130, 0, 130, 0, SMOOTH);
+noperspective	KEYWORD(130, 0, 130, 0, NOPERSPECTIVE);
 
 sampler1D	return SAMPLER1D;
 sampler2D	return SAMPLER2D;
 sampler3D	return SAMPLER3D;
 samplerCube	return SAMPLERCUBE;
-sampler1DArray	KEYWORD(130, 130, SAMPLER1DARRAY);
-sampler2DArray	KEYWORD(130, 130, SAMPLER2DARRAY);
+sampler1DArray	KEYWORD(130, 0, 130, 0, SAMPLER1DARRAY);
+sampler2DArray	KEYWORD(130, 0, 130, 0, SAMPLER2DARRAY);
 sampler1DShadow	return SAMPLER1DSHADOW;
 sampler2DShadow	return SAMPLER2DSHADOW;
-samplerCubeShadow	KEYWORD(130, 130, SAMPLERCUBESHADOW);
-sampler1DArrayShadow	KEYWORD(130, 130, SAMPLER1DARRAYSHADOW);
-sampler2DArrayShadow	KEYWORD(130, 130, SAMPLER2DARRAYSHADOW);
-isampler1D		KEYWORD(130, 130, ISAMPLER1D);
-isampler2D		KEYWORD(130, 130, ISAMPLER2D);
-isampler3D		KEYWORD(130, 130, ISAMPLER3D);
-isamplerCube		KEYWORD(130, 130, ISAMPLERCUBE);
-isampler1DArray		KEYWORD(130, 130, ISAMPLER1DARRAY);
-isampler2DArray		KEYWORD(130, 130, ISAMPLER2DARRAY);
-usampler1D		KEYWORD(130, 130, USAMPLER1D);
-usampler2D		KEYWORD(130, 130, USAMPLER2D);
-usampler3D		KEYWORD(130, 130, USAMPLER3D);
-usamplerCube		KEYWORD(130, 130, USAMPLERCUBE);
-usampler1DArray		KEYWORD(130, 130, USAMPLER1DARRAY);
-usampler2DArray		KEYWORD(130, 130, USAMPLER2DARRAY);
+samplerCubeShadow	KEYWORD(130, 0, 130, 0, SAMPLERCUBESHADOW);
+sampler1DArrayShadow	KEYWORD(130, 0, 130, 0, SAMPLER1DARRAYSHADOW);
+sampler2DArrayShadow	KEYWORD(130, 0, 130, 0, SAMPLER2DARRAYSHADOW);
+isampler1D		KEYWORD(130, 0, 130, 0, ISAMPLER1D);
+isampler2D		KEYWORD(130, 0, 130, 0, ISAMPLER2D);
+isampler3D		KEYWORD(130, 0, 130, 0, ISAMPLER3D);
+isamplerCube		KEYWORD(130, 0, 130, 0, ISAMPLERCUBE);
+isampler1DArray		KEYWORD(130, 0, 130, 0, ISAMPLER1DARRAY);
+isampler2DArray		KEYWORD(130, 0, 130, 0, ISAMPLER2DARRAY);
+usampler1D		KEYWORD(130, 0, 130, 0, USAMPLER1D);
+usampler2D		KEYWORD(130, 0, 130, 0, USAMPLER2D);
+usampler3D		KEYWORD(130, 0, 130, 0, USAMPLER3D);
+usamplerCube		KEYWORD(130, 0, 130, 0, USAMPLERCUBE);
+usampler1DArray		KEYWORD(130, 0, 130, 0, USAMPLER1DARRAY);
+usampler2DArray		KEYWORD(130, 0, 130, 0, USAMPLER2DARRAY);
 
 samplerCubeArray	{
 			  if (yyextra->ARB_texture_cube_map_array_enable)
@@ -411,96 +415,96 @@ false			{
 
 
     /* Reserved words in GLSL 1.10. */
-asm		KEYWORD(110 || ES, 999, ASM);
-class		KEYWORD(110 || ES, 999, CLASS);
-union		KEYWORD(110 || ES, 999, UNION);
-enum		KEYWORD(110 || ES, 999, ENUM);
-typedef		KEYWORD(110 || ES, 999, TYPEDEF);
-template	KEYWORD(110 || ES, 999, TEMPLATE);
-this		KEYWORD(110 || ES, 999, THIS);
-packed		KEYWORD(110 || ES, 140 || yyextra->ARB_uniform_buffer_object_enable, PACKED_TOK);
-goto		KEYWORD(110 || ES, 999, GOTO);
-switch		KEYWORD(110 || ES, 130, SWITCH);
-default		KEYWORD(110 || ES, 130, DEFAULT);
-inline		KEYWORD(110 || ES, 999, INLINE_TOK);
-noinline	KEYWORD(110 || ES, 999, NOINLINE);
-volatile	KEYWORD(110 || ES, 999, VOLATILE);
-public		KEYWORD(110 || ES, 999, PUBLIC_TOK);
-static		KEYWORD(110 || ES, 999, STATIC);
-extern		KEYWORD(110 || ES, 999, EXTERN);
-external	KEYWORD(110 || ES, 999, EXTERNAL);
-interface	KEYWORD(110 || ES, 999, INTERFACE);
-long		KEYWORD(110 || ES, 999, LONG_TOK);
-short		KEYWORD(110 || ES, 999, SHORT_TOK);
-double		KEYWORD(110 || ES, 400, DOUBLE_TOK);
-half		KEYWORD(110 || ES, 999, HALF);
-fixed		KEYWORD(110 || ES, 999, FIXED_TOK);
-unsigned	KEYWORD(110 || ES, 999, UNSIGNED);
-input		KEYWORD(110 || ES, 999, INPUT_TOK);
-output		KEYWORD(110 || ES, 999, OUTPUT);
-hvec2		KEYWORD(110 || ES, 999, HVEC2);
-hvec3		KEYWORD(110 || ES, 999, HVEC3);
-hvec4		KEYWORD(110 || ES, 999, HVEC4);
-dvec2		KEYWORD(110 || ES, 400, DVEC2);
-dvec3		KEYWORD(110 || ES, 400, DVEC3);
-dvec4		KEYWORD(110 || ES, 400, DVEC4);
-fvec2		KEYWORD(110 || ES, 999, FVEC2);
-fvec3		KEYWORD(110 || ES, 999, FVEC3);
-fvec4		KEYWORD(110 || ES, 999, FVEC4);
+asm		KEYWORD(110, 100, 0, 0, ASM);
+class		KEYWORD(110, 100, 0, 0, CLASS);
+union		KEYWORD(110, 100, 0, 0, UNION);
+enum		KEYWORD(110, 100, 0, 0, ENUM);
+typedef		KEYWORD(110, 100, 0, 0, TYPEDEF);
+template	KEYWORD(110, 100, 0, 0, TEMPLATE);
+this		KEYWORD(110, 100, 0, 0, THIS);
+packed		KEYWORD_WITH_ALT(110, 100, 140, 0, yyextra->ARB_uniform_buffer_object_enable, PACKED_TOK);
+goto		KEYWORD(110, 100, 0, 0, GOTO);
+switch		KEYWORD(110, 100, 130, 0, SWITCH);
+default		KEYWORD(110, 100, 130, 0, DEFAULT);
+inline		KEYWORD(110, 100, 0, 0, INLINE_TOK);
+noinline	KEYWORD(110, 100, 0, 0, NOINLINE);
+volatile	KEYWORD(110, 100, 0, 0, VOLATILE);
+public		KEYWORD(110, 100, 0, 0, PUBLIC_TOK);
+static		KEYWORD(110, 100, 0, 0, STATIC);
+extern		KEYWORD(110, 100, 0, 0, EXTERN);
+external	KEYWORD(110, 100, 0, 0, EXTERNAL);
+interface	KEYWORD(110, 100, 0, 0, INTERFACE);
+long		KEYWORD(110, 100, 0, 0, LONG_TOK);
+short		KEYWORD(110, 100, 0, 0, SHORT_TOK);
+double		KEYWORD(110, 100, 400, 0, DOUBLE_TOK);
+half		KEYWORD(110, 100, 0, 0, HALF);
+fixed		KEYWORD(110, 100, 0, 0, FIXED_TOK);
+unsigned	KEYWORD(110, 100, 0, 0, UNSIGNED);
+input		KEYWORD(110, 100, 0, 0, INPUT_TOK);
+output		KEYWORD(110, 100, 0, 0, OUTPUT);
+hvec2		KEYWORD(110, 100, 0, 0, HVEC2);
+hvec3		KEYWORD(110, 100, 0, 0, HVEC3);
+hvec4		KEYWORD(110, 100, 0, 0, HVEC4);
+dvec2		KEYWORD(110, 100, 400, 0, DVEC2);
+dvec3		KEYWORD(110, 100, 400, 0, DVEC3);
+dvec4		KEYWORD(110, 100, 400, 0, DVEC4);
+fvec2		KEYWORD(110, 100, 0, 0, FVEC2);
+fvec3		KEYWORD(110, 100, 0, 0, FVEC3);
+fvec4		KEYWORD(110, 100, 0, 0, FVEC4);
 sampler2DRect		return SAMPLER2DRECT;
-sampler3DRect		KEYWORD(110 || ES, 999, SAMPLER3DRECT);
+sampler3DRect		KEYWORD(110, 100, 0, 0, SAMPLER3DRECT);
 sampler2DRectShadow	return SAMPLER2DRECTSHADOW;
-sizeof		KEYWORD(110 || ES, 999, SIZEOF);
-cast		KEYWORD(110 || ES, 999, CAST);
-namespace	KEYWORD(110 || ES, 999, NAMESPACE);
-using		KEYWORD(110 || ES, 999, USING);
+sizeof		KEYWORD(110, 100, 0, 0, SIZEOF);
+cast		KEYWORD(110, 100, 0, 0, CAST);
+namespace	KEYWORD(110, 100, 0, 0, NAMESPACE);
+using		KEYWORD(110, 100, 0, 0, USING);
 
     /* Additional reserved words in GLSL 1.20. */
-lowp		KEYWORD(120, 130 || ES, LOWP);
-mediump		KEYWORD(120, 130 || ES, MEDIUMP);
-highp		KEYWORD(120, 130 || ES, HIGHP);
-precision	KEYWORD(120, 130 || ES, PRECISION);
+lowp		KEYWORD(120, 100, 130, 100, LOWP);
+mediump		KEYWORD(120, 100, 130, 100, MEDIUMP);
+highp		KEYWORD(120, 100, 130, 100, HIGHP);
+precision	KEYWORD(120, 100, 130, 100, PRECISION);
 
     /* Additional reserved words in GLSL 1.30. */
-case		KEYWORD(130, 130, CASE);
-common		KEYWORD(130, 999, COMMON);
-partition	KEYWORD(130, 999, PARTITION);
-active		KEYWORD(130, 999, ACTIVE);
-superp		KEYWORD(130 || ES, 999, SUPERP);
-samplerBuffer	KEYWORD(130, 140, SAMPLERBUFFER);
-filter		KEYWORD(130, 999, FILTER);
-image1D		KEYWORD(130, 999, IMAGE1D);
-image2D		KEYWORD(130, 999, IMAGE2D);
-image3D		KEYWORD(130, 999, IMAGE3D);
-imageCube	KEYWORD(130, 999, IMAGECUBE);
-iimage1D	KEYWORD(130, 999, IIMAGE1D);
-iimage2D	KEYWORD(130, 999, IIMAGE2D);
-iimage3D	KEYWORD(130, 999, IIMAGE3D);
-iimageCube	KEYWORD(130, 999, IIMAGECUBE);
-uimage1D	KEYWORD(130, 999, UIMAGE1D);
-uimage2D	KEYWORD(130, 999, UIMAGE2D);
-uimage3D	KEYWORD(130, 999, UIMAGE3D);
-uimageCube	KEYWORD(130, 999, UIMAGECUBE);
-image1DArray	KEYWORD(130, 999, IMAGE1DARRAY);
-image2DArray	KEYWORD(130, 999, IMAGE2DARRAY);
-iimage1DArray	KEYWORD(130, 999, IIMAGE1DARRAY);
-iimage2DArray	KEYWORD(130, 999, IIMAGE2DARRAY);
-uimage1DArray	KEYWORD(130, 999, UIMAGE1DARRAY);
-uimage2DArray	KEYWORD(130, 999, UIMAGE2DARRAY);
-image1DShadow	KEYWORD(130, 999, IMAGE1DSHADOW);
-image2DShadow	KEYWORD(130, 999, IMAGE2DSHADOW);
-image1DArrayShadow KEYWORD(130, 999, IMAGE1DARRAYSHADOW);
-image2DArrayShadow KEYWORD(130, 999, IMAGE2DARRAYSHADOW);
-imageBuffer	KEYWORD(130, 999, IMAGEBUFFER);
-iimageBuffer	KEYWORD(130, 999, IIMAGEBUFFER);
-uimageBuffer	KEYWORD(130, 999, UIMAGEBUFFER);
-row_major	KEYWORD(130, 140 || yyextra->ARB_uniform_buffer_object_enable, ROW_MAJOR);
+case		KEYWORD(130, 0, 130, 0, CASE);
+common		KEYWORD(130, 0, 0, 0, COMMON);
+partition	KEYWORD(130, 0, 0, 0, PARTITION);
+active		KEYWORD(130, 0, 0, 0, ACTIVE);
+superp		KEYWORD(130, 100, 0, 0, SUPERP);
+samplerBuffer	KEYWORD(130, 0, 140, 0, SAMPLERBUFFER);
+filter		KEYWORD(130, 0, 0, 0, FILTER);
+image1D		KEYWORD(130, 0, 0, 0, IMAGE1D);
+image2D		KEYWORD(130, 0, 0, 0, IMAGE2D);
+image3D		KEYWORD(130, 0, 0, 0, IMAGE3D);
+imageCube	KEYWORD(130, 0, 0, 0, IMAGECUBE);
+iimage1D	KEYWORD(130, 0, 0, 0, IIMAGE1D);
+iimage2D	KEYWORD(130, 0, 0, 0, IIMAGE2D);
+iimage3D	KEYWORD(130, 0, 0, 0, IIMAGE3D);
+iimageCube	KEYWORD(130, 0, 0, 0, IIMAGECUBE);
+uimage1D	KEYWORD(130, 0, 0, 0, UIMAGE1D);
+uimage2D	KEYWORD(130, 0, 0, 0, UIMAGE2D);
+uimage3D	KEYWORD(130, 0, 0, 0, UIMAGE3D);
+uimageCube	KEYWORD(130, 0, 0, 0, UIMAGECUBE);
+image1DArray	KEYWORD(130, 0, 0, 0, IMAGE1DARRAY);
+image2DArray	KEYWORD(130, 0, 0, 0, IMAGE2DARRAY);
+iimage1DArray	KEYWORD(130, 0, 0, 0, IIMAGE1DARRAY);
+iimage2DArray	KEYWORD(130, 0, 0, 0, IIMAGE2DARRAY);
+uimage1DArray	KEYWORD(130, 0, 0, 0, UIMAGE1DARRAY);
+uimage2DArray	KEYWORD(130, 0, 0, 0, UIMAGE2DARRAY);
+image1DShadow	KEYWORD(130, 0, 0, 0, IMAGE1DSHADOW);
+image2DShadow	KEYWORD(130, 0, 0, 0, IMAGE2DSHADOW);
+image1DArrayShadow KEYWORD(130, 0, 0, 0, IMAGE1DARRAYSHADOW);
+image2DArrayShadow KEYWORD(130, 0, 0, 0, IMAGE2DARRAYSHADOW);
+imageBuffer	KEYWORD(130, 0, 0, 0, IMAGEBUFFER);
+iimageBuffer	KEYWORD(130, 0, 0, 0, IIMAGEBUFFER);
+uimageBuffer	KEYWORD(130, 0, 0, 0, UIMAGEBUFFER);
+row_major	KEYWORD_WITH_ALT(130, 0, 140, 0, yyextra->ARB_uniform_buffer_object_enable, ROW_MAJOR);
 
     /* Additional reserved words in GLSL 1.40 */
-isampler2DRect	KEYWORD(140, 140, ISAMPLER2DRECT);
-usampler2DRect	KEYWORD(140, 140, USAMPLER2DRECT);
-isamplerBuffer	KEYWORD(140, 140, ISAMPLERBUFFER);
-usamplerBuffer	KEYWORD(140, 140, USAMPLERBUFFER);
+isampler2DRect	KEYWORD(140, 0, 140, 0, ISAMPLER2DRECT);
+usampler2DRect	KEYWORD(140, 0, 140, 0, USAMPLER2DRECT);
+isamplerBuffer	KEYWORD(140, 0, 140, 0, ISAMPLERBUFFER);
+usamplerBuffer	KEYWORD(140, 0, 140, 0, USAMPLERBUFFER);
 
 [_a-zA-Z][_a-zA-Z0-9]*	{
 			    struct _mesa_glsl_parse_state *state = yyextra;
-- 
1.7.11.7



More information about the mesa-dev mailing list