// MonoGame Effect Parser // // For use with our fork of the "Tiny Parser Generator" // https://github.com/SickheadGames/TinyPG // <% @TinyPG Namespace="TwoMGFX.TPGParser" Language="C#"%> [Skip] BlockComment -> @"/\*([^*]|\*[^/])*\*/"; [Skip] Comment -> @"//[^\n\r]*"; [Skip] Whitespace -> @"[ \t\n\r]+"; [FileAndLine] LinePragma -> @"^[ \t]*#line[ \t]*(?\d*)[ \t]*(\""(?[^\""\\]*(?:\\.[^\""\\]*)*)\"")?\n"; // TOKENS [IgnoreCase] Pass -> @"pass"; [IgnoreCase] Technique -> @"technique"; [IgnoreCase] Sampler -> @"sampler1D|sampler2D|sampler3D|samplerCUBE|SamplerState|sampler"; [IgnoreCase] SamplerState -> @"sampler_state"; [IgnoreCase] VertexShader -> @"VertexShader"; [IgnoreCase] PixelShader -> @"PixelShader"; [IgnoreCase] Register -> @"register"; [IgnoreCase] Boolean -> @"true|false|0|1"; Number -> @"[+-]? ?[0-9]?\.?[0-9]+[fF]?"; [IgnoreCase] HexColor -> @"0x[0-9a-f]{6}([0-9a-f][0-9a-f])?"; Identifier -> @"[A-Za-z_][A-Za-z0-9_]*"; OpenBracket -> @"{"; CloseBracket -> @"}"; Equals -> @"="; Colon -> @":"; Comma -> @","; Semicolon -> @";"; Or -> @"\|"; OpenParenthesis -> @"\("; CloseParenthesis -> @"\)"; OpenSquareBracket -> @"\["; CloseSquareBracket -> @"\]"; LessThan -> @"<"; GreaterThan -> @">"; [IgnoreCase] Compile -> @"compile"; ShaderModel -> @"[A-Za-z_][A-Za-z0-9_]*"; Code -> @"[\S]+"; EndOfFile -> @"^$"; // Sampler states [IgnoreCase] MinFilter -> @"MinFilter"; [IgnoreCase] MagFilter -> @"MagFilter"; [IgnoreCase] MipFilter -> @"MipFilter"; [IgnoreCase] Filter -> @"Filter"; [IgnoreCase] Texture -> @"Texture"; [IgnoreCase] AddressU -> @"AddressU"; [IgnoreCase] AddressV -> @"AddressV"; [IgnoreCase] AddressW -> @"AddressW"; [IgnoreCase] BorderColor -> @"BorderColor"; [IgnoreCase] MaxAnisotropy -> @"MaxAnisotropy"; [IgnoreCase] MaxMipLevel -> @"MaxMipLevel|MaxLod"; [IgnoreCase] MipLodBias -> @"MipLodBias"; // Address Mode [IgnoreCase] Clamp -> @"Clamp"; [IgnoreCase] Wrap -> @"Wrap"; [IgnoreCase] Mirror -> @"Mirror"; [IgnoreCase] Border -> @"Border"; // Texture Filters [IgnoreCase] None -> @"None"; [IgnoreCase] Linear -> @"Linear"; [IgnoreCase] Point -> @"Point"; [IgnoreCase] Anisotropic -> @"Anisotropic"; // Render states [IgnoreCase] AlphaBlendEnable -> @"AlphaBlendEnable"; [IgnoreCase] SrcBlend -> @"SrcBlend"; [IgnoreCase] DestBlend -> @"DestBlend"; [IgnoreCase] BlendOp -> @"BlendOp"; [IgnoreCase] ColorWriteEnable -> @"ColorWriteEnable"; [IgnoreCase] ZEnable -> @"ZEnable"; [IgnoreCase] ZWriteEnable -> @"ZWriteEnable"; [IgnoreCase] ZFunc-> @"ZFunc"; [IgnoreCase] DepthBias -> @"DepthBias"; [IgnoreCase] CullMode -> @"CullMode"; [IgnoreCase] FillMode -> @"FillMode"; [IgnoreCase] MultiSampleAntiAlias -> @"MultiSampleAntiAlias"; [IgnoreCase] ScissorTestEnable -> @"ScissorTestEnable"; [IgnoreCase] SlopeScaleDepthBias -> @"SlopeScaleDepthBias"; [IgnoreCase] StencilEnable -> @"StencilEnable"; [IgnoreCase] StencilFail -> @"StencilFail"; [IgnoreCase] StencilFunc -> @"StencilFunc"; [IgnoreCase] StencilMask -> @"StencilMask"; [IgnoreCase] StencilPass -> @"StencilPass"; [IgnoreCase] StencilRef -> @"StencilRef"; [IgnoreCase] StencilWriteMask -> @"StencilWriteMask"; [IgnoreCase] StencilZFail -> @"StencilZFail"; // Compare function [IgnoreCase] Never -> @"Never"; [IgnoreCase] Less -> @"Less"; [IgnoreCase] Equal -> @"Equal"; [IgnoreCase] LessEqual -> @"LessEqual"; [IgnoreCase] Greater -> @"Greater"; [IgnoreCase] NotEqual -> @"NotEqual"; [IgnoreCase] GreaterEqual -> @"GreaterEqual"; [IgnoreCase] Always -> @"Always"; // Stencil operation [IgnoreCase] Keep -> @"Keep"; [IgnoreCase] Zero -> @"Zero"; [IgnoreCase] Replace -> @"Replace"; [IgnoreCase] IncrSat -> @"IncrSat"; [IgnoreCase] DecrSat -> @"DecrSat"; [IgnoreCase] Invert -> @"Invert"; [IgnoreCase] Incr -> @"Incr"; [IgnoreCase] Decr -> @"Decr"; // Colors [IgnoreCase] Red -> @"Red"; [IgnoreCase] Green -> @"Green"; [IgnoreCase] Blue -> @"Blue"; [IgnoreCase] Alpha -> @"Alpha"; [IgnoreCase] All -> @"All"; // Cull mode [IgnoreCase] Cw -> @"Cw"; [IgnoreCase] Ccw -> @"Ccw"; // Fill mode [IgnoreCase] Solid -> @"Solid"; [IgnoreCase] WireFrame -> @"WireFrame"; // Blend function [IgnoreCase] Add -> @"Add"; [IgnoreCase] Subtract -> @"Subtract"; [IgnoreCase] RevSubtract -> @"RevSubtract"; [IgnoreCase] Min -> @"Min"; [IgnoreCase] Max -> @"Max"; // Blend [IgnoreCase] Zero -> @"Zero"; [IgnoreCase] One -> @"One"; [IgnoreCase] SrcColor -> @"SrcColor"; [IgnoreCase] InvSrcColor -> @"InvSrcColor"; [IgnoreCase] SrcAlpha -> @"SrcAlpha"; [IgnoreCase] InvSrcAlpha -> @"InvSrcAlpha"; [IgnoreCase] DestAlpha -> @"DestAlpha"; [IgnoreCase] InvDestAlpha -> @"InvDestAlpha"; [IgnoreCase] DestColor -> @"DestColor"; [IgnoreCase] InvDestColor -> @"InvDestColor"; [IgnoreCase] SrcAlphaSat -> @"SrcAlphaSat"; [IgnoreCase] BlendFactor -> @"BlendFactor"; [IgnoreCase] InvBlendFactor -> @"InvBlendFactor"; // Productions Start -> (Code | Technique_Declaration | Sampler_Declaration)* EndOfFile { var shader = new ShaderInfo(); foreach (var node in Nodes) node.Eval(tree, shader); return shader; }; Technique_Declaration -> Technique Identifier? OpenBracket Pass_Declaration+ CloseBracket { var technique = new TechniqueInfo(); technique.name = $Identifier as string ?? string.Empty; technique.startPos = Token.StartPos; technique.length = Token.Length; foreach (var node in Nodes) node.Eval(tree, technique); // Make sure we have at least one pass. if (technique.Passes.Count > 0) { var shaderInfo = paramlist[0] as ShaderInfo; shaderInfo.Techniques.Add(technique); } return null; }; FillMode_Solid -> Solid { return FillMode.Solid; }; FillMode_WireFrame -> WireFrame { return FillMode.WireFrame; }; FillModes -> (FillMode_Solid|FillMode_WireFrame) { return $FillMode_Solid ?? $FillMode_WireFrame; }; CullMode_None -> None { return CullMode.None; }; CullMode_Cw -> Cw { return CullMode.CullClockwiseFace; }; CullMode_Ccw -> Ccw { return CullMode.CullCounterClockwiseFace; }; CullModes -> (CullMode_None|CullMode_Cw|CullMode_Ccw) { return $CullMode_None ?? $CullMode_Cw ?? $CullMode_Ccw; }; Colors_None -> None { return ColorWriteChannels.None; }; Colors_Red -> Red { return ColorWriteChannels.Red; }; Colors_Green -> Green { return ColorWriteChannels.Green; }; Colors_Blue -> Blue { return ColorWriteChannels.Blue; }; Colors_Alpha -> Alpha { return ColorWriteChannels.Alpha; }; Colors_All -> All { return ColorWriteChannels.All; }; Colors_Boolean -> Boolean { return ParseTreeTools.ParseBool((string)$Boolean) ? ColorWriteChannels.All : ColorWriteChannels.None; }; Colors -> (Colors_Red|Colors_Green|Colors_Blue|Colors_Alpha|Colors_None|Colors_All|Colors_Boolean) { return $Colors_Red ?? $Colors_Green ?? $Colors_Blue ?? $Colors_Alpha ?? $Colors_None ?? $Colors_All ?? $Colors_Boolean; }; ColorsMasks -> Colors (Or Colors)? (Or Colors)? (Or Colors)? { return (ColorWriteChannels)($Colors[0] ?? 0) | (ColorWriteChannels)($Colors[1] ?? 0) | (ColorWriteChannels)($Colors[2] ?? 0) | (ColorWriteChannels)($Colors[3] ?? 0); }; Blend_Zero -> Zero { return Blend.Zero; }; Blend_One -> One { return Blend.One; }; Blend_SrcColor -> SrcColor { return Blend.SourceColor; }; Blend_InvSrcColor -> InvSrcColor { return Blend.InverseSourceColor; }; Blend_SrcAlpha -> SrcAlpha { return Blend.SourceAlpha; }; Blend_InvSrcAlpha -> InvSrcAlpha { return Blend.InverseSourceAlpha; }; Blend_DestAlpha -> DestAlpha { return Blend.DestinationAlpha; }; Blend_InvDestAlpha -> InvDestAlpha { return Blend.InverseDestinationAlpha; }; Blend_DestColor -> DestColor { return Blend.DestinationColor; }; Blend_InvDestColor -> InvDestColor { return Blend.InverseDestinationColor; }; Blend_SrcAlphaSat -> SrcAlphaSat { return Blend.SourceAlphaSaturation; }; Blend_BlendFactor -> BlendFactor { return Blend.BlendFactor; }; Blend_InvBlendFactor -> InvBlendFactor { return Blend.InverseBlendFactor; }; Blends -> ( Blend_Zero|Blend_One|Blend_SrcColor|Blend_InvSrcColor|Blend_SrcAlpha|Blend_InvSrcAlpha| Blend_DestAlpha|Blend_InvDestAlpha|Blend_DestColor|Blend_InvDestColor|Blend_SrcAlphaSat| Blend_BlendFactor|Blend_InvBlendFactor) { return $Blend_Zero ?? $Blend_One ?? $Blend_SrcColor ?? $Blend_InvSrcColor ?? $Blend_SrcAlpha ?? $Blend_InvSrcAlpha ?? $Blend_DestAlpha ?? $Blend_InvDestAlpha ?? $Blend_DestColor ?? $Blend_InvDestColor ?? $Blend_SrcAlphaSat ?? $Blend_BlendFactor ?? $Blend_InvBlendFactor; }; BlendOp_Add -> Add { return BlendFunction.Add; }; BlendOp_Subtract -> Subtract { return BlendFunction.Subtract; }; BlendOp_RevSubtract -> RevSubtract { return BlendFunction.ReverseSubtract; }; BlendOp_Min -> Min { return BlendFunction.Min; }; BlendOp_Max -> Max { return BlendFunction.Max; }; BlendOps -> (BlendOp_Add|BlendOp_Subtract|BlendOp_RevSubtract|BlendOp_Min|BlendOp_Max) { return $BlendOp_Add ?? $BlendOp_Subtract ?? $BlendOp_RevSubtract ?? $BlendOp_Min ?? $BlendOp_Max; }; CmpFunc_Never -> Never { return CompareFunction.Never; }; CmpFunc_Less -> Less { return CompareFunction.Less; }; CmpFunc_Equal -> Equal { return CompareFunction.Equal; }; CmpFunc_LessEqual -> LessEqual { return CompareFunction.LessEqual; }; CmpFunc_Greater -> Greater { return CompareFunction.Greater; }; CmpFunc_NotEqual -> NotEqual { return CompareFunction.NotEqual; }; CmpFunc_GreaterEqual -> GreaterEqual { return CompareFunction.GreaterEqual; }; CmpFunc_Always -> Always { return CompareFunction.Always; }; CmpFunc -> (CmpFunc_Never|CmpFunc_Less|CmpFunc_Equal|CmpFunc_LessEqual|CmpFunc_Greater|CmpFunc_NotEqual|CmpFunc_GreaterEqual|CmpFunc_Always) { return $CmpFunc_Never ?? $CmpFunc_Less ?? $CmpFunc_Equal ?? $CmpFunc_LessEqual ?? $CmpFunc_Greater ?? $CmpFunc_NotEqual ?? $CmpFunc_GreaterEqual ?? $CmpFunc_Always; }; StencilOp_Keep -> Keep { return StencilOperation.Keep; }; StencilOp_Zero -> Zero { return StencilOperation.Zero; }; StencilOp_Replace -> Replace { return StencilOperation.Replace; }; StencilOp_IncrSat -> IncrSat { return StencilOperation.IncrementSaturation; }; StencilOp_DecrSat -> DecrSat { return StencilOperation.DecrementSaturation; }; StencilOp_Invert -> Invert { return StencilOperation.Invert; }; StencilOp_Incr -> Incr { return StencilOperation.Increment; }; StencilOp_Decr -> Decr { return StencilOperation.Decrement; }; StencilOp -> (StencilOp_Keep|StencilOp_Zero|StencilOp_Replace|StencilOp_IncrSat|StencilOp_DecrSat|StencilOp_Invert|StencilOp_Incr|StencilOp_Decr) { return $StencilOp_Keep ?? $StencilOp_Zero ?? $StencilOp_Replace ?? $StencilOp_IncrSat ?? $StencilOp_DecrSat ?? $StencilOp_Invert ?? $StencilOp_Incr ?? $StencilOp_Decr; }; // Render states Render_State_CullMode -> CullMode Equals CullModes Semicolon { (paramlist[0] as PassInfo).CullMode = (CullMode)$CullModes; return null; }; Render_State_FillMode -> FillMode Equals FillModes Semicolon { (paramlist[0] as PassInfo).FillMode = (FillMode)$FillModes; return null; }; Render_State_AlphaBlendEnable -> AlphaBlendEnable Equals Boolean Semicolon { (paramlist[0] as PassInfo).AlphaBlendEnable = ParseTreeTools.ParseBool((string)$Boolean); return null; }; Render_State_SrcBlend -> SrcBlend Equals Blends Semicolon { (paramlist[0] as PassInfo).SrcBlend = (Blend)$Blends; return null; }; Render_State_DestBlend -> DestBlend Equals Blends Semicolon { (paramlist[0] as PassInfo).DestBlend = (Blend)$Blends; return null; }; Render_State_BlendOp -> BlendOp Equals BlendOps Semicolon { (paramlist[0] as PassInfo).BlendOp = (BlendFunction)$BlendOps; return null; }; Render_State_ColorWriteEnable -> ColorWriteEnable Equals ColorsMasks Semicolon { (paramlist[0] as PassInfo).ColorWriteEnable = (ColorWriteChannels)$ColorsMasks; return null; }; Render_State_DepthBias -> DepthBias Equals Number Semicolon { (paramlist[0] as PassInfo).DepthBias = ParseTreeTools.ParseFloat((string)$Number); return null; }; Render_State_SlopeScaleDepthBias -> SlopeScaleDepthBias Equals Number Semicolon { (paramlist[0] as PassInfo).SlopeScaleDepthBias = ParseTreeTools.ParseFloat((string)$Number); return null; }; Render_State_ZEnable -> ZEnable Equals Boolean Semicolon { (paramlist[0] as PassInfo).ZEnable = ParseTreeTools.ParseBool((string)$Boolean); return null; }; Render_State_ZWriteEnable -> ZWriteEnable Equals Boolean Semicolon { (paramlist[0] as PassInfo).ZWriteEnable = ParseTreeTools.ParseBool((string)$Boolean); return null; }; Render_State_ZFunc -> ZFunc Equals CmpFunc Semicolon { (paramlist[0] as PassInfo).DepthBufferFunction = (CompareFunction)$CmpFunc; return null; }; Render_State_MultiSampleAntiAlias -> MultiSampleAntiAlias Equals Boolean Semicolon { (paramlist[0] as PassInfo).MultiSampleAntiAlias = ParseTreeTools.ParseBool((string)$Boolean); return null; }; Render_State_ScissorTestEnable -> ScissorTestEnable Equals Boolean Semicolon { (paramlist[0] as PassInfo).ScissorTestEnable = ParseTreeTools.ParseBool((string)$Boolean); return null; }; Render_State_StencilEnable -> StencilEnable Equals Boolean Semicolon { (paramlist[0] as PassInfo).StencilEnable = ParseTreeTools.ParseBool((string)$Boolean); return null; }; Render_State_StencilFail -> StencilFail Equals StencilOp Semicolon { (paramlist[0] as PassInfo).StencilFail = (StencilOperation)$StencilOp; return null; }; Render_State_StencilFunc -> StencilFunc Equals CmpFunc Semicolon { (paramlist[0] as PassInfo).StencilFunc = (CompareFunction)$CmpFunc; return null; }; Render_State_StencilMask -> StencilMask Equals Number Semicolon { (paramlist[0] as PassInfo).StencilMask = ParseTreeTools.ParseInt((string)$Number); return null; }; Render_State_StencilPass -> StencilPass Equals StencilOp Semicolon { (paramlist[0] as PassInfo).StencilPass = (StencilOperation)$StencilOp; return null; }; Render_State_StencilRef -> StencilRef Equals Number Semicolon { (paramlist[0] as PassInfo).StencilRef = ParseTreeTools.ParseInt((string)$Number); return null; }; Render_State_StencilWriteMask -> StencilWriteMask Equals Number Semicolon { (paramlist[0] as PassInfo).StencilWriteMask = ParseTreeTools.ParseInt((string)$Number); return null; }; Render_State_StencilZFail -> StencilZFail Equals StencilOp Semicolon { (paramlist[0] as PassInfo).StencilZFail = (StencilOperation)$StencilOp; return null; }; Render_State_Expression -> Render_State_CullMode | Render_State_FillMode | Render_State_AlphaBlendEnable | Render_State_SrcBlend | Render_State_DestBlend | Render_State_BlendOp | Render_State_ColorWriteEnable | Render_State_DepthBias | Render_State_SlopeScaleDepthBias | Render_State_ZEnable | Render_State_ZWriteEnable | Render_State_ZFunc | Render_State_MultiSampleAntiAlias | Render_State_ScissorTestEnable | Render_State_StencilEnable | Render_State_StencilFail | Render_State_StencilFunc | Render_State_StencilMask | Render_State_StencilPass | Render_State_StencilRef | Render_State_StencilWriteMask | Render_State_StencilZFail; Pass_Declaration -> Pass Identifier? OpenBracket (VertexShader_Pass_Expression | PixelShader_Pass_Expression | Render_State_Expression)* CloseBracket { var pass = new PassInfo(); pass.name = $Identifier as string ?? string.Empty; foreach (var node in Nodes) node.Eval(tree, pass); // We need to have a pixel or vertex shader to keep this pass. if (!string.IsNullOrEmpty(pass.psFunction) || !string.IsNullOrEmpty(pass.vsFunction)) { var technique = paramlist[0] as TechniqueInfo; technique.Passes.Add(pass); } return null; }; VertexShader_Pass_Expression -> VertexShader Equals Compile ShaderModel Identifier OpenParenthesis CloseParenthesis Semicolon { var pass = paramlist[0] as PassInfo; pass.vsModel = $ShaderModel as string; pass.vsFunction = $Identifier as string; return null; }; PixelShader_Pass_Expression -> PixelShader Equals Compile ShaderModel Identifier OpenParenthesis CloseParenthesis Semicolon { var pass = paramlist[0] as PassInfo; pass.psModel = $ShaderModel as string; pass.psFunction = $Identifier as string; return null; }; AddressMode_Clamp -> Clamp { return TextureAddressMode.Clamp; }; AddressMode_Wrap -> Wrap { return TextureAddressMode.Wrap; }; AddressMode_Mirror -> Mirror { return TextureAddressMode.Mirror; }; AddressMode_Border -> Border { return TextureAddressMode.Border; }; AddressMode -> (AddressMode_Clamp|AddressMode_Wrap|AddressMode_Mirror|AddressMode_Border) { return $AddressMode_Clamp ?? $AddressMode_Wrap ?? $AddressMode_Mirror ?? $AddressMode_Border; }; TextureFilter_None -> None { return TextureFilterType.None; }; TextureFilter_Linear -> Linear { return TextureFilterType.Linear; }; TextureFilter_Point -> Point { return TextureFilterType.Point; }; TextureFilter_Anisotropic -> Anisotropic { return TextureFilterType.Anisotropic; }; TextureFilter -> (TextureFilter_None|TextureFilter_Linear|TextureFilter_Point|TextureFilter_Anisotropic) { return $TextureFilter_None ?? $TextureFilter_Linear ?? $TextureFilter_Point ?? $TextureFilter_Anisotropic; }; // Sampler States Sampler_State_Texture -> Texture Equals (LessThan|OpenParenthesis) Identifier (GreaterThan|CloseParenthesis) Semicolon { (paramlist[0] as SamplerStateInfo).TextureName = (string)$Identifier; return null; }; Sampler_State_MinFilter -> MinFilter Equals TextureFilter Semicolon { (paramlist[0] as SamplerStateInfo).MinFilter = (TextureFilterType)$TextureFilter; return null; }; Sampler_State_MagFilter -> MagFilter Equals TextureFilter Semicolon { (paramlist[0] as SamplerStateInfo).MagFilter = (TextureFilterType)$TextureFilter; return null; }; Sampler_State_MipFilter -> MipFilter Equals TextureFilter Semicolon { (paramlist[0] as SamplerStateInfo).MipFilter = (TextureFilterType)$TextureFilter; return null; }; Sampler_State_Filter -> Filter Equals TextureFilter Semicolon { (paramlist[0] as SamplerStateInfo).Filter = (TextureFilterType)$TextureFilter; return null; }; Sampler_State_AddressU -> AddressU Equals AddressMode Semicolon { (paramlist[0] as SamplerStateInfo).AddressU = (TextureAddressMode)$AddressMode; return null; }; Sampler_State_AddressV -> AddressV Equals AddressMode Semicolon { (paramlist[0] as SamplerStateInfo).AddressV = (TextureAddressMode)$AddressMode; return null; }; Sampler_State_AddressW -> AddressW Equals AddressMode Semicolon { (paramlist[0] as SamplerStateInfo).AddressW = (TextureAddressMode)$AddressMode; return null; }; Sampler_State_BorderColor -> BorderColor Equals HexColor Semicolon { (paramlist[0] as SamplerStateInfo).BorderColor = ParseTreeTools.ParseColor((string)$HexColor); return null; }; Sampler_State_MaxMipLevel -> MaxMipLevel Equals Number Semicolon { (paramlist[0] as SamplerStateInfo).MaxMipLevel = ParseTreeTools.ParseInt((string)$Number); return null; }; Sampler_State_MaxAnisotropy -> MaxAnisotropy Equals Number Semicolon { (paramlist[0] as SamplerStateInfo).MaxAnisotropy = ParseTreeTools.ParseInt((string)$Number); return null; }; Sampler_State_MipLodBias -> MipLodBias Equals Number Semicolon { (paramlist[0] as SamplerStateInfo).MipMapLevelOfDetailBias = ParseTreeTools.ParseFloat((string)$Number); return null; }; Sampler_State_Expression -> Sampler_State_Texture | Sampler_State_MinFilter | Sampler_State_MagFilter | Sampler_State_MipFilter | Sampler_State_Filter | Sampler_State_AddressU | Sampler_State_AddressV | Sampler_State_AddressW | Sampler_State_BorderColor | Sampler_State_MaxMipLevel | Sampler_State_MaxAnisotropy | Sampler_State_MipLodBias; Sampler_Register_Expression -> Colon Register OpenParenthesis Identifier (Comma Identifier (OpenSquareBracket Number CloseSquareBracket)?)? CloseParenthesis { return null; }; Sampler_Declaration_States -> (Equals SamplerState)? OpenBracket Sampler_State_Expression* CloseBracket; Sampler_Declaration -> Sampler Identifier Sampler_Register_Expression* Sampler_Declaration_States? (Semicolon | Comma | CloseParenthesis) { // if there is a comma or closing paren at the end this is a sampler as a parameter of a function if ($Semicolon == null) return null; var sampler = new SamplerStateInfo(); sampler.Name = $Identifier[0] as string; foreach (ParseNode node in Nodes) node.Eval(tree, sampler); var shaderInfo = paramlist[0] as ShaderInfo; shaderInfo.SamplerStates.Add(sampler.Name, sampler); return null; };