private void ParseTechnique(UnifiedShaderInfo info, List<UnifiedShaderToken> tokens)
        {
            var name = ConsumeToken(tokens);
            ExpectToken(name, UnifiedShaderTokenType.StringToken);
            ExpectToken(ConsumeToken(tokens), UnifiedShaderTokenType.OpenBrace);

            var technique = new TechniqueInfo
            {
                Name = name.Text,
                Passes = new List<PassInfo>()
            };

            while (tokens[0].TokenType == UnifiedShaderTokenType.StringToken &&
                   tokens[0].Text == "pass")
            {
                var pass = new PassInfo();
                ExpectToken(ConsumeToken(tokens), "pass");
                var passName = ConsumeToken(tokens);
                ExpectToken(passName, UnifiedShaderTokenType.StringToken);
                pass.Name = passName.Text;
                ParsePass(pass, tokens);
                technique.Passes.Add(pass);
            }

            info.Techniques.Add(technique);

            ExpectToken(ConsumeToken(tokens), UnifiedShaderTokenType.CloseBrace);
        }
 private void ParseTopLevel(UnifiedShaderInfo info, List<UnifiedShaderToken> tokens)
 {
     while (tokens.Count > 0)
     {
         var token = ConsumeToken(tokens);
         switch (token.TokenType)
         {
             case UnifiedShaderTokenType.VersionDeclaration:
                 break;
             case UnifiedShaderTokenType.StringToken:
                 switch (token.Text)
                 {
                     case "cbuffers":
                         ParseConstantBuffers(info, tokens);
                         break;
                     case "parameters":
                         ParseParameters(info, tokens);
                         break;
                     case "shaders":
                         ParseShaders(info, tokens);
                         break;
                     case "technique":
                         ParseTechnique(info, tokens);
                         break;
                     default:
                         throw new UnifiedShaderParsingUnexpectedTokenException(token, "cbuffers", "parameters",
                             "shaders", "technique");
                 }
                 break;
             default:
                 throw new UnifiedShaderParsingUnexpectedTokenException(token,
                     UnifiedShaderTokenType.VersionDeclaration, UnifiedShaderTokenType.StringToken);
         }
     }
 }
        public UnifiedShaderInfo Parse(string input)
        {
            var tokens = Lex(input);
            var info = new UnifiedShaderInfo
            {
                ConstantBuffers = new List<ConstantBufferInfo>(),
                Parameters = new List<ParameterInfo>(),
                ShaderBlocks = new Dictionary<string, ShaderBlockInfo>(),
                Techniques = new List<TechniqueInfo>()
            };

            ParseTopLevel(info, tokens);

            return info;
        }
        private void ParseConstantBuffers(UnifiedShaderInfo info, List<UnifiedShaderToken> tokens)
        {
            ExpectToken(ConsumeToken(tokens), UnifiedShaderTokenType.OpenBrace);

            while (tokens[0].TokenType == UnifiedShaderTokenType.StringToken && tokens[0].Text == "cbuffer")
            {
                var buffer = new ConstantBufferInfo();
                ParseConstantBuffer(buffer, tokens);
                info.ConstantBuffers.Add(buffer);
            }

            ExpectToken(ConsumeToken(tokens), UnifiedShaderTokenType.CloseBrace);
        }
        private void ParseParameters(UnifiedShaderInfo info, List<UnifiedShaderToken> tokens)
        {
            ExpectToken(ConsumeToken(tokens), UnifiedShaderTokenType.OpenBrace);

            ParseParameterList(info.Parameters, tokens);

            ExpectToken(ConsumeToken(tokens), UnifiedShaderTokenType.CloseBrace);
        }
        private void ParseShaders(UnifiedShaderInfo info, List<UnifiedShaderToken> tokens)
        {
            ExpectToken(ConsumeToken(tokens), UnifiedShaderTokenType.OpenBrace);

            while (tokens[0].TokenType == UnifiedShaderTokenType.LanguageStart)
            {
                var languageStart = ConsumeToken(tokens);
                var languageBlock = ConsumeToken(tokens);
                var languageEnd = ConsumeToken(tokens);
                ExpectToken(languageStart, UnifiedShaderTokenType.LanguageStart);
                ExpectToken(languageBlock, UnifiedShaderTokenType.LanguageBlock);
                ExpectToken(languageEnd, UnifiedShaderTokenType.LanguageEnd);

                if (!info.ShaderBlocks.ContainsKey(languageStart.Text))
                {
                    info.ShaderBlocks[languageStart.Text] = new ShaderBlockInfo
                    {
                        ShaderText = String.Empty
                    };
                }

                info.ShaderBlocks[languageStart.Text].ShaderText += languageBlock.Text;
            }

            ExpectToken(ConsumeToken(tokens), UnifiedShaderTokenType.CloseBrace);
        }