Merge branch 'texformat-rework'
[mesa.git] / src / mesa / shader / program_lexer.l
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 "prog_instruction.h"
27 #include "prog_statevars.h"
28
29 #include "symbol_table.h"
30 #include "program_parser.h"
31 #include "program_parse.tab.h"
32
33 #define require_ARB_vp (yyextra->mode == ARB_vertex)
34 #define require_ARB_fp (yyextra->mode == ARB_fragment)
35 #define require_NV_fp (yyextra->option.NV_fragment)
36 #define require_shadow (yyextra->option.Shadow)
37 #define require_rect (yyextra->option.TexRect)
38 #define require_texarray (yyextra->option.TexArray)
39
40 #ifndef HAVE_UNISTD_H
41 #define YY_NO_UNISTD_H
42 #endif
43
44 #define return_token_or_IDENTIFIER(condition, token) \
45 do { \
46 if (condition) { \
47 return token; \
48 } else { \
49 yylval->string = return_string(yyextra, yytext); \
50 return IDENTIFIER; \
51 } \
52 } while (0)
53
54 #define return_token_or_DOT(condition, token) \
55 do { \
56 if (condition) { \
57 return token; \
58 } else { \
59 yyless(1); \
60 return DOT; \
61 } \
62 } while (0)
63
64
65 #define return_opcode(condition, token, opcode, len) \
66 do { \
67 if (condition && \
68 _mesa_parse_instruction_suffix(yyextra, \
69 yytext + len, \
70 & yylval->temp_inst)) { \
71 yylval->temp_inst.Opcode = OPCODE_ ## opcode; \
72 return token; \
73 } else { \
74 yylval->string = return_string(yyextra, yytext); \
75 return IDENTIFIER; \
76 } \
77 } while (0)
78
79 #define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
80 SWIZZLE_NIL, SWIZZLE_NIL)
81
82 /**
83 * Send a string to the parser using asm_parser_state::string_dumpster
84 *
85 * Sends a string to the parser using asm_parser_state::string_dumpster as a
86 * temporary storage buffer. Data previously stored in
87 * asm_parser_state::string_dumpster will be lost. If
88 * asm_parser_state::string_dumpster is not large enough to hold the new
89 * string, the buffer size will be increased. The buffer size is \b never
90 * decreased.
91 *
92 * \param state Assembler parser state tracking
93 * \param str String to be passed to the parser
94 *
95 * \return
96 * A pointer to asm_parser_state::string_dumpster on success or \c NULL on
97 * failure. Currently the only failure case is \c ENOMEM.
98 */
99 static char *
100 return_string(struct asm_parser_state *state, const char *str)
101 {
102 const size_t len = strlen(str);
103
104 if (len >= state->dumpster_size) {
105 char *const dumpster = _mesa_realloc(state->string_dumpster,
106 state->dumpster_size,
107 len + 1);
108 if (dumpster == NULL) {
109 return NULL;
110 }
111
112 state->string_dumpster = dumpster;
113 state->dumpster_size = len + 1;
114 }
115
116 memcpy(state->string_dumpster, str, len + 1);
117 return state->string_dumpster;
118 }
119
120
121 static unsigned
122 mask_from_char(char c)
123 {
124 switch (c) {
125 case 'x':
126 case 'r':
127 return WRITEMASK_X;
128 case 'y':
129 case 'g':
130 return WRITEMASK_Y;
131 case 'z':
132 case 'b':
133 return WRITEMASK_Z;
134 case 'w':
135 case 'a':
136 return WRITEMASK_W;
137 }
138
139 return 0;
140 }
141
142 static unsigned
143 swiz_from_char(char c)
144 {
145 switch (c) {
146 case 'x':
147 case 'r':
148 return SWIZZLE_X;
149 case 'y':
150 case 'g':
151 return SWIZZLE_Y;
152 case 'z':
153 case 'b':
154 return SWIZZLE_Z;
155 case 'w':
156 case 'a':
157 return SWIZZLE_W;
158 }
159
160 return 0;
161 }
162
163 static int
164 handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
165 {
166 lval->string = strdup(text);
167
168 return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
169 ? IDENTIFIER : USED_IDENTIFIER;
170 }
171
172 #define YY_USER_ACTION \
173 do { \
174 yylloc->first_column = yylloc->last_column; \
175 yylloc->last_column += yyleng; \
176 if ((yylloc->first_line == 1) \
177 && (yylloc->first_column == 1)) { \
178 yylloc->position = 1; \
179 } else { \
180 yylloc->position += yylloc->last_column - yylloc->first_column; \
181 } \
182 } while(0);
183
184 #define YY_EXTRA_TYPE struct asm_parser_state *
185 %}
186
187 num [0-9]+
188 exp [Ee][-+]?[0-9]+
189 frac "."[0-9]+
190 dot "."[ \t]*
191
192 sz [HRX]?
193 szf [HR]?
194 cc C?
195 sat (_SAT)?
196
197 %option bison-bridge bison-locations reentrant noyywrap
198 %%
199
200 "!!ARBvp1.0" { return ARBvp_10; }
201 "!!ARBfp1.0" { return ARBfp_10; }
202 ADDRESS {
203 yylval->integer = at_address;
204 return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
205 }
206 ALIAS { return ALIAS; }
207 ATTRIB { return ATTRIB; }
208 END { return END; }
209 OPTION { return OPTION; }
210 OUTPUT { return OUTPUT; }
211 PARAM { return PARAM; }
212 TEMP { yylval->integer = at_temp; return TEMP; }
213
214 ABS{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, ABS, 3); }
215 ADD{sz}{cc}{sat} { return_opcode( 1, BIN_OP, ADD, 3); }
216 ARL { return_opcode(require_ARB_vp, ARL, ARL, 3); }
217
218 CMP{sat} { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
219 COS{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
220
221 DDX{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDX, 3); }
222 DDY{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDY, 3); }
223 DP3{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP3, 3); }
224 DP4{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP4, 3); }
225 DPH{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DPH, 3); }
226 DST{szf}{cc}{sat} { return_opcode( 1, BIN_OP, DST, 3); }
227
228 EX2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, EX2, 3); }
229 EXP { return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
230
231 FLR{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FLR, 3); }
232 FRC{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FRC, 3); }
233
234 KIL { return_opcode(require_ARB_fp, KIL, KIL, 3); }
235
236 LIT{szf}{cc}{sat} { return_opcode( 1, VECTOR_OP, LIT, 3); }
237 LG2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, LG2, 3); }
238 LOG { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
239 LRP{sz}{cc}{sat} { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
240
241 MAD{sz}{cc}{sat} { return_opcode( 1, TRI_OP, MAD, 3); }
242 MAX{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MAX, 3); }
243 MIN{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MIN, 3); }
244 MOV{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, MOV, 3); }
245 MUL{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MUL, 3); }
246
247 PK2H { return_opcode(require_NV_fp, VECTOR_OP, PK2H, 4); }
248 PK2US { return_opcode(require_NV_fp, VECTOR_OP, PK2US, 5); }
249 PK4B { return_opcode(require_NV_fp, VECTOR_OP, PK4B, 4); }
250 PK4UB { return_opcode(require_NV_fp, VECTOR_OP, PK4UB, 5); }
251 POW{szf}{cc}{sat} { return_opcode( 1, BINSC_OP, POW, 3); }
252
253 RCP{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RCP, 3); }
254 RFL{szf}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, RFL, 3); }
255 RSQ{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RSQ, 3); }
256
257 SCS{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
258 SEQ{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SEQ, 3); }
259 SFL{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SFL, 3); }
260 SGE{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SGE, 3); }
261 SGT{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SGT, 3); }
262 SIN{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
263 SLE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SLE, 3); }
264 SLT{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SLT, 3); }
265 SNE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SNE, 3); }
266 STR{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, STR, 3); }
267 SUB{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SUB, 3); }
268 SWZ{sat} { return_opcode( 1, SWZ, SWZ, 3); }
269
270 TEX{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
271 TXB{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
272 TXD{cc}{sat} { return_opcode(require_NV_fp, TXD_OP, TXD, 3); }
273 TXP{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
274
275 UP2H{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP2H, 4); }
276 UP2US{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP2US, 5); }
277 UP4B{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP4B, 4); }
278 UP4UB{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP4UB, 5); }
279
280 X2D{szf}{cc}{sat} { return_opcode(require_NV_fp, TRI_OP, X2D, 3); }
281 XPD{sat} { return_opcode( 1, BIN_OP, XPD, 3); }
282
283 vertex { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
284 fragment { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
285 program { return PROGRAM; }
286 state { return STATE; }
287 result { return RESULT; }
288
289 {dot}ambient { return AMBIENT; }
290 {dot}attenuation { return ATTENUATION; }
291 {dot}back { return BACK; }
292 {dot}clip { return_token_or_DOT(require_ARB_vp, CLIP); }
293 {dot}color { return COLOR; }
294 {dot}depth { return_token_or_DOT(require_ARB_fp, DEPTH); }
295 {dot}diffuse { return DIFFUSE; }
296 {dot}direction { return DIRECTION; }
297 {dot}emission { return EMISSION; }
298 {dot}env { return ENV; }
299 {dot}eye { return EYE; }
300 {dot}fogcoord { return FOGCOORD; }
301 {dot}fog { return FOG; }
302 {dot}front { return FRONT; }
303 {dot}half { return HALF; }
304 {dot}inverse { return INVERSE; }
305 {dot}invtrans { return INVTRANS; }
306 {dot}light { return LIGHT; }
307 {dot}lightmodel { return LIGHTMODEL; }
308 {dot}lightprod { return LIGHTPROD; }
309 {dot}local { return LOCAL; }
310 {dot}material { return MATERIAL; }
311 {dot}program { return MAT_PROGRAM; }
312 {dot}matrix { return MATRIX; }
313 {dot}matrixindex { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
314 {dot}modelview { return MODELVIEW; }
315 {dot}mvp { return MVP; }
316 {dot}normal { return_token_or_DOT(require_ARB_vp, NORMAL); }
317 {dot}object { return OBJECT; }
318 {dot}palette { return PALETTE; }
319 {dot}params { return PARAMS; }
320 {dot}plane { return PLANE; }
321 {dot}point { return_token_or_DOT(require_ARB_vp, POINT_TOK); }
322 {dot}pointsize { return_token_or_DOT(require_ARB_vp, POINTSIZE); }
323 {dot}position { return POSITION; }
324 {dot}primary { return PRIMARY; }
325 {dot}projection { return PROJECTION; }
326 {dot}range { return_token_or_DOT(require_ARB_fp, RANGE); }
327 {dot}row { return ROW; }
328 {dot}scenecolor { return SCENECOLOR; }
329 {dot}secondary { return SECONDARY; }
330 {dot}shininess { return SHININESS; }
331 {dot}size { return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
332 {dot}specular { return SPECULAR; }
333 {dot}spot { return SPOT; }
334 {dot}texcoord { return TEXCOORD; }
335 {dot}texenv { return_token_or_DOT(require_ARB_fp, TEXENV); }
336 {dot}texgen { return_token_or_DOT(require_ARB_vp, TEXGEN); }
337 {dot}q { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
338 {dot}s { return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
339 {dot}t { return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
340 {dot}texture { return TEXTURE; }
341 {dot}transpose { return TRANSPOSE; }
342 {dot}attrib { return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
343 {dot}weight { return_token_or_DOT(require_ARB_vp, WEIGHT); }
344
345 texture { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
346 1D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
347 2D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
348 3D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
349 CUBE { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
350 RECT { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
351 SHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
352 SHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
353 SHADOWRECT { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
354 ARRAY1D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
355 ARRAY2D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
356 ARRAYSHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
357 ARRAYSHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
358
359 [_a-zA-Z$][_a-zA-Z0-9$]* { return handle_ident(yyextra, yytext, yylval); }
360
361 ".." { return DOT_DOT; }
362
363 {num} {
364 yylval->integer = strtol(yytext, NULL, 10);
365 return INTEGER;
366 }
367 {num}?{frac}{exp}? {
368 yylval->real = _mesa_strtod(yytext, NULL);
369 return REAL;
370 }
371 {num}"."/[^.] {
372 yylval->real = _mesa_strtod(yytext, NULL);
373 return REAL;
374 }
375 {num}{exp} {
376 yylval->real = _mesa_strtod(yytext, NULL);
377 return REAL;
378 }
379 {num}"."{exp} {
380 yylval->real = _mesa_strtod(yytext, NULL);
381 return REAL;
382 }
383
384 ".xyzw" {
385 yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
386 yylval->swiz_mask.mask = WRITEMASK_XYZW;
387 return MASK4;
388 }
389
390 ".xy"[zw] {
391 yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
392 yylval->swiz_mask.mask = WRITEMASK_XY
393 | mask_from_char(yytext[3]);
394 return MASK3;
395 }
396 ".xzw" {
397 yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
398 yylval->swiz_mask.mask = WRITEMASK_XZW;
399 return MASK3;
400 }
401 ".yzw" {
402 yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
403 yylval->swiz_mask.mask = WRITEMASK_YZW;
404 return MASK3;
405 }
406
407 ".x"[yzw] {
408 yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
409 yylval->swiz_mask.mask = WRITEMASK_X
410 | mask_from_char(yytext[2]);
411 return MASK2;
412 }
413 ".y"[zw] {
414 yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
415 yylval->swiz_mask.mask = WRITEMASK_Y
416 | mask_from_char(yytext[2]);
417 return MASK2;
418 }
419 ".zw" {
420 yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
421 yylval->swiz_mask.mask = WRITEMASK_ZW;
422 return MASK2;
423 }
424
425 "."[xyzw] {
426 const unsigned s = swiz_from_char(yytext[1]);
427 yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
428 yylval->swiz_mask.mask = mask_from_char(yytext[1]);
429 return MASK1;
430 }
431
432 "."[xyzw]{4} {
433 yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
434 swiz_from_char(yytext[2]),
435 swiz_from_char(yytext[3]),
436 swiz_from_char(yytext[4]));
437 yylval->swiz_mask.mask = 0;
438 return SWIZZLE;
439 }
440
441 ".rgba" {
442 yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
443 yylval->swiz_mask.mask = WRITEMASK_XYZW;
444 return_token_or_DOT(require_ARB_fp, MASK4);
445 }
446
447 ".rg"[ba] {
448 yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
449 yylval->swiz_mask.mask = WRITEMASK_XY
450 | mask_from_char(yytext[3]);
451 return_token_or_DOT(require_ARB_fp, MASK3);
452 }
453 ".rba" {
454 yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
455 yylval->swiz_mask.mask = WRITEMASK_XZW;
456 return_token_or_DOT(require_ARB_fp, MASK3);
457 }
458 ".gba" {
459 yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
460 yylval->swiz_mask.mask = WRITEMASK_YZW;
461 return_token_or_DOT(require_ARB_fp, MASK3);
462 }
463
464 ".r"[gba] {
465 yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
466 yylval->swiz_mask.mask = WRITEMASK_X
467 | mask_from_char(yytext[2]);
468 return_token_or_DOT(require_ARB_fp, MASK2);
469 }
470 ".g"[ba] {
471 yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
472 yylval->swiz_mask.mask = WRITEMASK_Y
473 | mask_from_char(yytext[2]);
474 return_token_or_DOT(require_ARB_fp, MASK2);
475 }
476 ".ba" {
477 yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
478 yylval->swiz_mask.mask = WRITEMASK_ZW;
479 return_token_or_DOT(require_ARB_fp, MASK2);
480 }
481
482 "."[gba] {
483 const unsigned s = swiz_from_char(yytext[1]);
484 yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
485 yylval->swiz_mask.mask = mask_from_char(yytext[1]);
486 return_token_or_DOT(require_ARB_fp, MASK1);
487 }
488
489
490 ".r" {
491 if (require_ARB_vp) {
492 return TEXGEN_R;
493 } else {
494 yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
495 SWIZZLE_X, SWIZZLE_X);
496 yylval->swiz_mask.mask = WRITEMASK_X;
497 return MASK1;
498 }
499 }
500
501 "."[rgba]{4} {
502 yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
503 swiz_from_char(yytext[2]),
504 swiz_from_char(yytext[3]),
505 swiz_from_char(yytext[4]));
506 yylval->swiz_mask.mask = 0;
507 return_token_or_DOT(require_ARB_fp, SWIZZLE);
508 }
509
510 "." { return DOT; }
511
512 \n {
513 yylloc->first_line++;
514 yylloc->first_column = 1;
515 yylloc->last_line++;
516 yylloc->last_column = 1;
517 yylloc->position++;
518 }
519 [ \t\r]+ /* eat whitespace */ ;
520 #.*$ /* eat comments */ ;
521 . { return yytext[0]; }
522 %%
523
524 void
525 _mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
526 const char *string, size_t len)
527 {
528 yylex_init_extra(state, scanner);
529 yy_scan_bytes(string, len, *scanner);
530 }
531
532 void
533 _mesa_program_lexer_dtor(void *scanner)
534 {
535 yylex_destroy(scanner);
536 }