Rewrote HLSL grammar, mostly from scratch.
authorRyan C. Gordon <icculus@icculus.org>
Fri, 06 Mar 2009 19:26:47 -0500
changeset 721 82d1aec6b549
parent 720 7b0bbd985de7
child 722 d483a61ef502
Rewrote HLSL grammar, mostly from scratch. I kept most of Jeff Lee's work for expressions, but the rest I rewrote, following the docs at MSDN for grammar details. I found this was both easier than weeding out the C-specific bits and wedging in the HLSL parts, and it should give me a richer understanding of how the guts of the parser work. This isn't quite complete yet. Notably, it doesn't handle HLSL-style constructors for vector types: float4 x = float4(1,2,3,4);" for example.
mojoshader_compiler.c
mojoshader_parser_hlsl.lemon
--- a/mojoshader_compiler.c	Sat Feb 28 18:32:05 2009 -0500
+++ b/mojoshader_compiler.c	Fri Mar 06 19:26:47 2009 -0500
@@ -60,8 +60,8 @@
         case ((Token) ']'): return TOKEN_HLSL_RBRACKET;
         case ((Token) '('): return TOKEN_HLSL_LPAREN;
         case ((Token) ')'): return TOKEN_HLSL_RPAREN;
-        case ((Token) TOKEN_INT_LITERAL): return TOKEN_HLSL_CONSTANT;
-        case ((Token) TOKEN_FLOAT_LITERAL): return TOKEN_HLSL_CONSTANT;
+        case ((Token) TOKEN_INT_LITERAL): return TOKEN_HLSL_INT_CONSTANT;
+        case ((Token) TOKEN_FLOAT_LITERAL): return TOKEN_HLSL_FLOAT_CONSTANT;
         case ((Token) TOKEN_STRING_LITERAL): return TOKEN_HLSL_STRING_LITERAL;
         case ((Token) ':'): return TOKEN_HLSL_COLON;
         case ((Token) ';'): return TOKEN_HLSL_SEMICOLON;
@@ -74,36 +74,177 @@
             //if (tokencmp("")) return TOKEN_HLSL_TYPE_NAME
             //if (tokencmp("...")) return TOKEN_HLSL_ELIPSIS
             if (tokencmp("else")) return TOKEN_HLSL_ELSE;
-            if (tokencmp("sizeof")) return TOKEN_HLSL_SIZEOF;
+            if (tokencmp("inline")) return TOKEN_HLSL_INLINE;
+            if (tokencmp("void")) return TOKEN_HLSL_VOID;
+            if (tokencmp("in")) return TOKEN_HLSL_IN;
+            if (tokencmp("inout")) return TOKEN_HLSL_INOUT;
+            if (tokencmp("out")) return TOKEN_HLSL_OUT;
+            if (tokencmp("uniform")) return TOKEN_HLSL_UNIFORM;
+            if (tokencmp("linear")) return TOKEN_HLSL_LINEAR;
+            if (tokencmp("centroid")) return TOKEN_HLSL_CENTROID;
+            if (tokencmp("nointerpolation")) return TOKEN_HLSL_NOINTERPOLATION;
+            if (tokencmp("noperspective")) return TOKEN_HLSL_NOPERSPECTIVE;
+            if (tokencmp("sample")) return TOKEN_HLSL_SAMPLE;
+            if (tokencmp("struct")) return TOKEN_HLSL_STRUCT;
             if (tokencmp("typedef")) return TOKEN_HLSL_TYPEDEF;
-            if (tokencmp("extern")) return TOKEN_HLSL_EXTERN;
-            if (tokencmp("static")) return TOKEN_HLSL_STATIC;
-            if (tokencmp("auto")) return TOKEN_HLSL_AUTO;
+            if (tokencmp("const")) return TOKEN_HLSL_CONST;
+            if (tokencmp("packoffset")) return TOKEN_HLSL_PACKOFFSET;
             if (tokencmp("register")) return TOKEN_HLSL_REGISTER;
-            if (tokencmp("char")) return TOKEN_HLSL_CHAR;
-            if (tokencmp("short")) return TOKEN_HLSL_SHORT;
+            if (tokencmp("extern")) return TOKEN_HLSL_EXTERN;
+            if (tokencmp("shared")) return TOKEN_HLSL_SHARED;
+            if (tokencmp("static")) return TOKEN_HLSL_STATIC;
+            if (tokencmp("volatile")) return TOKEN_HLSL_VOLATILE;
+            if (tokencmp("row_major")) return TOKEN_HLSL_ROWMAJOR;
+            if (tokencmp("column_major")) return TOKEN_HLSL_COLUMNMAJOR;
+            if (tokencmp("bool")) return TOKEN_HLSL_BOOL;
             if (tokencmp("int")) return TOKEN_HLSL_INT;
-            if (tokencmp("long")) return TOKEN_HLSL_LONG;
-            if (tokencmp("signed")) return TOKEN_HLSL_SIGNED;
-            if (tokencmp("unsigned")) return TOKEN_HLSL_UNSIGNED;
+            if (tokencmp("uint")) return TOKEN_HLSL_UINT;
+            if (tokencmp("half")) return TOKEN_HLSL_HALF;
             if (tokencmp("float")) return TOKEN_HLSL_FLOAT;
             if (tokencmp("double")) return TOKEN_HLSL_DOUBLE;
