1 %{
2 /*
3  * Copyright © 2009 Intel Corporation
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 #include "main/glheader.h"
25 #include "main/imports.h"
26 #include "program/prog_instruction.h"
27 #include "program/prog_statevars.h"
28 #include "program/symbol_table.h"
29 #include "program/program_parser.h"
30 #include "program/program_parse.tab.h"
31 
32 #define require_ARB_vp (yyextra->mode == ARB_vertex)
33 #define require_ARB_fp (yyextra->mode == ARB_fragment)
34 #define require_NV_fp  (yyextra->option.NV_fragment)
35 #define require_shadow (yyextra->option.Shadow)
36 #define require_rect   (yyextra->option.TexRect)
37 #define require_texarray        (yyextra->option.TexArray)
38 
39 #ifndef HAVE_UNISTD_H
40 #define YY_NO_UNISTD_H
41 #endif
42 
43 #define return_token_or_IDENTIFIER(condition, token)	\
44    do {							\
45       if (condition) {					\
46 	 return token;					\
47       } else {						\
48 	 return handle_ident(yyextra, yytext, yylval);	\
49       }							\
50    } while (0)
51 
52 #define return_token_or_DOT(condition, token)		\
53    do {							\
54       if (condition) {					\
55 	 return token;					\
56       } else {						\
57 	 yyless(1);					\
58 	 return DOT;					\
59       }							\
60    } while (0)
61 
62 
63 #define return_opcode(condition, token, opcode, len)	\
64    do {							\
65       if (condition &&					\
66 	  _mesa_parse_instruction_suffix(yyextra,	\
67 					 yytext + len,	\
68 					 & yylval->temp_inst)) {	\
69 	 yylval->temp_inst.Opcode = OPCODE_ ## opcode;	\
70 	 return token;					\
71       } else {						\
72 	 return handle_ident(yyextra, yytext, yylval);	\
73       }							\
74    } while (0)
75 
76 #define SWIZZLE_INVAL  MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
77 				     SWIZZLE_NIL, SWIZZLE_NIL)
78 
79 static unsigned
mask_from_char(char c)80 mask_from_char(char c)
81 {
82    switch (c) {
83    case 'x':
84    case 'r':
85       return WRITEMASK_X;
86    case 'y':
87    case 'g':
88       return WRITEMASK_Y;
89    case 'z':
90    case 'b':
91       return WRITEMASK_Z;
92    case 'w':
93    case 'a':
94       return WRITEMASK_W;
95    }
96 
97    return 0;
98 }
99 
100 static unsigned
swiz_from_char(char c)101 swiz_from_char(char c)
102 {
103    switch (c) {
104    case 'x':
105    case 'r':
106       return SWIZZLE_X;
107    case 'y':
108    case 'g':
109       return SWIZZLE_Y;
110    case 'z':
111    case 'b':
112       return SWIZZLE_Z;
113    case 'w':
114    case 'a':
115       return SWIZZLE_W;
116    }
117 
118    return 0;
119 }
120 
121 static int
handle_ident(struct asm_parser_state * state,const char * text,YYSTYPE * lval)122 handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
123 {
124    lval->string = strdup(text);
125 
126    return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
127       ? IDENTIFIER : USED_IDENTIFIER;
128 }
129 
130 #define YY_USER_ACTION							\
131    do {									\
132       yylloc->first_column = yylloc->last_column;			\
133       yylloc->last_column += yyleng;					\
134       if ((yylloc->first_line == 1)					\
135 	  && (yylloc->first_column == 1)) {				\
136 	 yylloc->position = 1;						\
137       } else {								\
138 	 yylloc->position += yylloc->last_column - yylloc->first_column; \
139       }									\
140    } while(0);
141 
142 #define YY_NO_INPUT
143 
144 /* Yes, this is intentionally doing nothing. We have this line of code
145 here only to avoid the compiler complaining about an unput function
146 that is defined, but never called. */
147 #define YY_USER_INIT while (0) { unput(0); }
148 
149 #define YY_EXTRA_TYPE struct asm_parser_state *
150 
151 /* Flex defines a couple of functions with no declarations nor the
152 static keyword. Declare them here to avoid a compiler warning. */
153 int yyget_column  (yyscan_t yyscanner);
154 void yyset_column (int  column_no , yyscan_t yyscanner);
155 
156 %}
157 
158 num    [0-9]+
159 exp    [Ee][-+]?[0-9]+
160 frac   "."[0-9]+
161 dot    "."[ \t]*
162 
163 sz     [HRX]?
164 szf    [HR]?
165 cc     C?
166 sat    (_SAT)?
167 
168 %option prefix="_mesa_program_"
169 %option bison-bridge bison-locations reentrant noyywrap
170 %%
171 
172 "!!ARBvp1.0"              { return ARBvp_10; }
173 "!!ARBfp1.0"              { return ARBfp_10; }
174 ADDRESS                   {
175    yylval->integer = at_address;
176    return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
177 }
178 ALIAS                     { return ALIAS; }
179 ATTRIB                    { return ATTRIB; }
180 END                       { return END; }
181 OPTION                    { return OPTION; }
182 OUTPUT                    { return OUTPUT; }
183 PARAM                     { return PARAM; }
184 TEMP                      { yylval->integer = at_temp; return TEMP; }
185 
186 ABS{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, ABS, 3); }
187 ADD{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, ADD, 3); }
188 ARL                { return_opcode(require_ARB_vp, ARL, ARL, 3); }
189 
190 CMP{sat}           { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
191 COS{szf}{cc}{sat}  { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
192 
193 DDX{szf}{cc}{sat}  { return_opcode(require_NV_fp,  VECTOR_OP, DDX, 3); }
194 DDY{szf}{cc}{sat}  { return_opcode(require_NV_fp,  VECTOR_OP, DDY, 3); }
195 DP3{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DP3, 3); }
196 DP4{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DP4, 3); }
197 DPH{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DPH, 3); }
198 DST{szf}{cc}{sat}  { return_opcode(             1, BIN_OP, DST, 3); }
199 
200 EX2{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, EX2, 3); }
201 EXP                { return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
202 
203 FLR{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, FLR, 3); }
204 FRC{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, FRC, 3); }
205 
206 KIL                { return_opcode(require_ARB_fp, KIL, KIL, 3); }
207 
208 LIT{szf}{cc}{sat}  { return_opcode(             1, VECTOR_OP, LIT, 3); }
209 LG2{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, LG2, 3); }
210 LOG                { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
211 LRP{sz}{cc}{sat}   { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
212 
213 MAD{sz}{cc}{sat}   { return_opcode(             1, TRI_OP, MAD, 3); }
214 MAX{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MAX, 3); }
215 MIN{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MIN, 3); }
216 MOV{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, MOV, 3); }
217 MUL{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MUL, 3); }
218 
219 PK2H               { return_opcode(require_NV_fp,  VECTOR_OP, PK2H, 4); }
220 PK2US              { return_opcode(require_NV_fp,  VECTOR_OP, PK2US, 5); }
221 PK4B               { return_opcode(require_NV_fp,  VECTOR_OP, PK4B, 4); }
222 PK4UB              { return_opcode(require_NV_fp,  VECTOR_OP, PK4UB, 5); }
223 POW{szf}{cc}{sat}  { return_opcode(             1, BINSC_OP, POW, 3); }
224 
225 RCP{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, RCP, 3); }
226 RFL{szf}{cc}{sat}  { return_opcode(require_NV_fp,  BIN_OP,    RFL, 3); }
227 RSQ{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, RSQ, 3); }
228 
229 SCS{sat}           { return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
230 SEQ{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SEQ, 3); }
231 SFL{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SFL, 3); }
232 SGE{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SGE, 3); }
233 SGT{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SGT, 3); }
234 SIN{szf}{cc}{sat}  { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
235 SLE{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SLE, 3); }
236 SLT{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SLT, 3); }
237 SNE{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SNE, 3); }
238 STR{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, STR, 3); }
239 SUB{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SUB, 3); }
240 SWZ{sat}           { return_opcode(             1, SWZ, SWZ, 3); }
241 
242 TEX{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
243 TXB{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
244 TXD{cc}{sat}       { return_opcode(require_NV_fp,  TXD_OP, TXD, 3); }
245 TXP{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
246 
247 UP2H{cc}{sat}      { return_opcode(require_NV_fp,  SCALAR_OP, UP2H, 4); }
248 UP2US{cc}{sat}     { return_opcode(require_NV_fp,  SCALAR_OP, UP2US, 5); }
249 UP4B{cc}{sat}      { return_opcode(require_NV_fp,  SCALAR_OP, UP4B, 4); }
250 UP4UB{cc}{sat}     { return_opcode(require_NV_fp,  SCALAR_OP, UP4UB, 5); }
251 
252 X2D{szf}{cc}{sat}  { return_opcode(require_NV_fp,  TRI_OP, X2D, 3); }
253 XPD{sat}           { return_opcode(             1, BIN_OP, XPD, 3); }
254 
255 vertex                    { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
256 fragment                  { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
257 program                   { return PROGRAM; }
258 state                     { return STATE; }
259 result                    { return RESULT; }
260 
261 {dot}ambient              { return AMBIENT; }
262 {dot}attenuation          { return ATTENUATION; }
263 {dot}back                 { return BACK; }
264 {dot}clip                 { return_token_or_DOT(require_ARB_vp, CLIP); }
265 {dot}color                { return COLOR; }
266 {dot}depth                { return_token_or_DOT(require_ARB_fp, DEPTH); }
267 {dot}diffuse              { return DIFFUSE; }
268 {dot}direction            { return DIRECTION; }
269 {dot}emission             { return EMISSION; }
270 {dot}env                  { return ENV; }
271 {dot}eye                  { return EYE; }
272 {dot}fogcoord             { return FOGCOORD; }
273 {dot}fog                  { return FOG; }
274 {dot}front                { return FRONT; }
275 {dot}half                 { return HALF; }
276 {dot}inverse              { return INVERSE; }
277 {dot}invtrans             { return INVTRANS; }
278 {dot}light                { return LIGHT; }
279 {dot}lightmodel           { return LIGHTMODEL; }
280 {dot}lightprod            { return LIGHTPROD; }
281 {dot}local                { return LOCAL; }
282 {dot}material             { return MATERIAL; }
283 {dot}program              { return MAT_PROGRAM; }
284 {dot}matrix               { return MATRIX; }
285 {dot}matrixindex          { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
286 {dot}modelview            { return MODELVIEW; }
287 {dot}mvp                  { return MVP; }
288 {dot}normal               { return_token_or_DOT(require_ARB_vp, NORMAL); }
289 {dot}object               { return OBJECT; }
290 {dot}palette              { return PALETTE; }
291 {dot}params               { return PARAMS; }
292 {dot}plane                { return PLANE; }
293 {dot}point                { return_token_or_DOT(require_ARB_vp, POINT_TOK); }
294 {dot}pointsize            { return_token_or_DOT(require_ARB_vp, POINTSIZE); }
295 {dot}position             { return POSITION; }
296 {dot}primary              { return PRIMARY; }
297 {dot}projection           { return PROJECTION; }
298 {dot}range                { return_token_or_DOT(require_ARB_fp, RANGE); }
299 {dot}row                  { return ROW; }
300 {dot}scenecolor           { return SCENECOLOR; }
301 {dot}secondary            { return SECONDARY; }
302 {dot}shininess            { return SHININESS; }
303 {dot}size                 { return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
304 {dot}specular             { return SPECULAR; }
305 {dot}spot                 { return SPOT; }
306 {dot}texcoord             { return TEXCOORD; }
307 {dot}texenv               { return_token_or_DOT(require_ARB_fp, TEXENV); }
308 {dot}texgen               { return_token_or_DOT(require_ARB_vp, TEXGEN); }
309 {dot}q                    { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
310 {dot}s                    { return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
311 {dot}t                    { return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
312 {dot}texture              { return TEXTURE; }
313 {dot}transpose            { return TRANSPOSE; }
314 {dot}attrib               { return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
315 {dot}weight               { return_token_or_DOT(require_ARB_vp, WEIGHT); }
316 
317 texture                   { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
318 1D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
319 2D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
320 3D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
321 CUBE                      { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
322 RECT                      { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
323 SHADOW1D                  { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
324 SHADOW2D                  { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
325 SHADOWRECT                { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
326 ARRAY1D                   { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
327 ARRAY2D                   { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
328 ARRAYSHADOW1D             { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
329 ARRAYSHADOW2D             { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
330 
331 [_a-zA-Z$][_a-zA-Z0-9$]*  { return handle_ident(yyextra, yytext, yylval); }
332 
333 ".."                      { return DOT_DOT; }
334 
335 {num}                     {
336    yylval->integer = strtol(yytext, NULL, 10);
337    return INTEGER;
338 }
339 {num}?{frac}{exp}?        {
340    yylval->real = _mesa_strtof(yytext, NULL);
341    return REAL;
342 }
343 {num}"."/[^.]             {
344    yylval->real = _mesa_strtof(yytext, NULL);
345    return REAL;
346 }
347 {num}{exp}                {
348    yylval->real = _mesa_strtof(yytext, NULL);
349    return REAL;
350 }
351 {num}"."{exp}             {
352    yylval->real = _mesa_strtof(yytext, NULL);
353    return REAL;
354 }
355 
356 ".xyzw"                   {
357    yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
358    yylval->swiz_mask.mask = WRITEMASK_XYZW;
359    return MASK4;
360 }
361 
362 ".xy"[zw]                 {
363    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
364    yylval->swiz_mask.mask = WRITEMASK_XY
365       | mask_from_char(yytext[3]);
366    return MASK3;
367 }
368 ".xzw"                    {
369    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
370    yylval->swiz_mask.mask = WRITEMASK_XZW;
371    return MASK3;
372 }
373 ".yzw"                    {
374    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
375    yylval->swiz_mask.mask = WRITEMASK_YZW;
376    return MASK3;
377 }
378 
379 ".x"[yzw]                 {
380    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
381    yylval->swiz_mask.mask = WRITEMASK_X
382       | mask_from_char(yytext[2]);
383    return MASK2;
384 }
385 ".y"[zw]                  {
386    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
387    yylval->swiz_mask.mask = WRITEMASK_Y
388       | mask_from_char(yytext[2]);
389    return MASK2;
390 }
391 ".zw"                     {
392    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
393    yylval->swiz_mask.mask = WRITEMASK_ZW;
394    return MASK2;
395 }
396 
397 "."[xyzw]                 {
398    const unsigned s = swiz_from_char(yytext[1]);
399    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
400    yylval->swiz_mask.mask = mask_from_char(yytext[1]);
401    return MASK1;
402 }
403 
404 "."[xyzw]{4}              {
405    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
406 					    swiz_from_char(yytext[2]),
407 					    swiz_from_char(yytext[3]),
408 					    swiz_from_char(yytext[4]));
409    yylval->swiz_mask.mask = 0;
410    return SWIZZLE;
411 }
412 
413 ".rgba"                   {
414    yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
415    yylval->swiz_mask.mask = WRITEMASK_XYZW;
416    return_token_or_DOT(require_ARB_fp, MASK4);
417 }
418 
419 ".rg"[ba]                 {
420    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
421    yylval->swiz_mask.mask = WRITEMASK_XY
422       | mask_from_char(yytext[3]);
423    return_token_or_DOT(require_ARB_fp, MASK3);
424 }
425 ".rba"                    {
426    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
427    yylval->swiz_mask.mask = WRITEMASK_XZW;
428    return_token_or_DOT(require_ARB_fp, MASK3);
429 }
430 ".gba"                    {
431    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
432    yylval->swiz_mask.mask = WRITEMASK_YZW;
433    return_token_or_DOT(require_ARB_fp, MASK3);
434 }
435 
436 ".r"[gba]                 {
437    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
438    yylval->swiz_mask.mask = WRITEMASK_X
439       | mask_from_char(yytext[2]);
440    return_token_or_DOT(require_ARB_fp, MASK2);
441 }
442 ".g"[ba]                  {
443    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
444    yylval->swiz_mask.mask = WRITEMASK_Y
445       | mask_from_char(yytext[2]);
446    return_token_or_DOT(require_ARB_fp, MASK2);
447 }
448 ".ba"                     {
449    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
450    yylval->swiz_mask.mask = WRITEMASK_ZW;
451    return_token_or_DOT(require_ARB_fp, MASK2);
452 }
453 
454 "."[gba]                  {
455    const unsigned s = swiz_from_char(yytext[1]);
456    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
457    yylval->swiz_mask.mask = mask_from_char(yytext[1]);
458    return_token_or_DOT(require_ARB_fp, MASK1);
459 }
460 
461 
462 ".r"                      {
463    if (require_ARB_vp) {
464       return TEXGEN_R;
465    } else {
466       yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
467 						SWIZZLE_X, SWIZZLE_X);
468       yylval->swiz_mask.mask = WRITEMASK_X;
469       return MASK1;
470    }
471 }
472 
473 "."[rgba]{4}              {
474    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
475 					    swiz_from_char(yytext[2]),
476 					    swiz_from_char(yytext[3]),
477 					    swiz_from_char(yytext[4]));
478    yylval->swiz_mask.mask = 0;
479    return_token_or_DOT(require_ARB_fp, SWIZZLE);
480 }
481 
482 "."                       { return DOT; }
483 
484 \n                        {
485    yylloc->first_line++;
486    yylloc->first_column = 1;
487    yylloc->last_line++;
488    yylloc->last_column = 1;
489    yylloc->position++;
490 }
491 [ \t\r]+                  /* eat whitespace */ ;
492 #.*$                      /* eat comments */ ;
493 .                         { return yytext[0]; }
494 %%
495 
496 void
497 _mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
498 			 const char *string, size_t len)
499 {
500    yylex_init_extra(state, scanner);
501    yy_scan_bytes(string, len, *scanner);
502 }
503 
504 void
_mesa_program_lexer_dtor(void * scanner)505 _mesa_program_lexer_dtor(void *scanner)
506 {
507    yylex_destroy(scanner);
508 }
509