vkd3d-shader/hlsl: Fix floating point literals matching.
[vkd3d/zf.git] / libs / vkd3d-shader / hlsl.l
blob267c8c30483830a51f6d13b5cae3e0c5d6cb298b
1 /*
2  * HLSL parser
3  *
4  * Copyright 2008 Stefan Dösinger
5  * Copyright 2012 Matteo Bruni for CodeWeavers
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
23 #define YY_NO_UNISTD_H
24 #include "hlsl.h"
25 #include "hlsl.tab.h"
27 #define YYSTYPE HLSL_YYSTYPE
28 #define YYLTYPE HLSL_YYLTYPE
30 static void update_location(struct hlsl_ctx *ctx, YYLTYPE *loc);
32 #define YY_USER_ACTION update_location(yyget_extra(yyscanner), yyget_lloc(yyscanner));
36 %option bison-bridge
37 %option bison-locations
38 %option extra-type="struct hlsl_ctx *"
39 %option never-interactive
40 %option noinput
41 %option nounput
42 %option noyywrap
43 %option prefix="hlsl_yy"
44 %option reentrant
46 %x pp pp_line pp_pragma pp_ignore
48 RESERVED1               auto|case|catch|char|class|const_cast|default|delete|dynamic_cast|enum
49 RESERVED2               explicit|friend|goto|long|mutable|new|operator|private|protected|public
50 RESERVED3               reinterpret_cast|short|signed|sizeof|static_cast|template|this|throw|try
51 RESERVED4               typename|union|unsigned|using|virtual
53 WS                      [ \t]
54 NEWLINE                 (\n)|(\r\n)
55 DOUBLESLASHCOMMENT      "//"[^\n]*
56 STRING                  \"[^\"]*\"
57 IDENTIFIER              [A-Za-z_][A-Za-z0-9_]*
59 ANY                     (.)
62 {RESERVED1}             |
63 {RESERVED2}             |
64 {RESERVED3}             |
65 {RESERVED4}             {
66                             struct hlsl_ctx *ctx = yyget_extra(yyscanner);
68                             hlsl_error(ctx, yylloc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
69                                     "Reserved keyword \"%s\" used.", yytext);
70                         }
72 BlendState              {return KW_BLENDSTATE;          }
73 break                   {return KW_BREAK;               }
74 Buffer                  {return KW_BUFFER;              }
75 cbuffer                 {return KW_CBUFFER;             }
76 compile                 {return KW_COMPILE;             }
77 const                   {return KW_CONST;               }
78 continue                {return KW_CONTINUE;            }
79 DepthStencilState       {return KW_DEPTHSTENCILSTATE;   }
80 DepthStencilView        {return KW_DEPTHSTENCILVIEW;    }
81 discard                 {return KW_DISCARD;             }
82 do                      {return KW_DO;                  }
83 double                  {return KW_DOUBLE;              }
84 else                    {return KW_ELSE;                }
85 extern                  {return KW_EXTERN;              }
86 false                   {return KW_FALSE;               }
87 for                     {return KW_FOR;                 }
88 GeometryShader          {return KW_GEOMETRYSHADER;      }
89 groupshared             {return KW_GROUPSHARED;         }
90 if                      {return KW_IF;                  }
91 in                      {return KW_IN;                  }
92 inline                  {return KW_INLINE;              }
93 inout                   {return KW_INOUT;               }
94 matrix                  {return KW_MATRIX;              }
95 namespace               {return KW_NAMESPACE;           }
96 nointerpolation         {return KW_NOINTERPOLATION;     }
97 out                     {return KW_OUT;                 }
98 pass                    {return KW_PASS;                }
99 PixelShader             {return KW_PIXELSHADER;         }
100 precise                 {return KW_PRECISE;             }
101 RasterizerState         {return KW_RASTERIZERSTATE;     }
102 RenderTargetView        {return KW_RENDERTARGETVIEW;    }
103 return                  {return KW_RETURN;              }
104 register                {return KW_REGISTER;            }
105 sampler                 {return KW_SAMPLER;             }
106 sampler1D               {return KW_SAMPLER1D;           }
107 sampler2D               {return KW_SAMPLER2D;           }
108 sampler3D               {return KW_SAMPLER3D;           }
109 samplerCUBE             {return KW_SAMPLERCUBE;         }
110 sampler_state           {return KW_SAMPLER_STATE;       }
111 SamplerComparisonState  {return KW_SAMPLERCOMPARISONSTATE;}
112 SamplerState            {return KW_SAMPLER;             }
113 shared                  {return KW_SHARED;              }
114 stateblock              {return KW_STATEBLOCK;          }
115 stateblock_state        {return KW_STATEBLOCK_STATE;    }
116 static                  {return KW_STATIC;              }
117 string                  {return KW_STRING;              }
118 struct                  {return KW_STRUCT;              }
119 switch                  {return KW_SWITCH;              }
120 tbuffer                 {return KW_TBUFFER;             }
121 technique               {return KW_TECHNIQUE;           }
122 technique10             {return KW_TECHNIQUE10;         }
123 texture                 {return KW_TEXTURE;             }
124 texture1D               {return KW_TEXTURE1D;           }
125 Texture1D               {return KW_TEXTURE1D;           }
126 Texture1DArray          {return KW_TEXTURE1DARRAY;      }
127 texture2D               {return KW_TEXTURE2D;           }
128 Texture2D               {return KW_TEXTURE2D;           }
129 Texture2DArray          {return KW_TEXTURE2DARRAY;      }
130 Texture2DMS             {return KW_TEXTURE2DMS;         }
131 Texture2DMSArray        {return KW_TEXTURE2DMSARRAY;    }
132 texture3D               {return KW_TEXTURE3D;           }
133 Texture3D               {return KW_TEXTURE3D;           }
134 textureCUBE             {return KW_TEXTURECUBE;         }
135 TextureCube             {return KW_TEXTURECUBE;         }
136 TextureCubeArray        {return KW_TEXTURECUBEARRAY;    }
137 true                    {return KW_TRUE;                }
138 typedef                 {return KW_TYPEDEF;             }
139 uniform                 {return KW_UNIFORM;             }
140 vector                  {return KW_VECTOR;              }
141 VertexShader            {return KW_VERTEXSHADER;        }
142 void                    {return KW_VOID;                }
143 volatile                {return KW_VOLATILE;            }
144 while                   {return KW_WHILE;               }
146 \+\+                    {return OP_INC;                 }
147 \-\-                    {return OP_DEC;                 }
148 &&                      {return OP_AND;                 }
149 \|\|                    {return OP_OR;                  }
150 ==                      {return OP_EQ;                  }
151 \<\<                    {return OP_LEFTSHIFT;           }
152 \<\<=                   {return OP_LEFTSHIFTASSIGN;     }
153 \>\>                    {return OP_RIGHTSHIFT;          }
154 \>\>=                   {return OP_RIGHTSHIFTASSIGN;    }
155 \.\.\.                  {return OP_ELLIPSIS;            }
156 \<=                     {return OP_LE;                  }
157 \>=                     {return OP_GE;                  }
158 !=                      {return OP_NE;                  }
159 \+=                     {return OP_ADDASSIGN;           }
160 \-=                     {return OP_SUBASSIGN;           }
161 \*=                     {return OP_MULASSIGN;           }
162 \/=                     {return OP_DIVASSIGN;           }
163 %=                      {return OP_MODASSIGN;           }
164 &=                      {return OP_ANDASSIGN;           }
165 \|=                     {return OP_ORASSIGN;            }
166 ^=                      {return OP_XORASSIGN;           }
167 ##                      {return OP_UNKNOWN1;            }
168 #@                      {return OP_UNKNOWN2;            }
169 ::                      {return OP_UNKNOWN3;            }
170 \-\>                    {return OP_UNKNOWN4;            }
172 column_major            {return KW_COLUMN_MAJOR;        }
173 row_major               {return KW_ROW_MAJOR;           }
175 {IDENTIFIER}            {
176                             struct hlsl_ctx *ctx = yyget_extra(yyscanner);
178                             yylval->name = hlsl_strdup(ctx, yytext);
179                             if (hlsl_get_var(ctx->cur_scope, yytext) || hlsl_get_function(ctx, yytext))
180                                 return VAR_IDENTIFIER;
181                             else if (hlsl_get_type(ctx->cur_scope, yytext, true))
182                                 return TYPE_IDENTIFIER;
183                             else
184                                 return NEW_IDENTIFIER;
185                         }
187 [0-9]*\.[0-9]+([eE][+-]?[0-9]+)?[h|H|f|F]? {
188                             yylval->floatval = atof(yytext);
189                             return C_FLOAT;
190                         }
191 [0-9]+\.([eE][+-]?[0-9]+)?[h|H|f|F]? {
192                             yylval->floatval = atof(yytext);
193                             return C_FLOAT;
194                         }
195 [0-9]+[eE][+-]?[0-9]+[h|H|f|F]? {
196                             yylval->floatval = atof(yytext);
197                             return C_FLOAT;
198                         }
199 0x[0-9a-fA-F]+          {
200                             sscanf(yytext, "0x%x", &yylval->intval);
201                             return C_INTEGER;
202                         }
203 0[0-7]+                 {
204                             sscanf(yytext, "0%o", &yylval->intval);
205                             return C_INTEGER;
206                         }
207 [0-9]+                  {
208                             yylval->intval = (atoi(yytext));
209                             return C_INTEGER;
210                         }
212 {DOUBLESLASHCOMMENT}    {}
214 {WS}+                   {}
215 {NEWLINE}               {
216                             struct hlsl_ctx *ctx = yyget_extra(yyscanner);
218                             ++ctx->location.line;
219                             ctx->location.column = 1;
220                         }
222 ^#                      {
223                             BEGIN(pp);
224                         }
226 <pp>pragma{WS}+         {
227                             BEGIN(pp_pragma);
228                         }
229 <pp_pragma>pack_matrix{WS}*\({WS}*row_major{WS}*\) {
230                             struct hlsl_ctx *ctx = yyget_extra(yyscanner);
232                             TRACE("#pragma setting row_major mode.\n");
233                             ctx->matrix_majority = HLSL_ROW_MAJOR;
234                             BEGIN(pp_ignore);
235                         }
236 <pp_pragma>pack_matrix{WS}*\({WS}*column_major{WS}*\) {
237                             struct hlsl_ctx *ctx = yyget_extra(yyscanner);
239                             TRACE("#pragma setting column_major mode.\n");
240                             ctx->matrix_majority = HLSL_COLUMN_MAJOR;
241                             BEGIN(pp_ignore);
242                         }
243 <pp_pragma>{NEWLINE}    {
244                             struct hlsl_ctx *ctx = yyget_extra(yyscanner);
246                             FIXME("Unsupported preprocessor #pragma directive at line %u.\n", ctx->location.line);
247                             BEGIN(INITIAL);
248                         }
249 <pp_pragma>{ANY}        {}
250 <pp>[0-9]+              {
251                             BEGIN(pp_line);
252                             yylval->intval = (atoi(yytext));
253                             return PRE_LINE;
254                         }
255 <pp_line>{STRING}       {
256                             struct hlsl_ctx *ctx = yyget_extra(yyscanner);
257                             char *string = hlsl_strdup(ctx, yytext + 1);
259                             BEGIN(pp_ignore);
260                             string[strlen(string) - 1] = 0;
261                             yylval->name = string;
262                             return STRING;
263                         }
264 <pp_line>{WS}+          {}
265 <pp_line>{NEWLINE}      {
266                             FIXME("Malformed preprocessor line directive?\n");
267                             BEGIN(INITIAL);
268                         }
269 <pp_ignore>{NEWLINE}    {
270                             BEGIN(INITIAL);
271                         }
272 <pp_ignore>{ANY}        {}
273 <pp>{NEWLINE}           {
274                             FIXME("Unexpected preprocessor directive.\n");
275                             BEGIN(INITIAL);
276                         }
277 <pp>{ANY}               {}
279 {ANY}                   {
280                             return yytext[0];
281                         }
285 static void update_location(struct hlsl_ctx *ctx, YYLTYPE *lloc)
287     *lloc = ctx->location;
288     ctx->location.column += yyget_leng(ctx->scanner);
291 int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hlsl)
293     YY_BUFFER_STATE buffer;
294     int ret;
296     yylex_init_extra(ctx, &ctx->scanner);
297     buffer = yy_scan_bytes(hlsl->code, hlsl->size, ctx->scanner);
298     yy_switch_to_buffer(buffer, ctx->scanner);
300     ret = hlsl_yyparse(ctx->scanner, ctx);
302     yy_delete_buffer(buffer, ctx->scanner);
303     yylex_destroy(ctx->scanner);
304     return ret;