-            if (tokencmp("const")) return TOKEN_HLSL_CONST;
-            if (tokencmp("volatile")) return TOKEN_HLSL_VOLATILE;
-            if (tokencmp("void")) return TOKEN_HLSL_VOID;
-            if (tokencmp("struct")) return TOKEN_HLSL_STRUCT;
-            if (tokencmp("union")) return TOKEN_HLSL_UNION;
+            if (tokencmp("string")) return TOKEN_HLSL_STRING;
+            if (tokencmp("snorm")) return TOKEN_HLSL_SNORM;
+            if (tokencmp("unorm")) return TOKEN_HLSL_UNORM;
+            if (tokencmp("buffer")) return TOKEN_HLSL_BUFFER;
+            if (tokencmp("vector")) return TOKEN_HLSL_VECTOR;
+            if (tokencmp("bool1")) return TOKEN_HLSL_BOOL1;
+            if (tokencmp("bool2")) return TOKEN_HLSL_BOOL2;
+            if (tokencmp("bool3")) return TOKEN_HLSL_BOOL3;
+            if (tokencmp("bool4")) return TOKEN_HLSL_BOOL4;
+            if (tokencmp("int1")) return TOKEN_HLSL_INT1;
+            if (tokencmp("int2")) return TOKEN_HLSL_INT2;
+            if (tokencmp("int3")) return TOKEN_HLSL_INT3;
+            if (tokencmp("int4")) return TOKEN_HLSL_INT4;
+            if (tokencmp("uint1")) return TOKEN_HLSL_UINT1;
+            if (tokencmp("uint2")) return TOKEN_HLSL_UINT2;
+            if (tokencmp("uint3")) return TOKEN_HLSL_UINT3;
+            if (tokencmp("uint4")) return TOKEN_HLSL_UINT4;
+            if (tokencmp("half1")) return TOKEN_HLSL_HALF1;
+            if (tokencmp("half2")) return TOKEN_HLSL_HALF2;
+            if (tokencmp("half3")) return TOKEN_HLSL_HALF3;
+            if (tokencmp("half4")) return TOKEN_HLSL_HALF4;
+            if (tokencmp("float1")) return TOKEN_HLSL_FLOAT1;
+            if (tokencmp("float2")) return TOKEN_HLSL_FLOAT2;
+            if (tokencmp("float3")) return TOKEN_HLSL_FLOAT3;
+            if (tokencmp("float4")) return TOKEN_HLSL_FLOAT4;
+            if (tokencmp("double1")) return TOKEN_HLSL_DOUBLE1;
+            if (tokencmp("double2")) return TOKEN_HLSL_DOUBLE2;
+            if (tokencmp("double3")) return TOKEN_HLSL_DOUBLE3;
+            if (tokencmp("double4")) return TOKEN_HLSL_DOUBLE4;
+            if (tokencmp("matrix")) return TOKEN_HLSL_MATRIX;
+            if (tokencmp("bool1x1")) return TOKEN_HLSL_BOOL1X1;
+            if (tokencmp("bool1x2")) return TOKEN_HLSL_BOOL1X2;
+            if (tokencmp("bool1x3")) return TOKEN_HLSL_BOOL1X3;
+            if (tokencmp("bool1x4")) return TOKEN_HLSL_BOOL1X4;
+            if (tokencmp("bool2x1")) return TOKEN_HLSL_BOOL2X1;
+            if (tokencmp("bool2x2")) return TOKEN_HLSL_BOOL2X2;
+            if (tokencmp("bool2x3")) return TOKEN_HLSL_BOOL2X3;
+            if (tokencmp("bool2x4")) return TOKEN_HLSL_BOOL2X4;
+            if (tokencmp("bool3x1")) return TOKEN_HLSL_BOOL3X1;
+            if (tokencmp("bool3x2")) return TOKEN_HLSL_BOOL3X2;
+            if (tokencmp("bool3x3")) return TOKEN_HLSL_BOOL3X3;
+            if (tokencmp("bool3x4")) return TOKEN_HLSL_BOOL3X4;
+            if (tokencmp("bool4x1")) return TOKEN_HLSL_BOOL4X1;
+            if (tokencmp("bool4x2")) return TOKEN_HLSL_BOOL4X2;
+            if (tokencmp("bool4x3")) return TOKEN_HLSL_BOOL4X3;
+            if (tokencmp("bool4x4")) return TOKEN_HLSL_BOOL4X4;
+            if (tokencmp("int1x1")) return TOKEN_HLSL_INT1X1;
+            if (tokencmp("int1x2")) return TOKEN_HLSL_INT1X2;
+            if (tokencmp("int1x3")) return TOKEN_HLSL_INT1X3;
+            if (tokencmp("int1x4")) return TOKEN_HLSL_INT1X4;
+            if (tokencmp("int2x1")) return TOKEN_HLSL_INT2X1;
+            if (tokencmp("int2x2")) return TOKEN_HLSL_INT2X2;
+            if (tokencmp("int2x3")) return TOKEN_HLSL_INT2X3;
+            if (tokencmp("int2x4")) return TOKEN_HLSL_INT2X4;
+            if (tokencmp("int3x1")) return TOKEN_HLSL_INT3X1;
+            if (tokencmp("int3x2")) return TOKEN_HLSL_INT3X2;
+            if (tokencmp("int3x3")) return TOKEN_HLSL_INT3X3;
+            if (tokencmp("int3x4")) return TOKEN_HLSL_INT3X4;
+            if (tokencmp("int4x1")) return TOKEN_HLSL_INT4X1;
+            if (tokencmp("int4x2")) return TOKEN_HLSL_INT4X2;
+            if (tokencmp("int4x3")) return TOKEN_HLSL_INT4X3;
+            if (tokencmp("int4x4")) return TOKEN_HLSL_INT4X4;
+            if (tokencmp("uint1x1")) return TOKEN_HLSL_UINT1X1;
+            if (tokencmp("uint1x2")) return TOKEN_HLSL_UINT1X2;
+            if (tokencmp("uint1x3")) return TOKEN_HLSL_UINT1X3;
+            if (tokencmp("uint1x4")) return TOKEN_HLSL_UINT1X4;
+            if (tokencmp("uint2x1")) return TOKEN_HLSL_UINT2X1;
+            if (tokencmp("uint2x2")) return TOKEN_HLSL_UINT2X2;
+            if (tokencmp("uint2x3")) return TOKEN_HLSL_UINT2X3;
+            if (tokencmp("uint2x4")) return TOKEN_HLSL_UINT2X4;
+            if (tokencmp("uint3x1")) return TOKEN_HLSL_UINT3X1;
+            if (tokencmp("uint3x2")) return TOKEN_HLSL_UINT3X2;
+            if (tokencmp("uint3x3")) return TOKEN_HLSL_UINT3X3;
+            if (tokencmp("uint3x4")) return TOKEN_HLSL_UINT3X4;
+            if (tokencmp("uint4x1")) return TOKEN_HLSL_UINT4X1;
+            if (tokencmp("uint4x2")) return TOKEN_HLSL_UINT4X2;
+            if (tokencmp("uint4x3")) return TOKEN_HLSL_UINT4X3;
+            if (tokencmp("uint4x4")) return TOKEN_HLSL_UINT4X4;
+            if (tokencmp("half1x1")) return TOKEN_HLSL_HALF1X1;
+            if (tokencmp("half1x2")) return TOKEN_HLSL_HALF1X2;
+            if (tokencmp("half1x3")) return TOKEN_HLSL_HALF1X3;
+            if (tokencmp("half1x4")) return TOKEN_HLSL_HALF1X4;
+            if (tokencmp("half2x1")) return TOKEN_HLSL_HALF2X1;
+            if (tokencmp("half2x2")) return TOKEN_HLSL_HALF2X2;
+            if (tokencmp("half2x3")) return TOKEN_HLSL_HALF2X3;
+            if (tokencmp("half2x4")) return TOKEN_HLSL_HALF2X4;
+            if (tokencmp("half3x1")) return TOKEN_HLSL_HALF3X1;
+            if (tokencmp("half3x2")) return TOKEN_HLSL_HALF3X2;
+            if (tokencmp("half3x3")) return TOKEN_HLSL_HALF3X3;
+            if (tokencmp("half3x4")) return TOKEN_HLSL_HALF3X4;
+            if (tokencmp("half4x1")) return TOKEN_HLSL_HALF4X1;
+            if (tokencmp("half4x2")) return TOKEN_HLSL_HALF4X2;
+            if (tokencmp("half4x3")) return TOKEN_HLSL_HALF4X3;
+            if (tokencmp("half4x4")) return TOKEN_HLSL_HALF4X4;
+            if (tokencmp("float1x1")) return TOKEN_HLSL_FLOAT1X1;
+            if (tokencmp("float1x2")) return TOKEN_HLSL_FLOAT1X2;
+            if (tokencmp("float1x3")) return TOKEN_HLSL_FLOAT1X3;
+            if (tokencmp("float1x4")) return TOKEN_HLSL_FLOAT1X4;
+            if (tokencmp("float2x1")) return TOKEN_HLSL_FLOAT2X1;
+            if (tokencmp("float2x2")) return TOKEN_HLSL_FLOAT2X2;
+            if (tokencmp("float2x3")) return TOKEN_HLSL_FLOAT2X3;
+            if (tokencmp("float2x4")) return TOKEN_HLSL_FLOAT2X4;
+            if (tokencmp("float3x1")) return TOKEN_HLSL_FLOAT3X1;
+            if (tokencmp("float3x2")) return TOKEN_HLSL_FLOAT3X2;
+            if (tokencmp("float3x3")) return TOKEN_HLSL_FLOAT3X3;
+            if (tokencmp("float3x4")) return TOKEN_HLSL_FLOAT3X4;
+            if (tokencmp("float4x1")) return TOKEN_HLSL_FLOAT4X1;
+            if (tokencmp("float4x2")) return TOKEN_HLSL_FLOAT4X2;
+            if (tokencmp("float4x3")) return TOKEN_HLSL_FLOAT4X3;
+            if (tokencmp("float4x4")) return TOKEN_HLSL_FLOAT4X4;
+            if (tokencmp("double1x1")) return TOKEN_HLSL_DOUBLE1X1;
+            if (tokencmp("double1x2")) return TOKEN_HLSL_DOUBLE1X2;
+            if (tokencmp("double1x3")) return TOKEN_HLSL_DOUBLE1X3;
+            if (tokencmp("double1x4")) return TOKEN_HLSL_DOUBLE1X4;
+            if (tokencmp("double2x1")) return TOKEN_HLSL_DOUBLE2X1;
+            if (tokencmp("double2x2")) return TOKEN_HLSL_DOUBLE2X2;
+            if (tokencmp("double2x3")) return TOKEN_HLSL_DOUBLE2X3;
+            if (tokencmp("double2x4")) return TOKEN_HLSL_DOUBLE2X4;
+            if (tokencmp("double3x1")) return TOKEN_HLSL_DOUBLE3X1;
+            if (tokencmp("double3x2")) return TOKEN_HLSL_DOUBLE3X2;
+            if (tokencmp("double3x3")) return TOKEN_HLSL_DOUBLE3X3;
+            if (tokencmp("double3x4")) return TOKEN_HLSL_DOUBLE3X4;
+            if (tokencmp("double4x1")) return TOKEN_HLSL_DOUBLE4X1;
+            if (tokencmp("double4x2")) return TOKEN_HLSL_DOUBLE4X2;
+            if (tokencmp("double4x3")) return TOKEN_HLSL_DOUBLE4X3;
+            if (tokencmp("double4x4")) return TOKEN_HLSL_DOUBLE4X4;
+            if (tokencmp("break")) return TOKEN_HLSL_BREAK;
+            if (tokencmp("continue")) return TOKEN_HLSL_CONTINUE;
+            if (tokencmp("discard")) return TOKEN_HLSL_DISCARD;
+            if (tokencmp("return")) return TOKEN_HLSL_RETURN;
+            if (tokencmp("while")) return TOKEN_HLSL_WHILE;
+            if (tokencmp("for")) return TOKEN_HLSL_FOR;
+            if (tokencmp("unroll")) return TOKEN_HLSL_UNROLL;
+            if (tokencmp("loop")) return TOKEN_HLSL_LOOP;
+            if (tokencmp("do")) return TOKEN_HLSL_DO;
+            if (tokencmp("if")) return TOKEN_HLSL_IF;
+            if (tokencmp("branch")) return TOKEN_HLSL_BRANCH;
+            if (tokencmp("flatten")) return TOKEN_HLSL_FLATTEN;
+            if (tokencmp("switch")) return TOKEN_HLSL_SWITCH;
+            if (tokencmp("forcecase")) return TOKEN_HLSL_FORCECASE;
+            if (tokencmp("call")) return TOKEN_HLSL_CALL;
             if (tokencmp("case")) return TOKEN_HLSL_CASE;
             if (tokencmp("default")) return TOKEN_HLSL_DEFAULT;
