| /* | 
 |  * HLSL parser | 
 |  * | 
 |  * Copyright 2008 Stefan Dösinger | 
 |  * Copyright 2012 Matteo Bruni for CodeWeavers | 
 |  * | 
 |  * This library is free software; you can redistribute it and/or | 
 |  * modify it under the terms of the GNU Lesser General Public | 
 |  * License as published by the Free Software Foundation; either | 
 |  * version 2.1 of the License, or (at your option) any later version. | 
 |  * | 
 |  * This library is distributed in the hope that it will be useful, | 
 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
 |  * Lesser General Public License for more details. | 
 |  * | 
 |  * You should have received a copy of the GNU Lesser General Public | 
 |  * License along with this library; if not, write to the Free Software | 
 |  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | 
 |  */ | 
 |  | 
 | %{ | 
 | #include "config.h" | 
 | #include "wine/port.h" | 
 | #include "wine/debug.h" | 
 |  | 
 | #define YY_NO_UNISTD_H | 
 | #include "d3dcompiler_private.h" | 
 | #include "hlsl.tab.h" | 
 |  | 
 | WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser); | 
 |  | 
 | #define YY_USER_ACTION                               \ | 
 |    do {                                              \ | 
 |       hlsl_lloc.first_column = hlsl_ctx.column;      \ | 
 |       hlsl_lloc.first_line = hlsl_ctx.line_no;       \ | 
 |       hlsl_ctx.column += yyleng;                     \ | 
 |    } while(0); | 
 |  | 
 | %} | 
 |  | 
 | %option noyywrap nounput noinput | 
 | %option prefix="hlsl_" | 
 |  | 
 | %x pp pp_line pp_pragma pp_ignore | 
 |  | 
 | RESERVED1               auto|case|catch|char|class|const_cast|default|delete|dynamic_cast|enum | 
 | RESERVED2               explicit|friend|goto|long|mutable|new|operator|private|protected|public | 
 | RESERVED3               reinterpret_cast|short|signed|sizeof|static_cast|template|this|throw|try | 
 | RESERVED4               typename|union|unsigned|using|virtual | 
 |  | 
 | WS                      [ \t] | 
 | NEWLINE                 (\n)|(\r\n) | 
 | DOUBLESLASHCOMMENT      "//"[^\n]* | 
 | STRING                  \"[^\"]*\" | 
 | IDENTIFIER              [A-Za-z_][A-Za-z0-9_]* | 
 |  | 
 | ANY                     (.) | 
 |  | 
 | %% | 
 | {RESERVED1}             { | 
 |                             hlsl_message("Line %u: Reserved keyword \"%s\" used.\n", hlsl_ctx.line_no, yytext); | 
 |                             set_parse_status(&hlsl_ctx.status, PARSE_ERR); | 
 |                         } | 
 | {RESERVED2}             { | 
 |                             hlsl_message("Line %u: Reserved keyword \"%s\" used.\n", hlsl_ctx.line_no, yytext); | 
 |                             set_parse_status(&hlsl_ctx.status, PARSE_ERR); | 
 |                         } | 
 | {RESERVED3}             { | 
 |                             hlsl_message("Line %u: Reserved keyword \"%s\" used.\n", hlsl_ctx.line_no, yytext); | 
 |                             set_parse_status(&hlsl_ctx.status, PARSE_ERR); | 
 |                         } | 
 | {RESERVED4}             { | 
 |                             hlsl_message("Line %u: Reserved keyword \"%s\" used.\n", hlsl_ctx.line_no, yytext); | 
 |                             set_parse_status(&hlsl_ctx.status, PARSE_ERR); | 
 |                         } | 
 |  | 
 | BlendState              {return KW_BLENDSTATE;          } | 
 | break                   {return KW_BREAK;               } | 
 | Buffer                  {return KW_BUFFER;              } | 
 | cbuffer                 {return KW_CBUFFER;             } | 
 | compile                 {return KW_COMPILE;             } | 
 | const                   {return KW_CONST;               } | 
 | continue                {return KW_CONTINUE;            } | 
 | DepthStencilState       {return KW_DEPTHSTENCILSTATE;   } | 
 | DepthStencilView        {return KW_DEPTHSTENCILVIEW;    } | 
 | discard                 {return KW_DISCARD;             } | 
 | do                      {return KW_DO;                  } | 
 | double                  {return KW_DOUBLE;              } | 
 | else                    {return KW_ELSE;                } | 
 | extern                  {return KW_EXTERN;              } | 
 | false                   {return KW_FALSE;               } | 
 | for                     {return KW_FOR;                 } | 
 | GeometryShader          {return KW_GEOMETRYSHADER;      } | 
 | groupshared             {return KW_GROUPSHARED;         } | 
 | if                      {return KW_IF;                  } | 
 | in                      {return KW_IN;                  } | 
 | inline                  {return KW_INLINE;              } | 
 | inout                   {return KW_INOUT;               } | 
 | matrix                  {return KW_MATRIX;              } | 
 | namespace               {return KW_NAMESPACE;           } | 
 | nointerpolation         {return KW_NOINTERPOLATION;     } | 
 | out                     {return KW_OUT;                 } | 
 | pass                    {return KW_PASS;                } | 
 | PixelShader             {return KW_PIXELSHADER;         } | 
 | precise                 {return KW_PRECISE;             } | 
 | RasterizerState         {return KW_RASTERIZERSTATE;     } | 
 | RenderTargetView        {return KW_RENDERTARGETVIEW;    } | 
 | return                  {return KW_RETURN;              } | 
 | register                {return KW_REGISTER;            } | 
 | sampler                 {return KW_SAMPLER;             } | 
 | sampler1D               {return KW_SAMPLER1D;           } | 
 | sampler2D               {return KW_SAMPLER2D;           } | 
 | sampler3D               {return KW_SAMPLER3D;           } | 
 | samplerCUBE             {return KW_SAMPLERCUBE;         } | 
 | sampler_state           {return KW_SAMPLER_STATE;       } | 
 | SamplerComparisonState  {return KW_SAMPLERCOMPARISONSTATE;} | 
 | shared                  {return KW_SHARED;              } | 
 | stateblock              {return KW_STATEBLOCK;          } | 
 | stateblock_state        {return KW_STATEBLOCK_STATE;    } | 
 | static                  {return KW_STATIC;              } | 
 | string                  {return KW_STRING;              } | 
 | struct                  {return KW_STRUCT;              } | 
 | switch                  {return KW_SWITCH;              } | 
 | tbuffer                 {return KW_TBUFFER;             } | 
 | technique               {return KW_TECHNIQUE;           } | 
 | technique10             {return KW_TECHNIQUE10;         } | 
 | texture                 {return KW_TEXTURE;             } | 
 | texture1D               {return KW_TEXTURE1D;           } | 
 | Texture1DArray          {return KW_TEXTURE1DARRAY;      } | 
 | texture2D               {return KW_TEXTURE2D;           } | 
 | Texture2DArray          {return KW_TEXTURE2DARRAY;      } | 
 | Texture2DMS             {return KW_TEXTURE2DMS;         } | 
 | Texture2DMSArray        {return KW_TEXTURE2DMSARRAY;    } | 
 | texture3D               {return KW_TEXTURE3D;           } | 
 | Texture3DArray          {return KW_TEXTURE3DARRAY;      } | 
 | textureCUBE             {return KW_TEXTURECUBE;         } | 
 | true                    {return KW_TRUE;                } | 
 | typedef                 {return KW_TYPEDEF;             } | 
 | uniform                 {return KW_UNIFORM;             } | 
 | vector                  {return KW_VECTOR;              } | 
 | VertexShader            {return KW_VERTEXSHADER;        } | 
 | void                    {return KW_VOID;                } | 
 | volatile                {return KW_VOLATILE;            } | 
 | while                   {return KW_WHILE;               } | 
 |  | 
 | \+\+                    {return OP_INC;                 } | 
 | \-\-                    {return OP_DEC;                 } | 
 | &&                      {return OP_AND;                 } | 
 | \|\|                    {return OP_OR;                  } | 
 | ==                      {return OP_EQ;                  } | 
 | \<\<                    {return OP_LEFTSHIFT;           } | 
 | \<\<=                   {return OP_LEFTSHIFTASSIGN;     } | 
 | \>\>                    {return OP_RIGHTSHIFT;          } | 
 | \>\>=                   {return OP_RIGHTSHIFTASSIGN;    } | 
 | \.\.\.                  {return OP_ELLIPSIS;            } | 
 | \<=                     {return OP_LE;                  } | 
 | \>=                     {return OP_GE;                  } | 
 | !=                      {return OP_NE;                  } | 
 | \+=                     {return OP_ADDASSIGN;           } | 
 | \-=                     {return OP_SUBASSIGN;           } | 
 | \*=                     {return OP_MULASSIGN;           } | 
 | \/=                     {return OP_DIVASSIGN;           } | 
 | %=                      {return OP_MODASSIGN;           } | 
 | &=                      {return OP_ANDASSIGN;           } | 
 | \|=                     {return OP_ORASSIGN;            } | 
 | ^=                      {return OP_XORASSIGN;           } | 
 | ##                      {return OP_UNKNOWN1;            } | 
 | #@                      {return OP_UNKNOWN2;            } | 
 | ::                      {return OP_UNKNOWN3;            } | 
 | \-\>                    {return OP_UNKNOWN4;            } | 
 |  | 
 | column_major            {return KW_COLUMN_MAJOR;        } | 
 | row_major               {return KW_ROW_MAJOR;           } | 
 |  | 
 | {IDENTIFIER}            { | 
 |                             hlsl_lval.name = d3dcompiler_strdup(yytext); | 
 |                             if (get_variable(hlsl_ctx.cur_scope, yytext) | 
 |                                     || find_function(yytext)) | 
 |                                 return VAR_IDENTIFIER; | 
 |                             else if (get_type(hlsl_ctx.cur_scope, yytext, TRUE)) | 
 |                                 return TYPE_IDENTIFIER; | 
 |                             else | 
 |                                 return NEW_IDENTIFIER; | 
 |                         } | 
 |  | 
 | [+-]?[0-9]*\.[0-9]+([eE][+-]?[0-9]+)?[h|H|f|F]? { | 
 |                             hlsl_lval.floatval = atof(yytext); | 
 |                             return C_FLOAT; | 
 |                         } | 
 | [+-]?[0-9]+\.([eE][+-]?[0-9]+)?[h|H|f|F]? { | 
 |                             hlsl_lval.floatval = atof(yytext); | 
 |                             return C_FLOAT; | 
 |                         } | 
 | [+-]?[0-9]+([eE][+-]?[0-9]+)?[h|H|f|F] { | 
 |                             hlsl_lval.floatval = atof(yytext); | 
 |                             return C_FLOAT; | 
 |                         } | 
 | 0x[0-9a-fA-F]+          { | 
 |                             sscanf(yytext, "0x%x", &hlsl_lval.intval); | 
 |                             return C_INTEGER; | 
 |                         } | 
 | 0[0-7]+                 { | 
 |                             sscanf(yytext, "0%o", &hlsl_lval.intval); | 
 |                             return C_INTEGER; | 
 |                         } | 
 | \-?[0-9]+               { | 
 |                             hlsl_lval.intval = (atoi(yytext)); | 
 |                             return C_INTEGER; | 
 |                         } | 
 |  | 
 | {DOUBLESLASHCOMMENT}    {} | 
 |  | 
 | {WS}+                   {} | 
 | {NEWLINE}               { | 
 |                             hlsl_ctx.line_no++; | 
 |                             hlsl_ctx.column = 1; | 
 |                         } | 
 |  | 
 | ^#                      { | 
 |                             BEGIN pp; | 
 |                         } | 
 |  | 
 | <pp>pragma{WS}+         { | 
 |                             TRACE("Got a #pragma.\n"); | 
 |                             BEGIN pp_pragma; | 
 |                         } | 
 | <pp_pragma>pack_matrix{WS}*\({WS}*row_major{WS}*\) { | 
 |                             TRACE("#pragma setting row_major mode.\n"); | 
 |                             hlsl_ctx.matrix_majority = HLSL_ROW_MAJOR; | 
 |                             BEGIN pp_ignore; | 
 |                         } | 
 | <pp_pragma>pack_matrix{WS}*\({WS}*column_major{WS}*\) { | 
 |                             TRACE("#pragma setting column_major mode.\n"); | 
 |                             hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR; | 
 |                             BEGIN pp_ignore; | 
 |                         } | 
 | <pp_pragma>{NEWLINE}    { | 
 |                             FIXME("Unsupported preprocessor #pragma directive at line %u.\n", hlsl_ctx.line_no); | 
 |                             BEGIN INITIAL; | 
 |                         } | 
 | <pp_pragma>{ANY}        {} | 
 | <pp>[0-9]+              { | 
 |                             TRACE("Preprocessor line info.\n"); | 
 |                             BEGIN pp_line; | 
 |                             hlsl_lval.intval = (atoi(yytext)); | 
 |                             return PRE_LINE; | 
 |                         } | 
 | <pp_line>{STRING}       { | 
 |                             char *string = d3dcompiler_strdup(yytext + 1); | 
 |  | 
 |                             BEGIN pp_ignore; | 
 |                             string[strlen(string) - 1] = 0; | 
 |                             hlsl_lval.name = string; | 
 |                             return STRING; | 
 |                         } | 
 | <pp_line>{WS}+          {} | 
 | <pp_line>{NEWLINE}      { | 
 |                             FIXME("Malformed preprocessor line directive?\n"); | 
 |                             BEGIN INITIAL; | 
 |                         } | 
 | <pp_ignore>{NEWLINE}    { | 
 |                             BEGIN INITIAL; | 
 |                         } | 
 | <pp_ignore>{ANY}        {} | 
 | <pp>{NEWLINE}           { | 
 |                             FIXME("Unexpected preprocessor directive.\n"); | 
 |                             BEGIN INITIAL; | 
 |                         } | 
 | <pp>{ANY}               {} | 
 |  | 
 | {ANY}                   { | 
 |                             return yytext[0]; | 
 |                         } | 
 |  | 
 | %% | 
 |  | 
 | struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor, | 
 |         const char *entrypoint, char **messages); | 
 |  | 
 | struct bwriter_shader *parse_hlsl_shader(const char *text, enum shader_type type, DWORD major, DWORD minor, | 
 |         const char *entrypoint, char **messages) | 
 | { | 
 |     struct bwriter_shader *ret = NULL; | 
 |     YY_BUFFER_STATE buffer; | 
 |  | 
 |     buffer = hlsl__scan_string(text); | 
 |     hlsl__switch_to_buffer(buffer); | 
 |  | 
 |     ret = parse_hlsl(type, major, minor, entrypoint, messages); | 
 |  | 
 |     hlsl__delete_buffer(buffer); | 
 |     return ret; | 
 | } |