-            if (tokencmp("discard")) return TOKEN_HLSL_DISCARD;
-            if (tokencmp("if")) return TOKEN_HLSL_IF;
-            if (tokencmp("switch")) return TOKEN_HLSL_SWITCH;
-            if (tokencmp("while")) return TOKEN_HLSL_WHILE;
-            if (tokencmp("do")) return TOKEN_HLSL_DO;
-            if (tokencmp("for")) return TOKEN_HLSL_FOR;
-            if (tokencmp("continue")) return TOKEN_HLSL_CONTINUE;
-            if (tokencmp("break")) return TOKEN_HLSL_BREAK;
-            if (tokencmp("return")) return TOKEN_HLSL_RETURN;
             #undef tokencmp
             return TOKEN_HLSL_IDENTIFIER;
 
--- a/mojoshader_parser_hlsl.lemon	Sat Feb 28 18:32:05 2009 -0500
+++ b/mojoshader_parser_hlsl.lemon	Fri Mar 06 19:26:47 2009 -0500
@@ -64,19 +64,402 @@
 
 // The rules...
 
-shader ::= file.
+shader ::= compilation_units.
+
+compilation_units ::= compilation_unit.
+compilation_units ::= compilation_units compilation_unit.
+
+compilation_unit ::= function_declaration.
+compilation_unit ::= function_definition.
+compilation_unit ::= global_variable.
+compilation_unit ::= typedef_statement.
+compilation_unit ::= struct_statement.
+
+function_declaration ::= function_signature SEMICOLON.
+
+function_definition ::= function_signature statement_block.
+
+function_signature ::= function_storageclass function_details semantic.
+function_signature ::= function_storageclass function_details.
+function_signature ::= function_details semantic.
+function_signature ::= function_details.
+
+function_details ::= datatype identifier LPAREN function_arguments RPAREN.
+
+// !!! FIXME: there is a "target" storage class that is the name of the
+// !!! FIXME:  platform that this function is meant for...but I don't know
+// !!! FIXME:  what tokens are valid here.
+
+// !!! FIXME: Also, the docs say "one of" inline or target, but I bet you can
+// !!! FIXME:  specify both.
+//function_storageclass ::= target.
+function_storageclass ::= INLINE.
+
+function_arguments ::= VOID.
+function_arguments ::= function_argument_list.
+function_arguments ::= .
+
+function_argument_list ::= function_argument.
+function_argument_list ::= function_argument_list COMMA function_argument.
+
+function_argument ::= input_modifier datatype identifier semantic interpolation_mod initializer.
+function_argument ::= input_modifier datatype identifier semantic interpolation_mod.
+function_argument ::= input_modifier datatype identifier semantic initializer.
+function_argument ::= input_modifier datatype identifier semantic.
+function_argument ::= input_modifier datatype identifier interpolation_mod initializer.
+function_argument ::= input_modifier datatype identifier interpolation_mod.
+function_argument ::= input_modifier datatype identifier initializer.
+function_argument ::= input_modifier datatype identifier.
+function_argument ::= datatype identifier semantic interpolation_mod initializer.
+function_argument ::= datatype identifier semantic interpolation_mod.
+function_argument ::= datatype identifier semantic initializer.
+function_argument ::= datatype identifier semantic.
+function_argument ::= datatype identifier interpolation_mod initializer.
+function_argument ::= datatype identifier interpolation_mod.
+function_argument ::= datatype identifier initializer.
+function_argument ::= datatype identifier.
+
+input_modifier ::= IN.
+input_modifier ::= INOUT.
+input_modifier ::= OUT.
+input_modifier ::= UNIFORM.
+
+semantic ::= COLON semantic_name.
+semantic_name ::= identifier.  // !!! FIXME: list these here
+
+// DX10 only?
+interpolation_mod ::= LINEAR.
+interpolation_mod ::= CENTROID.
+interpolation_mod ::= NOINTERPOLATION.
+interpolation_mod ::= NOPERSPECTIVE.
+interpolation_mod ::= SAMPLE.
+
+global_variable ::= variable_declaration.
+
+variable_declaration ::= variable_attribute_list datatype scalar_or_array semantic annotations initializer variable_lowlevel SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array semantic annotations initializer SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array semantic annotations variable_lowlevel SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array semantic annotations SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array semantic initializer variable_lowlevel SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array semantic initializer SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array semantic variable_lowlevel SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array semantic SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array annotations initializer variable_lowlevel SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array annotations initializer SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array annotations variable_lowlevel SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array variable_lowlevel SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array initializer variable_lowlevel SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array initializer SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array annotations SEMICOLON.
+variable_declaration ::= variable_attribute_list datatype scalar_or_array SEMICOLON.
+variable_declaration ::= datatype scalar_or_array semantic annotations initializer variable_lowlevel SEMICOLON.
+variable_declaration ::= datatype scalar_or_array semantic annotations initializer SEMICOLON.
+variable_declaration ::= datatype scalar_or_array semantic annotations variable_lowlevel SEMICOLON.
+variable_declaration ::= datatype scalar_or_array semantic annotations SEMICOLON.
+variable_declaration ::= datatype scalar_or_array semantic initializer variable_lowlevel SEMICOLON.
+variable_declaration ::= datatype scalar_or_array semantic initializer SEMICOLON.
+variable_declaration ::= datatype scalar_or_array semantic variable_lowlevel SEMICOLON.
+variable_declaration ::= datatype scalar_or_array semantic SEMICOLON.
+variable_declaration ::= datatype scalar_or_array annotations initializer variable_lowlevel SEMICOLON.
+variable_declaration ::= datatype scalar_or_array annotations initializer SEMICOLON.
+variable_declaration ::= datatype scalar_or_array annotations variable_lowlevel SEMICOLON.
+variable_declaration ::= datatype scalar_or_array annotations SEMICOLON.
+variable_declaration ::= datatype scalar_or_array initializer variable_lowlevel SEMICOLON.
+variable_declaration ::= datatype scalar_or_array initializer SEMICOLON.
+variable_declaration ::= datatype scalar_or_array variable_lowlevel SEMICOLON.
+variable_declaration ::= datatype scalar_or_array SEMICOLON.
+variable_declaration ::= struct_declaration scalar_or_array SEMICOLON.
+
+struct_declaration ::= STRUCT identifier LBRACE struct_member_list RBRACE.
+
+struct_member_list ::= struct_member.
+struct_member_list ::= struct_member_list struct_member.
+
+struct_member ::= interpolation_mod struct_member_details.
+struct_member ::= struct_member_details.
+
+struct_member_details ::= scalar_or_array identifier SEMICOLON.
+
+typedef_statement ::= TYPEDEF CONST datatype scalar_or_array.
+typedef_statement ::= TYPEDEF datatype scalar_or_array.
+
+variable_lowlevel ::= packoffset register.
+variable_lowlevel ::= packoffset.
+variable_lowlevel ::= register.
+
+scalar_or_array ::= identifier LBRACKET INT_CONSTANT RBRACKET.
+scalar_or_array ::= identifier.
+
+packoffset ::= PACKOFFSET LPAREN identifier identifier RPAREN.
+packoffset ::= PACKOFFSET LPAREN identifier RPAREN.
+
+register ::= COLON REGISTER LPAREN identifier RPAREN.
+
+annotations ::= LT annotation_list GT.
+
+annotation_list ::= annotation.
+annotation_list ::= annotation_list annotation.
+
+annotation ::= datatype_scalar initializer SEMICOLON.
+
+variable_attribute_list ::= variable_attribute.
+variable_attribute_list ::= variable_attribute_list variable_attribute.
+
+variable_attribute ::= EXTERN.
+variable_attribute ::= NOINTERPOLATION.
+variable_attribute ::= SHARED.
+variable_attribute ::= STATIC.
+variable_attribute ::= UNIFORM.
+variable_attribute ::= VOLATILE.
+variable_attribute ::= CONST.
+variable_attribute ::= ROWMAJOR.
+variable_attribute ::= COLUMNMAJOR.
+
+initializer ::= ASSIGN expression.
+
+intrinsic_datatype ::= datatype_vector.
+intrinsic_datatype ::= datatype_matrix.
+intrinsic_datatype ::= datatype_scalar.
+
+datatype ::= intrinsic_datatype.
+datatype ::= USERTYPE.
+
+datatype_scalar ::= BOOL.
+datatype_scalar ::= INT.
+datatype_scalar ::= UINT.
+datatype_scalar ::= HALF.
+datatype_scalar ::= FLOAT.
+datatype_scalar ::= DOUBLE.
+datatype_scalar ::= STRING.  // this is for the effects framework, not HLSL.
+datatype_scalar ::= SNORM FLOAT.
+datatype_scalar ::= UNORM FLOAT.
+datatype_scalar ::= BUFFER LT datatype_scalar GT.
 
+// !!! FIXME: MSDN suggests that the matrix ones are just typedefs inserted
+// !!! FIXME:  before parsing begins, like:
+// !!! FIXME: typedef matrix <bool,4,3> bool4x3;
+// !!! FIXME:  ...maybe we can rip these out of the grammar and just create
+// !!! FIXME:  them at startup?
+datatype_vector ::= VECTOR LT datatype_scalar COMMA INT_CONSTANT GT.
+datatype_vector ::= BOOL1.
+datatype_vector ::= BOOL2.
+datatype_vector ::= BOOL3.
+datatype_vector ::= BOOL4.
+datatype_vector ::= INT1.
+datatype_vector ::= INT2.
+datatype_vector ::= INT3.
+datatype_vector ::= INT4.
+datatype_vector ::= UINT1.
+datatype_vector ::= UINT2.
+datatype_vector ::= UINT3.
+datatype_vector ::= UINT4.
+datatype_vector ::= HALF1.
+datatype_vector ::= HALF2.
+datatype_vector ::= HALF3.
+datatype_vector ::= HALF4.
+datatype_vector ::= FLOAT1.
+datatype_vector ::= FLOAT2.
+datatype_vector ::= FLOAT3.
+datatype_vector ::= FLOAT4.
+datatype_vector ::= DOUBLE1.
+datatype_vector ::= DOUBLE2.
+datatype_vector ::= DOUBLE3.
+datatype_vector ::= DOUBLE4.
+
+datatype_matrix ::= MATRIX LT datatype_scalar COMMA INT_CONSTANT COMMA INT_CONSTANT GT.
+datatype_matrix ::= BOOL1X1.
+datatype_matrix ::= BOOL1X2.
+datatype_matrix ::= BOOL1X3.
+datatype_matrix ::= BOOL1X4.
+datatype_matrix ::= BOOL2X1.
+datatype_matrix ::= BOOL2X2.
+datatype_matrix ::= BOOL2X3.
+datatype_matrix ::= BOOL2X4.
+datatype_matrix ::= BOOL3X1.
+datatype_matrix ::= BOOL3X2.
+datatype_matrix ::= BOOL3X3.
+datatype_matrix ::= BOOL3X4.
+datatype_matrix ::= BOOL4X1.
+datatype_matrix ::= BOOL4X2.
+datatype_matrix ::= BOOL4X3.
+datatype_matrix ::= BOOL4X4.
+datatype_matrix ::= INT1X1.
+datatype_matrix ::= INT1X2.
+datatype_matrix ::= INT1X3.
+datatype_matrix ::= INT1X4.
+datatype_matrix ::= INT2X1.
+datatype_matrix ::= INT2X2.
+datatype_matrix ::= INT2X3.
+datatype_matrix ::= INT2X4.
+datatype_matrix ::= INT3X1.
+datatype_matrix ::= INT3X2.
+datatype_matrix ::= INT3X3.
+datatype_matrix ::= INT3X4.
+datatype_matrix ::= INT4X1.
+datatype_matrix ::= INT4X2.
+datatype_matrix ::= INT4X3.
+datatype_matrix ::= INT4X4.
+datatype_matrix ::= UINT1X1.
+datatype_matrix ::= UINT1X2.
+datatype_matrix ::= UINT1X3.
+datatype_matrix ::= UINT1X4.
+datatype_matrix ::= UINT2X1.
+datatype_matrix ::= UINT2X2.
+datatype_matrix ::= UINT2X3.
+datatype_matrix ::= UINT2X4.
+datatype_matrix ::= UINT3X1.
+datatype_matrix ::= UINT3X2.
+datatype_matrix ::= UINT3X3.
+datatype_matrix ::= UINT3X4.
+datatype_matrix ::= UINT4X1.
+datatype_matrix ::= UINT4X2.
+datatype_matrix ::= UINT4X3.
+datatype_matrix ::= UINT4X4.
+datatype_matrix ::= HALF1X1.
+datatype_matrix ::= HALF1X2.
+datatype_matrix ::= HALF1X3.
+datatype_matrix ::= HALF1X4.
+datatype_matrix ::= HALF2X1.
+datatype_matrix ::= HALF2X2.
+datatype_matrix ::= HALF2X3.
+datatype_matrix ::= HALF2X4.
+datatype_matrix ::= HALF3X1.
+datatype_matrix ::= HALF3X2.
+datatype_matrix ::= HALF3X3.
+datatype_matrix ::= HALF3X4.
+datatype_matrix ::= HALF4X1.
+datatype_matrix ::= HALF4X2.
+datatype_matrix ::= HALF4X3.
+datatype_matrix ::= HALF4X4.
+datatype_matrix ::= FLOAT1X1.
+datatype_matrix ::= FLOAT1X2.
+datatype_matrix ::= FLOAT1X3.
+datatype_matrix ::= FLOAT1X4.
+datatype_matrix ::= FLOAT2X1.
+datatype_matrix ::= FLOAT2X2.
+datatype_matrix ::= FLOAT2X3.
+datatype_matrix ::= FLOAT2X4.
+datatype_matrix ::= FLOAT3X1.
+datatype_matrix ::= FLOAT3X2.
+datatype_matrix ::= FLOAT3X3.
+datatype_matrix ::= FLOAT3X4.
+datatype_matrix ::= FLOAT4X1.
+datatype_matrix ::= FLOAT4X2.
+datatype_matrix ::= FLOAT4X3.
+datatype_matrix ::= FLOAT4X4.
+datatype_matrix ::= DOUBLE1X1.
+datatype_matrix ::= DOUBLE1X2.
+datatype_matrix ::= DOUBLE1X3.
+datatype_matrix ::= DOUBLE1X4.
+datatype_matrix ::= DOUBLE2X1.
+datatype_matrix ::= DOUBLE2X2.
+datatype_matrix ::= DOUBLE2X3.
+datatype_matrix ::= DOUBLE2X4.
+datatype_matrix ::= DOUBLE3X1.
+datatype_matrix ::= DOUBLE3X2.
+datatype_matrix ::= DOUBLE3X3.
+datatype_matrix ::= DOUBLE3X4.
+datatype_matrix ::= DOUBLE4X1.
+datatype_matrix ::= DOUBLE4X2.
+datatype_matrix ::= DOUBLE4X3.
+datatype_matrix ::= DOUBLE4X4.
+
+statement_block ::= LBRACE RBRACE.
+statement_block ::= LBRACE statement_list RBRACE.
+
+statement_list ::= statement.
+statement_list ::= statement_list statement.
+
+statement ::= return_statement.
+statement ::= BREAK SEMICOLON.
+statement ::= CONTINUE SEMICOLON.
+statement ::= DISCARD SEMICOLON.
+statement ::= statement_block.
+statement ::= for_statement.
+statement ::= do_statement.
+statement ::= while_statement.
+statement ::= if_statement.
+statement ::= switch_statement.
+statement ::= variable_declaration.
+statement ::= typedef_statement.
+statement ::= expression_statement.
+statement ::= struct_statement.
+
+struct_statement ::= struct_declaration SEMICOLON.
+
+expression_statement ::= SEMICOLON.
+expression_statement ::= expression SEMICOLON.
+
+return_statement ::= RETURN SEMICOLON.
+return_statement ::= RETURN expression SEMICOLON.
+
+while_statement ::= loop_attribute while_details.
+while_statement ::= while_details.
+
+while_details ::= WHILE LPAREN expression RPAREN statement.
+
+for_statement ::= loop_attribute for_details.
+for_statement ::= for_details.
+
+for_details ::= FOR LPAREN expression SEMICOLON expression SEMICOLON expression RPAREN statement.
+for_details ::= FOR LPAREN SEMICOLON SEMICOLON RPAREN statement.
+for_details ::= FOR LPAREN SEMICOLON SEMICOLON expression RPAREN statement.
+for_details ::= FOR LPAREN SEMICOLON expression SEMICOLON RPAREN statement.
+for_details ::= FOR LPAREN SEMICOLON expression SEMICOLON expression RPAREN statement.
+for_details ::= FOR LPAREN expression SEMICOLON SEMICOLON RPAREN statement.
+for_details ::= FOR LPAREN expression SEMICOLON SEMICOLON expression RPAREN statement.
+for_details ::= FOR LPAREN expression SEMICOLON expression SEMICOLON RPAREN statement.
+
+loop_attribute ::= UNROLL LPAREN INT_CONSTANT RPAREN.
+loop_attribute ::= UNROLL.
+loop_attribute ::= LOOP.
+
+do_statement ::= DO statement WHILE LPAREN expression RPAREN SEMICOLON.
+
+if_statement ::= if_attribute IF LPAREN expression RPAREN statement.
+if_statement ::= IF LPAREN expression RPAREN statement.
+if_statement ::= if_attribute IF LPAREN expression RPAREN statement ELSE statement.
+if_statement ::= IF LPAREN expression RPAREN statement ELSE statement.
+
+if_attribute ::= BRANCH.
+if_attribute ::= FLATTEN.
+
+switch_statement ::= switch_attribute switch_details.
+switch_statement ::= switch_details.
+
+switch_details ::= SWITCH LPAREN expression RPAREN LBRACE switch_case_list RBRACE.
+
+switch_attribute ::= FLATTEN.
+switch_attribute ::= BRANCH.
+switch_attribute ::= FORCECASE.
+switch_attribute ::= CALL.
+
+switch_case_list ::= switch_case.
+switch_case_list ::= switch_case_list switch_case.
+
+// You can do math here, apparently, as long as it produces an int constant.
+//  ...so "case 3+2:" works.
+switch_case ::= CASE expression COLON statement_list.
+switch_case ::= CASE expression COLON.
+switch_case ::= DEFAULT COLON statement_list.
+switch_case ::= DEFAULT COLON.
+
+// I may want to do more with this at some point.
+identifier ::= IDENTIFIER.
+
+
+// the expression stuff is based on Jeff Lee's ANSI C grammar.
 primary_expr ::= identifier.
-primary_expr ::= CONSTANT.
+primary_expr ::= INT_CONSTANT.
+primary_expr ::= FLOAT_CONSTANT.
 primary_expr ::= STRING_LITERAL.
-primary_expr ::= LPAREN expr RPAREN.
+primary_expr ::= LPAREN expression RPAREN.
 
 postfix_expr ::= primary_expr.
-postfix_expr ::= postfix_expr LBRACKET expr RBRACKET.
+postfix_expr ::= postfix_expr LBRACKET expression RBRACKET.
 postfix_expr ::= postfix_expr LPAREN RPAREN.
 postfix_expr ::= postfix_expr LPAREN argument_expr_list RPAREN.
 postfix_expr ::= postfix_expr DOT identifier.
-postfix_expr ::= postfix_expr PTR_OP identifier.
 postfix_expr ::= postfix_expr PLUSPLUS.
 postfix_expr ::= postfix_expr MINUSMINUS.
 
@@ -87,18 +470,14 @@
 unary_expr ::= PLUSPLUS unary_expr.
 unary_expr ::= MINUSMINUS unary_expr.
 unary_expr ::= unary_operator cast_expr.
-unary_expr ::= SIZEOF unary_expr.
-unary_expr ::= SIZEOF LPAREN type_name RPAREN.
 
-unary_operator ::= AND.
-unary_operator ::= STAR.
 unary_operator ::= PLUS.
 unary_operator ::= MINUS.
 unary_operator ::= COMPLEMENT.
 unary_operator ::= EXCLAMATION.
 
 cast_expr ::= unary_expr.
-cast_expr ::= LPAREN type_name RPAREN cast_expr.
+cast_expr ::= LPAREN datatype RPAREN cast_expr.
 
 multiplicative_expr ::= cast_expr.
 multiplicative_expr ::= multiplicative_expr STAR cast_expr.
@@ -156,173 +535,8 @@
 assignment_operator ::= XORASSIGN.
 assignment_operator ::= ORASSIGN.
 
-expr ::= assignment_expr.
-expr ::= expr COMMA assignment_expr.
-
-constant_expr ::= conditional_expr.
-
-declaration ::= declaration_specifiers SEMICOLON.
-declaration ::= declaration_specifiers init_declarator_list SEMICOLON.
-
-declaration_specifiers ::= storage_class_specifier.
-declaration_specifiers ::= storage_class_specifier declaration_specifiers.
-declaration_specifiers ::= type_specifier.
-declaration_specifiers ::= type_specifier declaration_specifiers.
-
-init_declarator_list ::= init_declarator.
-init_declarator_list ::= init_declarator_list COMMA init_declarator.
-
-init_declarator ::= declarator.
-init_declarator ::= declarator ASSIGN initializer.
-
-storage_class_specifier ::= TYPEDEF.
-storage_class_specifier ::= EXTERN.
-storage_class_specifier ::= STATIC.
-storage_class_specifier ::= AUTO.
-storage_class_specifier ::= REGISTER.
-
-type_specifier ::= CHAR.
-type_specifier ::= SHORT.
-type_specifier ::= INT.
-type_specifier ::= LONG.
-type_specifier ::= SIGNED.
-type_specifier ::= UNSIGNED.
-type_specifier ::= FLOAT.
-type_specifier ::= DOUBLE.
-type_specifier ::= CONST.
-type_specifier ::= VOLATILE.
-type_specifier ::= VOID.
-type_specifier ::= struct_or_union_specifier.
-type_specifier ::= TYPE_NAME.
-
-struct_or_union_specifier ::= struct_or_union identifier LBRACE
-                              struct_declaration_list RBRACE.
-struct_or_union_specifier ::= struct_or_union LBRACE struct_declaration_list
-                              RBRACE.
-struct_or_union_specifier ::= struct_or_union identifier.
-
-struct_or_union ::= STRUCT.
-struct_or_union ::= UNION.
-
-struct_declaration_list ::= struct_declaration.
-struct_declaration_list ::= struct_declaration_list struct_declaration.
-
-struct_declaration ::= type_specifier_list struct_declarator_list SEMICOLON.
-
-struct_declarator_list ::= struct_declarator.
-struct_declarator_list ::= struct_declarator_list COMMA struct_declarator.
-
-struct_declarator ::= declarator.
-struct_declarator ::= COLON constant_expr.
-struct_declarator ::= declarator COLON constant_expr.
-
-declarator ::= declarator2.
-
-declarator2 ::= identifier.
-declarator2 ::= LPAREN declarator RPAREN.
-declarator2 ::= declarator2 LBRACKET RBRACKET.
-declarator2 ::= declarator2 LBRACKET constant_expr RBRACKET.
-declarator2 ::= declarator2 LPAREN RPAREN.
-declarator2 ::= declarator2 LPAREN parameter_type_list RPAREN.
-declarator2 ::= declarator2 LPAREN parameter_identifier_list RPAREN.
-
-type_specifier_list ::= type_specifier.
-type_specifier_list ::= type_specifier_list type_specifier.
-
-parameter_identifier_list ::= identifier_list.
-
-identifier_list ::= identifier.
-identifier_list ::= identifier_list COMMA identifier.
-
-parameter_type_list ::= parameter_list.
-
-parameter_list ::= parameter_declaration.
-parameter_list ::= parameter_list COMMA parameter_declaration.
-
-parameter_declaration ::= type_specifier_list declarator.
-parameter_declaration ::= type_name.
-
-type_name ::= type_specifier_list.
-type_name ::= type_specifier_list abstract_declarator.
-
-abstract_declarator ::= abstract_declarator2.
-
-abstract_declarator2 ::= LPAREN abstract_declarator RPAREN.
-abstract_declarator2 ::= LBRACKET RBRACKET.
-abstract_declarator2 ::= LBRACKET constant_expr RBRACKET.
-abstract_declarator2 ::= abstract_declarator2 LBRACKET RBRACKET.
-abstract_declarator2 ::= abstract_declarator2 LBRACKET constant_expr RBRACKET.
-abstract_declarator2 ::= LPAREN RPAREN.
-abstract_declarator2 ::= LPAREN parameter_type_list RPAREN.
-abstract_declarator2 ::= abstract_declarator2 LPAREN RPAREN.
-abstract_declarator2 ::= abstract_declarator2 LPAREN parameter_type_list RPAREN.
-
-initializer ::= assignment_expr.
-initializer ::= LBRACE initializer_list RBRACE.
-initializer ::= LBRACE initializer_list COMMA RBRACE.
-
-initializer_list ::= initializer.
-initializer_list ::= initializer_list COMMA initializer.
-
-statement ::= labeled_statement.
-statement ::= compound_statement.
-statement ::= expression_statement.
-statement ::= selection_statement.
-statement ::= iteration_statement.
-statement ::= jump_statement.
-
-labeled_statement ::= identifier COLON statement.
-labeled_statement ::= CASE constant_expr COLON statement.
-labeled_statement ::= DEFAULT COLON statement.
-
-compound_statement ::= LBRACE RBRACE.
-compound_statement ::= LBRACE statement_list RBRACE.
-compound_statement ::= LBRACE declaration_list RBRACE.
-compound_statement ::= LBRACE declaration_list statement_list RBRACE.
-
-declaration_list ::= declaration.
-declaration_list ::= declaration_list declaration.
-
-statement_list ::= statement.
-statement_list ::= statement_list statement.
-
-expression_statement ::= SEMICOLON.
-expression_statement ::= expr SEMICOLON.
-
-selection_statement ::= IF LPAREN expr RPAREN statement.
-selection_statement ::= IF LPAREN expr RPAREN statement ELSE statement.
-selection_statement ::= SWITCH LPAREN expr RPAREN statement.
-
-iteration_statement ::= WHILE LPAREN expr RPAREN statement.
-iteration_statement ::= DO statement WHILE LPAREN expr RPAREN SEMICOLON.
-iteration_statement ::= FOR LPAREN SEMICOLON SEMICOLON RPAREN statement.
-iteration_statement ::= FOR LPAREN SEMICOLON SEMICOLON expr RPAREN statement.
-iteration_statement ::= FOR LPAREN SEMICOLON expr SEMICOLON RPAREN statement.
-iteration_statement ::= FOR LPAREN SEMICOLON expr SEMICOLON expr RPAREN statement.
-iteration_statement ::= FOR LPAREN expr SEMICOLON SEMICOLON RPAREN statement.
-iteration_statement ::= FOR LPAREN expr SEMICOLON SEMICOLON expr RPAREN statement.
-iteration_statement ::= FOR LPAREN expr SEMICOLON expr SEMICOLON RPAREN statement.
-iteration_statement ::= FOR LPAREN expr SEMICOLON expr SEMICOLON expr RPAREN statement.
-
-jump_statement ::= CONTINUE SEMICOLON.
-jump_statement ::= BREAK SEMICOLON.
-jump_statement ::= DISCARD SEMICOLON.
-jump_statement ::= RETURN SEMICOLON.
-jump_statement ::= RETURN expr SEMICOLON.
-
-file ::= external_definition.
-file ::= file external_definition.
-
-external_definition ::= function_definition.
-external_definition ::= declaration.
-
-function_definition ::= declarator function_body.
-function_definition ::= declaration_specifiers declarator function_body.
-
-function_body ::= compound_statement.
-function_body ::= declaration_list compound_statement.
-
-identifier ::= IDENTIFIER.
+expression ::= assignment_expr.
+expression ::= expression COMMA assignment_expr.
 
 // end of mojoshader_parser_hlsl.lemon ...