blob: d21358bd6d601e595cff93c1848dd294824f2bf7 [file] [log] [blame]
Brian Paul9a0d97a2003-07-18 16:43:45 +00001/*
2 * Mesa 3-D graphics library
3 * Version: 5.1
4 *
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#include "glheader.h"
26#include "context.h"
27#include "hash.h"
28#include "imports.h"
29#include "macros.h"
30#include "mtypes.h"
31#include "nvprogram.h"
32#include "nvvertparse.h"
33#include "nvvertprog.h"
34
35#include "arbvertparse.h"
36
37/**
38 * Overview:
39 *
40 * This is a simple top-down predictive parser. In a nutshell, there are two key
41 * elements to a predictive parser. First, is the 'look ahead' symbol. This is simply
42 * the next token in the input stream. The other component is a stack of symbols.
43 *
44 * Given the grammar, we can derive a look ahead table. This is just a 2D array,
45 * where one axis is the non-terminal on top of the stack and the other axis is
46 * the look ahead. Each entry in the array is the production to apply when the pair
47 * of stack symbol & look ahead is encountered. If no production is listed at
48 * a given entry in the table, a parse error occurs if this combination
49 * is seen.
50 *
51 * Since we want to drive the parsing from a couple of huge tables, we have to
52 * save some information later on for processing (e.g. for code generation).
53 * For this, we explicitly recreate the parse tree representing the derivation.
54 * We can then make several passes over the parse tree to perform all additional
55 * processing, and we can be sure the the parse is valid.
56 *
57 * The stack is initialized by pushing the start symbol onto it. The look ahead
58 * symbol is initially the first token in the program string.
59 *
60 * If there is a non-terminal symbol on top of the stack, the look ahead table
61 * is consulted to find if a production exists for the top of the stack
62 * and the look ahead.
63 *
64 * When we find a matching production, we pop the non-terminal off the top of
65 * the stack (the LHS of the production), and push the tokens on the RHS of
66 * the production onto the stack. Note that we store a pointer to the parse_tree_node
67 * containing the LHS token on the stack. This way, we can setup the children in
68 * the parse tree as we apply the production.
69 *
70 * If there is a terminal symbol on top of the stack, we compare it with the
71 * look ahead symbol. If they match, or we don't care about the value of the
72 * terminal (e.g. we know its an integer, but don't necessairly care what
73 * integer), the terminal symbol is popped off the stack and the look ahead
74 * is advanced.
75 *
76 * There are a few special nasty cases of productions for which we make special
77 * cases. These aren't found in the production/look-ahead tables, but listed
78 * out explicitly.
79 *
80 * After the parse tree has been constructed, we make several recusive passes
81 * over it to perform various tasks.
82 *
83 * The first pass is made to clean up the state bindings. This is done in
84 * parse_tree_fold_bindings(). The goal is to reduce the big mess of a parse tree
85 * created by strings such as:
86 *
87 * result.color.secondary
88 *
89 * and roll them up into one token and fill out some information in a symbol table.
90 * In this case, the token at the root of the derivation becomes BINDING_TOKEN,
91 * and the token attribute is an index into the binding table where this state
92 * is held.
93 *
94 * The next two passes go about associating variables with BINDING_TOKENs. This
95 * takes care of the cases like:
96 *
97 * OUTPUT foo = result.color.secondary;
98 *
99 * by inserting the index in the binding table for result.color.secondary into
100 * the attr field in the identifier table where the 'foo' variable sits.
101 * The second such pass deals with setting up arrays of program parameters,
102 * while the first only deals with scalars.
103 *
104 * We then examine all the information on variables and state that we have
105 * gathered, and layout which 'register' each variable or bit-of-state should use.
106 *
107 *
108 * Finally, we make a recursive pass of the parse tree and generate opcodes
109 * for Mesa to interpret while executing the program.
110 *
111 * It should be noted that each input/stack token has two parts, an 'identifier'
112 * and an 'attribute'. The identifier tells what class the token is, e.g. INTEGER_TOKEN,
113 * or NT_PROGRAM_SINGLE_ITEM_TOKEN. For some tokens, e.g. INTEGER_TOKEN, ID_TOKEN,
114 * FLOAT_TOKEN, or BINDING_TOKEN, the attribute for the token is an index into a table
115 * giving various properties about the token.
116 *
117 */
118
119/**
120 * Here are all of the structs used to hold parse state and symbol
121 * tables used.
122 *
123 * All strings which are not reserved words, floats, ints, or misc
124 * puncuation (ie .) are considered to be [potential] identifiers.
125 * When we encounter such a string while lex'ing, insert it into
126 * the id symbol table, shown below.
127 *
128 * Sometime later, we'll initialize the variable types for identifiers
129 * which really are variables. This gets shoved into the 'type' field.
130 *
131 * For variables, we'll need additional info (e.g. state it is bound to,
132 * variable we're aliased to, etc). This is stored in the 'attr' field.
133 * - For alias variables, the attr is the idx in the id table of
134 * the variable we are bound to.
135 * - For other variables, we need a whole mess of info. This can be
136 * found in the binding symbol table, below. In this case, the
137 * attr field is the idx into the binding table that describes us.
138 * - For uninitialized ids, attr is -1.
139 *
140 * The data field holds the string of the id.
141 *
142 * len is the number of identifiers in the table.
143 */
144typedef struct st_id_table
145{
146 GLint len;
147 GLint *type;
148 GLint *attr;
149 GLubyte **data;
150}
151id_table;
152
153/**
154 * For PARAM arrays, we need to record the contents for use when
155 * laying out registers and loading state.
156 *
157 * len is the number of arrays in the table.
158 *
159 * num_elements[i] is the number of items in array i. In other words, this
160 * is the number of registers it would require when allocating.
161 *
162 * data[i][n] is the state bound to element n in array i. It is an idx into
163 * the binding table
164 */
165typedef struct st_array_table
166{
167 GLint len;
168 GLint *num_elements;
169 GLint **data;
170}
171array_table;
172
173/**
174 * For holding all of the data used to describe an identifier, we have the catch
175 * all binding symbol table.
176 *
177 * len is the number of bound items;
178 *
179 * type[i] tells what we are binding too, e.g. ATTRIB_POSITION, FOG_COLOR, or CONSTANT
180 *
181 * offset[i] gives the matrix number for matrix bindings, e.g. MATRIXROWS_MODELVIEW.
182 * Alternativly, it gives the number of the first parameter for PROGRAM_ENV_* and
183 * PROGRAM_LOCAL_*.
184 *
185 * num_rows[i] gives the number of rows for multiple matrix rows, or the number
186 * of parameters in a env/local array.
187 *
188 * consts gives the 4-GLfloat constant value for bindings of type CONSTANT
189 *
190 * reg_num gives the register number which this binding is held in.
191 */
192typedef struct st_binding_table
193{
194 GLint len;
195 GLint *type;
196 GLint *offset;
197 GLint *row;
198 GLint *num_rows;
199 GLfloat **consts;
200 GLint *reg_num;
201}
202binding_table;
203
204/**
205 * Integers and floats are stored here.
206 */
207typedef struct st_int_table
208{
209 GLint len;
210 GLint *data;
211}
212int_table;
213
214typedef struct st_float_table
215{
216 GLint len;
217 GLdouble *data;
218}
219float_table;
220
221/**
222 * To avoid writing tons of mindless parser code, the parsing is driven by
223 * a few big tables of rules, plus a few special cases. However, this means
224 * that we have to do all of our analysis outside of the parsing step.
225 *
226 * So, the parser will contruct a parse tree describing the program string
227 * which we can then operate on to do things like code generation.
228 *
229 * This struct represents a node in the parse tree.
230 *
231 * If tok is a non-terminal token, tok_attr is not relevant.
232 * If tok is BINDING_TOKEN, tok_attr is the index into the binding table.
233 * if tok is INTEGER_TOKEN or FLOAT_TOKEN, tok_attr is the index in the integer/GLfloat table
234 *
235 * prod_applied is the production number applied to this token in the derivation of
236 * the program string. See arbvp_grammar.txt for a listing of the productions, and
237 * their numbers.
238 */
239typedef struct st_parse_tree_node
240{
241 GLint tok, tok_attr, is_terminal;
242 GLint prod_applied;
243 struct st_parse_tree_node *children[4];
244}
245parse_tree_node;
246
247/** This stores tokens that we lex out
248 */
249typedef struct st_token_list
250{
251 GLint tok, tok_attr;
252 parse_tree_node *pt;
253
254 struct st_token_list *next;
255}
256token_list;
257
258/**
259 * This holds all of the productions in the grammar.
260 *
261 * lhs is a non-terminal token, e.g. NT_PROGRAM_TOKEN.
262 * rhs is either NULL_TOKEN, another non-terminal token, or a terminal token.
263 * In some cases, we need the RHS to be a certain value, e.g. for the dst reg write masks.
264 * For this, key is used to specify the string. If we don't care about the key, just
265 * specify "".
266 * Int/floats are slightly different, "-1" specifies 'we don't care'.
267 *
268 * lhs is not very useful here, but is is convient for sanity sake when specifing productions.
269 */
270typedef struct st_prod_table
271{
272 GLint lhs;
273 GLint rhs[4];
274 GLubyte *key[4];
275}
276prod_table;
277
278/**
279 * This holds the look ahead table to drive the parser. We examine the token on
280 * the top of the stack, as well as the next token in the input stream (the look ahead).
281 * We then match this against the table, and apply the approprate production. If nothing
282 * matches, we have a parse error.
283 *
284 * Here, LHS is the (non-terminal) token to match against the top of the stack.
285 *
286 * la is the token to match against the look ahead.
287 *
288 * If la is ID_TOKEN, we have to match a given keyword (e.g. 'ambient'). This is specified in
289 * la_kw.
290 *
291 * prod_idx is the idx into the prod_table of the production that we are to apply if this
292 * rule matches.
293 */
294typedef struct st_look_ahead_table
295{
296 GLint lhs;
297 GLint la;
298 GLubyte *la_kw;
299 GLint prod_idx;
300}
301look_ahead_table;
302
303/**
304 * This is the general catch-all for the parse state
305 */
306typedef struct st_parse_state
307{
308 GLubyte *str;
309 GLint len;
310
311 /* lex stuff ------ */
312 GLint start_pos, curr_pos;
313 GLint curr_state;
314 /* ---------------- */
315
316 id_table idents;
317 int_table ints;
318 float_table floats;
319 binding_table binds;
320 array_table arrays;
321
322 token_list *stack_head, *stack_free_list;
323
324 parse_tree_node *pt_head;
325}
326parse_state;
327
328/* local prototypes */
329static GLint float_table_add(float_table * tab, GLubyte * str, GLint start,
330 GLint end);
331static GLint int_table_add(int_table * tab, GLubyte * str, GLint start,
332 GLint end);
333static GLint id_table_add(id_table * tab, GLubyte * str, GLint start,
334 GLint end);
335static void parse_tree_free_children(parse_tree_node * ptn);
336
337/**
338 * Here we have a ton of defined terms that we use to identify productions,
339 * terminals, and nonterminals.
340 */
341
342/**
343 * Terminal tokens
344 */
345#define EOF_TOKEN 0
346#define ID_TOKEN 1
347#define ABS_TOKEN 2
348#define ADD_TOKEN 3
349#define ADDRESS_TOKEN 4
350#define ALIAS_TOKEN 5
351#define ARL_TOKEN 6
352#define ATTRIB_TOKEN 7
353
354#define DP3_TOKEN 8
355#define DP4_TOKEN 9
356#define DPH_TOKEN 10
357#define DST_TOKEN 11
358
359#define END_TOKEN 12
360#define EX2_TOKEN 13
361#define EXP_TOKEN 14
362
363#define FLR_TOKEN 15
364#define FRC_TOKEN 16
365
366#define LG2_TOKEN 17
367#define LIT_TOKEN 18
368#define LOG_TOKEN 19
369
370#define MAD_TOKEN 20
371#define MAX_TOKEN 21
372#define MIN_TOKEN 22
373#define MOV_TOKEN 23
374#define MUL_TOKEN 24
375
376#define OPTION_TOKEN 25
377#define OUTPUT_TOKEN 26
378
379#define PARAM_TOKEN 27
380#define POW_TOKEN 28
381
382#define RCP_TOKEN 29
383#define RSQ_TOKEN 30
384
385#define SGE_TOKEN 31
386#define SLT_TOKEN 32
387#define SUB_TOKEN 33
388#define SWZ_TOKEN 34
389
390#define TEMP_TOKEN 35
391
392#define XPD_TOKEN 36
393
394#define SEMICOLON_TOKEN 37
395#define COMMA_TOKEN 38
396#define PLUS_TOKEN 39
397#define MINUS_TOKEN 40
398#define PERIOD_TOKEN 41
399#define DOTDOT_TOKEN 42
400#define LBRACKET_TOKEN 43
401#define RBRACKET_TOKEN 44
402#define LBRACE_TOKEN 45
403#define RBRACE_TOKEN 46
404#define EQUAL_TOKEN 47
405
406#define INTEGER_TOKEN 48
407#define FLOAT_TOKEN 49
408
409#define PROGRAM_TOKEN 50
410#define RESULT_TOKEN 51
411#define STATE_TOKEN 52
412#define VERTEX_TOKEN 53
413
414#define NULL_TOKEN 54
415
416#define BINDING_TOKEN 55
417
418/**
419 * Non-terminal tokens
420 */
421#define NT_PROGRAM_TOKEN 100
422#define NT_OPTION_SEQUENCE_TOKEN 101
423#define NT_OPTION_SEQUENCE2_TOKEN 102
424#define NT_OPTION_TOKEN 103
425#define NT_STATEMENT_SEQUENCE_TOKEN 104
426#define NT_STATEMENT_SEQUENCE2_TOKEN 105
427#define NT_STATEMENT_TOKEN 106
428
429#define NT_INSTRUCTION_TOKEN 107
430#define NT_ARL_INSTRUCTION_TOKEN 108
431#define NT_VECTOROP_INSTRUCTION_TOKEN 109
432#define NT_VECTOROP_TOKEN 110
433#define NT_SCALAROP_INSTRUCTION_TOKEN 111
434#define NT_SCALAROP_TOKEN 112
435#define NT_BINSCOP_INSTRUCTION_TOKEN 113
436#define NT_BINSCOP_INSTRUCTION2_TOKEN 114
437#define NT_BINSCOP_TOKEN 115
438#define NT_BINOP_INSTRUCTION_TOKEN 116
439#define NT_BINOP_INSTRUCTION2_TOKEN 117
440#define NT_BINOP_TOKEN 118
441#define NT_TRIOP_INSTRUCTION_TOKEN 119
442#define NT_TRIOP_INSTRUCTION2_TOKEN 120
443#define NT_TRIOP_INSTRUCTION3_TOKEN 121
444#define NT_TRIOP_TOKEN 122
445#define NT_SWZ_INSTRUCTION_TOKEN 123
446#define NT_SWZ_INSTRUCTION2_TOKEN 124
447
448#define NT_SCALAR_SRC_REG_TOKEN 130
449#define NT_SWIZZLE_SRC_REG_TOKEN 131
450#define NT_MASKED_DST_REG_TOKEN 132
451#define NT_MASKED_ADDR_REG_TOKEN 133
452#define NT_EXTENDED_SWIZZLE_TOKEN 134
453#define NT_EXTENDED_SWIZZLE2_TOKEN 135
454#define NT_EXT_SWIZ_COMP_TOKEN 136
455#define NT_EXT_SWIZ_SEL_TOKEN 137
456#define NT_SRC_REG_TOKEN 138
457#define NT_DST_REG_TOKEN 139
458#define NT_VERTEX_ATTRIB_REG_TOKEN 140
459
460#define NT_TEMPORARY_REG_TOKEN 150
461#define NT_PROG_PARAM_REG_TOKEN 151
462#define NT_PROG_PARAM_SINGLE_TOKEN 152
463#define NT_PROG_PARAM_ARRAY_TOKEN 153
464#define NT_PROG_PARAM_ARRAY_MEM_TOKEN 154
465#define NT_PROG_PARAM_ARRAY_ABS_TOKEN 155
466#define NT_PROG_PARAM_ARRAY_REL_TOKEN 156
467
468#define NT_ADDR_REG_REL_OFFSET_TOKEN 157
469#define NT_ADDR_REG_POS_OFFSET_TOKEN 158
470#define NT_ADDR_REG_NEG_OFFSET_TOKEN 159
471
472#define NT_VERTEX_RESULT_REG_TOKEN 160
473#define NT_ADDR_REG_TOKEN 161
474#define NT_ADDR_COMPONENT_TOKEN 162
475#define NT_ADDR_WRITE_MASK_TOKEN 163
476#define NT_SCALAR_SUFFIX_TOKEN 164
477#define NT_SWIZZLE_SUFFIX_TOKEN 165
478
479#define NT_COMPONENT_TOKEN 166
480#define NT_OPTIONAL_MASK_TOKEN 167
481#define NT_OPTIONAL_MASK2_TOKEN 168
482#define NT_NAMING_STATEMENT_TOKEN 169
483
484#define NT_ATTRIB_STATEMENT_TOKEN 170
485#define NT_VTX_ATTRIB_BINDING_TOKEN 171
486#define NT_VTX_ATTRIB_ITEM_TOKEN 172
487#define NT_VTX_ATTRIB_NUM_TOKEN 173
488#define NT_VTX_OPT_WEIGHT_NUM_TOKEN 174
489#define NT_VTX_WEIGHT_NUM_TOKEN 175
490#define NT_PARAM_STATEMENT_TOKEN 176
491#define NT_PARAM_STATEMENT2_TOKEN 177
492#define NT_OPT_ARRAY_SIZE_TOKEN 178
493#define NT_PARAM_SINGLE_INIT_TOKEN 179
494#define NT_PARAM_MULTIPLE_INIT_TOKEN 180
495#define NT_PARAM_MULT_INIT_LIST_TOKEN 181
496#define NT_PARAM_MULT_INIT_LIST2_TOKEN 182
497#define NT_PARAM_SINGLE_ITEM_DECL_TOKEN 183
498#define NT_PARAM_SINGLE_ITEM_USE_TOKEN 184
499#define NT_PARAM_MULTIPLE_ITEM_TOKEN 185
500#define NT_STATE_MULTIPLE_ITEM_TOKEN 186
501#define NT_STATE_MULTIPLE_ITEM2_TOKEN 187
502#define NT_FOO_TOKEN 188
503#define NT_FOO2_TOKEN 189
504#define NT_FOO3_TOKEN 190
505#define NT_FOO35_TOKEN 191
506#define NT_FOO4_TOKEN 192
507#define NT_STATE_SINGLE_ITEM_TOKEN 193
508#define NT_STATE_SINGLE_ITEM2_TOKEN 194
509#define NT_STATE_MATERIAL_ITEM_TOKEN 195
510#define NT_STATE_MATERIAL_ITEM2_TOKEN 196
511#define NT_STATE_MAT_PROPERTY_TOKEN 197
512#define NT_STATE_LIGHT_ITEM_TOKEN 198
513#define NT_STATE_LIGHT_ITEM2_TOKEN 199
514#define NT_STATE_LIGHT_PROPERTY_TOKEN 200
515#define NT_STATE_SPOT_PROPERTY_TOKEN 201
516#define NT_STATE_LIGHT_MODEL_ITEM_TOKEN 202
517#define NT_STATE_LMOD_PROPERTY_TOKEN 203
518#define NT_STATE_LMOD_PROPERTY2_TOKEN 204
519
520#define NT_STATE_LIGHT_PROD_ITEM_TOKEN 207
521#define NT_STATE_LIGHT_PROD_ITEM15_TOKEN 208
522#define NT_STATE_LIGHT_PROD_ITEM2_TOKEN 209
523#define NT_STATE_LPROD_PROPERTY_TOKEN 210
524#define NT_STATE_LIGHT_NUMBER_TOKEN 211
525#define NT_STATE_TEX_GEN_ITEM_TOKEN 212
526#define NT_STATE_TEX_GEN_ITEM2_TOKEN 213
527#define NT_STATE_TEX_GEN_TYPE_TOKEN 214
528#define NT_STATE_TEX_GEN_COORD_TOKEN 215
529#define NT_STATE_FOG_ITEM_TOKEN 216
530#define NT_STATE_FOG_PROPERTY_TOKEN 217
531
532#define NT_STATE_CLIP_PLANE_ITEM_TOKEN 218
533#define NT_STATE_CLIP_PLANE_ITEM2_TOKEN 219
534#define NT_STATE_CLIP_PLANE_NUM_TOKEN 220
535#define NT_STATE_POINT_ITEM_TOKEN 221
536#define NT_STATE_POINT_PROPERTY_TOKEN 222
537#define NT_STATE_MATRIX_ROW_TOKEN 223
538#define NT_STATE_MATRIX_ROW15_TOKEN 224
539#define NT_STATE_MATRIX_ROW2_TOKEN 225
540#define NT_STATE_MATRIX_ROW3_TOKEN 226
541#define NT_STATE_MAT_MODIFIER_TOKEN 227
542#define NT_STATE_MATRIX_ROW_NUM_TOKEN 228
543#define NT_STATE_MATRIX_NAME_TOKEN 229
544#define NT_STATE_OPT_MOD_MAT_NUM_TOKEN 230
545#define NT_STATE_MOD_MAT_NUM_TOKEN 231
546#define NT_STATE_PALETTE_MAT_NUM_TOKEN 232
547#define NT_STATE_PROGRAM_MAT_NUM_TOKEN 233
548
549#define NT_PROGRAM_SINGLE_ITEM_TOKEN 234
550#define NT_PROGRAM_SINGLE_ITEM2_TOKEN 235
551#define NT_PROGRAM_MULTIPLE_ITEM_TOKEN 236
552#define NT_PROGRAM_MULTIPLE_ITEM2_TOKEN 237
553#define NT_PROG_ENV_PARAMS_TOKEN 238
554#define NT_PROG_ENV_PARAM_NUMS_TOKEN 239
555#define NT_PROG_ENV_PARAM_NUMS2_TOKEN 240
556#define NT_PROG_ENV_PARAM_TOKEN 250
557#define NT_PROG_LOCAL_PARAMS_TOKEN 251
558#define NT_PROG_LOCAL_PARAM_NUMS_TOKEN 252
559#define NT_PROG_LOCAL_PARAM_NUMS2_TOKEN 253
560#define NT_PROG_LOCAL_PARAM_TOKEN 254
561#define NT_PROG_ENV_PARAM_NUM_TOKEN 255
562#define NT_PROG_LOCAL_PARAM_NUM_TOKEN 256
563
564#define NT_PARAM_CONST_DECL_TOKEN 257
565#define NT_PARAM_CONST_USE_TOKEN 258
566#define NT_PARAM_CONST_SCALAR_DECL_TOKEN 259
567#define NT_PARAM_CONST_SCALAR_USE_TOKEN 260
568#define NT_PARAM_CONST_VECTOR_TOKEN 261
569#define NT_PARAM_CONST_VECTOR2_TOKEN 262
570#define NT_PARAM_CONST_VECTOR3_TOKEN 263
571#define NT_PARAM_CONST_VECTOR4_TOKEN 264
572
573#define NT_SIGNED_FLOAT_CONSTANT_TOKEN 265
574#define NT_FLOAT_CONSTANT_TOKEN 266
575#define NT_OPTIONAL_SIGN_TOKEN 267
576
577#define NT_TEMP_STATEMENT_TOKEN 268
578#define NT_ADDRESS_STATEMENT_TOKEN 269
579#define NT_VAR_NAME_LIST_TOKEN 270
580#define NT_OUTPUT_STATEMENT_TOKEN 271
581#define NT_RESULT_BINDING_TOKEN 272
582#define NT_RESULT_BINDING2_TOKEN 273
583#define NT_RESULT_COL_BINDING_TOKEN 274
584#define NT_RESULT_COL_BINDING2_TOKEN 275
585#define NT_RESULT_COL_BINDING3_TOKEN 276
586#define NT_RESULT_COL_BINDING4_TOKEN 277
587#define NT_RESULT_COL_BINDING5_TOKEN 278
588
589#define NT_OPT_FACE_TYPE2_TOKEN 279
590#define NT_OPT_COLOR_TYPE_TOKEN 280
591#define NT_OPT_COLOR_TYPE2_TOKEN 281
592#define NT_OPT_TEX_COORD_NUM_TOKEN 282
593#define NT_TEX_COORD_NUM_TOKEN 283
594
595#define NT_ALIAS_STATEMENT_TOKEN 284
596#define NT_ESTABLISH_NAME_TOKEN 285
597#define NT_ESTABLISHED_NAME_TOKEN 286
598
599#define NT_SWIZZLE_SUFFIX2_TOKEN 287
600#define NT_COMPONENT4_TOKEN 288
601
602/**
603 * FSA States for lex
604 *
605 * XXX: These can be turned into enums
606 */
607#define STATE_BASE 0
608#define STATE_IDENT 1
609
610#define STATE_A 2
611#define STATE_AB 3
612#define STATE_ABS 4
613#define STATE_AD 5
614#define STATE_ADD 6
615#define STATE_ADDR 7
616#define STATE_ADDRE 8
617#define STATE_ADDRES 9
618#define STATE_ADDRESS 10
619#define STATE_AL 11
620#define STATE_ALI 12
621#define STATE_ALIA 13
622#define STATE_ALIAS 14
623#define STATE_AR 15
624#define STATE_ARL 16
625#define STATE_AT 17
626#define STATE_ATT 18
627#define STATE_ATTR 19
628#define STATE_ATTRI 20
629#define STATE_ATTRIB 21
630
631#define STATE_D 22
632#define STATE_DP 23
633#define STATE_DP3 24
634#define STATE_DP4 25
635#define STATE_DPH 26
636#define STATE_DS 27
637#define STATE_DST 28
638
639#define STATE_E 29
640#define STATE_EN 30
641#define STATE_END 31
642#define STATE_EX 32
643#define STATE_EX2 33
644#define STATE_EXP 34
645
646#define STATE_F 35
647#define STATE_FL 36
648#define STATE_FLR 37
649#define STATE_FR 38
650#define STATE_FRC 39
651
652#define STATE_L 40
653#define STATE_LG 41
654#define STATE_LG2 42
655#define STATE_LI 43
656#define STATE_LIT 44
657#define STATE_LO 45
658#define STATE_LOG 46
659
660#define STATE_M 47
661#define STATE_MA 48
662#define STATE_MAD 49
663#define STATE_MAX 50
664#define STATE_MI 51
665#define STATE_MIN 52
666#define STATE_MO 53
667#define STATE_MOV 54
668#define STATE_MU 55
669#define STATE_MUL 56
670
671#define STATE_O 57
672#define STATE_OP 58
673#define STATE_OPT 59
674#define STATE_OPTI 60
675#define STATE_OPTIO 61
676#define STATE_OPTION 62
677#define STATE_OU 63
678#define STATE_OUT 64
679#define STATE_OUTP 65
680#define STATE_OUTPU 66
681#define STATE_OUTPUT 67
682
683#define STATE_P 68
684#define STATE_PA 69
685#define STATE_PAR 70
686#define STATE_PARA 71
687#define STATE_PARAM 72
688#define STATE_PO 73
689#define STATE_POW 74
690
691#define STATE_R 75
692#define STATE_RC 76
693#define STATE_RCP 77
694#define STATE_RS 78
695#define STATE_RSQ 79
696
697#define STATE_S 80
698#define STATE_SG 81
699#define STATE_SGE 82
700#define STATE_SL 83
701#define STATE_SLT 84
702#define STATE_SU 85
703#define STATE_SUB 86
704#define STATE_SW 87
705#define STATE_SWZ 88
706
707#define STATE_T 89
708#define STATE_TE 90
709#define STATE_TEM 91
710#define STATE_TEMP 92
711
712#define STATE_X 93
713#define STATE_XP 94
714#define STATE_XPD 95
715
716#define STATE_N1 96
717#define STATE_N2 97
718#define STATE_N3 98
719#define STATE_N4 99
720#define STATE_N5 100
721#define STATE_N6 101
722#define STATE_N7 102
723
724#define STATE_COMMENT 103
725
726/* LC == lower case, as in 'program' */
727#define STATE_LC_P 104
728#define STATE_LC_PR 105
729#define STATE_LC_PRO 106
730#define STATE_LC_PROG 107
731#define STATE_LC_PROGR 108
732#define STATE_LC_PROGRA 109
733
734#define STATE_LC_R 110
735#define STATE_LC_RE 111
736#define STATE_LC_RES 112
737#define STATE_LC_RESU 113
738#define STATE_LC_RESUL 114
739#define STATE_LC_RESULT 115
740
741#define STATE_LC_S 116
742#define STATE_LC_ST 117
743#define STATE_LC_STA 118
744#define STATE_LC_STAT 119
745#define STATE_LC_STATE 120
746
747#define STATE_LC_V 121
748#define STATE_LC_VE 122
749#define STATE_LC_VER 123
750#define STATE_LC_VERT 124
751#define STATE_LC_VERTE 125
752#define STATE_LC_VERTEX 126
753#define STATE_LC_PROGRAM 127
754
755/**
756 * Error codes
757 */
758#define ARB_VP_ERROR -1
759#define ARB_VP_SUCESS 0
760
761/**
762 * Variable types
763 */
764#define TYPE_NONE 0
765#define TYPE_ATTRIB 1
766#define TYPE_PARAM 2
767#define TYPE_PARAM_SINGLE 3
768#define TYPE_PARAM_ARRAY 4
769#define TYPE_TEMP 5
770#define TYPE_ADDRESS 6
771#define TYPE_OUTPUT 7
772#define TYPE_ALIAS 8
773
774/**
775 * Vertex Attrib Bindings
776 */
777#define ATTRIB_POSITION 1
778#define ATTRIB_WEIGHT 2
779#define ATTRIB_NORMAL 3
780#define ATTRIB_COLOR_PRIMARY 4
781#define ATTRIB_COLOR_SECONDARY 5
782#define ATTRIB_FOGCOORD 6
783#define ATTRIB_TEXCOORD 7
784#define ATTRIB_MATRIXINDEX 8
785#define ATTRIB_ATTRIB 9
786
787/**
788 * Result Bindings
789 */
790#define RESULT_POSITION 10
791#define RESULT_FOGCOORD 11
792#define RESULT_POINTSIZE 12
793#define RESULT_COLOR_FRONT_PRIMARY 13
794#define RESULT_COLOR_FRONT_SECONDARY 14
795#define RESULT_COLOR_BACK_PRIMARY 15
796#define RESULT_COLOR_BACK_SECONDARY 16
797#define RESULT_TEXCOORD 17
798
799/**
800 * Material Property Bindings
801 */
802#define MATERIAL_FRONT_AMBIENT 18
803#define MATERIAL_FRONT_DIFFUSE 19
804#define MATERIAL_FRONT_SPECULAR 20
805#define MATERIAL_FRONT_EMISSION 21
806#define MATERIAL_FRONT_SHININESS 22
807#define MATERIAL_BACK_AMBIENT 23
808#define MATERIAL_BACK_DIFFUSE 24
809#define MATERIAL_BACK_SPECULAR 25
810#define MATERIAL_BACK_EMISSION 26
811#define MATERIAL_BACK_SHININESS 27
812
813/**
814 * Light Property Bindings
815 */
816#define LIGHT_AMBIENT 28
817#define LIGHT_DIFFUSE 29
818#define LIGHT_SPECULAR 30
819#define LIGHT_POSITION 31
820#define LIGHT_ATTENUATION 32
821#define LIGHT_SPOT_DIRECTION 33
822#define LIGHT_HALF 34
823#define LIGHTMODEL_AMBIENT 35
824#define LIGHTMODEL_FRONT_SCENECOLOR 36
825#define LIGHTMODEL_BACK_SCENECOLOR 37
826#define LIGHTPROD_FRONT_AMBIENT 38
827#define LIGHTPROD_FRONT_DIFFUSE 39
828#define LIGHTPROD_FRONT_SPECULAR 40
829#define LIGHTPROD_BACK_AMBIENT 41
830#define LIGHTPROD_BACK_DIFFUSE 42
831#define LIGHTPROD_BACK_SPECULAR 43
832
833/**
834 * Texgen Property Bindings
835 */
836#define TEXGEN_EYE_S 44
837#define TEXGEN_EYE_T 45
838#define TEXGEN_EYE_R 46
839#define TEXGEN_EYE_Q 47
840#define TEXGEN_OBJECT_S 48
841#define TEXGEN_OBJECT_T 49
842#define TEXGEN_OBJECT_R 50
843#define TEXGEN_OBJECT_Q 51
844
845/**
846 * Fog Property Bindings
847 */
848#define FOG_COLOR 52
849#define FOG_PARAMS 53
850
851/**
852 * Clip Property Bindings
853 */
854#define CLIP_PLANE 54
855
856/**
857 * Point Property Bindings
858 */
859#define POINT_SIZE 55
860#define POINT_ATTENUATION 56
861
862/**
863 * Matrix Row Property Bindings
864 */
865#define MATRIXROW_MODELVIEW 57
866#define MATRIXROW_MODELVIEW_INVERSE 58
867#define MATRIXROW_MODELVIEW_INVTRANS 59
868#define MATRIXROW_MODELVIEW_TRANSPOSE 60
869#define MATRIXROW_PROJECTION 61
870#define MATRIXROW_PROJECTION_INVERSE 62
871#define MATRIXROW_PROJECTION_INVTRANS 63
872#define MATRIXROW_PROJECTION_TRANSPOSE 64
873#define MATRIXROW_MVP 65
874#define MATRIXROW_MVP_INVERSE 66
875#define MATRIXROW_MVP_INVTRANS 67
876#define MATRIXROW_MVP_TRANSPOSE 68
877#define MATRIXROW_TEXTURE 69
878#define MATRIXROW_TEXTURE_INVERSE 70
879#define MATRIXROW_TEXTURE_INVTRANS 71
880#define MATRIXROW_TEXTURE_TRANSPOSE 72
881#define MATRIXROW_PALETTE 73
882#define MATRIXROW_PALETTE_INVERSE 74
883#define MATRIXROW_PALETTE_INVTRANS 75
884#define MATRIXROW_PALETTE_TRANSPOSE 76
885#define MATRIXROW_PROGRAM 77
886#define MATRIXROW_PROGRAM_INVERSE 78
887#define MATRIXROW_PROGRAM_INVTRANS 79
888#define MATRIXROW_PROGRAM_TRANSPOSE 80
889
890#define MATRIXROWS_MODELVIEW 81
891#define MATRIXROWS_MODELVIEW_INVERSE 82
892#define MATRIXROWS_MODELVIEW_INVTRANS 83
893#define MATRIXROWS_MODELVIEW_TRANSPOSE 84
894#define MATRIXROWS_PROJECTION 85
895#define MATRIXROWS_PROJECTION_INVERSE 86
896#define MATRIXROWS_PROJECTION_INVTRANS 87
897#define MATRIXROWS_PROJECTION_TRANSPOSE 88
898#define MATRIXROWS_MVP 89
899#define MATRIXROWS_MVP_INVERSE 90
900#define MATRIXROWS_MVP_INVTRANS 91
901#define MATRIXROWS_MVP_TRANSPOSE 92
902#define MATRIXROWS_TEXTURE 93
903#define MATRIXROWS_TEXTURE_INVERSE 94
904#define MATRIXROWS_TEXTURE_INVTRANS 95
905#define MATRIXROWS_TEXTURE_TRANSPOSE 96
906#define MATRIXROWS_PALETTE 97
907#define MATRIXROWS_PALETTE_INVERSE 98
908#define MATRIXROWS_PALETTE_INVTRANS 99
909#define MATRIXROWS_PALETTE_TRANSPOSE 100
910#define MATRIXROWS_PROGRAM 101
911#define MATRIXROWS_PROGRAM_INVERSE 102
912#define MATRIXROWS_PROGRAM_INVTRANS 103
913#define MATRIXROWS_PROGRAM_TRANSPOSE 104
914
915#define PROGRAM_ENV_SINGLE 105
916#define PROGRAM_LOCAL_SINGLE 106
917#define PROGRAM_ENV_MULTI 107
918#define PROGRAM_LOCAL_MULTI 108
919
920#define CONSTANT 109
921
922
923
924
925#define IS_WHITESPACE(c) (c == ' ') || (c == '\t') || (c == '\n')
926#define IS_IDCHAR(c) ((c >= 'A') && (c <= 'Z')) || \
927 ((c >= 'a') && (c <= 'z')) || \
928 (c == '_') || (c == '$')
929#define IS_DIGIT(c) (c >= '0') && (c <= '9')
930#define IS_CD(c) (IS_DIGIT(c)) || (IS_IDCHAR(c))
931
932#define ADV_TO_STATE(state) s->curr_state = state; s->curr_pos++;
933
934#define ADV_OR_FALLBACK(c, state) if (curr == c) { \
935 ADV_TO_STATE(state); \
936 } else {\
937 if (IS_CD(curr)) { \
938 ADV_TO_STATE(STATE_IDENT); \
939 } else \
940 s->curr_state = 1;\
941 }
942
943#define FINISH(tok) *token = tok; s->start_pos = s->curr_pos; s->curr_state = STATE_BASE; return ARB_VP_SUCESS;
944#define ADV_AND_FINISH(tok) *token = tok; s->start_pos = s->curr_pos+1; s->curr_pos++; \
945 s->curr_state = STATE_BASE; return ARB_VP_SUCESS;
946
947#define FINISH_OR_FALLBACK(tok) if (IS_CD(curr)) {\
948 ADV_TO_STATE(STATE_IDENT); \
949 } else { \
950 FINISH(tok)\
951 }
952
953#define NO_KW {"", "", "", ""}
954#define NULL2 NULL_TOKEN, NULL_TOKEN
955#define NULL3 NULL_TOKEN, NULL2
956#define NULL4 NULL2, NULL2
957
958/* This uglyness is the production table. See the prod_table struct definition for a description */
959prod_table ptab[] = {
960 {NT_PROGRAM_TOKEN,
961 {NT_OPTION_SEQUENCE_TOKEN, NT_STATEMENT_SEQUENCE_TOKEN, END_TOKEN, NULL_TOKEN}, NO_KW},
962 {NT_OPTION_SEQUENCE_TOKEN, {NT_OPTION_SEQUENCE2_TOKEN, NULL3}, NO_KW},
963 {NT_OPTION_SEQUENCE2_TOKEN, {NT_OPTION_TOKEN, NT_OPTION_SEQUENCE2_TOKEN, NULL2}, NO_KW},
964 {NT_OPTION_SEQUENCE2_TOKEN, {NULL4}, NO_KW},
965 {NT_OPTION_TOKEN, {OPTION_TOKEN, ID_TOKEN, SEMICOLON_TOKEN, NULL_TOKEN}, NO_KW},
966
967
968 /* 5: */
969 {NT_STATEMENT_SEQUENCE_TOKEN, {NT_STATEMENT_SEQUENCE2_TOKEN, NULL3}, NO_KW},
970 {NT_STATEMENT_SEQUENCE2_TOKEN, {NT_STATEMENT_TOKEN, NT_STATEMENT_SEQUENCE2_TOKEN, NULL2}, NO_KW},
971 {NT_STATEMENT_SEQUENCE2_TOKEN, {NULL4}, NO_KW},
972 {NT_STATEMENT_TOKEN, {NT_INSTRUCTION_TOKEN, SEMICOLON_TOKEN, NULL2}, NO_KW},
973 {NT_STATEMENT_TOKEN, {NT_NAMING_STATEMENT_TOKEN, SEMICOLON_TOKEN, NULL2}, NO_KW},
974
975 /* 10: */
976 {NT_INSTRUCTION_TOKEN, {NT_ARL_INSTRUCTION_TOKEN, NULL3}, NO_KW},
977 {NT_INSTRUCTION_TOKEN, {NT_VECTOROP_INSTRUCTION_TOKEN, NULL3}, NO_KW},
978 {NT_INSTRUCTION_TOKEN, {NT_SCALAROP_INSTRUCTION_TOKEN, NULL3}, NO_KW},
979 {NT_INSTRUCTION_TOKEN, {NT_BINSCOP_INSTRUCTION_TOKEN, NULL3}, NO_KW},
980 {NT_INSTRUCTION_TOKEN, {NT_BINOP_INSTRUCTION_TOKEN, NULL3}, NO_KW},
981
982 /* 15: */
983 {NT_INSTRUCTION_TOKEN, {NT_TRIOP_INSTRUCTION_TOKEN, NULL3}, NO_KW},
984 {NT_INSTRUCTION_TOKEN, {NT_SWZ_INSTRUCTION_TOKEN, NULL3}, NO_KW},
985 {NT_ARL_INSTRUCTION_TOKEN, {ARL_TOKEN, NT_MASKED_ADDR_REG_TOKEN,
986 COMMA_TOKEN, NT_SCALAR_SRC_REG_TOKEN}, NO_KW},
987 {NT_VECTOROP_INSTRUCTION_TOKEN, {NT_VECTOROP_TOKEN, NT_MASKED_DST_REG_TOKEN, COMMA_TOKEN,
988 NT_SWIZZLE_SRC_REG_TOKEN}, NO_KW},
989 {NT_VECTOROP_TOKEN, {ABS_TOKEN, NULL3}, NO_KW},
990
991 /* 20: */
992 {NT_VECTOROP_TOKEN, {FLR_TOKEN, NULL3}, NO_KW},
993 {NT_VECTOROP_TOKEN, {FRC_TOKEN, NULL3}, NO_KW},
994 {NT_VECTOROP_TOKEN, {LIT_TOKEN, NULL3}, NO_KW},
995 {NT_VECTOROP_TOKEN, {MOV_TOKEN, NULL3}, NO_KW},
996 {NT_SCALAROP_INSTRUCTION_TOKEN, {NT_SCALAROP_TOKEN, NT_MASKED_DST_REG_TOKEN, COMMA_TOKEN,
997 NT_SCALAR_SRC_REG_TOKEN}, NO_KW},
998
999 /* 25: */
1000 {NT_SCALAROP_TOKEN, {EX2_TOKEN, NULL3}, NO_KW},
1001 {NT_SCALAROP_TOKEN, {EXP_TOKEN, NULL3}, NO_KW},
1002 {NT_SCALAROP_TOKEN, {LG2_TOKEN, NULL3}, NO_KW},
1003 {NT_SCALAROP_TOKEN, {LOG_TOKEN, NULL3}, NO_KW},
1004 {NT_SCALAROP_TOKEN, {RCP_TOKEN, NULL3}, NO_KW},
1005
1006 /* 30: */
1007 {NT_SCALAROP_TOKEN, {RSQ_TOKEN, NULL3}, NO_KW},
1008 {NT_BINSCOP_INSTRUCTION_TOKEN,
1009 {NT_BINSCOP_TOKEN, NT_MASKED_DST_REG_TOKEN, NT_BINSCOP_INSTRUCTION2_TOKEN,
1010 NULL_TOKEN}, NO_KW},
1011 {NT_BINSCOP_INSTRUCTION2_TOKEN,
1012 {COMMA_TOKEN, NT_SCALAR_SRC_REG_TOKEN, COMMA_TOKEN,
1013 NT_SCALAR_SRC_REG_TOKEN}, NO_KW},
1014 {NT_BINSCOP_TOKEN, {POW_TOKEN, NULL3}, NO_KW},
1015 {NT_BINOP_INSTRUCTION_TOKEN,
1016 {NT_BINOP_TOKEN, NT_MASKED_DST_REG_TOKEN, NT_BINOP_INSTRUCTION2_TOKEN,
1017 NULL_TOKEN}, NO_KW},
1018
1019 /* 35: */
1020 {NT_BINOP_INSTRUCTION2_TOKEN,
1021 {COMMA_TOKEN, NT_SWIZZLE_SRC_REG_TOKEN, COMMA_TOKEN,
1022 NT_SWIZZLE_SRC_REG_TOKEN}, NO_KW},
1023 {NT_BINOP_TOKEN, {ADD_TOKEN, NULL3}, NO_KW},
1024 {NT_BINOP_TOKEN, {DP3_TOKEN, NULL3}, NO_KW},
1025 {NT_BINOP_TOKEN, {DP4_TOKEN, NULL3}, NO_KW},
1026 {NT_BINOP_TOKEN, {DPH_TOKEN, NULL3}, NO_KW},
1027
1028 /* 40: */
1029 {NT_BINOP_TOKEN, {DST_TOKEN, NULL3}, NO_KW},
1030 {NT_BINOP_TOKEN, {MAX_TOKEN, NULL3}, NO_KW},
1031 {NT_BINOP_TOKEN, {MIN_TOKEN, NULL3}, NO_KW},
1032 {NT_BINOP_TOKEN, {MUL_TOKEN, NULL3}, NO_KW},
1033 {NT_BINOP_TOKEN, {SGE_TOKEN, NULL3}, NO_KW},
1034
1035 /* 45: */
1036 {NT_BINOP_TOKEN, {SLT_TOKEN, NULL3}, NO_KW},
1037 {NT_BINOP_TOKEN, {SUB_TOKEN, NULL3}, NO_KW},
1038 {NT_BINOP_TOKEN, {XPD_TOKEN, NULL3}, NO_KW},
1039 {NT_TRIOP_INSTRUCTION_TOKEN,
1040 {NT_TRIOP_TOKEN, NT_MASKED_DST_REG_TOKEN, NT_TRIOP_INSTRUCTION2_TOKEN,
1041 NULL_TOKEN}, NO_KW},
1042 {NT_TRIOP_INSTRUCTION2_TOKEN,
1043 {COMMA_TOKEN, NT_SWIZZLE_SRC_REG_TOKEN, NT_TRIOP_INSTRUCTION3_TOKEN,
1044 NULL_TOKEN}, NO_KW},
1045
1046 /* 50: */
1047 {NT_TRIOP_INSTRUCTION3_TOKEN,
1048 {COMMA_TOKEN, NT_SWIZZLE_SRC_REG_TOKEN, COMMA_TOKEN,
1049 NT_SWIZZLE_SRC_REG_TOKEN}, NO_KW},
1050 {NT_TRIOP_TOKEN, {MAD_TOKEN, NULL3}, NO_KW},
1051 {NT_SWZ_INSTRUCTION_TOKEN,
1052 {SWZ_TOKEN, NT_MASKED_DST_REG_TOKEN, NT_SWZ_INSTRUCTION2_TOKEN,
1053 NULL_TOKEN}, NO_KW},
1054 {NT_SWZ_INSTRUCTION2_TOKEN,
1055 {COMMA_TOKEN, NT_SRC_REG_TOKEN, COMMA_TOKEN, NT_EXTENDED_SWIZZLE_TOKEN},
1056 NO_KW},
1057 {NT_SCALAR_SRC_REG_TOKEN,
1058 {NT_OPTIONAL_SIGN_TOKEN, NT_SRC_REG_TOKEN, NT_SCALAR_SUFFIX_TOKEN,
1059 NULL_TOKEN}, NO_KW},
1060
1061 /* 55 */
1062 {NT_SWIZZLE_SRC_REG_TOKEN,
1063 {NT_OPTIONAL_SIGN_TOKEN, NT_SRC_REG_TOKEN, NT_SWIZZLE_SUFFIX_TOKEN,
1064 NULL_TOKEN}, NO_KW},
1065 {NT_MASKED_DST_REG_TOKEN,
1066 {NT_DST_REG_TOKEN, NT_OPTIONAL_MASK_TOKEN, NULL2}, NO_KW},
1067 {NT_MASKED_ADDR_REG_TOKEN,
1068 {NT_ADDR_REG_TOKEN, NT_ADDR_WRITE_MASK_TOKEN, NULL2}, NO_KW},
1069 {NT_EXTENDED_SWIZZLE_TOKEN,
1070 {NT_EXT_SWIZ_COMP_TOKEN, COMMA_TOKEN, NT_EXT_SWIZ_COMP_TOKEN,
1071 NT_EXTENDED_SWIZZLE2_TOKEN}, NO_KW},
1072 {NT_EXTENDED_SWIZZLE2_TOKEN,
1073 {COMMA_TOKEN, NT_EXT_SWIZ_COMP_TOKEN, COMMA_TOKEN,
1074 NT_EXT_SWIZ_COMP_TOKEN}, NO_KW},
1075
1076 /* 60 */
1077 {NT_EXT_SWIZ_COMP_TOKEN,{NT_OPTIONAL_SIGN_TOKEN, NT_EXT_SWIZ_SEL_TOKEN, NULL2},
1078 NO_KW},
1079 {NT_EXT_SWIZ_SEL_TOKEN, {INTEGER_TOKEN, NULL3}, {"0", "", "", ""}},
1080 {NT_EXT_SWIZ_SEL_TOKEN, {INTEGER_TOKEN, NULL3}, {"1", "", "", ""}},
1081 {NT_EXT_SWIZ_SEL_TOKEN, {NT_COMPONENT_TOKEN, NULL3}, NO_KW},
1082 {NT_SRC_REG_TOKEN, {NT_VERTEX_ATTRIB_REG_TOKEN, NULL3}, NO_KW},
1083
1084 /* 65: */
1085 {NT_SRC_REG_TOKEN, {NT_TEMPORARY_REG_TOKEN, NULL3}, NO_KW},
1086 {NT_SRC_REG_TOKEN, {NT_PROG_PARAM_REG_TOKEN, NULL3}, NO_KW},
1087 {NT_DST_REG_TOKEN, {NT_TEMPORARY_REG_TOKEN, NULL3}, NO_KW},
1088 {NT_DST_REG_TOKEN, {NT_VERTEX_RESULT_REG_TOKEN, NULL3}, NO_KW},
1089 {NT_VERTEX_ATTRIB_REG_TOKEN, {NT_ESTABLISHED_NAME_TOKEN, NULL3}, NO_KW},
1090
1091 /* 70: */
1092 {NT_VERTEX_ATTRIB_REG_TOKEN, {NT_VTX_ATTRIB_BINDING_TOKEN, NULL3}, NO_KW},
1093 {NT_TEMPORARY_REG_TOKEN, {NT_ESTABLISHED_NAME_TOKEN, NULL3}, NO_KW},
1094 {NT_PROG_PARAM_REG_TOKEN, {NT_PROG_PARAM_SINGLE_TOKEN, NULL3}, NO_KW},
1095 {NT_PROG_PARAM_REG_TOKEN,
1096 {NT_PROG_PARAM_ARRAY_TOKEN, LBRACKET_TOKEN, NT_PROG_PARAM_ARRAY_MEM_TOKEN,
1097 RBRACKET_TOKEN}, NO_KW},
1098 {NT_PROG_PARAM_REG_TOKEN, {NT_PARAM_SINGLE_ITEM_USE_TOKEN, NULL3}, NO_KW},
1099
1100 /* 75: */
1101 {NT_PROG_PARAM_SINGLE_TOKEN, {NT_ESTABLISHED_NAME_TOKEN, NULL3}, NO_KW},
1102 {NT_PROG_PARAM_ARRAY_TOKEN, {NT_ESTABLISHED_NAME_TOKEN, NULL3}, NO_KW},
1103 {NT_PROG_PARAM_ARRAY_MEM_TOKEN, {NT_PROG_PARAM_ARRAY_ABS_TOKEN, NULL3}, NO_KW},
1104 {NT_PROG_PARAM_ARRAY_MEM_TOKEN, {NT_PROG_PARAM_ARRAY_REL_TOKEN, NULL3}, NO_KW},
1105 /* -1 matches all */
1106 {NT_PROG_PARAM_ARRAY_ABS_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1107
1108
1109 /* 80: */
1110 {NT_PROG_PARAM_ARRAY_REL_TOKEN,
1111 {NT_ADDR_REG_TOKEN, NT_ADDR_COMPONENT_TOKEN, NT_ADDR_REG_REL_OFFSET_TOKEN,
1112 NULL_TOKEN}, NO_KW},
1113 {NT_ADDR_REG_REL_OFFSET_TOKEN, {NULL4}, NO_KW},
1114 {NT_ADDR_REG_REL_OFFSET_TOKEN,
1115 {PLUS_TOKEN, NT_ADDR_REG_POS_OFFSET_TOKEN, NULL2}, NO_KW},
1116 {NT_ADDR_REG_REL_OFFSET_TOKEN,
1117 {MINUS_TOKEN, NT_ADDR_REG_NEG_OFFSET_TOKEN, NULL2}, NO_KW},
1118 {NT_ADDR_REG_POS_OFFSET_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1119
1120 /* 85: */
1121 {NT_ADDR_REG_NEG_OFFSET_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1122 {NT_VERTEX_RESULT_REG_TOKEN, {NT_ESTABLISHED_NAME_TOKEN, NULL3}, NO_KW},
1123 {NT_VERTEX_RESULT_REG_TOKEN, {NT_RESULT_BINDING_TOKEN, NULL3}, NO_KW},
1124 {NT_ADDR_REG_TOKEN, {NT_ESTABLISHED_NAME_TOKEN, NULL3}, NO_KW},
1125 {NT_ADDR_COMPONENT_TOKEN, {PERIOD_TOKEN, ID_TOKEN, NULL2}, {"", "x", "", ""}},
1126
1127 /* 90: */
1128 {NT_ADDR_WRITE_MASK_TOKEN, {PERIOD_TOKEN, ID_TOKEN, NULL2}, {"", "x", "", ""}},
1129 {NT_SCALAR_SUFFIX_TOKEN, {PERIOD_TOKEN, NT_COMPONENT_TOKEN, NULL2}, {"", "x", "", ""}},
1130 {NT_SWIZZLE_SUFFIX_TOKEN, {NULL4}, NO_KW},
1131 {NT_COMPONENT_TOKEN, {ID_TOKEN, NULL3}, {"x", "", "", ""}},
1132 {NT_COMPONENT_TOKEN, {ID_TOKEN, NULL3}, {"y", "", "", ""}},
1133
1134 /* 95: */
1135 {NT_COMPONENT_TOKEN, {ID_TOKEN, NULL3}, {"z", "", "", ""}},
1136 {NT_COMPONENT_TOKEN, {ID_TOKEN, NULL3}, {"w", "", "", ""}},
1137 {NT_OPTIONAL_MASK_TOKEN, {PERIOD_TOKEN, NT_OPTIONAL_MASK2_TOKEN, NULL2}, NO_KW},
1138 {NT_OPTIONAL_MASK_TOKEN, {NULL4}, NO_KW},
1139 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"x", "", "", ""}},
1140
1141 /* 100: */
1142 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"y", "", "", ""}},
1143 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"xy", "", "", ""}},
1144 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"z", "", "", ""}},
1145 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"xz", "", "", ""}},
1146 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"yz", "", "", ""}},
1147
1148 /* 105: */
1149 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"xyz", "", "", ""}},
1150 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"w", "", "", ""}},
1151 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"xw", "", "", ""}},
1152 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"yw", "", "", ""}},
1153 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"xyw", "", "", ""}},
1154
1155 /* 110: */
1156 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"zw", "", "", ""}},
1157 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"xzw", "", "", ""}},
1158 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"yzw", "", "", ""}},
1159 {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"xyzw", "", "", ""}},
1160 {NT_NAMING_STATEMENT_TOKEN, {NT_ATTRIB_STATEMENT_TOKEN, NULL3}, NO_KW},
1161
1162 /* 115: */
1163 {NT_NAMING_STATEMENT_TOKEN, {NT_PARAM_STATEMENT_TOKEN, NULL3}, NO_KW},
1164 {NT_NAMING_STATEMENT_TOKEN, {NT_TEMP_STATEMENT_TOKEN, NULL3}, NO_KW},
1165 {NT_NAMING_STATEMENT_TOKEN, {NT_ADDRESS_STATEMENT_TOKEN, NULL3}, NO_KW},
1166 {NT_NAMING_STATEMENT_TOKEN, {NT_OUTPUT_STATEMENT_TOKEN, NULL3}, NO_KW},
1167 {NT_NAMING_STATEMENT_TOKEN, {NT_ALIAS_STATEMENT_TOKEN, NULL3}, NO_KW},
1168
1169 /* 120: */
1170 {NT_ATTRIB_STATEMENT_TOKEN,
1171 {ATTRIB_TOKEN, NT_ESTABLISH_NAME_TOKEN, EQUAL_TOKEN, NT_VTX_ATTRIB_BINDING_TOKEN}, NO_KW},
1172 {NT_VTX_ATTRIB_BINDING_TOKEN,
1173 {VERTEX_TOKEN, PERIOD_TOKEN, NT_VTX_ATTRIB_ITEM_TOKEN, NULL_TOKEN}, NO_KW},
1174 {NT_VTX_ATTRIB_ITEM_TOKEN, {ID_TOKEN, NULL3}, {"position", "", "", ""}},
1175 {NT_VTX_ATTRIB_ITEM_TOKEN, {ID_TOKEN, NT_VTX_OPT_WEIGHT_NUM_TOKEN, NULL2},{"weight", "", "", ""}},
1176 {NT_VTX_ATTRIB_ITEM_TOKEN, {ID_TOKEN, NULL3}, {"normal", "", "", ""}},
1177
1178 /* 125: */
1179 {NT_VTX_ATTRIB_ITEM_TOKEN, {ID_TOKEN, NT_OPT_COLOR_TYPE_TOKEN, NULL2},
1180 {"color", "", "", ""}},
1181 {NT_VTX_ATTRIB_ITEM_TOKEN, {ID_TOKEN, NULL3}, {"fogcoord", "", "", ""}},
1182 {NT_VTX_ATTRIB_ITEM_TOKEN, {ID_TOKEN, NT_OPT_TEX_COORD_NUM_TOKEN, NULL2},
1183 {"texcoord", "", "", ""}},
1184 {NT_VTX_ATTRIB_ITEM_TOKEN,
1185 {ID_TOKEN, LBRACKET_TOKEN, NT_VTX_WEIGHT_NUM_TOKEN, RBRACKET_TOKEN},
1186 {"matrixindex", "", "", ""}},
1187 {NT_VTX_ATTRIB_ITEM_TOKEN,
1188 {ID_TOKEN, LBRACKET_TOKEN, NT_VTX_ATTRIB_NUM_TOKEN, RBRACKET_TOKEN},
1189 {"attrib", "", "", ""}},
1190
1191 /* 130: */
1192 {NT_VTX_ATTRIB_NUM_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1193 {NT_VTX_OPT_WEIGHT_NUM_TOKEN, {NULL4}, NO_KW},
1194 {NT_VTX_OPT_WEIGHT_NUM_TOKEN, {LBRACKET_TOKEN, NT_VTX_WEIGHT_NUM_TOKEN, RBRACKET_TOKEN, NULL_TOKEN},
1195 NO_KW},
1196 {NT_VTX_WEIGHT_NUM_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1197 {NT_PARAM_STATEMENT_TOKEN,
1198 {PARAM_TOKEN, NT_ESTABLISH_NAME_TOKEN, NT_PARAM_STATEMENT2_TOKEN,
1199 NULL_TOKEN}, NO_KW},
1200
1201 /* 135: */
1202 {NT_PARAM_STATEMENT2_TOKEN, {NT_PARAM_SINGLE_INIT_TOKEN, NULL3}, NO_KW},
1203 {NT_PARAM_STATEMENT2_TOKEN, {LBRACKET_TOKEN, NT_OPT_ARRAY_SIZE_TOKEN, RBRACKET_TOKEN,
1204 NT_PARAM_MULTIPLE_INIT_TOKEN}, NO_KW},
1205 {NT_OPT_ARRAY_SIZE_TOKEN, {NULL4}, NO_KW},
1206 {NT_OPT_ARRAY_SIZE_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1207 {NT_PARAM_SINGLE_INIT_TOKEN, {EQUAL_TOKEN, NT_PARAM_SINGLE_ITEM_DECL_TOKEN, NULL2},
1208 NO_KW},
1209
1210
1211 /* 140: */
1212 {NT_PARAM_MULTIPLE_INIT_TOKEN,
1213 {EQUAL_TOKEN, LBRACE_TOKEN, NT_PARAM_MULT_INIT_LIST_TOKEN, RBRACE_TOKEN},
1214 NO_KW},
1215 {NT_PARAM_MULT_INIT_LIST_TOKEN,
1216 {NT_PARAM_MULTIPLE_ITEM_TOKEN, NT_PARAM_MULT_INIT_LIST2_TOKEN, NULL2},
1217 NO_KW},
1218 {NT_PARAM_MULT_INIT_LIST2_TOKEN,
1219 {COMMA_TOKEN, NT_PARAM_MULT_INIT_LIST_TOKEN, NULL2},
1220 NO_KW},
1221 {NT_PARAM_MULT_INIT_LIST2_TOKEN, {NULL4}, NO_KW},
1222 {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, {NT_STATE_SINGLE_ITEM_TOKEN, NULL3},
1223 NO_KW},
1224
1225 /* 145: */
1226 {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, {NT_PROGRAM_SINGLE_ITEM_TOKEN, NULL3}, NO_KW},
1227 {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, {NT_PARAM_CONST_DECL_TOKEN, NULL3}, NO_KW},
1228 {NT_PARAM_SINGLE_ITEM_USE_TOKEN, {NT_STATE_SINGLE_ITEM_TOKEN, NULL3}, NO_KW},
1229 {NT_PARAM_SINGLE_ITEM_USE_TOKEN, {NT_PROGRAM_SINGLE_ITEM_TOKEN, NULL3}, NO_KW},
1230 {NT_PARAM_SINGLE_ITEM_USE_TOKEN, {NT_PARAM_CONST_USE_TOKEN, NULL3}, NO_KW},
1231
1232 /* 150: */
1233 {NT_PARAM_MULTIPLE_ITEM_TOKEN, {NT_STATE_MULTIPLE_ITEM_TOKEN, NULL3}, NO_KW},
1234 {NT_PARAM_MULTIPLE_ITEM_TOKEN, {NT_PROGRAM_MULTIPLE_ITEM_TOKEN, NULL3}, NO_KW},
1235 {NT_PARAM_MULTIPLE_ITEM_TOKEN, {NT_PARAM_CONST_DECL_TOKEN, NULL3}, NO_KW},
1236 {NT_STATE_MULTIPLE_ITEM_TOKEN,
1237 {STATE_TOKEN, PERIOD_TOKEN, NT_STATE_MULTIPLE_ITEM2_TOKEN, NULL_TOKEN},
1238 NO_KW},
1239 {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_MATERIAL_ITEM_TOKEN, NULL3}, NO_KW},
1240
1241 /* 155: */
1242 {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_LIGHT_ITEM_TOKEN, NULL3}, NO_KW},
1243 {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_LIGHT_MODEL_ITEM_TOKEN, NULL3}, NO_KW},
1244 {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_LIGHT_PROD_ITEM_TOKEN, NULL3}, NO_KW},
1245 {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_TEX_GEN_ITEM_TOKEN, NULL3}, NO_KW},
1246 {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_FOG_ITEM_TOKEN, NULL3}, NO_KW},
1247
1248 /* 160: */
1249 {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_CLIP_PLANE_ITEM_TOKEN, NULL3}, NO_KW},
1250 {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_POINT_ITEM_TOKEN, NULL3}, NO_KW},
1251 {NT_STATE_MULTIPLE_ITEM2_TOKEN,
1252 {ID_TOKEN, PERIOD_TOKEN, NT_STATE_MATRIX_NAME_TOKEN, NT_FOO_TOKEN},
1253 {"matrix", "", "", ""}},
1254 {NT_FOO_TOKEN, {PERIOD_TOKEN, NT_FOO2_TOKEN, NULL2}, NO_KW},
1255 {NT_FOO2_TOKEN, {NT_STATE_MAT_MODIFIER_TOKEN, NT_FOO3_TOKEN, NULL2}, NO_KW},
1256
1257 /* 165: */
1258 {NT_FOO2_TOKEN, {ID_TOKEN, LBRACKET_TOKEN, NT_STATE_MATRIX_ROW_NUM_TOKEN, NT_FOO4_TOKEN},
1259 {"row", "", "", ""}},
1260 {NT_FOO3_TOKEN, {NULL4}, NO_KW},
1261 {NT_FOO3_TOKEN, {PERIOD_TOKEN, ID_TOKEN, LBRACKET_TOKEN, NT_FOO35_TOKEN},
1262 {"", "row", "", ""}},
1263 {NT_FOO35_TOKEN, {NT_STATE_MATRIX_ROW_NUM_TOKEN, NT_FOO4_TOKEN, NULL2},
1264 NO_KW},
1265 {NT_FOO4_TOKEN, {RBRACKET_TOKEN, NULL3}, NO_KW},
1266
1267 /* 170: */
1268 {NT_FOO4_TOKEN, {DOTDOT_TOKEN, NT_STATE_MATRIX_ROW_NUM_TOKEN, RBRACKET_TOKEN, NULL_TOKEN},
1269 NO_KW},
1270 {NT_STATE_SINGLE_ITEM_TOKEN,
1271 {STATE_TOKEN, PERIOD_TOKEN, NT_STATE_SINGLE_ITEM2_TOKEN, NULL_TOKEN},
1272 NO_KW},
1273 {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_MATERIAL_ITEM_TOKEN, NULL3},
1274 NO_KW},
1275 {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_LIGHT_ITEM_TOKEN, NULL3},
1276 NO_KW},
1277 {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_LIGHT_MODEL_ITEM_TOKEN, NULL3},
1278 NO_KW},
1279
1280 /* 175: */
1281 {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_LIGHT_PROD_ITEM_TOKEN, NULL3}, NO_KW},
1282 {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_TEX_GEN_ITEM_TOKEN, NULL3}, NO_KW},
1283 {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_FOG_ITEM_TOKEN, NULL3}, NO_KW},
1284 {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_CLIP_PLANE_ITEM_TOKEN, NULL3}, NO_KW},
1285 {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_POINT_ITEM_TOKEN, NULL3}, NO_KW},
1286
1287 /* 180: */
1288 {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_MATRIX_ROW_TOKEN, NULL3}, NO_KW},
1289 {NT_STATE_MATERIAL_ITEM_TOKEN,
1290 {ID_TOKEN, PERIOD_TOKEN, NT_STATE_MATERIAL_ITEM2_TOKEN, NULL_TOKEN},
1291 {"material", "", "", ""}},
1292 {NT_STATE_MATERIAL_ITEM2_TOKEN, {NT_STATE_MAT_PROPERTY_TOKEN, NULL3},
1293 NO_KW},
1294 {NT_STATE_MATERIAL_ITEM2_TOKEN,
1295 {PERIOD_TOKEN, NT_OPT_FACE_TYPE2_TOKEN, PERIOD_TOKEN,
1296 NT_STATE_MAT_PROPERTY_TOKEN}, NO_KW},
1297 {NT_STATE_MAT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"ambient", "", "", ""}},
1298
1299 /* 185 */
1300 {NT_STATE_MAT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"diffuse", "", "", ""}},
1301 {NT_STATE_MAT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"specular", "", "", ""}},
1302 {NT_STATE_MAT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"emission", "", "", ""}},
1303 {NT_STATE_MAT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"shininess", "", "", ""}},
1304 {NT_STATE_LIGHT_ITEM_TOKEN,
1305 {ID_TOKEN, LBRACKET_TOKEN, NT_STATE_LIGHT_NUMBER_TOKEN,
1306 NT_STATE_LIGHT_ITEM2_TOKEN}, {"light", "", "", ""}},
1307
1308 /* 190: */
1309 {NT_STATE_LIGHT_ITEM2_TOKEN, {RBRACKET_TOKEN, PERIOD_TOKEN, NT_STATE_LIGHT_PROPERTY_TOKEN, NULL_TOKEN},
1310 NO_KW},
1311 {NT_STATE_LIGHT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"ambient", "", "", ""}},
1312 {NT_STATE_LIGHT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"diffuse", "", "", ""}},
1313 {NT_STATE_LIGHT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"specular", "", "", ""}},
1314 {NT_STATE_LIGHT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"position", "", "", ""}},
1315
1316 /* 195: */
1317 {NT_STATE_LIGHT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"attenuation", "", "", ""}},
1318 {NT_STATE_LIGHT_PROPERTY_TOKEN,
1319 {ID_TOKEN, PERIOD_TOKEN, NT_STATE_SPOT_PROPERTY_TOKEN, NULL_TOKEN},
1320 {"spot", "", "", ""}},
1321 {NT_STATE_LIGHT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"half", "", "", ""}},
1322 {NT_STATE_SPOT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"direction", "", "", ""}},
1323 {NT_STATE_LIGHT_MODEL_ITEM_TOKEN,
1324 {ID_TOKEN, NT_STATE_LMOD_PROPERTY_TOKEN, NULL2}, {"lightmodel", "", "", ""}},
1325
1326 /* 200: */
1327 {NT_STATE_LMOD_PROPERTY_TOKEN, {PERIOD_TOKEN, NT_STATE_LMOD_PROPERTY2_TOKEN, NULL2}, NO_KW},
1328 {NT_STATE_LMOD_PROPERTY2_TOKEN, {ID_TOKEN, NULL3}, {"ambient", "", "", ""}},
1329 {NT_STATE_LMOD_PROPERTY2_TOKEN, {ID_TOKEN, NULL3}, {"scenecolor", "", "", ""}},
1330 {NT_STATE_LMOD_PROPERTY2_TOKEN,
1331 {NT_OPT_FACE_TYPE2_TOKEN, PERIOD_TOKEN, ID_TOKEN, NULL_TOKEN},
1332 {"scenecolor", "", "", ""}},
1333 {NT_STATE_LIGHT_PROD_ITEM_TOKEN,
1334 {ID_TOKEN, LBRACKET_TOKEN, NT_STATE_LIGHT_NUMBER_TOKEN,
1335 NT_STATE_LIGHT_PROD_ITEM15_TOKEN}, {"lightprod", "", "", ""}},
1336
1337 /* 205: */
1338 {NT_STATE_LIGHT_PROD_ITEM15_TOKEN,
1339 {RBRACKET_TOKEN, PERIOD_TOKEN, NT_STATE_LIGHT_PROD_ITEM2_TOKEN, NULL_TOKEN}, NO_KW},
1340 {NT_STATE_LIGHT_PROD_ITEM2_TOKEN, {NT_STATE_LPROD_PROPERTY_TOKEN, NULL3}, NO_KW},
1341 {NT_STATE_LIGHT_PROD_ITEM2_TOKEN,
1342 {NT_OPT_FACE_TYPE2_TOKEN, PERIOD_TOKEN, NT_STATE_LPROD_PROPERTY_TOKEN, NULL_TOKEN}, NO_KW},
1343 {NT_STATE_LPROD_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"diffuse", "", "", ""}},
1344 {NT_STATE_LPROD_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"ambient", "", "", ""}},
1345
1346 /* 210: */
1347 {NT_STATE_LPROD_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"specular", "", "", ""}},
1348 {NT_STATE_LIGHT_NUMBER_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1349 {NT_STATE_TEX_GEN_ITEM_TOKEN, {ID_TOKEN, NT_OPT_TEX_COORD_NUM_TOKEN,
1350 NT_STATE_TEX_GEN_ITEM2_TOKEN, NULL_TOKEN}, {"texgen", "", "", ""}},
1351 {NT_STATE_TEX_GEN_ITEM2_TOKEN,{PERIOD_TOKEN, NT_STATE_TEX_GEN_TYPE_TOKEN, PERIOD_TOKEN,
1352 NT_STATE_TEX_GEN_COORD_TOKEN}, NO_KW},
1353 {NT_STATE_TEX_GEN_TYPE_TOKEN, {ID_TOKEN, NULL3}, {"eye", "", "", ""}},
1354
1355 /* 215: */
1356 {NT_STATE_TEX_GEN_TYPE_TOKEN, {ID_TOKEN, NULL3}, {"object", "", "", ""}},
1357 {NT_STATE_TEX_GEN_COORD_TOKEN, {ID_TOKEN, NULL3}, {"s", "", "", ""}},
1358 {NT_STATE_TEX_GEN_COORD_TOKEN, {ID_TOKEN, NULL3}, {"t", "", "", ""}},
1359 {NT_STATE_TEX_GEN_COORD_TOKEN, {ID_TOKEN, NULL3}, {"r", "", "", ""}},
1360 {NT_STATE_TEX_GEN_COORD_TOKEN, {ID_TOKEN, NULL3}, {"q", "", "", ""}},
1361
1362 /* 220: */
1363 {NT_STATE_FOG_ITEM_TOKEN, {ID_TOKEN, PERIOD_TOKEN, NT_STATE_FOG_PROPERTY_TOKEN, NULL_TOKEN},
1364 {"fog", "","",""}},
1365 {NT_STATE_FOG_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"color", "", "", ""}},
1366 {NT_STATE_FOG_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"params", "", "", ""}},
1367 {NT_STATE_CLIP_PLANE_ITEM_TOKEN,
1368 {ID_TOKEN, LBRACKET_TOKEN, NT_STATE_CLIP_PLANE_NUM_TOKEN,
1369 NT_STATE_CLIP_PLANE_ITEM2_TOKEN}, {"clip", "", "", ""}},
1370 {NT_STATE_CLIP_PLANE_ITEM2_TOKEN,
1371 {RBRACKET_TOKEN, PERIOD_TOKEN, ID_TOKEN, NULL_TOKEN},
1372 {"", "", "plane", ""}},
1373
1374 /* 225: */
1375 {NT_STATE_CLIP_PLANE_NUM_TOKEN,{INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1376 {NT_STATE_POINT_ITEM_TOKEN, {ID_TOKEN, PERIOD_TOKEN, NT_STATE_POINT_PROPERTY_TOKEN, NULL_TOKEN},
1377 {"point", "", "", ""}},
1378 {NT_STATE_POINT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"size", "", "", ""}},
1379 {NT_STATE_POINT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"attenuation", "", "", ""}},
1380 {NT_STATE_MATRIX_ROW_TOKEN, {ID_TOKEN, PERIOD_TOKEN, NT_STATE_MATRIX_NAME_TOKEN,
1381 NT_STATE_MATRIX_ROW15_TOKEN}, {"matrix", "", "", ""}},
1382
1383 /* 230: */
1384 {NT_STATE_MATRIX_ROW15_TOKEN, {PERIOD_TOKEN, NT_STATE_MATRIX_ROW2_TOKEN, NULL2}, NO_KW},
1385 {NT_STATE_MATRIX_ROW2_TOKEN, {ID_TOKEN, LBRACKET_TOKEN,
1386 NT_STATE_MATRIX_ROW_NUM_TOKEN, RBRACKET_TOKEN},
1387 {"row", "", "", ""}},
1388 {NT_STATE_MATRIX_ROW2_TOKEN, {NT_STATE_MAT_MODIFIER_TOKEN, PERIOD_TOKEN, ID_TOKEN,
1389 NT_STATE_MATRIX_ROW3_TOKEN},
1390 {"", "", "row", ""}},
1391 {NT_STATE_MATRIX_ROW3_TOKEN, {LBRACKET_TOKEN, NT_STATE_MATRIX_ROW_NUM_TOKEN, RBRACKET_TOKEN,
1392 NULL_TOKEN}, NO_KW},
1393 {NT_STATE_MAT_MODIFIER_TOKEN, {ID_TOKEN, NULL3}, {"inverse", "", "", ""}},
1394
1395 /* 235: */
1396 {NT_STATE_MAT_MODIFIER_TOKEN, {ID_TOKEN, NULL3}, {"transpose", "", "", ""}},
1397 {NT_STATE_MAT_MODIFIER_TOKEN, {ID_TOKEN, NULL3}, {"invtrans", "", "", ""}},
1398 {NT_STATE_MATRIX_ROW_NUM_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1399 {NT_STATE_MATRIX_NAME_TOKEN, {ID_TOKEN, NT_STATE_OPT_MOD_MAT_NUM_TOKEN, NULL2},
1400 {"modelview", "", "", ""}},
1401 {NT_STATE_MATRIX_NAME_TOKEN, {ID_TOKEN, NULL3}, {"projection", "", "", ""}},
1402
1403 /* 240: */
1404 {NT_STATE_MATRIX_NAME_TOKEN, {ID_TOKEN, NULL3}, {"mvp", "", "", ""}},
1405 {NT_STATE_MATRIX_NAME_TOKEN, {ID_TOKEN, NT_OPT_TEX_COORD_NUM_TOKEN, NULL2},
1406 {"texture", "", "", ""}},
1407 {NT_STATE_MATRIX_NAME_TOKEN, {ID_TOKEN, LBRACKET_TOKEN, NT_STATE_PALETTE_MAT_NUM_TOKEN,
1408 RBRACKET_TOKEN}, {"palette", "", "", ""}},
1409 {NT_STATE_MATRIX_NAME_TOKEN, {PROGRAM_TOKEN, LBRACKET_TOKEN, NT_STATE_PROGRAM_MAT_NUM_TOKEN,
1410 RBRACKET_TOKEN}, NO_KW},
1411 {NT_STATE_OPT_MOD_MAT_NUM_TOKEN, {NULL4}, NO_KW},
1412
1413 /* 245: */
1414 {NT_STATE_OPT_MOD_MAT_NUM_TOKEN,
1415 {LBRACKET_TOKEN, NT_STATE_MOD_MAT_NUM_TOKEN, RBRACKET_TOKEN, NULL_TOKEN}, NO_KW},
1416 {NT_STATE_MOD_MAT_NUM_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1417 {NT_STATE_PALETTE_MAT_NUM_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1418 {NT_STATE_PROGRAM_MAT_NUM_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1419 {NT_PROGRAM_SINGLE_ITEM_TOKEN,
1420 {PROGRAM_TOKEN, PERIOD_TOKEN, NT_PROGRAM_SINGLE_ITEM2_TOKEN, NULL_TOKEN}, NO_KW},
1421
1422 /* 250: */
1423 {NT_PROGRAM_SINGLE_ITEM2_TOKEN, {NT_PROG_ENV_PARAM_TOKEN, NULL3}, NO_KW},
1424 {NT_PROGRAM_SINGLE_ITEM2_TOKEN, {NT_PROG_LOCAL_PARAM_TOKEN, NULL3}, NO_KW},
1425 {NT_PROGRAM_MULTIPLE_ITEM_TOKEN,
1426 {PROGRAM_TOKEN, PERIOD_TOKEN, NT_PROGRAM_MULTIPLE_ITEM2_TOKEN, NULL_TOKEN}, NO_KW},
1427 {NT_PROGRAM_MULTIPLE_ITEM2_TOKEN, {NT_PROG_ENV_PARAMS_TOKEN, NULL3}, NO_KW},
1428 {NT_PROGRAM_MULTIPLE_ITEM2_TOKEN, {NT_PROG_LOCAL_PARAMS_TOKEN, NULL3}, NO_KW},
1429
1430 /* 255: */
1431 {NT_PROG_ENV_PARAMS_TOKEN, {ID_TOKEN, LBRACKET_TOKEN, NT_PROG_ENV_PARAM_NUMS_TOKEN, RBRACKET_TOKEN},
1432 {"env", "", "", ""}},
1433 {NT_PROG_ENV_PARAM_NUMS_TOKEN, {NT_PROG_ENV_PARAM_NUM_TOKEN, NT_PROG_ENV_PARAM_NUMS2_TOKEN, NULL2},
1434 NO_KW},
1435 {NT_PROG_ENV_PARAM_NUMS2_TOKEN, {DOTDOT_TOKEN, NT_PROG_ENV_PARAM_NUM_TOKEN, NULL2}, NO_KW},
1436 {NT_PROG_ENV_PARAM_NUMS2_TOKEN, {NULL4}, NO_KW},
1437 {NT_PROG_ENV_PARAM_TOKEN,
1438 {ID_TOKEN, LBRACKET_TOKEN, NT_PROG_ENV_PARAM_NUM_TOKEN, RBRACKET_TOKEN},
1439 {"env", "", "", ""}},
1440
1441 /* 260: */
1442 {NT_PROG_LOCAL_PARAMS_TOKEN, {ID_TOKEN, LBRACKET_TOKEN, NT_PROG_LOCAL_PARAM_NUMS_TOKEN,
1443 RBRACKET_TOKEN}, {"local", "", "", ""}},
1444 {NT_PROG_LOCAL_PARAM_NUMS_TOKEN,
1445 {NT_PROG_LOCAL_PARAM_NUM_TOKEN, NT_PROG_LOCAL_PARAM_NUMS2_TOKEN, NULL2},
1446 NO_KW},
1447 {NT_PROG_LOCAL_PARAM_NUMS2_TOKEN, {DOTDOT_TOKEN, NT_PROG_LOCAL_PARAM_NUM_TOKEN, NULL2}, NO_KW},
1448 {NT_PROG_LOCAL_PARAM_NUMS2_TOKEN, {NULL4}, NO_KW},
1449 {NT_PROG_LOCAL_PARAM_TOKEN, {ID_TOKEN, LBRACKET_TOKEN, NT_PROG_LOCAL_PARAM_NUM_TOKEN, RBRACKET_TOKEN},
1450 {"local", "", "", ""}},
1451
1452 /* 265: */
1453 {NT_PROG_ENV_PARAM_NUM_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1454 {NT_PROG_LOCAL_PARAM_NUM_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1455 {NT_PARAM_CONST_DECL_TOKEN, {NT_PARAM_CONST_SCALAR_DECL_TOKEN, NULL3}, NO_KW},
1456 {NT_PARAM_CONST_DECL_TOKEN, {NT_PARAM_CONST_VECTOR_TOKEN, NULL3}, NO_KW},
1457 {NT_PARAM_CONST_USE_TOKEN, {NT_PARAM_CONST_SCALAR_USE_TOKEN, NULL3}, NO_KW},
1458
1459 /* 270: */
1460 {NT_PARAM_CONST_USE_TOKEN, {NT_PARAM_CONST_VECTOR_TOKEN, NULL3}, NO_KW},
1461 {NT_PARAM_CONST_SCALAR_DECL_TOKEN, {NT_SIGNED_FLOAT_CONSTANT_TOKEN, NULL3}, NO_KW},
1462 {NT_PARAM_CONST_SCALAR_USE_TOKEN, {FLOAT_TOKEN, NULL3}, {"-1", "", "", ""}},
1463 {NT_PARAM_CONST_VECTOR_TOKEN, {LBRACE_TOKEN, NT_SIGNED_FLOAT_CONSTANT_TOKEN,
1464 NT_PARAM_CONST_VECTOR2_TOKEN, NULL_TOKEN}, NO_KW},
1465 {NT_PARAM_CONST_VECTOR2_TOKEN,{RBRACE_TOKEN, NULL3}, NO_KW},
1466
1467 /* 275: */
1468 {NT_PARAM_CONST_VECTOR2_TOKEN, {COMMA_TOKEN, NT_SIGNED_FLOAT_CONSTANT_TOKEN,
1469 NT_PARAM_CONST_VECTOR3_TOKEN, NULL_TOKEN}, NO_KW},
1470 {NT_PARAM_CONST_VECTOR3_TOKEN, {RBRACE_TOKEN, NULL3}, NO_KW},
1471 {NT_PARAM_CONST_VECTOR3_TOKEN, {COMMA_TOKEN, NT_SIGNED_FLOAT_CONSTANT_TOKEN,
1472 NT_PARAM_CONST_VECTOR4_TOKEN, NULL_TOKEN}, NO_KW},
1473 {NT_PARAM_CONST_VECTOR4_TOKEN, {RBRACE_TOKEN, NULL3}, NO_KW},
1474 {NT_PARAM_CONST_VECTOR4_TOKEN, {COMMA_TOKEN, NT_SIGNED_FLOAT_CONSTANT_TOKEN,
1475 RBRACE_TOKEN, NULL_TOKEN}, NO_KW},
1476
1477 /* 280: */
1478 {NT_SIGNED_FLOAT_CONSTANT_TOKEN, {NT_OPTIONAL_SIGN_TOKEN, FLOAT_TOKEN, NULL2},
1479 {"", "-1", "", ""}},
1480 {NT_OPTIONAL_SIGN_TOKEN, {NULL4}, NO_KW},
1481 {NT_OPTIONAL_SIGN_TOKEN, {MINUS_TOKEN, NULL3}, NO_KW},
1482 {NT_OPTIONAL_SIGN_TOKEN, {PLUS_TOKEN, NULL3}, NO_KW},
1483 {NT_TEMP_STATEMENT_TOKEN, {TEMP_TOKEN, NT_VAR_NAME_LIST_TOKEN, NULL2},
1484 NO_KW},
1485
1486 /* 285: */
1487 {NT_ADDRESS_STATEMENT_TOKEN, {ADDRESS_TOKEN, NT_VAR_NAME_LIST_TOKEN, NULL2}, NO_KW},
1488 {NT_VAR_NAME_LIST_TOKEN, {NT_ESTABLISH_NAME_TOKEN, NULL3}, NO_KW},
1489 {NT_VAR_NAME_LIST_TOKEN, {NT_ESTABLISH_NAME_TOKEN, COMMA_TOKEN, NT_VAR_NAME_LIST_TOKEN,
1490 NULL_TOKEN}, NO_KW},
1491 {NT_OUTPUT_STATEMENT_TOKEN, {OUTPUT_TOKEN, NT_ESTABLISH_NAME_TOKEN, EQUAL_TOKEN,
1492 NT_RESULT_BINDING_TOKEN}, NO_KW},
1493 {NT_RESULT_BINDING_TOKEN, {RESULT_TOKEN, PERIOD_TOKEN, NT_RESULT_BINDING2_TOKEN, NULL_TOKEN},
1494 NO_KW},
1495
1496 /* 290: */
1497 {NT_RESULT_BINDING2_TOKEN, {ID_TOKEN, NULL3}, {"position", "", "", ""}},
1498 {NT_RESULT_BINDING2_TOKEN, {ID_TOKEN, NULL3}, {"fogcoord", "", "", ""}},
1499 {NT_RESULT_BINDING2_TOKEN, {ID_TOKEN, NULL3}, {"pointsize", "", "", ""}},
1500 {NT_RESULT_BINDING2_TOKEN, {NT_RESULT_COL_BINDING_TOKEN, NULL3}, NO_KW},
1501 {NT_RESULT_BINDING2_TOKEN, {ID_TOKEN, NT_OPT_TEX_COORD_NUM_TOKEN, NULL2},
1502 {"texcoord", "", "", ""}},
1503
1504 /* 295: */
1505 {NT_RESULT_COL_BINDING_TOKEN, {ID_TOKEN, NT_RESULT_COL_BINDING2_TOKEN, NULL2}, {"color", "", "", ""}},
1506 {NT_RESULT_COL_BINDING2_TOKEN, {NULL4}, NO_KW},
1507 {NT_RESULT_COL_BINDING2_TOKEN, {PERIOD_TOKEN, NT_RESULT_COL_BINDING3_TOKEN, NULL2}, NO_KW},
1508 {NT_RESULT_COL_BINDING3_TOKEN, {ID_TOKEN, NT_RESULT_COL_BINDING4_TOKEN, NULL2}, {"front", "", "", ""}},
1509 {NT_RESULT_COL_BINDING3_TOKEN, {ID_TOKEN, NT_RESULT_COL_BINDING4_TOKEN, NULL2}, {"back", "", "", ""}},
1510
1511 /* 300: */
1512 {NT_RESULT_COL_BINDING4_TOKEN, {NULL4}, NO_KW},
1513 {NT_RESULT_COL_BINDING4_TOKEN, {PERIOD_TOKEN, NT_RESULT_COL_BINDING5_TOKEN, NULL2}, NO_KW},
1514 {NT_RESULT_COL_BINDING5_TOKEN, {ID_TOKEN, NULL3}, {"primary", "", "", ""}},
1515 {NT_RESULT_COL_BINDING5_TOKEN, {ID_TOKEN, NULL3}, {"secondary", "", "", ""}},
1516 {NT_OPT_FACE_TYPE2_TOKEN, {ID_TOKEN, NULL3}, {"front", "", "", ""}},
1517
1518 /* 305: */
1519 {NT_OPT_FACE_TYPE2_TOKEN, {ID_TOKEN, NULL3}, {"back", "", "", ""}},
1520 {NT_OPT_COLOR_TYPE_TOKEN, {PERIOD_TOKEN, NT_OPT_COLOR_TYPE2_TOKEN, NULL2}, NO_KW},
1521 {NT_OPT_COLOR_TYPE_TOKEN, {NULL4}, NO_KW},
1522 {NT_OPT_COLOR_TYPE2_TOKEN, {ID_TOKEN, NULL3}, {"primary", "", "", ""}},
1523 {NT_OPT_COLOR_TYPE2_TOKEN, {ID_TOKEN, NULL3}, {"secondary", "", "", ""}},
1524
1525 /* 310: */
1526 {NT_OPT_TEX_COORD_NUM_TOKEN, {NULL4}, NO_KW},
1527 {NT_OPT_TEX_COORD_NUM_TOKEN,
1528 {LBRACKET_TOKEN, NT_TEX_COORD_NUM_TOKEN, RBRACKET_TOKEN, NULL_TOKEN}, NO_KW},
1529 {NT_TEX_COORD_NUM_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
1530 {NT_ALIAS_STATEMENT_TOKEN, {ALIAS_TOKEN, NT_ESTABLISH_NAME_TOKEN, EQUAL_TOKEN,
1531 NT_ESTABLISHED_NAME_TOKEN}, NO_KW},
1532 {NT_ESTABLISH_NAME_TOKEN, {ID_TOKEN, NULL3}, {"-1", "", "", ""}},
1533
1534 /* 315: */
1535 {NT_ESTABLISHED_NAME_TOKEN, {ID_TOKEN, NULL3}, {"-1", "", "", ""}},
1536 {NT_FOO_TOKEN, {NULL4}, NO_KW},
1537 {NT_SWIZZLE_SUFFIX_TOKEN, {PERIOD_TOKEN, NT_SWIZZLE_SUFFIX2_TOKEN, NULL2},
1538 NO_KW},
1539 {NT_SWIZZLE_SUFFIX2_TOKEN, {NT_COMPONENT_TOKEN, NULL3}, NO_KW},
1540 {NT_SWIZZLE_SUFFIX2_TOKEN, {NT_COMPONENT4_TOKEN, NULL3}, NO_KW},
1541};
1542
1543/* This is the look ahead table. See the look_ahead_table struct def for a description */
1544look_ahead_table latab[] = {
1545 {NT_PROGRAM_TOKEN, ABS_TOKEN, "", 0},
1546 {NT_PROGRAM_TOKEN, ADD_TOKEN, "", 0},
1547 {NT_PROGRAM_TOKEN, ADDRESS_TOKEN, "", 0},
1548 {NT_PROGRAM_TOKEN, ALIAS_TOKEN, "", 0},
1549 {NT_PROGRAM_TOKEN, ARL_TOKEN, "", 0},
1550 {NT_PROGRAM_TOKEN, ATTRIB_TOKEN, "", 0},
1551 {NT_PROGRAM_TOKEN, DP3_TOKEN, "", 0},
1552 {NT_PROGRAM_TOKEN, DP4_TOKEN, "", 0},
1553 {NT_PROGRAM_TOKEN, DPH_TOKEN, "", 0},
1554 {NT_PROGRAM_TOKEN, DST_TOKEN, "", 0},
1555 {NT_PROGRAM_TOKEN, END_TOKEN, "", 0},
1556 {NT_PROGRAM_TOKEN, EOF_TOKEN, "", 0},
1557 {NT_PROGRAM_TOKEN, EX2_TOKEN, "", 0},
1558 {NT_PROGRAM_TOKEN, EXP_TOKEN, "", 0},
1559 {NT_PROGRAM_TOKEN, FLR_TOKEN, "", 0},
1560 {NT_PROGRAM_TOKEN, FRC_TOKEN, "", 0},
1561 {NT_PROGRAM_TOKEN, LIT_TOKEN, "", 0},
1562 {NT_PROGRAM_TOKEN, LG2_TOKEN, "", 0},
1563 {NT_PROGRAM_TOKEN, LOG_TOKEN, "", 0},
1564 {NT_PROGRAM_TOKEN, MAD_TOKEN, "", 0},
1565 {NT_PROGRAM_TOKEN, MAX_TOKEN, "", 0},
1566 {NT_PROGRAM_TOKEN, MIN_TOKEN, "", 0},
1567 {NT_PROGRAM_TOKEN, MOV_TOKEN, "", 0},
1568 {NT_PROGRAM_TOKEN, MUL_TOKEN, "", 0},
1569 {NT_PROGRAM_TOKEN, OPTION_TOKEN, "", 0},
1570 {NT_PROGRAM_TOKEN, OUTPUT_TOKEN, "", 0},
1571 {NT_PROGRAM_TOKEN, PARAM_TOKEN, "", 0},
1572 {NT_PROGRAM_TOKEN, POW_TOKEN, "", 0},
1573 {NT_PROGRAM_TOKEN, RCP_TOKEN, "", 0},
1574 {NT_PROGRAM_TOKEN, RSQ_TOKEN, "", 0},
1575 {NT_PROGRAM_TOKEN, SGE_TOKEN, "", 0},
1576 {NT_PROGRAM_TOKEN, SLT_TOKEN, "", 0},
1577 {NT_PROGRAM_TOKEN, SUB_TOKEN, "", 0},
1578 {NT_PROGRAM_TOKEN, SWZ_TOKEN, "", 0},
1579 {NT_PROGRAM_TOKEN, XPD_TOKEN, "", 0},
1580 {NT_PROGRAM_TOKEN, TEMP_TOKEN, "", 0},
1581
1582 {NT_OPTION_SEQUENCE_TOKEN, ABS_TOKEN, "", 1},
1583 {NT_OPTION_SEQUENCE_TOKEN, ADD_TOKEN, "", 1},
1584 {NT_OPTION_SEQUENCE_TOKEN, ADDRESS_TOKEN, "", 1},
1585 {NT_OPTION_SEQUENCE_TOKEN, ALIAS_TOKEN, "", 1},
1586 {NT_OPTION_SEQUENCE_TOKEN, ARL_TOKEN, "", 1},
1587 {NT_OPTION_SEQUENCE_TOKEN, ATTRIB_TOKEN, "", 1},
1588 {NT_OPTION_SEQUENCE_TOKEN, DP3_TOKEN, "", 1},
1589 {NT_OPTION_SEQUENCE_TOKEN, DP4_TOKEN, "", 1},
1590 {NT_OPTION_SEQUENCE_TOKEN, DPH_TOKEN, "", 1},
1591 {NT_OPTION_SEQUENCE_TOKEN, DST_TOKEN, "", 1},
1592 {NT_OPTION_SEQUENCE_TOKEN, END_TOKEN, "", 1},
1593 {NT_OPTION_SEQUENCE_TOKEN, EX2_TOKEN, "", 1},
1594 {NT_OPTION_SEQUENCE_TOKEN, EXP_TOKEN, "", 1},
1595 {NT_OPTION_SEQUENCE_TOKEN, FLR_TOKEN, "", 1},
1596 {NT_OPTION_SEQUENCE_TOKEN, FRC_TOKEN, "", 1},
1597 {NT_OPTION_SEQUENCE_TOKEN, LIT_TOKEN, "", 1},
1598 {NT_OPTION_SEQUENCE_TOKEN, LG2_TOKEN, "", 1},
1599 {NT_OPTION_SEQUENCE_TOKEN, LOG_TOKEN, "", 1},
1600 {NT_OPTION_SEQUENCE_TOKEN, MAD_TOKEN, "", 1},
1601 {NT_OPTION_SEQUENCE_TOKEN, MAX_TOKEN, "", 1},
1602 {NT_OPTION_SEQUENCE_TOKEN, MIN_TOKEN, "", 1},
1603 {NT_OPTION_SEQUENCE_TOKEN, MOV_TOKEN, "", 1},
1604 {NT_OPTION_SEQUENCE_TOKEN, MUL_TOKEN, "", 1},
1605 {NT_OPTION_SEQUENCE_TOKEN, OPTION_TOKEN, "", 1},
1606 {NT_OPTION_SEQUENCE_TOKEN, OUTPUT_TOKEN, "", 1},
1607 {NT_OPTION_SEQUENCE_TOKEN, PARAM_TOKEN, "", 1},
1608 {NT_OPTION_SEQUENCE_TOKEN, POW_TOKEN, "", 1},
1609 {NT_OPTION_SEQUENCE_TOKEN, RCP_TOKEN, "", 1},
1610 {NT_OPTION_SEQUENCE_TOKEN, RSQ_TOKEN, "", 1},
1611 {NT_OPTION_SEQUENCE_TOKEN, SGE_TOKEN, "", 1},
1612 {NT_OPTION_SEQUENCE_TOKEN, SLT_TOKEN, "", 1},
1613 {NT_OPTION_SEQUENCE_TOKEN, SUB_TOKEN, "", 1},
1614 {NT_OPTION_SEQUENCE_TOKEN, SWZ_TOKEN, "", 1},
1615 {NT_OPTION_SEQUENCE_TOKEN, XPD_TOKEN, "", 1},
1616 {NT_OPTION_SEQUENCE_TOKEN, TEMP_TOKEN, "", 1},
1617
1618 {NT_OPTION_SEQUENCE2_TOKEN, OPTION_TOKEN, "", 2},
1619
1620 {NT_OPTION_SEQUENCE2_TOKEN, ABS_TOKEN, "", 3},
1621 {NT_OPTION_SEQUENCE2_TOKEN, ADD_TOKEN, "", 3},
1622 {NT_OPTION_SEQUENCE2_TOKEN, ADDRESS_TOKEN, "", 3},
1623 {NT_OPTION_SEQUENCE2_TOKEN, ALIAS_TOKEN, "", 3},
1624 {NT_OPTION_SEQUENCE2_TOKEN, ARL_TOKEN, "", 3},
1625 {NT_OPTION_SEQUENCE2_TOKEN, ATTRIB_TOKEN, "", 3},
1626 {NT_OPTION_SEQUENCE2_TOKEN, DP3_TOKEN, "", 3},
1627 {NT_OPTION_SEQUENCE2_TOKEN, DP4_TOKEN, "", 3},
1628 {NT_OPTION_SEQUENCE2_TOKEN, DPH_TOKEN, "", 3},
1629 {NT_OPTION_SEQUENCE2_TOKEN, DST_TOKEN, "", 3},
1630 {NT_OPTION_SEQUENCE2_TOKEN, END_TOKEN, "", 3},
1631 {NT_OPTION_SEQUENCE2_TOKEN, EX2_TOKEN, "", 3},
1632 {NT_OPTION_SEQUENCE2_TOKEN, EXP_TOKEN, "", 3},
1633 {NT_OPTION_SEQUENCE2_TOKEN, FLR_TOKEN, "", 3},
1634 {NT_OPTION_SEQUENCE2_TOKEN, FRC_TOKEN, "", 3},
1635 {NT_OPTION_SEQUENCE2_TOKEN, LIT_TOKEN, "", 3},
1636 {NT_OPTION_SEQUENCE2_TOKEN, LG2_TOKEN, "", 3},
1637 {NT_OPTION_SEQUENCE2_TOKEN, LOG_TOKEN, "", 3},
1638 {NT_OPTION_SEQUENCE2_TOKEN, MAD_TOKEN, "", 3},
1639 {NT_OPTION_SEQUENCE2_TOKEN, MAX_TOKEN, "", 3},
1640 {NT_OPTION_SEQUENCE2_TOKEN, MIN_TOKEN, "", 3},
1641 {NT_OPTION_SEQUENCE2_TOKEN, MOV_TOKEN, "", 3},
1642 {NT_OPTION_SEQUENCE2_TOKEN, MUL_TOKEN, "", 3},
1643 {NT_OPTION_SEQUENCE2_TOKEN, OUTPUT_TOKEN, "", 3},
1644 {NT_OPTION_SEQUENCE2_TOKEN, PARAM_TOKEN, "", 3},
1645 {NT_OPTION_SEQUENCE2_TOKEN, POW_TOKEN, "", 3},
1646 {NT_OPTION_SEQUENCE2_TOKEN, RCP_TOKEN, "", 3},
1647 {NT_OPTION_SEQUENCE2_TOKEN, RSQ_TOKEN, "", 3},
1648 {NT_OPTION_SEQUENCE2_TOKEN, SGE_TOKEN, "", 3},
1649 {NT_OPTION_SEQUENCE2_TOKEN, SLT_TOKEN, "", 3},
1650 {NT_OPTION_SEQUENCE2_TOKEN, SUB_TOKEN, "", 3},
1651 {NT_OPTION_SEQUENCE2_TOKEN, SWZ_TOKEN, "", 3},
1652 {NT_OPTION_SEQUENCE2_TOKEN, XPD_TOKEN, "", 3},
1653 {NT_OPTION_SEQUENCE2_TOKEN, TEMP_TOKEN, "", 3},
1654
1655 {NT_OPTION_TOKEN, OPTION_TOKEN, "", 4},
1656
1657 {NT_STATEMENT_SEQUENCE_TOKEN, ABS_TOKEN, "", 5},
1658 {NT_STATEMENT_SEQUENCE_TOKEN, ADD_TOKEN, "", 5},
1659 {NT_STATEMENT_SEQUENCE_TOKEN, ADDRESS_TOKEN, "", 5},
1660 {NT_STATEMENT_SEQUENCE_TOKEN, ALIAS_TOKEN, "", 5},
1661 {NT_STATEMENT_SEQUENCE_TOKEN, ARL_TOKEN, "", 5},
1662 {NT_STATEMENT_SEQUENCE_TOKEN, ATTRIB_TOKEN, "", 5},
1663 {NT_STATEMENT_SEQUENCE_TOKEN, DP3_TOKEN, "", 5},
1664 {NT_STATEMENT_SEQUENCE_TOKEN, DP4_TOKEN, "", 5},
1665 {NT_STATEMENT_SEQUENCE_TOKEN, DPH_TOKEN, "", 5},
1666 {NT_STATEMENT_SEQUENCE_TOKEN, DST_TOKEN, "", 5},
1667 {NT_STATEMENT_SEQUENCE_TOKEN, END_TOKEN, "", 5},
1668 {NT_STATEMENT_SEQUENCE_TOKEN, EX2_TOKEN, "", 5},
1669 {NT_STATEMENT_SEQUENCE_TOKEN, EXP_TOKEN, "", 5},
1670 {NT_STATEMENT_SEQUENCE_TOKEN, FLR_TOKEN, "", 5},
1671 {NT_STATEMENT_SEQUENCE_TOKEN, FRC_TOKEN, "", 5},
1672 {NT_STATEMENT_SEQUENCE_TOKEN, LIT_TOKEN, "", 5},
1673 {NT_STATEMENT_SEQUENCE_TOKEN, LG2_TOKEN, "", 5},
1674 {NT_STATEMENT_SEQUENCE_TOKEN, LOG_TOKEN, "", 5},
1675 {NT_STATEMENT_SEQUENCE_TOKEN, MAD_TOKEN, "", 5},
1676 {NT_STATEMENT_SEQUENCE_TOKEN, MAX_TOKEN, "", 5},
1677 {NT_STATEMENT_SEQUENCE_TOKEN, MIN_TOKEN, "", 5},
1678 {NT_STATEMENT_SEQUENCE_TOKEN, MOV_TOKEN, "", 5},
1679 {NT_STATEMENT_SEQUENCE_TOKEN, MUL_TOKEN, "", 5},
1680 {NT_STATEMENT_SEQUENCE_TOKEN, OUTPUT_TOKEN, "", 5},
1681 {NT_STATEMENT_SEQUENCE_TOKEN, PARAM_TOKEN, "", 5},
1682 {NT_STATEMENT_SEQUENCE_TOKEN, POW_TOKEN, "", 5},
1683 {NT_STATEMENT_SEQUENCE_TOKEN, RCP_TOKEN, "", 5},
1684 {NT_STATEMENT_SEQUENCE_TOKEN, RSQ_TOKEN, "", 5},
1685 {NT_STATEMENT_SEQUENCE_TOKEN, SGE_TOKEN, "", 5},
1686 {NT_STATEMENT_SEQUENCE_TOKEN, SLT_TOKEN, "", 5},
1687 {NT_STATEMENT_SEQUENCE_TOKEN, SUB_TOKEN, "", 5},
1688 {NT_STATEMENT_SEQUENCE_TOKEN, SWZ_TOKEN, "", 5},
1689 {NT_STATEMENT_SEQUENCE_TOKEN, XPD_TOKEN, "", 5},
1690 {NT_STATEMENT_SEQUENCE_TOKEN, TEMP_TOKEN, "", 5},
1691
1692 {NT_STATEMENT_SEQUENCE2_TOKEN, ABS_TOKEN, "", 6},
1693 {NT_STATEMENT_SEQUENCE2_TOKEN, ADD_TOKEN, "", 6},
1694 {NT_STATEMENT_SEQUENCE2_TOKEN, ADDRESS_TOKEN, "", 6},
1695 {NT_STATEMENT_SEQUENCE2_TOKEN, ALIAS_TOKEN, "", 6},
1696 {NT_STATEMENT_SEQUENCE2_TOKEN, ARL_TOKEN, "", 6},
1697 {NT_STATEMENT_SEQUENCE2_TOKEN, ATTRIB_TOKEN, "", 6},
1698 {NT_STATEMENT_SEQUENCE2_TOKEN, DP3_TOKEN, "", 6},
1699 {NT_STATEMENT_SEQUENCE2_TOKEN, DP4_TOKEN, "", 6},
1700 {NT_STATEMENT_SEQUENCE2_TOKEN, DPH_TOKEN, "", 6},
1701 {NT_STATEMENT_SEQUENCE2_TOKEN, DST_TOKEN, "", 6},
1702 {NT_STATEMENT_SEQUENCE2_TOKEN, EX2_TOKEN, "", 6},
1703 {NT_STATEMENT_SEQUENCE2_TOKEN, EXP_TOKEN, "", 6},
1704 {NT_STATEMENT_SEQUENCE2_TOKEN, FLR_TOKEN, "", 6},
1705 {NT_STATEMENT_SEQUENCE2_TOKEN, FRC_TOKEN, "", 6},
1706 {NT_STATEMENT_SEQUENCE2_TOKEN, LIT_TOKEN, "", 6},
1707 {NT_STATEMENT_SEQUENCE2_TOKEN, LG2_TOKEN, "", 6},
1708 {NT_STATEMENT_SEQUENCE2_TOKEN, LOG_TOKEN, "", 6},
1709 {NT_STATEMENT_SEQUENCE2_TOKEN, MAD_TOKEN, "", 6},
1710 {NT_STATEMENT_SEQUENCE2_TOKEN, MAX_TOKEN, "", 6},
1711 {NT_STATEMENT_SEQUENCE2_TOKEN, MIN_TOKEN, "", 6},
1712 {NT_STATEMENT_SEQUENCE2_TOKEN, MOV_TOKEN, "", 6},
1713 {NT_STATEMENT_SEQUENCE2_TOKEN, MUL_TOKEN, "", 6},
1714 {NT_STATEMENT_SEQUENCE2_TOKEN, OUTPUT_TOKEN, "", 6},
1715 {NT_STATEMENT_SEQUENCE2_TOKEN, PARAM_TOKEN, "", 6},
1716 {NT_STATEMENT_SEQUENCE2_TOKEN, POW_TOKEN, "", 6},
1717 {NT_STATEMENT_SEQUENCE2_TOKEN, RCP_TOKEN, "", 6},
1718 {NT_STATEMENT_SEQUENCE2_TOKEN, RSQ_TOKEN, "", 6},
1719 {NT_STATEMENT_SEQUENCE2_TOKEN, SGE_TOKEN, "", 6},
1720 {NT_STATEMENT_SEQUENCE2_TOKEN, SLT_TOKEN, "", 6},
1721 {NT_STATEMENT_SEQUENCE2_TOKEN, SUB_TOKEN, "", 6},
1722 {NT_STATEMENT_SEQUENCE2_TOKEN, SWZ_TOKEN, "", 6},
1723 {NT_STATEMENT_SEQUENCE2_TOKEN, XPD_TOKEN, "", 6},
1724 {NT_STATEMENT_SEQUENCE2_TOKEN, TEMP_TOKEN, "", 6},
1725
1726 {NT_STATEMENT_SEQUENCE2_TOKEN, END_TOKEN, "", 7},
1727
1728
1729 {NT_STATEMENT_TOKEN, ABS_TOKEN, "", 8},
1730 {NT_STATEMENT_TOKEN, ADD_TOKEN, "", 8},
1731 {NT_STATEMENT_TOKEN, ARL_TOKEN, "", 8},
1732 {NT_STATEMENT_TOKEN, DP3_TOKEN, "", 8},
1733 {NT_STATEMENT_TOKEN, DP4_TOKEN, "", 8},
1734 {NT_STATEMENT_TOKEN, DPH_TOKEN, "", 8},
1735 {NT_STATEMENT_TOKEN, DST_TOKEN, "", 8},
1736 {NT_STATEMENT_TOKEN, EX2_TOKEN, "", 8},
1737 {NT_STATEMENT_TOKEN, EXP_TOKEN, "", 8},
1738 {NT_STATEMENT_TOKEN, FLR_TOKEN, "", 8},
1739 {NT_STATEMENT_TOKEN, FRC_TOKEN, "", 8},
1740 {NT_STATEMENT_TOKEN, LIT_TOKEN, "", 8},
1741 {NT_STATEMENT_TOKEN, LG2_TOKEN, "", 8},
1742 {NT_STATEMENT_TOKEN, LOG_TOKEN, "", 8},
1743 {NT_STATEMENT_TOKEN, MAD_TOKEN, "", 8},
1744 {NT_STATEMENT_TOKEN, MAX_TOKEN, "", 8},
1745 {NT_STATEMENT_TOKEN, MIN_TOKEN, "", 8},
1746 {NT_STATEMENT_TOKEN, MOV_TOKEN, "", 8},
1747 {NT_STATEMENT_TOKEN, MUL_TOKEN, "", 8},
1748 {NT_STATEMENT_TOKEN, POW_TOKEN, "", 8},
1749 {NT_STATEMENT_TOKEN, RCP_TOKEN, "", 8},
1750 {NT_STATEMENT_TOKEN, RSQ_TOKEN, "", 8},
1751 {NT_STATEMENT_TOKEN, SGE_TOKEN, "", 8},
1752 {NT_STATEMENT_TOKEN, SLT_TOKEN, "", 8},
1753 {NT_STATEMENT_TOKEN, SUB_TOKEN, "", 8},
1754 {NT_STATEMENT_TOKEN, SWZ_TOKEN, "", 8},
1755 {NT_STATEMENT_TOKEN, XPD_TOKEN, "", 8},
1756
1757 {NT_STATEMENT_TOKEN, ADDRESS_TOKEN, "", 9},
1758 {NT_STATEMENT_TOKEN, ALIAS_TOKEN, "", 9},
1759 {NT_STATEMENT_TOKEN, ATTRIB_TOKEN, "", 9},
1760 {NT_STATEMENT_TOKEN, OUTPUT_TOKEN, "", 9},
1761 {NT_STATEMENT_TOKEN, PARAM_TOKEN, "", 9},
1762 {NT_STATEMENT_TOKEN, TEMP_TOKEN, "", 9},
1763
1764 {NT_INSTRUCTION_TOKEN, ARL_TOKEN, "", 10},
1765
1766 {NT_INSTRUCTION_TOKEN, ABS_TOKEN, "", 11},
1767 {NT_INSTRUCTION_TOKEN, FLR_TOKEN, "", 11},
1768 {NT_INSTRUCTION_TOKEN, FRC_TOKEN, "", 11},
1769 {NT_INSTRUCTION_TOKEN, LIT_TOKEN, "", 11},
1770 {NT_INSTRUCTION_TOKEN, MOV_TOKEN, "", 11},
1771
1772 {NT_INSTRUCTION_TOKEN, EX2_TOKEN, "", 12},
1773 {NT_INSTRUCTION_TOKEN, EXP_TOKEN, "", 12},
1774 {NT_INSTRUCTION_TOKEN, LG2_TOKEN, "", 12},
1775 {NT_INSTRUCTION_TOKEN, LOG_TOKEN, "", 12},
1776 {NT_INSTRUCTION_TOKEN, RCP_TOKEN, "", 12},
1777 {NT_INSTRUCTION_TOKEN, RSQ_TOKEN, "", 12},
1778
1779 {NT_INSTRUCTION_TOKEN, POW_TOKEN, "", 13},
1780
1781 {NT_INSTRUCTION_TOKEN, ADD_TOKEN, "", 14},
1782 {NT_INSTRUCTION_TOKEN, DP3_TOKEN, "", 14},
1783 {NT_INSTRUCTION_TOKEN, DP4_TOKEN, "", 14},
1784 {NT_INSTRUCTION_TOKEN, DPH_TOKEN, "", 14},
1785 {NT_INSTRUCTION_TOKEN, DST_TOKEN, "", 14},
1786 {NT_INSTRUCTION_TOKEN, MAX_TOKEN, "", 14},
1787 {NT_INSTRUCTION_TOKEN, MIN_TOKEN, "", 14},
1788 {NT_INSTRUCTION_TOKEN, MUL_TOKEN, "", 14},
1789 {NT_INSTRUCTION_TOKEN, SGE_TOKEN, "", 14},
1790 {NT_INSTRUCTION_TOKEN, SLT_TOKEN, "", 14},
1791 {NT_INSTRUCTION_TOKEN, SUB_TOKEN, "", 14},
1792 {NT_INSTRUCTION_TOKEN, XPD_TOKEN, "", 14},
1793
1794 {NT_INSTRUCTION_TOKEN, MAD_TOKEN, "", 15},
1795
1796 {NT_INSTRUCTION_TOKEN, SWZ_TOKEN, "", 16},
1797
1798 {NT_ARL_INSTRUCTION_TOKEN, ARL_TOKEN, "", 17},
1799
1800 {NT_VECTOROP_INSTRUCTION_TOKEN, ABS_TOKEN, "", 18},
1801 {NT_VECTOROP_INSTRUCTION_TOKEN, FLR_TOKEN, "", 18},
1802 {NT_VECTOROP_INSTRUCTION_TOKEN, FRC_TOKEN, "", 18},
1803 {NT_VECTOROP_INSTRUCTION_TOKEN, LIT_TOKEN, "", 18},
1804 {NT_VECTOROP_INSTRUCTION_TOKEN, MOV_TOKEN, "", 18},
1805
1806 {NT_VECTOROP_TOKEN, ABS_TOKEN, "", 19},
1807
1808 {NT_VECTOROP_TOKEN, FLR_TOKEN, "", 20},
1809
1810 {NT_VECTOROP_TOKEN, FRC_TOKEN, "", 21},
1811
1812 {NT_VECTOROP_TOKEN, LIT_TOKEN, "", 22},
1813
1814 {NT_VECTOROP_TOKEN, MOV_TOKEN, "", 23},
1815
1816 {NT_SCALAROP_INSTRUCTION_TOKEN, EX2_TOKEN, "", 24},
1817 {NT_SCALAROP_INSTRUCTION_TOKEN, EXP_TOKEN, "", 24},
1818 {NT_SCALAROP_INSTRUCTION_TOKEN, LG2_TOKEN, "", 24},
1819 {NT_SCALAROP_INSTRUCTION_TOKEN, LOG_TOKEN, "", 24},
1820 {NT_SCALAROP_INSTRUCTION_TOKEN, RCP_TOKEN, "", 24},
1821 {NT_SCALAROP_INSTRUCTION_TOKEN, RSQ_TOKEN, "", 24},
1822
1823 {NT_SCALAROP_TOKEN, EX2_TOKEN, "", 25},
1824
1825 {NT_SCALAROP_TOKEN, EXP_TOKEN, "", 26},
1826
1827 {NT_SCALAROP_TOKEN, LG2_TOKEN, "", 27},
1828
1829 {NT_SCALAROP_TOKEN, LOG_TOKEN, "", 28},
1830
1831 {NT_SCALAROP_TOKEN, RCP_TOKEN, "", 29},
1832
1833 {NT_SCALAROP_TOKEN, RSQ_TOKEN, "", 30},
1834
1835 {NT_BINSCOP_INSTRUCTION_TOKEN, POW_TOKEN, "", 31},
1836
1837 {NT_BINSCOP_INSTRUCTION2_TOKEN, COMMA_TOKEN, "", 32},
1838
1839 {NT_BINSCOP_TOKEN, POW_TOKEN, "", 33},
1840
1841 {NT_BINOP_INSTRUCTION_TOKEN, ADD_TOKEN, "", 34},
1842 {NT_BINOP_INSTRUCTION_TOKEN, DP3_TOKEN, "", 34},
1843 {NT_BINOP_INSTRUCTION_TOKEN, DP4_TOKEN, "", 34},
1844 {NT_BINOP_INSTRUCTION_TOKEN, DPH_TOKEN, "", 34},
1845 {NT_BINOP_INSTRUCTION_TOKEN, DST_TOKEN, "", 34},
1846 {NT_BINOP_INSTRUCTION_TOKEN, MAX_TOKEN, "", 34},
1847 {NT_BINOP_INSTRUCTION_TOKEN, MIN_TOKEN, "", 34},
1848 {NT_BINOP_INSTRUCTION_TOKEN, MUL_TOKEN, "", 34},
1849 {NT_BINOP_INSTRUCTION_TOKEN, SGE_TOKEN, "", 34},
1850 {NT_BINOP_INSTRUCTION_TOKEN, SLT_TOKEN, "", 34},
1851 {NT_BINOP_INSTRUCTION_TOKEN, SUB_TOKEN, "", 34},
1852 {NT_BINOP_INSTRUCTION_TOKEN, XPD_TOKEN, "", 34},
1853
1854 {NT_BINOP_INSTRUCTION2_TOKEN, COMMA_TOKEN, "", 35},
1855
1856 {NT_BINOP_TOKEN, ADD_TOKEN, "", 36},
1857 {NT_BINOP_TOKEN, DP3_TOKEN, "", 37},
1858 {NT_BINOP_TOKEN, DP4_TOKEN, "", 38},
1859 {NT_BINOP_TOKEN, DPH_TOKEN, "", 39},
1860 {NT_BINOP_TOKEN, DST_TOKEN, "", 40},
1861 {NT_BINOP_TOKEN, MAX_TOKEN, "", 41},
1862 {NT_BINOP_TOKEN, MIN_TOKEN, "", 42},
1863 {NT_BINOP_TOKEN, MUL_TOKEN, "", 43},
1864 {NT_BINOP_TOKEN, SGE_TOKEN, "", 44},
1865 {NT_BINOP_TOKEN, SLT_TOKEN, "", 45},
1866 {NT_BINOP_TOKEN, SUB_TOKEN, "", 46},
1867 {NT_BINOP_TOKEN, XPD_TOKEN, "", 47},
1868
1869 {NT_TRIOP_INSTRUCTION_TOKEN, MAD_TOKEN, "", 48},
1870 {NT_TRIOP_INSTRUCTION2_TOKEN, COMMA_TOKEN, "", 49},
1871 {NT_TRIOP_INSTRUCTION3_TOKEN, COMMA_TOKEN, "", 50},
1872
1873 {NT_TRIOP_TOKEN, MAD_TOKEN, "", 51},
1874 {NT_SWZ_INSTRUCTION_TOKEN, SWZ_TOKEN, "", 52},
1875 {NT_SWZ_INSTRUCTION2_TOKEN, COMMA_TOKEN, "", 53},
1876
1877 {NT_SCALAR_SRC_REG_TOKEN, PLUS_TOKEN, "", 54},
1878 {NT_SCALAR_SRC_REG_TOKEN, MINUS_TOKEN, "", 54},
1879 {NT_SCALAR_SRC_REG_TOKEN, VERTEX_TOKEN, "", 54},
1880 {NT_SCALAR_SRC_REG_TOKEN, STATE_TOKEN, "", 54},
1881 {NT_SCALAR_SRC_REG_TOKEN, PROGRAM_TOKEN, "", 54},
1882 {NT_SCALAR_SRC_REG_TOKEN, LBRACE_TOKEN, "", 54},
1883 {NT_SCALAR_SRC_REG_TOKEN, FLOAT_TOKEN, "-1", 54},
1884 {NT_SCALAR_SRC_REG_TOKEN, INTEGER_TOKEN, "-1", 54},
1885 {NT_SCALAR_SRC_REG_TOKEN, ID_TOKEN, "-1", 54},
1886
1887 {NT_SWIZZLE_SRC_REG_TOKEN, PLUS_TOKEN, "", 55},
1888 {NT_SWIZZLE_SRC_REG_TOKEN, MINUS_TOKEN, "", 55},
1889 {NT_SWIZZLE_SRC_REG_TOKEN, VERTEX_TOKEN, "", 55},
1890 {NT_SWIZZLE_SRC_REG_TOKEN, STATE_TOKEN, "", 55},
1891 {NT_SWIZZLE_SRC_REG_TOKEN, PROGRAM_TOKEN, "", 55},
1892 {NT_SWIZZLE_SRC_REG_TOKEN, LBRACE_TOKEN, "", 55},
1893 {NT_SWIZZLE_SRC_REG_TOKEN, FLOAT_TOKEN, "-1", 55},
1894 {NT_SWIZZLE_SRC_REG_TOKEN, INTEGER_TOKEN, "-1", 55},
1895 {NT_SWIZZLE_SRC_REG_TOKEN, ID_TOKEN, "-1", 55},
1896
1897 {NT_MASKED_DST_REG_TOKEN, ID_TOKEN, "-1", 56},
1898 {NT_MASKED_DST_REG_TOKEN, RESULT_TOKEN, "", 56},
1899 {NT_MASKED_ADDR_REG_TOKEN, ID_TOKEN, "-1", 57},
1900
1901 {NT_EXTENDED_SWIZZLE_TOKEN, PLUS_TOKEN, "", 58},
1902 {NT_EXTENDED_SWIZZLE_TOKEN, MINUS_TOKEN, "", 58},
1903 {NT_EXTENDED_SWIZZLE_TOKEN, INTEGER_TOKEN, "0", 58},
1904 {NT_EXTENDED_SWIZZLE_TOKEN, INTEGER_TOKEN, "1", 58},
1905 {NT_EXTENDED_SWIZZLE_TOKEN, ID_TOKEN, "x", 58},
1906 {NT_EXTENDED_SWIZZLE_TOKEN, ID_TOKEN, "y", 58},
1907 {NT_EXTENDED_SWIZZLE_TOKEN, ID_TOKEN, "z", 58},
1908 {NT_EXTENDED_SWIZZLE_TOKEN, ID_TOKEN, "w", 58},
1909
1910 {NT_EXTENDED_SWIZZLE2_TOKEN, COMMA_TOKEN, "", 59},
1911
1912 {NT_EXT_SWIZ_COMP_TOKEN, PLUS_TOKEN, "", 60},
1913 {NT_EXT_SWIZ_COMP_TOKEN, MINUS_TOKEN, "", 60},
1914 {NT_EXT_SWIZ_COMP_TOKEN, INTEGER_TOKEN, "0", 60},
1915 {NT_EXT_SWIZ_COMP_TOKEN, INTEGER_TOKEN, "1", 60},
1916 {NT_EXT_SWIZ_COMP_TOKEN, ID_TOKEN, "x", 60},
1917 {NT_EXT_SWIZ_COMP_TOKEN, ID_TOKEN, "y", 60},
1918 {NT_EXT_SWIZ_COMP_TOKEN, ID_TOKEN, "z", 60},
1919 {NT_EXT_SWIZ_COMP_TOKEN, ID_TOKEN, "w", 60},
1920
1921 {NT_EXT_SWIZ_SEL_TOKEN, INTEGER_TOKEN, "0", 61},
1922 {NT_EXT_SWIZ_SEL_TOKEN, INTEGER_TOKEN, "1", 62},
1923 {NT_EXT_SWIZ_SEL_TOKEN, ID_TOKEN, "x", 63},
1924 {NT_EXT_SWIZ_SEL_TOKEN, ID_TOKEN, "y", 63},
1925 {NT_EXT_SWIZ_SEL_TOKEN, ID_TOKEN, "z", 63},
1926 {NT_EXT_SWIZ_SEL_TOKEN, ID_TOKEN, "w", 63},
1927
1928 /* Special case for 64 - 68 */
1929
1930 {NT_DST_REG_TOKEN, RESULT_TOKEN, "", 68},
1931 {NT_VERTEX_ATTRIB_REG_TOKEN, ID_TOKEN, "-1", 69},
1932 {NT_VERTEX_ATTRIB_REG_TOKEN, VERTEX_TOKEN, "", 70},
1933 {NT_TEMPORARY_REG_TOKEN, ID_TOKEN, "-1", 71},
1934
1935 /* Special case for 72 - 73 */
1936
1937 {NT_PROG_PARAM_REG_TOKEN, STATE_TOKEN, "", 74},
1938 {NT_PROG_PARAM_REG_TOKEN, PROGRAM_TOKEN, "", 74},
1939 {NT_PROG_PARAM_REG_TOKEN, LBRACE_TOKEN, "", 74},
1940 {NT_PROG_PARAM_REG_TOKEN, FLOAT_TOKEN, "-1", 74},
1941
1942 {NT_PROG_PARAM_SINGLE_TOKEN, ID_TOKEN, "-1", 75},
1943 {NT_PROG_PARAM_ARRAY_TOKEN, ID_TOKEN, "-1", 76},
1944 {NT_PROG_PARAM_ARRAY_MEM_TOKEN, INTEGER_TOKEN, "-1", 77},
1945 {NT_PROG_PARAM_ARRAY_MEM_TOKEN, ID_TOKEN, "-1", 78},
1946 {NT_PROG_PARAM_ARRAY_ABS_TOKEN, INTEGER_TOKEN, "-1", 79},
1947 {NT_PROG_PARAM_ARRAY_REL_TOKEN, ID_TOKEN, "-1", 80},
1948
1949 {NT_ADDR_REG_REL_OFFSET_TOKEN, RBRACKET_TOKEN, "", 81},
1950 {NT_ADDR_REG_REL_OFFSET_TOKEN, PLUS_TOKEN, "", 82},
1951 {NT_ADDR_REG_REL_OFFSET_TOKEN, MINUS_TOKEN, "", 83},
1952 {NT_ADDR_REG_POS_OFFSET_TOKEN, INTEGER_TOKEN, "-1", 84},
1953 {NT_ADDR_REG_NEG_OFFSET_TOKEN, INTEGER_TOKEN, "-1", 85},
1954
1955
1956 {NT_VERTEX_RESULT_REG_TOKEN, ID_TOKEN, "-1", 86},
1957 {NT_VERTEX_RESULT_REG_TOKEN, RESULT_TOKEN, "", 87},
1958 {NT_ADDR_REG_TOKEN, ID_TOKEN, "-1", 88},
1959 {NT_ADDR_COMPONENT_TOKEN, PERIOD_TOKEN, "", 89},
1960 {NT_ADDR_WRITE_MASK_TOKEN, PERIOD_TOKEN, "", 90},
1961
1962 {NT_SCALAR_SUFFIX_TOKEN, PERIOD_TOKEN, "", 91},
1963
1964 {NT_SWIZZLE_SUFFIX_TOKEN, COMMA_TOKEN, "", 92},
1965 {NT_SWIZZLE_SUFFIX_TOKEN, SEMICOLON_TOKEN, "", 92},
1966 {NT_SWIZZLE_SUFFIX_TOKEN, PERIOD_TOKEN, "", 317},
1967
1968 {NT_COMPONENT_TOKEN, ID_TOKEN, "x", 93},
1969 {NT_COMPONENT_TOKEN, ID_TOKEN, "y", 94},
1970 {NT_COMPONENT_TOKEN, ID_TOKEN, "z", 95},
1971 {NT_COMPONENT_TOKEN, ID_TOKEN, "w", 96},
1972
1973 {NT_OPTIONAL_MASK_TOKEN, PERIOD_TOKEN, "", 97},
1974 {NT_OPTIONAL_MASK_TOKEN, COMMA_TOKEN, "", 98},
1975
1976 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "x", 99},
1977 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "y", 100},
1978 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xy", 101},
1979 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "z", 102},
1980 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xz", 103},
1981 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "yz", 104},
1982 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xyz", 105},
1983 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "w", 106},
1984 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xw", 107},
1985 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "yw", 108},
1986 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xyw", 109},
1987 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "zw", 110},
1988 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xzw", 111},
1989 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "yzw", 112},
1990 {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xyzw", 113},
1991
1992
1993 {NT_NAMING_STATEMENT_TOKEN, ATTRIB_TOKEN, "", 114},
1994 {NT_NAMING_STATEMENT_TOKEN, PARAM_TOKEN, "", 115},
1995 {NT_NAMING_STATEMENT_TOKEN, TEMP_TOKEN, "", 116},
1996 {NT_NAMING_STATEMENT_TOKEN, ADDRESS_TOKEN, "", 117},
1997 {NT_NAMING_STATEMENT_TOKEN, OUTPUT_TOKEN, "", 118},
1998 {NT_NAMING_STATEMENT_TOKEN, ALIAS_TOKEN, "", 119},
1999
2000 {NT_ATTRIB_STATEMENT_TOKEN, ATTRIB_TOKEN, "", 120},
2001 {NT_VTX_ATTRIB_BINDING_TOKEN, VERTEX_TOKEN, "", 121},
2002
2003 {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "position", 122},
2004 {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "weight", 123},
2005 {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "normal", 124},
2006 {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "color", 125},
2007 {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "fogcoord", 126},
2008 {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "texcoord", 127},
2009 {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "matrixindex", 128},
2010 {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "attrib", 129},
2011
2012 {NT_VTX_ATTRIB_NUM_TOKEN, INTEGER_TOKEN, "-1", 130},
2013 {NT_VTX_OPT_WEIGHT_NUM_TOKEN, SEMICOLON_TOKEN, "", 131},
2014 {NT_VTX_OPT_WEIGHT_NUM_TOKEN, COMMA_TOKEN, "", 131},
2015 {NT_VTX_OPT_WEIGHT_NUM_TOKEN, PERIOD_TOKEN, "", 131},
2016 {NT_VTX_OPT_WEIGHT_NUM_TOKEN, LBRACKET_TOKEN, "", 132},
2017
2018 {NT_VTX_WEIGHT_NUM_TOKEN, INTEGER_TOKEN, "-1", 133},
2019 {NT_PARAM_STATEMENT_TOKEN, PARAM_TOKEN, "", 134},
2020 {NT_PARAM_STATEMENT2_TOKEN, EQUAL_TOKEN, "", 135},
2021 {NT_PARAM_STATEMENT2_TOKEN, LBRACKET_TOKEN, "", 136},
2022
2023 {NT_OPT_ARRAY_SIZE_TOKEN, RBRACKET_TOKEN, "", 137},
2024 {NT_OPT_ARRAY_SIZE_TOKEN, INTEGER_TOKEN, "-1", 138},
2025
2026 {NT_PARAM_SINGLE_INIT_TOKEN, EQUAL_TOKEN, "", 139},
2027 {NT_PARAM_MULTIPLE_INIT_TOKEN, EQUAL_TOKEN, "", 140},
2028
2029 {NT_PARAM_MULT_INIT_LIST_TOKEN, STATE_TOKEN, "", 141},
2030 {NT_PARAM_MULT_INIT_LIST_TOKEN, PROGRAM_TOKEN, "", 141},
2031 {NT_PARAM_MULT_INIT_LIST_TOKEN, PLUS_TOKEN, "", 141},
2032 {NT_PARAM_MULT_INIT_LIST_TOKEN, MINUS_TOKEN, "", 141},
2033 {NT_PARAM_MULT_INIT_LIST_TOKEN, FLOAT_TOKEN, "-1", 141},
2034 {NT_PARAM_MULT_INIT_LIST_TOKEN, INTEGER_TOKEN, "-1", 141},
2035 {NT_PARAM_MULT_INIT_LIST_TOKEN, LBRACE_TOKEN, "", 141},
2036
2037
2038 {NT_PARAM_MULT_INIT_LIST2_TOKEN, COMMA_TOKEN, "", 142},
2039 {NT_PARAM_MULT_INIT_LIST2_TOKEN, RBRACE_TOKEN, "", 143},
2040
2041
2042 {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, STATE_TOKEN, "", 144},
2043 {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, PROGRAM_TOKEN, "", 145},
2044 {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, PLUS_TOKEN, "", 146},
2045 {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, MINUS_TOKEN, "", 146},
2046 {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, FLOAT_TOKEN, "-1", 146},
2047 {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, INTEGER_TOKEN, "-1", 146},
2048 {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, LBRACE_TOKEN, "", 146},
2049
2050
2051 {NT_PARAM_SINGLE_ITEM_USE_TOKEN, STATE_TOKEN, "", 147},
2052 {NT_PARAM_SINGLE_ITEM_USE_TOKEN, PROGRAM_TOKEN, "", 148},
2053 {NT_PARAM_SINGLE_ITEM_USE_TOKEN, LBRACE_TOKEN, "", 149},
2054 {NT_PARAM_SINGLE_ITEM_USE_TOKEN, FLOAT_TOKEN, "-1", 149},
2055 {NT_PARAM_SINGLE_ITEM_USE_TOKEN, INTEGER_TOKEN, "-1", 149},
2056
2057 {NT_PARAM_MULTIPLE_ITEM_TOKEN, STATE_TOKEN, "", 150},
2058 {NT_PARAM_MULTIPLE_ITEM_TOKEN, PROGRAM_TOKEN, "", 151},
2059 {NT_PARAM_MULTIPLE_ITEM_TOKEN, PLUS_TOKEN, "", 152},
2060 {NT_PARAM_MULTIPLE_ITEM_TOKEN, MINUS_TOKEN, "", 152},
2061 {NT_PARAM_MULTIPLE_ITEM_TOKEN, FLOAT_TOKEN, "-1", 152},
2062 {NT_PARAM_MULTIPLE_ITEM_TOKEN, INTEGER_TOKEN, "-1", 152},
2063 {NT_PARAM_MULTIPLE_ITEM_TOKEN, LBRACE_TOKEN, "", 152},
2064
2065 {NT_STATE_MULTIPLE_ITEM_TOKEN, STATE_TOKEN, "", 153},
2066 {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "material", 154},
2067 {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "light", 155},
2068 {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "lightmodel", 156},
2069 {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "lightprod", 157},
2070 {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "texgen", 158},
2071 {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "fog", 159},
2072 {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "clip", 160},
2073 {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "point", 161},
2074 {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "matrix", 162},
2075
2076 {NT_FOO_TOKEN, PERIOD_TOKEN, "", 163},
2077 {NT_FOO_TOKEN, COMMA_TOKEN, "", 316},
2078 {NT_FOO_TOKEN, RBRACE_TOKEN, "", 316},
2079 {NT_FOO2_TOKEN, ID_TOKEN, "inverse", 164},
2080 {NT_FOO2_TOKEN, ID_TOKEN, "transpose", 164},
2081 {NT_FOO2_TOKEN, ID_TOKEN, "invtrans", 164},
2082 {NT_FOO2_TOKEN, ID_TOKEN, "row", 165},
2083 {NT_FOO3_TOKEN, COMMA_TOKEN, "", 166},
2084 {NT_FOO3_TOKEN, RBRACE_TOKEN, "", 166},
2085 {NT_FOO3_TOKEN, PERIOD_TOKEN, "", 167},
2086
2087 {NT_FOO35_TOKEN, INTEGER_TOKEN, "-1", 168},
2088 {NT_FOO4_TOKEN, RBRACKET_TOKEN, "", 169},
2089 {NT_FOO4_TOKEN, DOTDOT_TOKEN, "", 170},
2090
2091 {NT_STATE_SINGLE_ITEM_TOKEN, STATE_TOKEN, "", 171},
2092 {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "material", 172},
2093 {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "light", 173},
2094 {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "lightmodel", 174},
2095 {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "lightprod", 175},
2096 {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "texgen", 176},
2097 {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "fog", 177},
2098 {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "clip", 178},
2099 {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "point", 179},
2100 {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "matrix", 180},
2101
2102
2103 {NT_STATE_MATERIAL_ITEM_TOKEN, ID_TOKEN, "material", 181},
2104 {NT_STATE_MATERIAL_ITEM2_TOKEN, ID_TOKEN, "ambient", 182},
2105 {NT_STATE_MATERIAL_ITEM2_TOKEN, ID_TOKEN, "diffuse", 182},
2106 {NT_STATE_MATERIAL_ITEM2_TOKEN, ID_TOKEN, "specular", 182},
2107 {NT_STATE_MATERIAL_ITEM2_TOKEN, ID_TOKEN, "emission", 182},
2108 {NT_STATE_MATERIAL_ITEM2_TOKEN, ID_TOKEN, "shininess", 182},
2109
2110 {NT_STATE_MATERIAL_ITEM2_TOKEN, PERIOD_TOKEN, "", 183},
2111 {NT_STATE_MAT_PROPERTY_TOKEN, ID_TOKEN, "ambient", 184},
2112 {NT_STATE_MAT_PROPERTY_TOKEN, ID_TOKEN, "diffuse", 185},
2113 {NT_STATE_MAT_PROPERTY_TOKEN, ID_TOKEN, "specular", 186},
2114 {NT_STATE_MAT_PROPERTY_TOKEN, ID_TOKEN, "emission", 187},
2115 {NT_STATE_MAT_PROPERTY_TOKEN, ID_TOKEN, "shininess", 188},
2116
2117
2118 {NT_STATE_LIGHT_ITEM_TOKEN, ID_TOKEN, "light", 189},
2119 {NT_STATE_LIGHT_ITEM2_TOKEN, RBRACKET_TOKEN, "", 190},
2120
2121
2122 {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "ambient", 191},
2123 {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "diffuse", 192},
2124 {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "specular", 193},
2125 {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "position", 194},
2126 {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "attenuation", 195},
2127 {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "spot", 196},
2128 {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "half", 197},
2129
2130 {NT_STATE_SPOT_PROPERTY_TOKEN, ID_TOKEN, "direction", 198},
2131 {NT_STATE_LIGHT_MODEL_ITEM_TOKEN, ID_TOKEN, "lightmodel", 199},
2132
2133
2134 {NT_STATE_LMOD_PROPERTY_TOKEN, PERIOD_TOKEN, "", 200},
2135 {NT_STATE_LMOD_PROPERTY2_TOKEN, ID_TOKEN, "ambient", 201},
2136 {NT_STATE_LMOD_PROPERTY2_TOKEN, ID_TOKEN, "scenecolor", 202},
2137 {NT_STATE_LMOD_PROPERTY2_TOKEN, ID_TOKEN, "front", 203},
2138 {NT_STATE_LMOD_PROPERTY2_TOKEN, ID_TOKEN, "back", 203},
2139
2140
2141 {NT_STATE_LIGHT_PROD_ITEM_TOKEN, ID_TOKEN, "lightprod", 204},
2142 {NT_STATE_LIGHT_PROD_ITEM15_TOKEN, RBRACKET_TOKEN, "", 205},
2143 {NT_STATE_LIGHT_PROD_ITEM2_TOKEN, ID_TOKEN, "ambient", 206},
2144 {NT_STATE_LIGHT_PROD_ITEM2_TOKEN, ID_TOKEN, "diffuse", 206},
2145 {NT_STATE_LIGHT_PROD_ITEM2_TOKEN, ID_TOKEN, "specular", 206},
2146 {NT_STATE_LIGHT_PROD_ITEM2_TOKEN, ID_TOKEN, "front", 207},
2147 {NT_STATE_LIGHT_PROD_ITEM2_TOKEN, ID_TOKEN, "back", 207},
2148
2149 {NT_STATE_LPROD_PROPERTY_TOKEN, ID_TOKEN, "ambient", 208},
2150 {NT_STATE_LPROD_PROPERTY_TOKEN, ID_TOKEN, "diffuse", 209},
2151 {NT_STATE_LPROD_PROPERTY_TOKEN, ID_TOKEN, "specular", 210},
2152
2153 {NT_STATE_LIGHT_NUMBER_TOKEN, INTEGER_TOKEN, "-1", 211},
2154 {NT_STATE_TEX_GEN_ITEM_TOKEN, ID_TOKEN, "texgen", 212},
2155 {NT_STATE_TEX_GEN_ITEM2_TOKEN, PERIOD_TOKEN, "", 213},
2156 {NT_STATE_TEX_GEN_TYPE_TOKEN, ID_TOKEN, "eye", 214},
2157 {NT_STATE_TEX_GEN_TYPE_TOKEN, ID_TOKEN, "object", 215},
2158
2159
2160 {NT_STATE_TEX_GEN_COORD_TOKEN, ID_TOKEN, "s", 216},
2161 {NT_STATE_TEX_GEN_COORD_TOKEN, ID_TOKEN, "t", 217},
2162 {NT_STATE_TEX_GEN_COORD_TOKEN, ID_TOKEN, "r", 218},
2163 {NT_STATE_TEX_GEN_COORD_TOKEN, ID_TOKEN, "q", 219},
2164
2165 {NT_STATE_FOG_ITEM_TOKEN, ID_TOKEN, "fog", 220},
2166
2167 {NT_STATE_FOG_PROPERTY_TOKEN, ID_TOKEN, "color", 221},
2168 {NT_STATE_FOG_PROPERTY_TOKEN, ID_TOKEN, "params", 222},
2169
2170 {NT_STATE_CLIP_PLANE_ITEM_TOKEN, ID_TOKEN, "clip", 223},
2171 {NT_STATE_CLIP_PLANE_ITEM2_TOKEN, RBRACKET_TOKEN, "", 224},
2172 {NT_STATE_CLIP_PLANE_NUM_TOKEN, INTEGER_TOKEN, "-1", 225},
2173 {NT_STATE_POINT_ITEM_TOKEN, ID_TOKEN, "point", 226},
2174 {NT_STATE_POINT_PROPERTY_TOKEN, ID_TOKEN, "size", 227},
2175 {NT_STATE_POINT_PROPERTY_TOKEN, ID_TOKEN, "attenuation", 228},
2176
2177
2178 {NT_STATE_MATRIX_ROW_TOKEN, ID_TOKEN, "matrix", 229},
2179 {NT_STATE_MATRIX_ROW15_TOKEN, PERIOD_TOKEN, "", 230},
2180 {NT_STATE_MATRIX_ROW2_TOKEN, ID_TOKEN, "row", 231},
2181 {NT_STATE_MATRIX_ROW2_TOKEN, ID_TOKEN, "inverse", 232},
2182 {NT_STATE_MATRIX_ROW2_TOKEN, ID_TOKEN, "transpose", 232},
2183 {NT_STATE_MATRIX_ROW2_TOKEN, ID_TOKEN, "invtrans", 232},
2184 {NT_STATE_MATRIX_ROW3_TOKEN, LBRACKET_TOKEN, "", 233},
2185
2186 {NT_STATE_MAT_MODIFIER_TOKEN, ID_TOKEN, "inverse", 234},
2187 {NT_STATE_MAT_MODIFIER_TOKEN, ID_TOKEN, "transpose", 235},
2188 {NT_STATE_MAT_MODIFIER_TOKEN, ID_TOKEN, "invtrans", 236},
2189 {NT_STATE_MATRIX_ROW_NUM_TOKEN, INTEGER_TOKEN, "-1", 237},
2190
2191
2192 {NT_STATE_MATRIX_NAME_TOKEN, ID_TOKEN, "modelview", 238},
2193 {NT_STATE_MATRIX_NAME_TOKEN, ID_TOKEN, "projection", 239},
2194 {NT_STATE_MATRIX_NAME_TOKEN, ID_TOKEN, "mvp", 240},
2195 {NT_STATE_MATRIX_NAME_TOKEN, ID_TOKEN, "texture", 241},
2196 {NT_STATE_MATRIX_NAME_TOKEN, ID_TOKEN, "palette", 242},
2197 {NT_STATE_MATRIX_NAME_TOKEN, PROGRAM_TOKEN, "", 243},
2198
2199 {NT_STATE_OPT_MOD_MAT_NUM_TOKEN, PERIOD_TOKEN, "", 244},
2200 {NT_STATE_OPT_MOD_MAT_NUM_TOKEN, COMMA_TOKEN, "", 244},
2201 {NT_STATE_OPT_MOD_MAT_NUM_TOKEN, RBRACE_TOKEN, "", 244},
2202 {NT_STATE_OPT_MOD_MAT_NUM_TOKEN, LBRACKET_TOKEN, "", 245},
2203
2204 {NT_STATE_MOD_MAT_NUM_TOKEN, INTEGER_TOKEN, "-1", 246},
2205 {NT_STATE_PALETTE_MAT_NUM_TOKEN, INTEGER_TOKEN, "-1", 247},
2206 {NT_STATE_PROGRAM_MAT_NUM_TOKEN, INTEGER_TOKEN, "-1", 248},
2207
2208 {NT_PROGRAM_SINGLE_ITEM_TOKEN, PROGRAM_TOKEN, "", 249},
2209 {NT_PROGRAM_SINGLE_ITEM2_TOKEN, ID_TOKEN, "env", 250},
2210 {NT_PROGRAM_SINGLE_ITEM2_TOKEN, ID_TOKEN, "local", 251},
2211
2212
2213 {NT_PROGRAM_MULTIPLE_ITEM_TOKEN, PROGRAM_TOKEN, "", 252},
2214 {NT_PROGRAM_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "env", 253},
2215 {NT_PROGRAM_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "local", 254},
2216 {NT_PROG_ENV_PARAMS_TOKEN, ID_TOKEN, "env", 255},
2217 {NT_PROG_ENV_PARAM_NUMS_TOKEN, INTEGER_TOKEN, "-1", 256},
2218 {NT_PROG_ENV_PARAM_NUMS2_TOKEN, DOTDOT_TOKEN, "", 257},
2219 {NT_PROG_ENV_PARAM_NUMS2_TOKEN, RBRACKET_TOKEN, "", 258},
2220 {NT_PROG_ENV_PARAM_TOKEN, ID_TOKEN, "env", 259},
2221
2222 {NT_PROG_LOCAL_PARAMS_TOKEN, ID_TOKEN, "local", 260},
2223 {NT_PROG_LOCAL_PARAM_NUMS_TOKEN, INTEGER_TOKEN, "-1", 261},
2224 {NT_PROG_LOCAL_PARAM_NUMS2_TOKEN, DOTDOT_TOKEN, "", 262},
2225 {NT_PROG_LOCAL_PARAM_NUMS2_TOKEN, RBRACKET_TOKEN, "", 263},
2226 {NT_PROG_LOCAL_PARAM_TOKEN, ID_TOKEN, "local", 264},
2227 {NT_PROG_ENV_PARAM_NUM_TOKEN, INTEGER_TOKEN, "-1", 265},
2228 {NT_PROG_LOCAL_PARAM_NUM_TOKEN, INTEGER_TOKEN, "-1", 266},
2229 {NT_PARAM_CONST_DECL_TOKEN, PLUS_TOKEN, "", 267},
2230 {NT_PARAM_CONST_DECL_TOKEN, MINUS_TOKEN, "", 267},
2231 {NT_PARAM_CONST_DECL_TOKEN, FLOAT_TOKEN, "-1", 267},
2232 {NT_PARAM_CONST_DECL_TOKEN, INTEGER_TOKEN, "-1", 267},
2233 {NT_PARAM_CONST_DECL_TOKEN, LBRACE_TOKEN, "", 268},
2234
2235 {NT_PARAM_CONST_USE_TOKEN, FLOAT_TOKEN, "-1", 269},
2236 {NT_PARAM_CONST_USE_TOKEN, INTEGER_TOKEN, "-1", 269},
2237 {NT_PARAM_CONST_USE_TOKEN, LBRACE_TOKEN, "", 270},
2238
2239
2240 {NT_PARAM_CONST_SCALAR_DECL_TOKEN, PLUS_TOKEN, "", 271},
2241 {NT_PARAM_CONST_SCALAR_DECL_TOKEN, MINUS_TOKEN, "", 271},
2242 {NT_PARAM_CONST_SCALAR_DECL_TOKEN, FLOAT_TOKEN, "-1", 271},
2243 {NT_PARAM_CONST_SCALAR_DECL_TOKEN, INTEGER_TOKEN, "-1", 271},
2244
2245 {NT_PARAM_CONST_SCALAR_USE_TOKEN, FLOAT_TOKEN, "-1", 272},
2246 {NT_PARAM_CONST_SCALAR_USE_TOKEN, INTEGER_TOKEN, "-1", 272},
2247 {NT_PARAM_CONST_VECTOR_TOKEN, LBRACE_TOKEN, "", 273},
2248 {NT_PARAM_CONST_VECTOR2_TOKEN, RBRACE_TOKEN, "", 274},
2249 {NT_PARAM_CONST_VECTOR2_TOKEN, COMMA_TOKEN, "", 275},
2250 {NT_PARAM_CONST_VECTOR3_TOKEN, RBRACE_TOKEN, "", 276},
2251 {NT_PARAM_CONST_VECTOR3_TOKEN, COMMA_TOKEN, "", 277},
2252 {NT_PARAM_CONST_VECTOR4_TOKEN, RBRACE_TOKEN, "", 278},
2253 {NT_PARAM_CONST_VECTOR4_TOKEN, COMMA_TOKEN, "", 279},
2254
2255 {NT_SIGNED_FLOAT_CONSTANT_TOKEN, PLUS_TOKEN, "", 280},
2256 {NT_SIGNED_FLOAT_CONSTANT_TOKEN, MINUS_TOKEN, "", 280},
2257 {NT_SIGNED_FLOAT_CONSTANT_TOKEN, FLOAT_TOKEN, "-1", 280},
2258 {NT_SIGNED_FLOAT_CONSTANT_TOKEN, INTEGER_TOKEN, "-1", 280},
2259
2260 {NT_OPTIONAL_SIGN_TOKEN, FLOAT_TOKEN, "-1", 281},
2261 {NT_OPTIONAL_SIGN_TOKEN, INTEGER_TOKEN, "0", 281},
2262 {NT_OPTIONAL_SIGN_TOKEN, INTEGER_TOKEN, "1", 281},
2263 {NT_OPTIONAL_SIGN_TOKEN, INTEGER_TOKEN, "-1", 281},
2264 {NT_OPTIONAL_SIGN_TOKEN, ID_TOKEN, "-1", 281},
2265 {NT_OPTIONAL_SIGN_TOKEN, STATE_TOKEN, "", 281},
2266 {NT_OPTIONAL_SIGN_TOKEN, PROGRAM_TOKEN, "", 281},
2267 {NT_OPTIONAL_SIGN_TOKEN, VERTEX_TOKEN, "", 281},
2268 {NT_OPTIONAL_SIGN_TOKEN, LBRACE_TOKEN, "", 281},
2269
2270
2271 {NT_OPTIONAL_SIGN_TOKEN, MINUS_TOKEN, "", 282},
2272 {NT_OPTIONAL_SIGN_TOKEN, PLUS_TOKEN, "", 283},
2273
2274 {NT_TEMP_STATEMENT_TOKEN, TEMP_TOKEN, "", 284},
2275 {NT_ADDRESS_STATEMENT_TOKEN, ADDRESS_TOKEN, "", 285},
2276
2277 /* Special case 286-7 */
2278
2279 {NT_OUTPUT_STATEMENT_TOKEN, OUTPUT_TOKEN, "", 288},
2280 {NT_RESULT_BINDING_TOKEN, RESULT_TOKEN, "", 289},
2281 {NT_RESULT_BINDING2_TOKEN, ID_TOKEN, "position", 290},
2282 {NT_RESULT_BINDING2_TOKEN, ID_TOKEN, "fogcoord", 291},
2283 {NT_RESULT_BINDING2_TOKEN, ID_TOKEN, "pointsize", 292},
2284 {NT_RESULT_BINDING2_TOKEN, ID_TOKEN, "color", 293},
2285 {NT_RESULT_BINDING2_TOKEN, ID_TOKEN, "texcoord", 294},
2286
2287 {NT_RESULT_COL_BINDING_TOKEN, ID_TOKEN, "color", 295},
2288
2289 /* Special case 296-7 */
2290
2291 {NT_RESULT_COL_BINDING3_TOKEN, ID_TOKEN, "front", 298},
2292 {NT_RESULT_COL_BINDING3_TOKEN, ID_TOKEN, "back", 299},
2293
2294 /* Special case 300-301 */
2295
2296 {NT_RESULT_COL_BINDING5_TOKEN, ID_TOKEN, "primary", 302},
2297 {NT_RESULT_COL_BINDING5_TOKEN, ID_TOKEN, "secondary", 303},
2298 {NT_OPT_FACE_TYPE2_TOKEN, ID_TOKEN, "front", 304},
2299 {NT_OPT_FACE_TYPE2_TOKEN, ID_TOKEN, "back", 305},
2300
2301 /* Special case 306-7 */
2302
2303 {NT_OPT_COLOR_TYPE2_TOKEN, ID_TOKEN, "primary", 308},
2304 {NT_OPT_COLOR_TYPE2_TOKEN, ID_TOKEN, "secondary", 309},
2305
2306 {NT_OPT_TEX_COORD_NUM_TOKEN, PERIOD_TOKEN, "", 310},
2307 {NT_OPT_TEX_COORD_NUM_TOKEN, SEMICOLON_TOKEN, "", 310},
2308 {NT_OPT_TEX_COORD_NUM_TOKEN, COMMA_TOKEN, "", 310},
2309 {NT_OPT_TEX_COORD_NUM_TOKEN, RBRACE_TOKEN, "", 310},
2310 {NT_OPT_TEX_COORD_NUM_TOKEN, LBRACKET_TOKEN, "", 311},
2311
2312 {NT_TEX_COORD_NUM_TOKEN, INTEGER_TOKEN, "-1", 312},
2313
2314 /* Special case for 313 to get aliasing correct */
2315
2316 {NT_ESTABLISH_NAME_TOKEN, ID_TOKEN, "-1", 314},
2317 {NT_ESTABLISHED_NAME_TOKEN, ID_TOKEN, "-1", 315},
2318
2319 /* Special case for 318-9 */
2320};
2321
2322static GLint nprods = sizeof(ptab) / sizeof(prod_table);
2323static GLint nlas = sizeof(latab) / sizeof(look_ahead_table);
2324
2325/**
2326 * This is a gigantic FSA to recognize the keywords put forth in the
2327 * GL_ARB_vertex_program spec.
2328 *
2329 * All other tokens are deemed 'identifiers', and shoved into the
2330 * identifier symbol table (as opposed to the GLint and GLfloat symbol tables)
2331 *
2332 * \param s The parse state
2333 * \param token The next token seen is returned in this value
2334 * \param token_attr The token attribute for the next token is returned here. This
2335 * is the index into the approprate symbol table if token is INTEGER_TOKEN,
2336 * FLOAT_TOKEN, or ID_TOKEN
2337 *
2338 * \return ARB_VP_ERROR on lex error, ARB_VP_SUCESS on sucess
2339 */
2340static GLint
2341get_next_token(parse_state * s, GLint * token, GLint * token_attr)
2342{
2343 GLubyte curr;
2344
2345 while (s->start_pos < s->len) {
2346 curr = s->str[s->curr_pos];
2347
2348 switch (s->curr_state) {
2349 /* Default state */
2350 case STATE_BASE:
2351 if (IS_WHITESPACE(curr)) {
2352 s->start_pos++;
2353 s->curr_pos++;
2354 }
2355 else {
2356 if (IS_IDCHAR(curr)) {
2357 switch (curr) {
2358 case 'A':
2359 ADV_TO_STATE(STATE_A);
2360 break;
2361
2362 case 'D':
2363 ADV_TO_STATE(STATE_D);
2364 break;
2365
2366 case 'E':
2367 ADV_TO_STATE(STATE_E);
2368 break;
2369
2370 case 'F':
2371 ADV_TO_STATE(STATE_F);
2372 break;
2373
2374 case 'L':
2375 ADV_TO_STATE(STATE_L);
2376 break;
2377
2378 case 'M':
2379 ADV_TO_STATE(STATE_M);
2380 break;
2381
2382 case 'O':
2383 ADV_TO_STATE(STATE_O);
2384 break;
2385
2386 case 'P':
2387 ADV_TO_STATE(STATE_P);
2388 break;
2389
2390 case 'R':
2391 ADV_TO_STATE(STATE_R);
2392 break;
2393
2394 case 'S':
2395 ADV_TO_STATE(STATE_S);
2396 break;
2397
2398 case 'T':
2399 ADV_TO_STATE(STATE_T);
2400 break;
2401
2402 case 'X':
2403 ADV_TO_STATE(STATE_X);
2404 break;
2405
2406 case 'p':
2407 ADV_TO_STATE(STATE_LC_P);
2408 break;
2409
2410 case 'r':
2411 ADV_TO_STATE(STATE_LC_R);
2412 break;
2413
2414 case 's':
2415 ADV_TO_STATE(STATE_LC_S);
2416 break;
2417
2418 case 'v':
2419 ADV_TO_STATE(STATE_LC_V);
2420 break;
2421
2422 default:
2423 s->curr_state = 1;
2424 s->start_pos = s->curr_pos;
2425 s->curr_pos++;
2426 }
2427 }
2428 else if (IS_DIGIT(curr)) {
2429 ADV_TO_STATE(STATE_N4);
2430 }
2431 else {
2432 switch (curr) {
2433 case '#':
2434 ADV_TO_STATE(STATE_COMMENT);
2435 break;
2436 case ';':
2437 ADV_AND_FINISH(SEMICOLON_TOKEN);
2438 break;
2439 case ',':
2440 ADV_AND_FINISH(COMMA_TOKEN);
2441 break;
2442 case '+':
2443 ADV_AND_FINISH(PLUS_TOKEN);
2444 break;
2445 case '-':
2446 ADV_AND_FINISH(MINUS_TOKEN);
2447 break;
2448 case '[':
2449 ADV_AND_FINISH(LBRACKET_TOKEN);
2450 break;
2451 case ']':
2452 ADV_AND_FINISH(RBRACKET_TOKEN);
2453 break;
2454 case '{':
2455 ADV_AND_FINISH(LBRACE_TOKEN);
2456 break;
2457 case '}':
2458 ADV_AND_FINISH(RBRACE_TOKEN);
2459 break;
2460 case '=':
2461 ADV_AND_FINISH(EQUAL_TOKEN);
2462 break;
2463
2464 case '.':
2465 ADV_TO_STATE(STATE_N1);
2466 break;
2467
2468 default:
2469 return ARB_VP_ERROR;
2470 break;
2471 }
2472 }
2473 }
2474 break;
2475
2476
2477 /* Main identifier state */
2478 case STATE_IDENT:
2479 if (IS_CD(curr)) {
2480 s->curr_pos++;
2481 }
2482 else {
2483 *token = ID_TOKEN;
2484 *token_attr =
2485 id_table_add(&s->idents, s->str, s->start_pos, s->curr_pos);
2486
2487 s->curr_state = 0;
2488 s->start_pos = s->curr_pos;
2489 return ARB_VP_SUCESS;
2490 }
2491 break;
2492
2493 /* -----------------------------------------------------
2494 * Beginning of the A* keywords
2495 */
2496 case STATE_A:
2497 if (IS_CD(curr)) {
2498 switch (curr) {
2499 case 'B':
2500 ADV_TO_STATE(STATE_AB);
2501 break;
2502 case 'D':
2503 ADV_TO_STATE(STATE_AD);
2504 break;
2505 case 'L':
2506 ADV_TO_STATE(STATE_AL);
2507 break;
2508 case 'R':
2509 ADV_TO_STATE(STATE_AR);
2510 break;
2511 case 'T':
2512 ADV_TO_STATE(STATE_AT);
2513 break;
2514 default:
2515 ADV_TO_STATE(STATE_IDENT);
2516 break;
2517 }
2518 }
2519 else {
2520 s->curr_state = 1;
2521 }
2522 break;
2523
2524 case STATE_AB:
2525 ADV_OR_FALLBACK('S', STATE_ABS);
2526 break;
2527
2528 case STATE_ABS:
2529 FINISH_OR_FALLBACK(ABS_TOKEN);
2530 break;
2531
2532 case STATE_AD:
2533 ADV_OR_FALLBACK('D', STATE_ADD);
2534 break;
2535
2536 case STATE_ADD:
2537 if (curr == 'R') {
2538 ADV_TO_STATE(STATE_ADDR);
2539 }
2540 else if (IS_CD(curr)) {
2541 ADV_TO_STATE(STATE_IDENT);
2542 }
2543 else {
2544 FINISH(ADD_TOKEN);
2545 }
2546 break;
2547
2548 case STATE_ADDR:
2549 ADV_OR_FALLBACK('E', STATE_ADDRE);
2550 break;
2551
2552 case STATE_ADDRE:
2553 ADV_OR_FALLBACK('S', STATE_ADDRES);
2554 break;
2555
2556 case STATE_ADDRES:
2557 ADV_OR_FALLBACK('S', STATE_ADDRESS);
2558 break;
2559
2560 case STATE_ADDRESS:
2561 FINISH_OR_FALLBACK(ADDRESS_TOKEN);
2562 break;
2563
2564 case STATE_AL:
2565 ADV_OR_FALLBACK('I', STATE_ALI);
2566 break;
2567
2568 case STATE_ALI:
2569 ADV_OR_FALLBACK('A', STATE_ALIA);
2570 break;
2571
2572 case STATE_ALIA:
2573 ADV_OR_FALLBACK('S', STATE_ALIAS);
2574 break;
2575
2576 case STATE_ALIAS:
2577 FINISH_OR_FALLBACK(ALIAS_TOKEN);
2578 break;
2579
2580 case STATE_AR:
2581 ADV_OR_FALLBACK('L', STATE_ARL);
2582 break;
2583
2584 case STATE_ARL:
2585 FINISH_OR_FALLBACK(ARL_TOKEN);
2586 break;
2587
2588 case STATE_AT:
2589 ADV_OR_FALLBACK('T', STATE_ATT);
2590 break;
2591
2592 case STATE_ATT:
2593 ADV_OR_FALLBACK('R', STATE_ATTR);
2594 break;
2595
2596 case STATE_ATTR:
2597 ADV_OR_FALLBACK('I', STATE_ATTRI);
2598 break;
2599
2600 case STATE_ATTRI:
2601 ADV_OR_FALLBACK('B', STATE_ATTRIB);
2602 break;
2603
2604 case STATE_ATTRIB:
2605 FINISH_OR_FALLBACK(ATTRIB_TOKEN);
2606 break;
2607
2608 /* -----------------------------------------------------
2609 * Beginning of the D* keywords
2610 */
2611 case STATE_D:
2612 if (IS_CD(curr)) {
2613 switch (curr) {
2614 case 'P':
2615 ADV_TO_STATE(STATE_DP);
2616 break;
2617 case 'S':
2618 ADV_TO_STATE(STATE_DS);
2619 break;
2620 default:
2621 ADV_TO_STATE(STATE_IDENT);
2622 break;
2623 }
2624 }
2625 else {
2626 s->curr_state = 1;
2627 }
2628 break;
2629
2630 case STATE_DP:
2631 if (IS_CD(curr)) {
2632 switch (curr) {
2633 case '3':
2634 ADV_TO_STATE(STATE_DP3);
2635 break;
2636 case '4':
2637 ADV_TO_STATE(STATE_DP4);
2638 break;
2639 case 'H':
2640 ADV_TO_STATE(STATE_DPH);
2641 break;
2642 default:
2643 ADV_TO_STATE(STATE_IDENT);
2644 break;
2645 }
2646 }
2647 else {
2648 s->curr_state = 1;
2649 }
2650 break;
2651
2652 case STATE_DP3:
2653 FINISH_OR_FALLBACK(DP3_TOKEN);
2654 break;
2655
2656 case STATE_DP4:
2657 FINISH_OR_FALLBACK(DP4_TOKEN);
2658 break;
2659
2660 case STATE_DPH:
2661 FINISH_OR_FALLBACK(DPH_TOKEN);
2662 break;
2663
2664 case STATE_DS:
2665 ADV_OR_FALLBACK('T', STATE_DST);
2666 break;
2667
2668 case STATE_DST:
2669 FINISH_OR_FALLBACK(DST_TOKEN);
2670 break;
2671
2672 /* -----------------------------------------------------
2673 * Beginning of the E* keywords
2674 */
2675 case STATE_E:
2676 if (IS_CD(curr)) {
2677 switch (curr) {
2678 case 'N':
2679 ADV_TO_STATE(STATE_EN);
2680 break;
2681 case 'X':
2682 ADV_TO_STATE(STATE_EX);
2683 break;
2684 default:
2685 ADV_TO_STATE(STATE_IDENT);
2686 break;
2687 }
2688 }
2689 else {
2690 s->curr_state = 1;
2691 }
2692 break;
2693
2694 case STATE_EN:
2695 ADV_OR_FALLBACK('D', STATE_END);
2696 break;
2697
2698 case STATE_END:
2699 FINISH_OR_FALLBACK(END_TOKEN);
2700 break;
2701
2702 case STATE_EX:
2703 if (IS_CD(curr)) {
2704 switch (curr) {
2705 case '2':
2706 ADV_TO_STATE(STATE_EX2);
2707 break;
2708 case 'P':
2709 ADV_TO_STATE(STATE_EXP);
2710 break;
2711 default:
2712 ADV_TO_STATE(STATE_IDENT);
2713 break;
2714 }
2715 }
2716 else {
2717 s->curr_state = 1;
2718 }
2719 break;
2720
2721 case STATE_EX2:
2722 FINISH_OR_FALLBACK(EX2_TOKEN);
2723 break;
2724
2725 case STATE_EXP:
2726 FINISH_OR_FALLBACK(EXP_TOKEN);
2727 break;
2728
2729 /* -----------------------------------------------------
2730 * Beginning of the F* keywords
2731 */
2732 case STATE_F:
2733 if (IS_CD(curr)) {
2734 switch (curr) {
2735 case 'L':
2736 ADV_TO_STATE(STATE_FL);
2737 break;
2738 case 'R':
2739 ADV_TO_STATE(STATE_FR);
2740 break;
2741 default:
2742 ADV_TO_STATE(STATE_IDENT);
2743 break;
2744 }
2745 }
2746 else {
2747 s->curr_state = 1;
2748 }
2749 break;
2750
2751 case STATE_FL:
2752 ADV_OR_FALLBACK('R', STATE_FLR);
2753 break;
2754
2755 case STATE_FLR:
2756 FINISH_OR_FALLBACK(FLR_TOKEN);
2757 break;
2758
2759 case STATE_FR:
2760 ADV_OR_FALLBACK('C', STATE_FRC);
2761 break;
2762
2763 case STATE_FRC:
2764 FINISH_OR_FALLBACK(FRC_TOKEN);
2765 break;
2766
2767 /* -----------------------------------------------------
2768 * Beginning of the L* keywords
2769 */
2770 case STATE_L:
2771 if (IS_CD(curr)) {
2772 switch (curr) {
2773 case 'G':
2774 ADV_TO_STATE(STATE_LG);
2775 break;
2776 case 'I':
2777 ADV_TO_STATE(STATE_LI);
2778 break;
2779 case 'O':
2780 ADV_TO_STATE(STATE_LO);
2781 break;
2782 default:
2783 ADV_TO_STATE(STATE_IDENT);
2784 break;
2785 }
2786 }
2787 else {
2788 s->curr_state = 1;
2789 }
2790 break;
2791
2792 case STATE_LG:
2793 ADV_OR_FALLBACK('2', STATE_LG2);
2794 break;
2795
2796 case STATE_LG2:
2797 FINISH_OR_FALLBACK(LG2_TOKEN);
2798 break;
2799
2800 case STATE_LI:
2801 ADV_OR_FALLBACK('T', STATE_LIT);
2802 break;
2803
2804 case STATE_LIT:
2805 FINISH_OR_FALLBACK(LIT_TOKEN);
2806 break;
2807
2808 case STATE_LO:
2809 ADV_OR_FALLBACK('G', STATE_LOG);
2810 break;
2811
2812 case STATE_LOG:
2813 FINISH_OR_FALLBACK(LOG_TOKEN);
2814 break;
2815
2816 /* -----------------------------------------------------
2817 * Beginning of the M* keywords
2818 */
2819 case STATE_M:
2820 if (IS_CD(curr)) {
2821 switch (curr) {
2822 case 'A':
2823 ADV_TO_STATE(STATE_MA);
2824 break;
2825 case 'I':
2826 ADV_TO_STATE(STATE_MI);
2827 break;
2828 case 'O':
2829 ADV_TO_STATE(STATE_MO);
2830 break;
2831 case 'U':
2832 ADV_TO_STATE(STATE_MU);
2833 break;
2834 default:
2835 ADV_TO_STATE(STATE_IDENT);
2836 break;
2837 }
2838 }
2839 else {
2840 s->curr_state = 1;
2841 }
2842 break;
2843
2844 case STATE_MA:
2845 if (IS_CD(curr)) {
2846 switch (curr) {
2847 case 'D':
2848 ADV_TO_STATE(STATE_MAD);
2849 break;
2850 case 'X':
2851 ADV_TO_STATE(STATE_MAX);
2852 break;
2853 default:
2854 ADV_TO_STATE(STATE_IDENT);
2855 break;
2856 }
2857 }
2858 else {
2859 s->curr_state = 1;
2860 }
2861 break;
2862
2863 case STATE_MAD:
2864 FINISH_OR_FALLBACK(MAD_TOKEN);
2865 break;
2866
2867 case STATE_MAX:
2868 FINISH_OR_FALLBACK(MAX_TOKEN);
2869 break;
2870
2871 case STATE_MI:
2872 ADV_OR_FALLBACK('N', STATE_MIN);
2873 break;
2874
2875 case STATE_MIN:
2876 FINISH_OR_FALLBACK(MIN_TOKEN);
2877 break;
2878
2879 case STATE_MO:
2880 ADV_OR_FALLBACK('V', STATE_MOV);
2881 break;
2882
2883 case STATE_MOV:
2884 FINISH_OR_FALLBACK(MOV_TOKEN);
2885 break;
2886
2887 case STATE_MU:
2888 ADV_OR_FALLBACK('L', STATE_MUL);
2889 break;
2890
2891 case STATE_MUL:
2892 FINISH_OR_FALLBACK(MUL_TOKEN);
2893 break;
2894
2895 /* -----------------------------------------------------
2896 * Beginning of the O* keywords
2897 */
2898 case STATE_O:
2899 if (IS_CD(curr)) {
2900 switch (curr) {
2901 case 'P':
2902 ADV_TO_STATE(STATE_OP);
2903 break;
2904 case 'U':
2905 ADV_TO_STATE(STATE_OU);
2906 break;
2907 default:
2908 ADV_TO_STATE(STATE_IDENT);
2909 break;
2910 }
2911 }
2912 else {
2913 s->curr_state = 1;
2914 }
2915 break;
2916
2917 case STATE_OP:
2918 ADV_OR_FALLBACK('T', STATE_OPT);
2919 break;
2920
2921 case STATE_OPT:
2922 ADV_OR_FALLBACK('I', STATE_OPTI);
2923 break;
2924
2925 case STATE_OPTI:
2926 ADV_OR_FALLBACK('O', STATE_OPTIO);
2927 break;
2928
2929 case STATE_OPTIO:
2930 ADV_OR_FALLBACK('N', STATE_OPTION);
2931 break;
2932
2933 case STATE_OPTION:
2934 FINISH_OR_FALLBACK(OPTION_TOKEN);
2935 break;
2936
2937 case STATE_OU:
2938 ADV_OR_FALLBACK('T', STATE_OUT);
2939 break;
2940
2941 case STATE_OUT:
2942 ADV_OR_FALLBACK('P', STATE_OUTP);
2943 break;
2944
2945 case STATE_OUTP:
2946 ADV_OR_FALLBACK('U', STATE_OUTPU);
2947 break;
2948
2949 case STATE_OUTPU:
2950 ADV_OR_FALLBACK('T', STATE_OUTPUT);
2951 break;
2952
2953 case STATE_OUTPUT:
2954 FINISH_OR_FALLBACK(OUTPUT_TOKEN);
2955 break;
2956
2957 /* -----------------------------------------------------
2958 * Beginning of the P* keywords
2959 */
2960 case STATE_P:
2961 if (IS_CD(curr)) {
2962 switch (curr) {
2963 case 'A':
2964 ADV_TO_STATE(STATE_PA);
2965 break;
2966 case 'O':
2967 ADV_TO_STATE(STATE_PO);
2968 break;
2969 default:
2970 ADV_TO_STATE(STATE_IDENT);
2971 break;
2972 }
2973 }
2974 else {
2975 s->curr_state = 1;
2976 }
2977 break;
2978
2979 case STATE_PA:
2980 ADV_OR_FALLBACK('R', STATE_PAR);
2981 break;
2982
2983 case STATE_PAR:
2984 ADV_OR_FALLBACK('A', STATE_PARA);
2985 break;
2986
2987 case STATE_PARA:
2988 ADV_OR_FALLBACK('M', STATE_PARAM);
2989 break;
2990
2991 case STATE_PARAM:
2992 FINISH_OR_FALLBACK(PARAM_TOKEN);
2993 break;
2994
2995 case STATE_PO:
2996 ADV_OR_FALLBACK('W', STATE_POW);
2997 break;
2998
2999 case STATE_POW:
3000 FINISH_OR_FALLBACK(POW_TOKEN);
3001 break;
3002
3003 /* -----------------------------------------------------
3004 * Beginning of the R* keywords
3005 */
3006 case STATE_R:
3007 if (IS_CD(curr)) {
3008 switch (curr) {
3009 case 'C':
3010 ADV_TO_STATE(STATE_RC);
3011 break;
3012 case 'S':
3013 ADV_TO_STATE(STATE_RS);
3014 break;
3015 default:
3016 ADV_TO_STATE(STATE_IDENT);
3017 break;
3018 }
3019 }
3020 else {
3021 s->curr_state = 1;
3022 }
3023 break;
3024
3025 case STATE_RC:
3026 ADV_OR_FALLBACK('P', STATE_RCP);
3027 break;
3028
3029 case STATE_RCP:
3030 FINISH_OR_FALLBACK(RCP_TOKEN);
3031 break;
3032
3033 case STATE_RS:
3034 ADV_OR_FALLBACK('Q', STATE_RSQ);
3035 break;
3036
3037 case STATE_RSQ:
3038 FINISH_OR_FALLBACK(RSQ_TOKEN);
3039 break;
3040
3041 /* -----------------------------------------------------
3042 * Beginning of the S* keywords
3043 */
3044 case STATE_S:
3045 if (IS_CD(curr)) {
3046 switch (curr) {
3047 case 'G':
3048 ADV_TO_STATE(STATE_SG);
3049 break;
3050 case 'L':
3051 ADV_TO_STATE(STATE_SL);
3052 break;
3053 case 'U':
3054 ADV_TO_STATE(STATE_SU);
3055 break;
3056 case 'W':
3057 ADV_TO_STATE(STATE_SW);
3058 break;
3059 default:
3060 ADV_TO_STATE(STATE_IDENT);
3061 break;
3062 }
3063 }
3064 else {
3065 s->curr_state = 1;
3066 }
3067 break;
3068
3069 case STATE_SG:
3070 ADV_OR_FALLBACK('E', STATE_SGE);
3071 break;
3072
3073 case STATE_SGE:
3074 FINISH_OR_FALLBACK(SGE_TOKEN);
3075 break;
3076
3077 case STATE_SL:
3078 ADV_OR_FALLBACK('T', STATE_SLT);
3079 break;
3080
3081 case STATE_SLT:
3082 FINISH_OR_FALLBACK(SLT_TOKEN);
3083 break;
3084
3085 case STATE_SU:
3086 ADV_OR_FALLBACK('B', STATE_SUB);
3087 break;
3088
3089 case STATE_SUB:
3090 FINISH_OR_FALLBACK(SUB_TOKEN);
3091 break;
3092
3093 case STATE_SW:
3094 ADV_OR_FALLBACK('Z', STATE_SWZ);
3095 break;
3096
3097 case STATE_SWZ:
3098 FINISH_OR_FALLBACK(SWZ_TOKEN);
3099 break;
3100
3101 /* -----------------------------------------------------
3102 * Beginning of the T* keywords
3103 */
3104 case STATE_T:
3105 ADV_OR_FALLBACK('E', STATE_TE);
3106 break;
3107
3108 case STATE_TE:
3109 ADV_OR_FALLBACK('M', STATE_TEM);
3110 break;
3111
3112 case STATE_TEM:
3113 ADV_OR_FALLBACK('P', STATE_TEMP);
3114 break;
3115
3116 case STATE_TEMP:
3117 FINISH_OR_FALLBACK(TEMP_TOKEN);
3118 break;
3119
3120 /* -----------------------------------------------------
3121 * Beginning of the X* keywords
3122 */
3123 case STATE_X:
3124 ADV_OR_FALLBACK('P', STATE_XP);
3125 break;
3126
3127 case STATE_XP:
3128 ADV_OR_FALLBACK('D', STATE_XPD);
3129 break;
3130
3131 case STATE_XPD:
3132 FINISH_OR_FALLBACK(XPD_TOKEN);
3133 break;
3134
3135 /* -----------------------------------------------------
3136 * Beginning of the p* keywords
3137 */
3138 case STATE_LC_P:
3139 ADV_OR_FALLBACK('r', STATE_LC_PR);
3140 break;
3141
3142 case STATE_LC_PR:
3143 ADV_OR_FALLBACK('o', STATE_LC_PRO);
3144 break;
3145
3146 case STATE_LC_PRO:
3147 ADV_OR_FALLBACK('g', STATE_LC_PROG);
3148 break;
3149
3150 case STATE_LC_PROG:
3151 ADV_OR_FALLBACK('r', STATE_LC_PROGR);
3152 break;
3153
3154 case STATE_LC_PROGR:
3155 ADV_OR_FALLBACK('a', STATE_LC_PROGRA);
3156 break;
3157
3158 case STATE_LC_PROGRA:
3159 ADV_OR_FALLBACK('m', STATE_LC_PROGRAM);
3160 break;
3161
3162 case STATE_LC_PROGRAM:
3163 FINISH_OR_FALLBACK(PROGRAM_TOKEN);
3164 break;
3165
3166 /* -----------------------------------------------------
3167 * Beginning of the r* keywords
3168 */
3169 case STATE_LC_R:
3170 ADV_OR_FALLBACK('e', STATE_LC_RE);
3171 break;
3172
3173 case STATE_LC_RE:
3174 ADV_OR_FALLBACK('s', STATE_LC_RES);
3175 break;
3176
3177 case STATE_LC_RES:
3178 ADV_OR_FALLBACK('u', STATE_LC_RESU);
3179 break;
3180
3181 case STATE_LC_RESU:
3182 ADV_OR_FALLBACK('l', STATE_LC_RESUL);
3183 break;
3184
3185 case STATE_LC_RESUL:
3186 ADV_OR_FALLBACK('t', STATE_LC_RESULT);
3187 break;
3188
3189 case STATE_LC_RESULT:
3190 FINISH_OR_FALLBACK(RESULT_TOKEN);
3191 break;
3192
3193 /* -----------------------------------------------------
3194 * Beginning of the s* keywords
3195 */
3196 case STATE_LC_S:
3197 ADV_OR_FALLBACK('t', STATE_LC_ST);
3198 break;
3199
3200 case STATE_LC_ST:
3201 ADV_OR_FALLBACK('a', STATE_LC_STA);
3202 break;
3203
3204 case STATE_LC_STA:
3205 ADV_OR_FALLBACK('t', STATE_LC_STAT);
3206 break;
3207
3208 case STATE_LC_STAT:
3209 ADV_OR_FALLBACK('e', STATE_LC_STATE);
3210 break;
3211
3212 case STATE_LC_STATE:
3213 FINISH_OR_FALLBACK(STATE_TOKEN);
3214 break;
3215
3216 /* -----------------------------------------------------
3217 * Beginning of the v* keywords
3218 */
3219 case STATE_LC_V:
3220 ADV_OR_FALLBACK('e', STATE_LC_VE);
3221 break;
3222
3223 case STATE_LC_VE:
3224 ADV_OR_FALLBACK('r', STATE_LC_VER);
3225 break;
3226
3227 case STATE_LC_VER:
3228 ADV_OR_FALLBACK('t', STATE_LC_VERT);
3229 break;
3230
3231 case STATE_LC_VERT:
3232 ADV_OR_FALLBACK('e', STATE_LC_VERTE);
3233 break;
3234
3235 case STATE_LC_VERTE:
3236 ADV_OR_FALLBACK('x', STATE_LC_VERTEX);
3237 break;
3238
3239 case STATE_LC_VERTEX:
3240 FINISH_OR_FALLBACK(VERTEX_TOKEN);
3241 break;
3242
3243 /* -----------------------------------------------------
3244 * Beginning of the number & comment FSAs
3245 */
3246 case STATE_N1:
3247 if (curr == '.') {
3248 ADV_TO_STATE(STATE_N2);
3249 }
3250 else if (IS_DIGIT(curr)) {
3251 ADV_TO_STATE(STATE_N3);
3252 }
3253 else {
3254 //ADV_AND_FINISH(PERIOD_TOKEN);
3255 FINISH(PERIOD_TOKEN);
3256 }
3257 break;
3258
3259 case STATE_N2:
3260#if 1
3261 //ADV_AND_FINISH(DOTDOT_TOKEN);
3262 FINISH(DOTDOT_TOKEN);
3263#else
3264 FINISH(PERIOD_TOKEN);
3265#endif
3266 break;
3267
3268 case STATE_N3:
3269 if (IS_DIGIT(curr)) {
3270 ADV_TO_STATE(STATE_N3);
3271 }
3272 else if ((curr == 'E') || (curr == 'e')) {
3273 ADV_TO_STATE(STATE_N5);
3274 }
3275 else if (curr == '.') {
3276 /* Blech! we have something like 1.. -> have to backup */
3277 s->curr_pos -= 1;
3278 *token_attr =
3279 int_table_add(&s->ints, s->str, s->start_pos, s->curr_pos);
3280 FINISH(INTEGER_TOKEN);
3281 }
3282 else {
3283 *token_attr =
3284 float_table_add(&s->floats, s->str, s->start_pos, s->curr_pos);
3285 //ADV_AND_FINISH(FLOAT_TOKEN);
3286 FINISH(FLOAT_TOKEN);
3287 }
3288 break;
3289
3290 case STATE_N4:
3291 if (IS_DIGIT(curr)) {
3292 ADV_TO_STATE(STATE_N4);
3293 }
3294 else if ((curr == 'E') || (curr == 'e')) {
3295 ADV_TO_STATE(STATE_N5);
3296 }
3297 else if (curr == '.') {
3298 ADV_TO_STATE(STATE_N3);
3299 }
3300 else {
3301 *token_attr =
3302 int_table_add(&s->ints, s->str, s->start_pos, s->curr_pos);
3303 //ADV_AND_FINISH(INTEGER_TOKEN);
3304 FINISH(INTEGER_TOKEN);
3305 }
3306 break;
3307
3308 case STATE_N5:
3309 if (IS_DIGIT(curr)) {
3310 ADV_TO_STATE(STATE_N6);
3311 }
3312 else if ((curr == '+') || (curr == '-')) {
3313 ADV_TO_STATE(STATE_N7)
3314 }
3315 else {
3316 return ARB_VP_ERROR;
3317 }
3318 break;
3319
3320 case STATE_N6:
3321 if (IS_DIGIT(curr)) {
3322 ADV_TO_STATE(STATE_N6);
3323 }
3324 else {
3325 *token_attr =
3326 float_table_add(&s->floats, s->str, s->start_pos, s->curr_pos);
3327 //ADV_AND_FINISH(FLOAT_TOKEN);
3328 FINISH(FLOAT_TOKEN);
3329 }
3330 break;
3331
3332 case STATE_N7:
3333 if (IS_DIGIT(curr)) {
3334 ADV_TO_STATE(STATE_N6);
3335 }
3336 else {
3337 return ARB_VP_ERROR;
3338 }
3339
3340 break;
3341
3342 case STATE_COMMENT:
3343 if ((curr == '\n') || (curr == '\r')) {
3344 s->start_pos = s->curr_pos + 1;
3345 s->curr_pos++;
3346 s->curr_state = 0;
3347 }
3348 else {
3349 ADV_TO_STATE(STATE_COMMENT);
3350 }
3351 }
3352 }
3353
3354 *token = EOF_TOKEN;
3355 return ARB_VP_SUCESS;
3356}
3357
3358/**
3359 * This does the same as get_next_token(), but it does not advance the
3360 * position pointers (Err, rather it does, but then it resets them)
3361 *
3362 * \param s The parse state
3363 * \param token The next token seen is returned in this value
3364 * \param token_attr The token attribute for the next token is returned here. This
3365 * is the index into the approprate symbol table if token is INTEGER_TOKEN,
3366 * FLOAT_TOKEN, or ID_TOKEN
3367 * \param how_many How many tokens to peek ahead
3368 *
3369 * \return ARB_VP_ERROR on lex error, ARB_VP_SUCESS on sucess
3370 */
3371static GLint
3372peek_next_token(parse_state * s, GLint * token, GLint * token_attr,
3373 GLint how_many)
3374{
3375 GLint tmp_state = s->curr_state;
3376 GLint tmp_sp = s->start_pos;
3377 GLint tmp_cp = s->curr_pos;
3378 GLint a, retval;
3379
3380 for (a = 0; a < how_many; a++) {
3381 retval = get_next_token(s, token, token_attr);
3382
3383 if (retval == ARB_VP_ERROR)
3384 return retval;
3385 }
3386
3387 s->curr_state = tmp_state;
3388 s->start_pos = tmp_sp;
3389 s->curr_pos = tmp_cp;
3390
3391 return retval;
3392}
3393
3394/**
3395 * Print out the value of a token
3396 */
3397static void
3398debug_token(parse_state * state, GLint t, GLint ta)
3399{
3400 switch (t) {
3401 case EOF_TOKEN:
3402 printf("EOF\n");
3403 break;
3404 case ID_TOKEN:
3405 printf("|%s| ", state->idents.data[ta]);
3406 break;
3407 case INTEGER_TOKEN:
3408 printf("|%d| ", state->ints.data[ta]);
3409 break;
3410 case FLOAT_TOKEN:
3411 printf("|%f| ", state->floats.data[ta]);
3412 break;
3413
3414 case ABS_TOKEN:
3415 printf("ABS ");
3416 break;
3417 case ADD_TOKEN:
3418 printf("ADD ");
3419 break;
3420 case ADDRESS_TOKEN:
3421 printf("ADDRESS ");
3422 break;
3423 case ALIAS_TOKEN:
3424 printf("ALIAS ");
3425 break;
3426 case ARL_TOKEN:
3427 printf("ARL ");
3428 break;
3429 case ATTRIB_TOKEN:
3430 printf("ATTRIB ");
3431 break;
3432
3433 case DP3_TOKEN:
3434 printf("DP3 ");
3435 break;
3436 case DP4_TOKEN:
3437 printf("DP4 ");
3438 break;
3439 case DPH_TOKEN:
3440 printf("DPH ");
3441 break;
3442 case DST_TOKEN:
3443 printf("DST ");
3444 break;
3445
3446 case END_TOKEN:
3447 printf("END ");
3448 break;
3449 case EX2_TOKEN:
3450 printf("EX2 ");
3451 break;
3452 case EXP_TOKEN:
3453 printf("EXP ");
3454 break;
3455
3456 case FLR_TOKEN:
3457 printf("FLR ");
3458 break;
3459 case FRC_TOKEN:
3460 printf("FRC ");
3461 break;
3462
3463 case LG2_TOKEN:
3464 printf("LG2 ");
3465 break;
3466 case LIT_TOKEN:
3467 printf("LIT ");
3468 break;
3469 case LOG_TOKEN:
3470 printf("LOG ");
3471 break;
3472
3473 case MAD_TOKEN:
3474 printf("MAD ");
3475 break;
3476 case MAX_TOKEN:
3477 printf("MAX ");
3478 break;
3479 case MIN_TOKEN:
3480 printf("MIN ");
3481 break;
3482 case MOV_TOKEN:
3483 printf("MOV ");
3484 break;
3485 case MUL_TOKEN:
3486 printf("MUL ");
3487 break;
3488
3489 case OPTION_TOKEN:
3490 printf("OPTION ");
3491 break;
3492 case OUTPUT_TOKEN:
3493 printf("OUTPUT ");
3494 break;
3495
3496 case PARAM_TOKEN:
3497 printf("PARAM ");
3498 break;
3499 case POW_TOKEN:
3500 printf("POW ");
3501 break;
3502
3503 case RCP_TOKEN:
3504 printf("RCP ");
3505 break;
3506 case RSQ_TOKEN:
3507 printf("RSQ ");
3508 break;
3509
3510 case SGE_TOKEN:
3511 printf("SGE ");
3512 break;
3513 case SLT_TOKEN:
3514 printf("SLT ");
3515 break;
3516 case SUB_TOKEN:
3517 printf("SUB ");
3518 break;
3519 case SWZ_TOKEN:
3520 printf("SWZ ");
3521 break;
3522
3523 case TEMP_TOKEN:
3524 printf("TEMP ");
3525 break;
3526
3527 case XPD_TOKEN:
3528 printf("XPD ");
3529 break;
3530
3531 case SEMICOLON_TOKEN:
3532 printf("; ");
3533 break;
3534 case COMMA_TOKEN:
3535 printf(", ");
3536 break;
3537 case PLUS_TOKEN:
3538 printf("+ ");
3539 break;
3540 case MINUS_TOKEN:
3541 printf("- ");
3542 break;
3543 case PERIOD_TOKEN:
3544 printf(". ");
3545 break;
3546 case DOTDOT_TOKEN:
3547 printf(".. ");
3548 break;
3549 case LBRACKET_TOKEN:
3550 printf("[ ");
3551 break;
3552 case RBRACKET_TOKEN:
3553 printf("] ");
3554 break;
3555 case LBRACE_TOKEN:
3556 printf("{ ");
3557 break;
3558 case RBRACE_TOKEN:
3559 printf("} ");
3560 break;
3561 case EQUAL_TOKEN:
3562 printf("= ");
3563 break;
3564
3565 case PROGRAM_TOKEN:
3566 printf("program ");
3567 break;
3568 case RESULT_TOKEN:
3569 printf("result ");
3570 break;
3571 case STATE_TOKEN:
3572 printf("state ");
3573 break;
3574 case VERTEX_TOKEN:
3575 printf("vertex ");
3576 break;
3577 default:
3578 printf("Unknown token type %d\n", t);
3579 }
3580}
3581
3582/**
3583 * Setup the state used by the parser / lex
3584 *
3585 * \param str The program string, with the !!ARBvp1.0 token stripped off
3586 * \param len The lenght of the given string
3587 *
3588 * \return A parse_state struct to keep track of all the things we need while parsing
3589 */
3590static parse_state *
3591parse_state_init(GLubyte * str, GLint len)
3592{
3593 parse_state *s = (parse_state *) _mesa_malloc(sizeof(parse_state));
3594
3595 s->str = _mesa_strdup(str);
3596 s->len = len;
3597 s->curr_pos = 0;
3598 s->start_pos = 0;
3599
3600 s->curr_state = 0;
3601
3602 s->idents.len = 0;
3603 s->idents.data = NULL;
3604
3605 s->ints.len = 0;
3606 s->ints.data = NULL;
3607
3608 s->floats.len = 0;
3609 s->floats.data = NULL;
3610 printf("%s\n", s->str);
3611
3612 s->binds.len = 0;
3613 s->binds.type = NULL;
3614 s->binds.offset = NULL;
3615 s->binds.row = NULL;
3616 s->binds.consts = NULL;
3617
3618 s->arrays.len = 0;
3619 s->arrays.num_elements = NULL;
3620 s->arrays.data = NULL;
3621
3622 s->stack_head = NULL;
3623 s->stack_free_list = NULL;
3624
3625 s->pt_head = NULL;
3626
3627 return s;
3628}
3629
3630/**
3631 * This frees all the things we hold while parsing.
3632 *
3633 * \param s The struct created by parse_state_init()
3634 */
3635static void
3636parse_state_cleanup(parse_state * s)
3637{
3638 GLint a;
3639 token_list *tl, *next;
3640
3641 /* Free our copy of the string [Mesa has its own] */
3642 _mesa_free(s->str);
3643
3644 /* Free all the tables ident, int, float, bind, mat */
3645 _mesa_free(s->idents.type);
3646 _mesa_free(s->idents.attr);
3647 for (a = 0; a < s->idents.len; a++)
3648 _mesa_free(s->idents.data[a]);
3649
3650 _mesa_free(s->ints.data);
3651 _mesa_free(s->floats.data);
3652
3653 _mesa_free(s->arrays.num_elements);
3654 for (a = 0; a < s->arrays.len; a++)
3655 _mesa_free(s->arrays.data[a]);
3656
3657 _mesa_free(s->binds.type);
3658 _mesa_free(s->binds.offset);
3659 _mesa_free(s->binds.row);
3660 _mesa_free(s->binds.num_rows);
3661 _mesa_free(s->binds.reg_num);
3662#if 0
3663 for (a = 0; a < s->binds.len; a++) {
3664 printf("6: %d/%d\n", a, s->binds.len - 1);
3665 _mesa_free(s->binds.consts[a]);
3666 }
3667#endif
3668
3669 /* Free the stack */
3670 tl = s->stack_head;
3671 while (tl) {
3672 next = tl->next;
3673 free(tl);
3674 tl = next;
3675 }
3676 tl = s->stack_free_list;
3677 while (tl) {
3678 next = tl->next;
3679 free(tl);
3680 tl = next;
3681 }
3682 printf("freed stack free list\n");
3683
3684#if 0
3685 /* Free the parse tree */
3686 parse_tree_free_children(s->pt_head);
3687 printf("freed parse_tree\n");
3688#endif
3689 free(s);
3690 printf("freed state\n");
3691}
3692
3693/**
3694 * Alloc a new node for a parse tree.
3695 *
3696 * \return An empty node to fill and stick into the parse tree
3697 */
3698static parse_tree_node *
3699parse_tree_node_init(void)
3700{
3701 GLint a;
3702 parse_tree_node *pt;
3703
3704 pt = (parse_tree_node *) _mesa_malloc(sizeof(parse_tree_node));
3705 pt->tok = -1;
3706 pt->tok_attr = -1;
3707 pt->is_terminal = 0;
3708 pt->prod_applied = -1;
3709
3710 for (a = 0; a < 4; a++)
3711 pt->children[a] = NULL;
3712
3713 return pt;
3714}
3715
3716/**
3717 * We maintain a stack of nonterminals used for predictive parsing. To keep
3718 * from thrashing malloc/free, we keep a free list of token_list structs
3719 * to be used for this stack. This function is called to refill the free
3720 * list, when we try to grab a new token_list struct, and find that there are none
3721 * available
3722 *
3723 * \param s The parse state
3724 */
3725static void
3726_fill_free_list(parse_state * s)
3727{
3728 GLint a;
3729 token_list *tl;
3730
3731 if (s->stack_free_list)
3732 return;
3733
3734 for (a = 0; a < 20; a++) {
3735 tl = (token_list *) _mesa_malloc(sizeof(token_list));
3736
3737 tl->next = s->stack_free_list;
3738 s->stack_free_list = tl;
3739 }
3740}
3741
3742/**
3743 * Peek at the head of the nonterminal stack,
3744 *
3745 * \param s The parse state
3746 * \param token Return for the nonterminal token on the top of the stack
3747 * \param token_attr Return for the the token attribute on the top of the stack
3748 *
3749 * \return ARB_VP_ERROR on an empty stack [not necessarily a bad thing], else ARB_VP_SUCESS
3750 */
3751static GLint
3752_stack_peek(parse_state * s, GLint * token, GLint * token_attr)
3753{
3754 if (!s->stack_head) {
3755 fprintf(stderr, "ACK! Empty stack on peek!\n");
3756 return ARB_VP_ERROR;
3757 }
3758
3759 *token = s->stack_head->tok;
3760 *token_attr = s->stack_head->tok_attr;
3761
3762 return ARB_VP_SUCESS;
3763}
3764
3765/**
3766 * Remove the token at the head of the nonterminal stack
3767 * \param s The parse state
3768 * \param token Return for the nonterminal token on the top of the stack
3769 * \param token_attr Return for the the token attribute on the top of the stack
3770 * \param ptn Return for a pointer to the place in the parse tree where
3771 * the token lives
3772 *
3773 * \return ARB_VP_ERROR on an empty stack [not necessarily a bad thing], else ARB_VP_SUCESS
3774 */
3775static GLint
3776_stack_pop(parse_state * s, GLint * token, GLint * token_attr,
3777 parse_tree_node ** ptn)
3778{
3779 token_list *tl;
3780
3781 if (!s->stack_head) {
3782 fprintf(stderr, "ACK! Empty stack!\n");
3783 return ARB_VP_ERROR;
3784 }
3785
3786 *token = s->stack_head->tok;
3787 *token_attr = s->stack_head->tok_attr;
3788 if (ptn)
3789 *ptn = s->stack_head->pt;
3790 tl = s->stack_head;
3791
3792 s->stack_head = tl->next;
3793 tl->next = s->stack_free_list;
3794 s->stack_free_list = tl;
3795
3796 return ARB_VP_SUCESS;
3797}
3798
3799/**
3800 * Put a token, its attribute, and the the parse tree node where the token is stored, onto
3801 * the parse stack.
3802 *
3803 * \param s The parse state
3804 * \param token Return for the nonterminal token on the top of the stack
3805 * \param token_attr Return for the the token attribute on the top of the stack
3806 * \param ptn Return for a pointer to the place in the parse tree where
3807 * the token lives
3808 *
3809 * \return ARB_VP_ERROR on out of memory while allocing more storage for the stack,
3810 * else ARB_VP_SUCESS
3811 */
3812static GLint
3813_stack_push(parse_state * s, GLint token, GLint token_attr,
3814 parse_tree_node * ptn)
3815{
3816 token_list *tl;
3817
3818 if (!s->stack_free_list) {
3819 _fill_free_list(s);
3820 if (!s->stack_free_list) {
3821 fprintf(stderr, "ACK! Error filling stack free list\n");
3822 return ARB_VP_ERROR;
3823 }
3824 }
3825
3826 tl = s->stack_free_list;
3827
3828 s->stack_free_list = tl->next;
3829
3830 tl->tok = token;
3831 tl->tok_attr = token_attr;
3832 tl->pt = ptn;
3833 tl->next = s->stack_head;
3834
3835 s->stack_head = tl;
3836
3837 return ARB_VP_SUCESS;
3838}
3839
3840/**
3841 * Allocate a new entry in the array table
3842 *
3843 * \param tab The array table to add a new element too
3844 *
3845 * \return The index into the array table where the new element is.
3846 */
3847static GLint
3848array_table_new(array_table * tab)
3849{
3850 GLint idx;
3851 if (tab->len == 0) {
3852 tab->num_elements = (GLint *) _mesa_malloc(sizeof(GLint));
3853 tab->data = (GLint **) _mesa_malloc(sizeof(GLint *));
3854 idx = 0;
3855 }
3856 else {
3857 tab->num_elements =
3858 (GLint *) _mesa_realloc(tab->num_elements, tab->len * sizeof(GLint),
3859 (tab->len + 1) * sizeof(GLint));
3860 tab->data =
3861 (GLint **) _mesa_realloc(tab->data, tab->len * sizeof(GLint *),
3862 (tab->len + 1) * sizeof(GLint *));
3863 idx = tab->len;
3864 }
3865
3866 tab->len++;
3867 tab->num_elements[idx] = 0;
3868 tab->data[idx] = NULL;
3869
3870 return idx;
3871}
3872
3873/**
3874 * Add a new element to a array in a array table
3875 *
3876 * \param tab The array table
3877 * \param idx The index into the array table of the array we want to append an item onto
3878 * \param data The program parameter that goes into the idx-th array
3879 */
3880static void
3881array_table_add_data(array_table * tab, GLint idx, GLint data)
3882{
3883 if ((idx < 0) || (idx >= tab->len)) {
3884 printf("Bad matrix index %d!\n", idx);
3885 return;
3886 }
3887
3888 if (tab->data[idx] == NULL) {
3889 tab->data[idx] = (GLint *) _mesa_malloc(sizeof(GLint));
3890 }
3891 else {
3892 tab->data[idx] =
3893 (GLint *) _mesa_realloc(tab->data[idx],
3894 tab->num_elements[idx] * sizeof(GLint),
3895 (tab->num_elements[idx] +
3896 1) * sizeof(GLint));
3897 }
3898
3899 tab->data[idx][tab->num_elements[idx]] = data;
3900 tab->num_elements[idx]++;
3901}
3902
3903
3904/**
3905 * This adds a new entry into the binding table.
3906 *
3907 * \param tab The binding table
3908 * \param type The type of the state
3909 * \param offset For matrix bindings, e.g. MATRIXROWS_MODELVIEW, this gives the matrix number.
3910 * For PROGRAM_ENV_* and PROGRAM_LOCAL_* bindings, this gives the number of the first parameter
3911 *
3912 * \param row For MATRIXROWS bindings, this is the first row in the matrix we're bound to
3913 * \param nrows For MATRIXROWS bindings, this is the number of rows of the matrix we have.
3914 * For PROGRAM_ENV/LOCAL bindings, this is the number of parameters in the array we're bound to
3915 * \param values For CONSTANT bindings, these are the constant values we're bound to
3916 * \return The index into the binding table where this state is bound
3917 */
3918static GLint
3919binding_table_add(binding_table * tab, GLint type, GLint offset, GLint row,
3920 GLint nrows, GLfloat * values)
3921{
3922 GLint key, a;
3923
3924 key = tab->len;
3925
3926 /* test for existance */
3927 for (a = 0; a < tab->len; a++) {
3928 if ((tab->type[a] == type) && (tab->offset[a] == offset)
3929 && (tab->row[a] == row) && (tab->num_rows[a] == nrows) &&
3930 (fabs(tab->consts[a][0] - values[0]) < .0001) &&
3931 (fabs(tab->consts[a][1] - values[1]) < .0001) &&
3932 (fabs(tab->consts[a][2] - values[2]) < .0001) &&
3933 (fabs(tab->consts[a][3] - values[3]) < .0001))
3934 return a;
3935 }
3936
3937 if (tab->len == 0) {
3938 tab->type = (GLint *) _mesa_malloc(sizeof(GLint));
3939 tab->offset = (GLint *) _mesa_malloc(sizeof(GLint));
3940 tab->row = (GLint *) _mesa_malloc(sizeof(GLint));
3941 tab->num_rows = (GLint *) _mesa_malloc(sizeof(GLint));
3942 tab->consts = (GLfloat **) _mesa_malloc(sizeof(GLfloat *));
3943 tab->consts[0] = (GLfloat *) _mesa_malloc(4 * sizeof(GLfloat));
3944 tab->reg_num = (GLint *) _mesa_malloc(sizeof(GLint));
3945 }
3946 else {
3947 tab->type =
3948 (GLint *) _mesa_realloc(tab->type, tab->len * sizeof(GLint),
3949 (tab->len + 1) * sizeof(GLint));
3950 tab->offset =
3951 (GLint *) _mesa_realloc(tab->offset, tab->len * sizeof(GLint),
3952 (tab->len + 1) * sizeof(GLint));
3953 tab->row =
3954 (GLint *) _mesa_realloc(tab->row, tab->len * sizeof(GLint),
3955 (tab->len + 1) * sizeof(GLint));
3956 tab->num_rows =
3957 (GLint *) _mesa_realloc(tab->num_rows, tab->len * sizeof(GLint),
3958 (tab->len + 1) * sizeof(GLint));
3959 tab->consts =
3960 (GLfloat **) _mesa_realloc(tab->consts, tab->len * sizeof(GLfloat),
3961 (tab->len + 1) * sizeof(GLfloat *));
3962 tab->consts[tab->len] = (GLfloat *) _mesa_malloc(4 * sizeof(GLfloat));
3963 tab->reg_num =
3964 (GLint *) _mesa_realloc(tab->reg_num, tab->len * sizeof(GLint),
3965 (tab->len + 1) * sizeof(GLint));
3966 }
3967
3968 tab->type[key] = type;
3969 tab->offset[key] = offset;
3970 tab->row[key] = row; //key;
3971 tab->num_rows[key] = nrows;
3972 tab->reg_num[key] = 0;
3973 _mesa_memcpy(tab->consts[key], values, 4 * sizeof(GLfloat));
3974 tab->len++;
3975
3976 return key;
3977}
3978
3979/**
3980 * Given a string and a start/end point, add a string into the float
3981 * symbol table (and convert it into a float)
3982 *
3983 * If we already have this GLfloat in the table, don't bother
3984 * adding another, just return the key to the existing one
3985 *
3986 * \param tab The float table
3987 * \param str The string containing the float
3988 * \param start The starting position of the float in str
3989 * \param end The ending position of the float in str
3990 *
3991 * \return The index of the float, after we insert it, in the float table
3992 */
3993static GLint
3994float_table_add(float_table * tab, GLubyte * str, GLint start, GLint end)
3995{
3996 GLint key, a;
3997 GLubyte *newstr;
3998
3999 key = tab->len;
4000
4001 newstr = (GLubyte *) _mesa_malloc(end - start + 2);
4002 _mesa_memset(newstr, 0, end - start + 2);
4003 _mesa_memcpy(newstr, str + start, end - start);
4004
4005 /* test for existance */
4006 for (a = 0; a < tab->len; a++) {
4007 if (tab->data[a] == atof(newstr)) {
4008 _mesa_free(newstr);
4009 return a;
4010 }
4011 }
4012
4013 if (tab->len == 0) {
4014 tab->data = (GLdouble *) _mesa_malloc(sizeof(GLdouble));
4015 }
4016 else {
4017 tab->data =
4018 (GLdouble *) _mesa_realloc(tab->data, tab->len * sizeof(GLdouble),
4019 (tab->len + 1) * sizeof(GLdouble));
4020 }
4021
4022 tab->data[key] = atof(newstr);
4023 tab->len++;
4024
4025 _mesa_free(newstr);
4026 return key;
4027}
4028
4029/**
4030 * Given a string and a start/end point, add a string into the int
4031 * symbol table (and convert it into a int)
4032 *
4033 * If we already have this int in the table, don't bother
4034 * adding another, just return the key to the existing one
4035 *
4036 * \param tab The int table
4037 * \param str The string containing the int
4038 * \param start The starting position of the int in str
4039 * \param end The ending position of the int in str
4040 *
4041 * \return The index of the int, after we insert it, in the int table
4042 */
4043static GLint
4044int_table_add(int_table * tab, GLubyte * str, GLint start, GLint end)
4045{
4046 GLint key, a;
4047 GLubyte *newstr;
4048
4049 key = tab->len;
4050
4051 newstr = (GLubyte *) _mesa_malloc(end - start + 2);
4052 _mesa_memset(newstr, 0, end - start + 2);
4053 _mesa_memcpy(newstr, str + start, end - start);
4054
4055 for (a = 0; a < tab->len; a++) {
4056 if (tab->data[a] == _mesa_atoi(newstr)) {
4057 _mesa_free(newstr);
4058 return a;
4059 }
4060 }
4061
4062 if (tab->len == 0) {
4063 tab->data = (GLint *) _mesa_malloc(sizeof(GLint));
4064 }
4065 else {
4066 tab->data =
4067 (GLint *) _mesa_realloc(tab->data, tab->len * sizeof(GLint),
4068 (tab->len + 1) * sizeof(GLint));
4069 }
4070
4071 tab->data[key] = _mesa_atoi(newstr);
4072 tab->len++;
4073
4074 _mesa_free(newstr);
4075 return key;
4076}
4077
4078/**
4079 * Insert an identifier into the identifier symbol table
4080 *
4081 * If we already have this id in the table, don't bother
4082 * adding another, just return the key to the existing one
4083 *
4084 * If we already have this id in the table, and it has been
4085 * initialized to an ALIAS, return what the alias points
4086 * to, not the alias var
4087 *
4088 * \param tab The ID table
4089 * \param str The string containing the id
4090 * \param start The position in str where the id begins
4091 * \param end The position in str where the id ends
4092 *
4093 * \return either:
4094 * 1) The index into the id table where the id is
4095 * 2) The index into the id table where the alias of id, if we already have id
4096 * in the table, and it has been initialized to type ALIAS
4097 */
4098static GLint
4099id_table_add(id_table * tab, GLubyte * str, GLint start, GLint end)
4100{
4101 GLint key, a;
4102 GLubyte *newstr;
4103
4104 key = tab->len;
4105
4106 if (tab->len == 0) {
4107 tab->data = (GLubyte **) _mesa_malloc(sizeof(GLubyte *));
4108 tab->type = (GLint *) _mesa_malloc(sizeof(GLint));
4109 tab->attr = (GLint *) _mesa_malloc(sizeof(GLint));
4110 }
4111 else {
4112 tab->data =
4113 (GLubyte **) _mesa_realloc(tab->data, tab->len * sizeof(GLubyte *),
4114 (tab->len + 1) * sizeof(GLubyte *));
4115 tab->type =
4116 (GLint *) _mesa_realloc(tab->type, tab->len * sizeof(GLint),
4117 (tab->len + 1) * sizeof(GLint));
4118 tab->attr =
4119 (GLint *) _mesa_realloc(tab->attr, tab->len * sizeof(GLint),
4120 (tab->len + 1) * sizeof(GLint));
4121 }
4122
4123 //tab->type[key] = TYPE_NONE;
4124
4125 newstr = (GLubyte *) _mesa_malloc((end - start + 2) * sizeof(GLubyte));
4126 _mesa_memset(newstr, 0, end - start + 2);
4127 _mesa_memcpy(newstr, str + start, end - start);
4128
4129 for (a = 0; a < tab->len; a++) {
4130 /* aha! we found it in the table */
4131 if (!_mesa_strcmp(tab->data[a], newstr)) {
4132 _mesa_free(newstr);
4133
4134 key = a;
4135 while ((tab->type[key] == TYPE_ALIAS) && (tab->attr[key] != -1)) {
4136 printf("----------- %s is an alias, renaming to %s\n",
4137 tab->data[key], tab->data[tab->attr[key]]);
4138 key = tab->attr[key];
4139 }
4140
4141 return key;
4142 }
4143 }
4144
4145 /* oh, we really have a new id */
4146 tab->data[key] = newstr;
4147 tab->type[key] = TYPE_NONE;
4148 tab->attr[key] = -1;
4149 tab->len++;
4150
4151 return key;
4152}
4153
4154//#define SHOW_STEPS 1
4155
4156
4157/**
4158 * Apply the specified production number to the parse state. This handles
4159 * looking at the production table and sticking new tokens onto the
4160 * parse stack.
4161 *
4162 * It also handles the construction of the parse tree
4163 *
4164 * \param s The parse state
4165 * \param num The production number to apply [the idx in the production table]
4166 *
4167 */
4168static void
4169apply_production(parse_state * s, int num)
4170{
4171 GLint a, str_key, stack_tok, stack_tok_attr;
4172 GLint tok, nnptr = 0;
4173 parse_tree_node *ptn;
4174 parse_tree_node *pt_ptr_new[4];
4175
4176 _stack_pop(s, &stack_tok, &stack_tok_attr, &ptn);
4177 /*printf("apply prod %d\n", num); */
4178
4179 ptn->prod_applied = num;
4180 for (a = 3; a >= 0; a--) {
4181 str_key = 0;
4182 tok = ptab[num].rhs[a];
4183
4184 if (tok == NULL_TOKEN)
4185 continue;
4186
4187 /* If we are pushing an identifier or a number, we need to translate the string literal
4188 * in the production table into an entry in the approprate symbol table
4189 */
4190 if (tok == ID_TOKEN) {
4191 str_key =
4192 id_table_add(&s->idents, ptab[num].key[a], 0,
4193 strlen(ptab[num].key[a]));
4194 }
4195 else if (tok == INTEGER_TOKEN) {
4196 str_key =
4197 int_table_add(&s->ints, ptab[num].key[a], 0,
4198 strlen(ptab[num].key[a]));
4199 }
4200 else if (tok == FLOAT_TOKEN) {
4201 str_key =
4202 float_table_add(&s->floats, ptab[num].key[a], 0,
4203 strlen(ptab[num].key[a]));
4204 }
4205
4206 /* "-1" is a wildcard flag, accept any id/float/int */
4207 if ((!_mesa_strcmp(ptab[num].key[a], "-1")) &&
4208 ((tok == FLOAT_TOKEN) || (tok == INTEGER_TOKEN)
4209 || (tok == ID_TOKEN))) {
4210 pt_ptr_new[nnptr] = parse_tree_node_init();
4211 pt_ptr_new[nnptr]->is_terminal = 0;
4212 pt_ptr_new[nnptr]->tok = tok;
4213 pt_ptr_new[nnptr]->tok_attr = str_key;
4214 nnptr++;
4215 _stack_push(s, ptab[num].rhs[a], str_key, pt_ptr_new[nnptr - 1]);
4216 }
4217 else if (tok >= NT_PROGRAM_TOKEN) {
4218 pt_ptr_new[nnptr] = parse_tree_node_init();
4219 pt_ptr_new[nnptr]->is_terminal = 0;
4220 pt_ptr_new[nnptr]->tok = tok;
4221 nnptr++;
4222 _stack_push(s, ptab[num].rhs[a], str_key, pt_ptr_new[nnptr - 1]);
4223 }
4224 else
4225 _stack_push(s, ptab[num].rhs[a], str_key, NULL);
4226 }
4227
4228 tok = 0;
4229 if (ptn) {
4230 /*printf("%x %d:[%x %x %x %x]\n", ptn, nnptr, pt_ptr_new[0], pt_ptr_new[1], pt_ptr_new[2], pt_ptr_new[3]); */
4231
4232 for (a = nnptr - 1; a >= 0; a--) {
4233 ptn->children[tok] = pt_ptr_new[a];
4234 /*printf("%x->children[%d] = %x\n", ptn, tok, pt_ptr_new[a]); */
4235 tok++;
4236 }
4237 }
4238}
4239
4240/**
4241 * Here we initialize a bunch of variables to a given type (e.g. TEMP).
4242 *
4243 * We stick the variable type into the 0-th element in the var_queue array, followed by var_queue_size
4244 * indicies into the identifier table which designate the variables we are to init.
4245 *
4246 * \param s The parse state
4247 * \param var_queue The queue of variables to initialize. The first element in the array is variable
4248 * type. It is followed by var_queue_size indicies into the identifier table
4249 * who we are supposed to init to type var_queue[0].
4250 * \param var_queue_size The number of variables listed in var_queue[].
4251 *
4252 * \return ARB_VP_ERROR if we have already initilized a variable in var_queue, otherwise
4253 * ARB_VP_SUCESS
4254 */
4255static GLint
4256init_vars(parse_state * s, GLint * var_queue, GLint var_queue_size)
4257{
4258 GLint a;
4259
4260 a = 1;
4261 while (a < var_queue_size) {
4262 /* Make sure we haven't already init'd this var. This will
4263 * catch multiple definations of the same symbol
4264 */
4265 if (s->idents.type[var_queue[a]] != TYPE_NONE) {
4266 printf("%s already init'd! (%d)\n", s->idents.data[var_queue[a]],
4267 s->idents.type[var_queue[a]]);
4268 return ARB_VP_ERROR;
4269 }
4270
4271 s->idents.type[var_queue[a]] = var_queue[0];
4272 s->idents.attr[var_queue[a]] = -1;
4273 a++;
4274 }
4275
4276 return ARB_VP_SUCESS;
4277}
4278
4279/**
4280 * The main parsing loop. This applies productions and builds the parse tree.
4281 *
4282 * \param s The parse state
4283 *
4284 * \return ARB_VP_ERROR on a parse error, else ARB_VP_SUCESS
4285 */
4286static GLint
4287parse(parse_state * s)
4288{
4289 GLint input_tok, input_tok_attr;
4290 GLint stack_tok, stack_tok_attr;
4291 GLint peek_tok, peek_tok_attr, ret;
4292 GLint idx, str_key;
4293 GLint var_queue_size = 0;
4294 GLint *var_queue;
4295 parse_tree_node *ptn, *ptn2;
4296
4297 /* This should be MAX_VAR + 1 */
4298 var_queue = (GLint *) _mesa_malloc(1000 * sizeof(int));
4299
4300 s->stack_head = NULL;
4301
4302 /* init the system by pushing the start symbol onto the stack */
4303 ptn = parse_tree_node_init();
4304 ptn->is_terminal = 0;
4305 ptn->tok = NT_PROGRAM_TOKEN;
4306 s->pt_head = ptn;
4307 _stack_push(s, NT_PROGRAM_TOKEN, 0, ptn);
4308
4309 /* and get the first token */
4310 if (get_next_token(s, &input_tok, &input_tok_attr) == ARB_VP_ERROR) {
4311 fprintf(stderr, "LEX ERROR!!\n");
4312 return ARB_VP_ERROR;
4313 }
4314
4315 while (1) {
4316 GLint la, is_nonterm;
4317
4318 /* If the stack is empty, and we've eaten all the input, we're done */
4319 if ((_stack_peek(s, &stack_tok, &stack_tok_attr) == ARB_VP_ERROR) &&
4320 (input_tok == EOF_TOKEN))
4321 break;
4322
4323#ifdef SHOW_STEPS
4324 printf("stack: %d input: ", stack_tok);
4325 debug_token(s, input_tok, input_tok_attr);
4326 printf("\n");
4327#endif
4328
4329 /* We [may] have a non-terminal on top of the stack, apply
4330 * productions!
4331 */
4332 switch (stack_tok) {
4333 /* Special case non-terminals */
4334
4335 /* productions 64-66 */
4336 case NT_SRC_REG_TOKEN:
4337 if ((input_tok == VERTEX_TOKEN) ||
4338 ((input_tok == ID_TOKEN)
4339 && (s->idents.type[input_tok_attr] == TYPE_ATTRIB))) {
4340 apply_production(s, 64);
4341 }
4342 else
4343 if ((input_tok == ID_TOKEN)
4344 && (s->idents.type[input_tok_attr] == TYPE_TEMP)) {
4345 apply_production(s, 65);
4346 }
4347 else
4348 if ((input_tok == STATE_TOKEN) ||
4349 (input_tok == PROGRAM_TOKEN) ||
4350 (input_tok == LBRACE_TOKEN) ||
4351 (input_tok == FLOAT_TOKEN) ||
4352 (input_tok == INTEGER_TOKEN) ||
4353 ((input_tok == ID_TOKEN)
4354 && (s->idents.type[input_tok_attr] == TYPE_PARAM_SINGLE))
4355 || ((input_tok == ID_TOKEN)
4356 && (s->idents.type[input_tok_attr] ==
4357 TYPE_PARAM_ARRAY))) {
4358 apply_production(s, 66);
4359 }
4360 else {
4361 return ARB_VP_ERROR;
4362 }
4363 break;
4364
4365 /* productions 67-68 */
4366 case NT_DST_REG_TOKEN:
4367 /* We can only write to result.*, TEMP vars, or OUTPUT vars */
4368 if (input_tok == RESULT_TOKEN) {
4369 apply_production(s, 68);
4370 }
4371 else if (input_tok == ID_TOKEN) {
4372 if (s->idents.type[input_tok_attr] == TYPE_TEMP) {
4373 apply_production(s, 67);
4374 }
4375 else if (s->idents.type[input_tok_attr] == TYPE_OUTPUT) {
4376 apply_production(s, 68);
4377 }
4378 else {
4379 return ARB_VP_ERROR;
4380 }
4381 }
4382 else {
4383 return ARB_VP_ERROR;
4384 }
4385 break;
4386
4387 /* productions 72-4 */
4388 case NT_PROG_PARAM_REG_TOKEN:
4389 if ((input_tok == ID_TOKEN)
4390 && (s->idents.type[input_tok_attr] == TYPE_PARAM_SINGLE)) {
4391 apply_production(s, 72);
4392 }
4393 else
4394 if ((input_tok == ID_TOKEN)
4395 && (s->idents.type[input_tok_attr] == TYPE_PARAM_ARRAY)) {
4396 apply_production(s, 73);
4397 }
4398 else
4399 if ((input_tok == STATE_TOKEN) ||
4400 (input_tok == PROGRAM_TOKEN) ||
4401 (input_tok == FLOAT_TOKEN) ||
4402 (input_tok == INTEGER_TOKEN) || (input_tok == LBRACE_TOKEN)) {
4403 apply_production(s, 74);
4404 }
4405 else {
4406 return ARB_VP_ERROR;
4407 }
4408 break;
4409
4410 /* productions 286-7 */
4411 case NT_VAR_NAME_LIST_TOKEN:
4412 ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
4413
4414 var_queue[var_queue_size] = input_tok_attr;
4415 var_queue_size++;
4416
4417 if ((ret == ARB_VP_ERROR) || (peek_tok != COMMA_TOKEN)) {
4418 apply_production(s, 286);
4419
4420 /* Dump the var_queue & assign types */
4421 if (init_vars(s, var_queue, var_queue_size) == ARB_VP_ERROR)
4422 return ARB_VP_ERROR;
4423 }
4424 else {
4425 apply_production(s, 287);
4426 }
4427 break;
4428
4429 /* productions 296-7 */
4430 case NT_RESULT_COL_BINDING2_TOKEN:
4431 if ((input_tok == SEMICOLON_TOKEN) || (input_tok == COMMA_TOKEN)) {
4432 apply_production(s, 296);
4433 }
4434 else if (input_tok == PERIOD_TOKEN) {
4435 ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
4436 if ((peek_tok == ID_TOKEN) &&
4437 ((!_mesa_strcmp(s->idents.data[peek_tok_attr], "back")) ||
4438 (!_mesa_strcmp(s->idents.data[peek_tok_attr], "front")))) {
4439 apply_production(s, 297);
4440 }
4441 else {
4442 apply_production(s, 296);
4443 }
4444 }
4445 else {
4446 return ARB_VP_ERROR;
4447 }
4448 break;
4449
4450 /* productions 300-1 */
4451 case NT_RESULT_COL_BINDING4_TOKEN:
4452 if ((input_tok == SEMICOLON_TOKEN) || (input_tok == COMMA_TOKEN)) {
4453 apply_production(s, 300);
4454 }
4455 else if (input_tok == PERIOD_TOKEN) {
4456 ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
4457 if ((ret == ARB_VP_SUCESS) && (peek_tok == ID_TOKEN) &&
4458 ((!_mesa_strcmp(s->idents.data[peek_tok_attr], "primary")) ||
4459 (!_mesa_strcmp(s->idents.data[peek_tok_attr], "secondary"))))
4460 {
4461 apply_production(s, 301);
4462 }
4463 else {
4464 apply_production(s, 300);
4465 }
4466 }
4467 else {
4468 return ARB_VP_ERROR;
4469 }
4470 break;
4471
4472 /* productions 306-7 */
4473 case NT_OPT_COLOR_TYPE_TOKEN:
4474 if ((input_tok == SEMICOLON_TOKEN) || (input_tok == COMMA_TOKEN)) {
4475 apply_production(s, 307);
4476 }
4477 else if (input_tok == PERIOD_TOKEN) {
4478 ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
4479 if ((ret == ARB_VP_SUCESS) && (peek_tok == ID_TOKEN) &&
4480 ((!_mesa_strcmp(s->idents.data[peek_tok_attr], "primary")) ||
4481 (!_mesa_strcmp(s->idents.data[peek_tok_attr], "secondary"))))
4482 {
4483 apply_production(s, 306);
4484 }
4485 else {
4486 apply_production(s, 307);
4487 }
4488 }
4489 else {
4490 return ARB_VP_ERROR;
4491 }
4492 break;
4493
4494 /* production 313 -- Do this so we can mangle IDs as they are
4495 * added into the ID table for the lex
4496 */
4497 case NT_ALIAS_STATEMENT_TOKEN:
4498 if (input_tok == ALIAS_TOKEN) {
4499 GLint alias_to;
4500
4501 apply_production(s, 313);
4502
4503 /* stack ALIAS */
4504 var_queue_size = 1;
4505 var_queue[0] = TYPE_ALIAS;
4506 ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
4507 var_queue[var_queue_size] = peek_tok_attr;
4508 var_queue_size++;
4509
4510 if (init_vars(s, var_queue, var_queue_size) == ARB_VP_ERROR)
4511 return ARB_VP_ERROR;
4512
4513 /* Now, peek ahead and see what we are aliasing _to_ */
4514 alias_to = peek_tok_attr;
4515 ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 3);
4516 if (ret == ARB_VP_SUCESS) {
4517 s->idents.attr[alias_to] = peek_tok_attr;
4518 }
4519 else
4520 return ARB_VP_ERROR;
4521 }
4522 else {
4523 return ARB_VP_ERROR;
4524 }
4525 break;
4526
4527 /* productions 314 (ESTABLISH_NAME) duplicates are caught by the ID symbol table */
4528
4529 /* productions 315 */
4530 case NT_ESTABLISHED_NAME_TOKEN:
4531 if (input_tok == ID_TOKEN) {
4532 if (s->idents.type[input_tok_attr] == TYPE_NONE) {
4533 printf("Trying to use variable %s before initializing!\n",
4534 s->idents.data[input_tok_attr]);
4535 return ARB_VP_ERROR;
4536 }
4537 else {
4538 apply_production(s, 315);
4539 }
4540 }
4541 else {
4542 return ARB_VP_ERROR;
4543 }
4544 break;
4545
4546
4547 /* productions 318-9 */
4548 case NT_SWIZZLE_SUFFIX2_TOKEN:
4549 if (strlen(s->idents.data[input_tok_attr]) == 1) {
4550 apply_production(s, 318);
4551 }
4552 else if (strlen(s->idents.data[input_tok_attr]) == 4) {
4553 apply_production(s, 319);
4554 }
4555 else {
4556 return ARB_VP_ERROR;
4557 }
4558 break;
4559
4560 /* 4-component swizzle mask -- this is a total hack */
4561#define IS_SWZ_CMP(foo) ((foo == 'x') || (foo == 'y') || (foo == 'z') || (foo == 'w'))
4562 case NT_COMPONENT4_TOKEN:
4563 {
4564 GLubyte *str = s->idents.data[input_tok_attr];
4565
4566 if (IS_SWZ_CMP(str[0]) && IS_SWZ_CMP(str[1]) && IS_SWZ_CMP(str[2])
4567 && IS_SWZ_CMP(str[3])) {
4568 _stack_pop(s, &stack_tok, &stack_tok_attr, &ptn);
4569// _stack_push(s, input_tok, input_tok_attr, NULL);
4570
4571 ptn2 = parse_tree_node_init();
4572 ptn2->tok = input_tok;
4573 ptn2->tok_attr = input_tok_attr;
4574 ptn2->is_terminal = 1;
4575 ptn->children[0] = ptn2;
4576 _stack_push(s, input_tok, input_tok_attr, ptn2);
4577 }
4578 else {
4579 return ARB_VP_ERROR;
4580 }
4581 }
4582 break;
4583
4584 /* Handle general non-terminals using tables, and terminals */
4585 default:
4586 is_nonterm = 0;
4587 for (la = 0; la < nlas; la++) {
4588 if (latab[la].lhs != stack_tok)
4589 continue;
4590
4591 if (latab[la].la != input_tok)
4592 continue;
4593
4594 if (input_tok == ID_TOKEN) {
4595 str_key =
4596 id_table_add(&s->idents, latab[la].la_kw, 0,
4597 strlen(latab[la].la_kw));
4598 if ((str_key != input_tok_attr)
4599 && (_mesa_strcmp(latab[la].la_kw, "-1")))
4600 continue;
4601 }
4602 else if (input_tok == INTEGER_TOKEN) {
4603 if ((s->ints.data[input_tok_attr] !=
4604 _mesa_atoi(latab[la].la_kw))
4605 && (_mesa_atoi(latab[la].la_kw) != -1)) {
4606 continue;
4607 }
4608 }
4609 else if (input_tok == FLOAT_TOKEN) {
4610 if ((s->floats.data[input_tok_attr] != atof(latab[la].la_kw))
4611 && (atof(latab[la].la_kw) != -1))
4612 continue;
4613 }
4614 idx = latab[la].prod_idx;
4615
4616 /* Here we stack identifiers onto the var_queue */
4617 switch (idx) {
4618 /* setup ATTRIB */
4619 case 120:
4620 var_queue_size = 1;
4621 var_queue[0] = TYPE_ATTRIB;
4622 ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
4623 var_queue[var_queue_size] = peek_tok_attr;
4624 var_queue_size++;
4625
4626 if (init_vars(s, var_queue, var_queue_size) == ARB_VP_ERROR)
4627 return ARB_VP_ERROR;
4628 break;
4629
4630 /* stack PARAM */
4631 case 134:
4632 var_queue_size = 1;
4633 var_queue[0] = TYPE_PARAM;
4634
4635 ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
4636 var_queue[var_queue_size] = peek_tok_attr;
4637 var_queue_size++;
4638
4639 break;
4640
4641 case 135:
4642 var_queue[0] = TYPE_PARAM_SINGLE;
4643
4644 if (init_vars(s, var_queue, var_queue_size) == ARB_VP_ERROR)
4645 return ARB_VP_ERROR;
4646 break;
4647
4648 case 136:
4649 var_queue[0] = TYPE_PARAM_ARRAY;
4650
4651 if (init_vars(s, var_queue, var_queue_size) == ARB_VP_ERROR)
4652 return ARB_VP_ERROR;
4653 break;
4654
4655 /* stack TEMP */
4656 case 284:
4657 var_queue_size = 1;
4658 var_queue[0] = TYPE_TEMP;
4659 break;
4660
4661 /* stack ADDRESS */
4662 case 285:
4663 var_queue_size = 1;
4664 var_queue[0] = TYPE_ADDRESS;
4665 break;
4666
4667 /* stack OUTPUT */
4668 case 288:
4669 var_queue_size = 1;
4670 var_queue[0] = TYPE_OUTPUT;
4671 ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
4672 var_queue[var_queue_size] = peek_tok_attr;
4673 var_queue_size++;
4674
4675 if (init_vars(s, var_queue, var_queue_size) == ARB_VP_ERROR)
4676 return ARB_VP_ERROR;
4677 break;
4678
4679
4680 /* stack opts for varNameList -- see above */
4681
4682 }
4683
4684 /* finally.. we match! apply the production */
4685 if ((idx < 0) || (idx >= nprods)) {
4686 fprintf(stderr,
4687 "Prod IDX of %d in look ahead table [%d] is horked!\n",
4688 idx, la);
4689 exit(1);
4690 }
4691
4692 apply_production(s, idx);
4693 is_nonterm = 1;
4694 break;
4695 }
4696
4697 if (!is_nonterm) {
4698 if ((stack_tok == EOF_TOKEN) && (s->stack_head == NULL))
4699 return ARB_VP_SUCESS;
4700
4701 if ((input_tok == stack_tok) ||
4702 ((stack_tok == FLOAT_TOKEN)
4703 && (input_tok == INTEGER_TOKEN))) {
4704 /* XXX: Need to check values for int/id/GLfloat tokens here -- yes! */
4705
4706 _stack_pop(s, &stack_tok, &stack_tok_attr, &ptn);
4707 if ((ptn)
4708 && ((stack_tok == FLOAT_TOKEN)
4709 || (stack_tok == INTEGER_TOKEN)
4710 || (stack_tok == ID_TOKEN))) {
4711 ptn->is_terminal = 1;
4712 ptn->tok = input_tok;
4713 ptn->tok_attr = input_tok_attr;
4714 }
4715
4716 if (get_next_token(s, &input_tok, &input_tok_attr) ==
4717 ARB_VP_ERROR) {
4718 fprintf(stderr, "PARSE ERROR!!\n");
4719 return ARB_VP_ERROR;
4720 }
4721 }
4722 else {
4723 fprintf(stderr, "PARSE ERROR!\n");
4724 return ARB_VP_ERROR;
4725 }
4726 }
4727 break;
4728 }
4729 }
4730
4731 return ARB_VP_SUCESS;
4732
4733
4734}
4735
4736/**
4737 * Print out the parse tree from a given point. Just for debugging.
4738 *
4739 * \param s The parse state
4740 * \param ptn The root to start printing from
4741 */
4742static void
4743print_parse_tree(parse_state * s, parse_tree_node * ptn)
4744{
4745 GLint a;
4746
4747 /* If we're terminal, prGLint and exit */
4748 if (ptn->is_terminal) {
4749 debug_token(s, ptn->tok, ptn->tok_attr);
4750 printf("\n");
4751 return;
4752 }
4753
4754 /* Else, recurse on all our children */
4755 for (a = 0; a < 4; a++) {
4756 if (!ptn->children[a])
4757 return;
4758
4759 print_parse_tree(s, ptn->children[a]);
4760 }
4761}
4762
4763/**
4764 * Free all of the children of a given parse tree node.
4765 *
4766 * \param ptn The root node whose children we recursively free
4767 */
4768static void
4769parse_tree_free_children(parse_tree_node * ptn)
4770{
4771 GLint a;
4772
4773 if (!ptn)
4774 return;
4775 if (!ptn->children[0])
4776 return;
4777
4778 for (a = 0; a < 4; a++) {
4779 if (ptn->children[a]) {
4780 parse_tree_free_children(ptn->children[a]);
4781 _mesa_free(ptn->children[a]);
4782 ptn->children[a] = NULL;
4783 }
4784 }
4785}
4786
4787/**
4788 * Given the name of a matrix, and a modifier, expand into a binding type.
4789 *
4790 * names: 0 -- modelview
4791 * 1 -- projection
4792 * 2 -- mvp
4793 * 3 -- texture
4794 * 4 -- palette
4795 * 5 -- program
4796 *
4797 * mods: 0 -- normal
4798 * 1 -- inverse
4799 * 2 -- invtrans
4800 * 3 -- transpose
4801 *
4802 * \param name The number of the matrix type
4803 * \param mod The number of the matrix modifier
4804 *
4805 * \return The binding state corresponding to name & mod
4806 */
4807static GLint
4808name_and_mod_to_matrixrows(GLint name, GLint mod)
4809{
4810 switch (name) {
4811 case 0: /* modelview */
4812 switch (mod) {
4813 case 0:
4814 return MATRIXROWS_MODELVIEW;
4815 case 1:
4816 return MATRIXROWS_MODELVIEW_INVERSE;
4817 case 2:
4818 return MATRIXROWS_MODELVIEW_INVTRANS;
4819 case 3:
4820 return MATRIXROWS_MODELVIEW_TRANSPOSE;
4821 }
4822 break;
4823 case 1: /* projection */
4824 switch (mod) {
4825 case 0:
4826 return MATRIXROWS_PROJECTION;
4827 case 1:
4828 return MATRIXROWS_PROJECTION_INVERSE;
4829 case 2:
4830 return MATRIXROWS_PROJECTION_INVTRANS;
4831 case 3:
4832 return MATRIXROWS_PROJECTION_TRANSPOSE;
4833 }
4834
4835 break;
4836 case 2: /* mvp */
4837 switch (mod) {
4838 case 0:
4839 return MATRIXROWS_MVP;
4840 case 1:
4841 return MATRIXROWS_MVP_INVERSE;
4842 case 2:
4843 return MATRIXROWS_MVP_INVTRANS;
4844 case 3:
4845 return MATRIXROWS_MVP_TRANSPOSE;
4846 }
4847
4848 break;
4849 case 3: /* texture */
4850 switch (mod) {
4851 case 0:
4852 return MATRIXROWS_TEXTURE;
4853 case 1:
4854 return MATRIXROWS_TEXTURE_INVERSE;
4855 case 2:
4856 return MATRIXROWS_TEXTURE_INVTRANS;
4857 case 3:
4858 return MATRIXROWS_TEXTURE_TRANSPOSE;
4859 }
4860 break;
4861 case 4: /* palette */
4862 switch (mod) {
4863 case 0:
4864 return MATRIXROWS_PALETTE;
4865 case 1:
4866 return MATRIXROWS_PALETTE_INVERSE;
4867 case 2:
4868 return MATRIXROWS_PALETTE_INVTRANS;
4869 case 3:
4870 return MATRIXROWS_PALETTE_TRANSPOSE;
4871 }
4872 break;
4873 case 5: /* program */
4874 switch (mod) {
4875 case 0:
4876 return MATRIXROWS_PROGRAM;
4877 case 1:
4878 return MATRIXROWS_PROGRAM_INVERSE;
4879 case 2:
4880 return MATRIXROWS_PROGRAM_INVTRANS;
4881 case 3:
4882 return MATRIXROWS_PROGRAM_TRANSPOSE;
4883 }
4884 break;
4885 }
4886
4887 return 0;
4888}
4889
4890/**
4891 * This takes a node in the parse tree for an OPTIONAL_MASK token
4892 * being derived into a write mask for a register.
4893 *
4894 * This will expand the production number into a 4-component
4895 * write mask.
4896 *
4897 * \param mask_node The parse tree node for the optional_mask non-termina
4898 * \param mask 4-component write mask
4899 */
4900static void
4901get_optional_mask(parse_tree_node * mask_node, GLint * mask)
4902{
4903 if (mask_node->prod_applied == 97) {
4904 switch (mask_node->children[0]->prod_applied) {
4905 case 99: /* x */
4906 mask[0] = 1;
4907 mask[1] = 0;
4908 mask[2] = 0;
4909 mask[3] = 0;
4910 break;
4911
4912 case 100: /* y */
4913 mask[0] = 0;
4914 mask[1] = 1;
4915 mask[2] = 0;
4916 mask[3] = 0;
4917 break;
4918
4919 case 101: /* xy */
4920 mask[0] = 1;
4921 mask[1] = 1;
4922 mask[2] = 0;
4923 mask[3] = 0;
4924 break;
4925
4926 case 102: /* z */
4927 mask[0] = 0;
4928 mask[1] = 0;
4929 mask[2] = 1;
4930 mask[3] = 0;
4931 break;
4932
4933 case 103: /* xz */
4934 mask[0] = 1;
4935 mask[1] = 0;
4936 mask[2] = 1;
4937 mask[3] = 0;
4938 break;
4939
4940 case 104: /* yz */
4941 mask[0] = 0;
4942 mask[1] = 1;
4943 mask[2] = 1;
4944 mask[3] = 0;
4945 break;
4946
4947 case 105: /* xyz */
4948 mask[0] = 1;
4949 mask[1] = 1;
4950 mask[2] = 1;
4951 mask[3] = 0;
4952 break;
4953
4954 case 106: /* w */
4955 mask[0] = 0;
4956 mask[1] = 0;
4957 mask[2] = 0;
4958 mask[3] = 1;
4959 break;
4960
4961 case 107: /* xw */
4962 mask[0] = 1;
4963 mask[1] = 0;
4964 mask[2] = 0;
4965 mask[3] = 1;
4966 break;
4967
4968 case 108: /* yw */
4969 mask[0] = 0;
4970 mask[1] = 1;
4971 mask[2] = 0;
4972 mask[3] = 1;
4973 break;
4974
4975 case 109: /* xyw */
4976 mask[0] = 1;
4977 mask[1] = 1;
4978 mask[2] = 0;
4979 mask[3] = 1;
4980 break;
4981
4982 case 110: /* zw */
4983 mask[0] = 0;
4984 mask[1] = 0;
4985 mask[2] = 1;
4986 mask[3] = 1;
4987 break;
4988
4989 case 111: /* xzw */
4990 mask[0] = 1;
4991 mask[1] = 0;
4992 mask[2] = 1;
4993 mask[3] = 1;
4994 break;
4995
4996 case 112: /* yzw */
4997 mask[0] = 0;
4998 mask[1] = 1;
4999 mask[2] = 1;
5000 mask[3] = 1;
5001 break;
5002
5003 case 113: /* xyzw */
5004 mask[0] = 1;
5005 mask[1] = 1;
5006 mask[2] = 1;
5007 mask[3] = 1;
5008 break;
5009 }
5010 }
5011}
5012
5013/**
5014 * Given a MASKED_DST_REG token in a parse tree node, figure out what
5015 * register number and write mask the production results in.
5016 *
5017 * \param s The parse state
5018 * \param mdr The parse tree node
5019 * \param dest The destination register number
5020 * \param dest_mask The 4-component write mask
5021 */
5022static void
5023get_masked_dst_reg(parse_state * s, parse_tree_node * mdr, GLint * dest,
5024 GLint * dest_mask)
5025{
5026 GLint a;
5027
5028 /* dest is a TEMP variable */
5029 if (mdr->children[0]->prod_applied == 67) {
5030 a = mdr->children[0]->children[0]->children[0]->children[0]->tok_attr;
5031 *dest = s->binds.reg_num[s->idents.attr[a]];
5032 printf("dst reg: %d (%s)\n", *dest, s->idents.data[a]);
5033 }
5034 else {
5035 /* dest is a result variable */
5036 if (mdr->children[0]->children[0]->prod_applied == 86) {
5037 a = mdr->children[0]->children[0]->children[0]->children[0]->
5038 tok_attr;
5039 *dest = s->binds.reg_num[s->idents.attr[a]];
5040 printf("dest reg: %d (%s)\n", *dest, s->idents.data[a]);
5041 }
5042 /* dest is an implicit binding to result/output state */
5043 else {
5044 a = mdr->children[0]->children[0]->children[0]->tok_attr;
5045 *dest = s->binds.reg_num[a];
5046 printf("dst: %d\n", *dest);
5047 }
5048 }
5049
5050 /* mdr->children[1] is the write mask */
5051 get_optional_mask(mdr->children[1], dest_mask);
5052}
5053
5054
5055/**
5056 * Given a parse tree node with a swizzled src token, figure out the swizzle
5057 * mask.
5058 *
5059 * \param s The parse state
5060 * \param ssr The parse tree node
5061 * \param swz The 4-component swizzle, 0 - x, 1 - y, 2 - z, 3 - w
5062 */
5063static void
5064get_src_swizzle(parse_state * s, parse_tree_node * ssr, GLint * swz)
5065{
5066 GLint a;
5067 GLubyte *c;
5068
5069 if (ssr->prod_applied == 317) {
5070 if (ssr->children[0]->prod_applied == 318) { /* single component */
5071 switch (ssr->children[0]->children[0]->prod_applied) {
5072 case 93: /* x */
5073 for (a = 0; a < 4; a++)
5074 swz[a] = 0;
5075 break;
5076
5077 case 94: /* y */
5078 for (a = 0; a < 4; a++)
5079 swz[a] = 1;
5080 break;
5081
5082 case 95: /* z */
5083 for (a = 0; a < 4; a++)
5084 swz[a] = 2;
5085 break;
5086
5087 case 96: /* w */
5088 for (a = 0; a < 4; a++)
5089 swz[a] = 3;
5090 break;
5091 }
5092 }
5093 else { /* 4-component */
5094
5095 c = s->idents.data[ssr->children[0]->children[0]->children[0]->
5096 tok_attr];
5097 for (a = 0; a < 4; a++) {
5098 switch (c[a]) {
5099 case 'x':
5100 swz[a] = 0;
5101 break;
5102 case 'y':
5103 swz[a] = 1;
5104 break;
5105 case 'z':
5106 swz[a] = 2;
5107 break;
5108 case 'w':
5109 swz[a] = 3;
5110 break;
5111 }
5112 }
5113 }
5114 }
5115}
5116
5117
5118/**
5119 * Given a parse tree node for a src register with an optional sign, figure out
5120 * what register the src maps to, and what the sign is
5121 *
5122 * \param s The parse state
5123 * \param ssr The parse tree node to work from
5124 * \param sign The sign (1 or -1)
5125 * \param ssrc The src register number
5126 */
5127static void
5128get_optional_sign_and_src_reg(parse_state * s, parse_tree_node * ssr,
5129 int *sign, int *ssrc)
5130{
5131 GLint a;
5132
5133 /* ssr->children[0] is the optionalSign */
5134 if (ssr->children[0]->prod_applied == 282) { /* - */
5135 *sign = -1;
5136 }
5137
5138 /* ssr->children[1] is the srcReg */
5139
5140 /* The src is a vertex attrib */
5141 if (ssr->children[1]->prod_applied == 64) {
5142 if (ssr->children[1]->children[0]->prod_applied == 69) { /* variable */
5143 a = ssr->children[1]->children[0]->children[0]->children[0]->
5144 tok_attr;
5145 *ssrc = s->binds.reg_num[s->idents.attr[a]];
5146 printf("src reg: %d (%s)\n", *ssrc, s->idents.data[a]);
5147 }
5148 else { /* implicit binding */
5149
5150 a = ssr->children[1]->children[0]->children[0]->tok_attr;
5151 *ssrc = s->binds.reg_num[a];
5152 printf("src reg: %d %d (implicit binding)\n",
5153 *ssrc, s->binds.type[a]);
5154 }
5155 }
5156 else
5157 /* The src is a temp variable */
5158 if (ssr->children[1]->prod_applied == 65) {
5159 a = ssr->children[1]->children[0]->children[0]->children[0]->tok_attr;
5160 *ssrc = s->binds.reg_num[s->idents.attr[a]];
5161 printf("src reg: %d (%s)\n", *ssrc, s->idents.data[a]);
5162 }
5163 /* The src is a param */
5164 else {
5165 /* We have a single item */
5166 if (ssr->children[1]->children[0]->prod_applied == 72) {
5167 a = ssr->children[1]->children[0]->children[0]->children[0]->
5168 children[0]->tok_attr;
5169 *ssrc = s->binds.reg_num[s->idents.attr[a]];
5170 printf("src reg: %d (%s)\n", *ssrc, s->idents.data[a]);
5171 }
5172 else
5173 /* We have an array of items */
5174 if (ssr->children[1]->children[0]->prod_applied == 73) {
5175 a = ssr->children[1]->children[0]->children[0]->children[0]->
5176 children[0]->tok_attr;
5177 *ssrc = s->binds.reg_num[s->idents.attr[a]];
5178
5179 /* We have an absolute offset into the array */
5180 if (ssr->children[1]->children[0]->children[1]->prod_applied == 77) {
5181 /* Ok, are array will be layed out fully in registers, so we can compute the reg */
5182 printf("array base: %s\n", s->idents.data[a]);
5183 a = ssr->children[1]->children[0]->children[1]->children[0]->
5184 children[0]->tok_attr;
5185 printf("array absolute offset: %d\n", s->ints.data[a]);
5186 *ssrc += s->ints.data[a];
5187 }
5188 /* Otherwise, we have to grab the offset register */
5189 else { /* progParamArrayRel */
5190
5191 /* XXX: We don't know the offset, so we have to grab the offset register # */
5192 }
5193 }
5194 /* Otherwise, we have an implicit binding */
5195 else { /* paramSingleItemUse */
5196
5197 if (ssr->children[1]->children[0]->children[0]->prod_applied == 148) { /* programSingleItem */
5198 a = ssr->children[1]->children[0]->children[0]->children[0]->
5199 tok_attr;
5200 }
5201 else {
5202 a = ssr->children[1]->children[0]->children[0]->children[0]->
5203 children[0]->tok_attr;
5204 }
5205 *ssrc = s->binds.reg_num[a];
5206 printf("src reg: %d %d (implicit binding)\n", *ssrc,
5207 s->binds.type[a]);
5208 }
5209 }
5210}
5211
5212
5213/**
5214 * Figure out what register a src reg is in, as well as the swizzle mask and the
5215 * sign
5216 *
5217 * \param s The parse state
5218 * \param ssr The swizzeled src reg parse tree node
5219 * \param sign The return value for the sign {1, -1}
5220 * \param ssrc The return value for the register number
5221 * \param swz The 4-component swizzle mask
5222 */
5223static void
5224get_swizzle_src_reg(parse_state * s, parse_tree_node * ssr, GLint * sign,
5225 GLint * ssrc, GLint * swz)
5226{
5227 get_optional_sign_and_src_reg(s, ssr, sign, ssrc);
5228
5229 /* ssr->children[2] is the swizzleSuffix */
5230 get_src_swizzle(s, ssr->children[2], swz);
5231}
5232
5233/**
5234 * Just like get_swizzle_src_reg, but find the scalar value to use from the register instead
5235 * of the swizzle mask
5236 *
5237 * \param s The parse state
5238 * \param ssr The swizzeled src reg parse tree node
5239 * \param sign The return value for the sign {1, -1}
5240 * \param ssrc The return value for the register number
5241 * \param scalar The 1-component scalar number
5242 */
5243static void
5244get_scalar_src_reg(parse_state * s, parse_tree_node * ssr, GLint * sign,
5245 GLint * ssrc, GLint * scalar)
5246{
5247 get_optional_sign_and_src_reg(s, ssr, sign, ssrc);
5248
5249 /* sn->children[2] is a scalarSuffix */
5250 switch (ssr->children[2]->children[0]->prod_applied) {
5251 case 93:
5252 *scalar = 0;
5253 break;
5254 case 94:
5255 *scalar = 1;
5256 break;
5257 case 95:
5258 *scalar = 2;
5259 break;
5260 case 96:
5261 *scalar = 3;
5262 break;
5263 }
5264}
5265
5266/**
5267 * Recursivly traverse the parse tree and generate Mesa opcodes
5268 *
5269 * \param s The parse state
5270 * \param ptn The parse tree node to process
5271 */
5272static void
5273parse_tree_generate_opcodes(parse_state * s, parse_tree_node * ptn)
5274{
5275 GLint a;
5276 GLint opcode, dst, src[3];
5277 GLint dst_mask[4], src_swz[3][4], src_scalar[2], src_sign[3];
5278 parse_tree_node *dn, *sn[3];
5279
5280 src_sign[0] = src_sign[1] = src_sign[2] = 1;
5281 for (a = 0; a < 4; a++) {
5282 src_swz[0][a] = a;
5283 src_swz[1][a] = a;
5284 src_swz[2][a] = a;
5285 }
5286 src_scalar[0] = src_scalar[1] = src_scalar[2] = 0;
5287 dst_mask[0] = dst_mask[1] = dst_mask[2] = dst_mask[3] = 1;
5288
5289 switch (ptn->prod_applied) {
5290 case 17: /* ARL */
5291 opcode = VP_OPCODE_ARL;
5292
5293 dn = ptn->children[0];
5294 sn[0] = ptn->children[1];
5295
5296 /* dn is a maskedAddrReg */
5297 /* dn->children[0] is an addrReg */
5298 /* dn->children[1] is an addrWriteMask */
5299 /* XXX: do this.. */
5300 break;
5301
5302 case 18: /* VECTORop */
5303 switch (ptn->children[0]->prod_applied) {
5304 case 19: /* ABS */
5305 opcode = VP_OPCODE_ABS;
5306 break;
5307 case 20: /* FLR */
5308 opcode = VP_OPCODE_FLR;
5309 break;
5310 case 21: /* FRC */
5311 opcode = VP_OPCODE_FRC;
5312 break;
5313 case 22: /* LIT */
5314 opcode = VP_OPCODE_LIT;
5315 break;
5316 case 23: /* MOV */
5317 opcode = VP_OPCODE_MOV;
5318 break;
5319 }
5320 printf("opcode: %d\n", opcode);
5321
5322 /* dn is a maskedDstReg */
5323 dn = ptn->children[1];
5324
5325 /* sn is a swizzleSrcReg */
5326 sn[0] = ptn->children[2];
5327
5328 get_masked_dst_reg(s, dn, &dst, dst_mask);
5329 printf("dst: %d mask: %d %d %d %d\n", dst, dst_mask[0], dst_mask[1],
5330 dst_mask[2], dst_mask[3]);
5331
5332 get_swizzle_src_reg(s, sn[0], &src_sign[0], &src[0], src_swz[0]);
5333
5334 printf("src sign: %d reg: %d swz: %d %d %d %d\n",
5335 src_sign[0], src[0], src_swz[0][0], src_swz[0][1], src_swz[0][2],
5336 src_swz[0][3]);
5337 break;
5338
5339 case 24: /* SCALARop */
5340 switch (ptn->children[0]->prod_applied) {
5341 case 25: /* EX2 */
5342 opcode = VP_OPCODE_EX2;
5343 break;
5344 case 26: /* EXP */
5345 opcode = VP_OPCODE_EXP;
5346 break;
5347 case 27: /* LG2 */
5348 opcode = VP_OPCODE_LG2;
5349 break;
5350 case 28: /* LOG */
5351 opcode = VP_OPCODE_LOG;
5352 break;
5353 case 29: /* RCP */
5354 opcode = VP_OPCODE_RCP;
5355 break;
5356 case 30: /* RSQ */
5357 opcode = VP_OPCODE_RSQ;
5358 break;
5359 }
5360
5361 printf("opcode: %d\n", opcode);
5362 /* dn is a maskedDstReg */
5363 dn = ptn->children[1];
5364
5365 get_masked_dst_reg(s, dn, &dst, dst_mask);
5366 printf("dst: %d mask: %d %d %d %d\n", dst, dst_mask[0], dst_mask[1],
5367 dst_mask[2], dst_mask[3]);
5368
5369 /* sn is a scalarSrcReg */
5370 sn[0] = ptn->children[2];
5371
5372 get_scalar_src_reg(s, sn[0], &src_sign[0], &src[0], &src_scalar[0]);
5373 printf("src sign: %d reg: %d scalar: %d\n", src_sign[0], src[0],
5374 src_scalar[0]);
5375 break;
5376
5377 case 31: /* BINSC */
5378 opcode = VP_OPCODE_POW;
5379
5380 printf("opcode: %d\n", opcode);
5381 /* maskedDstReg */
5382 dn = ptn->children[1];
5383 get_masked_dst_reg(s, dn, &dst, dst_mask);
5384 printf("dst: %d mask: %d %d %d %d\n", dst, dst_mask[0], dst_mask[1],
5385 dst_mask[2], dst_mask[3]);
5386
5387 /* sn are scalarSrcReg's */
5388 sn[0] = ptn->children[2]->children[0];
5389 sn[1] = ptn->children[2]->children[1];
5390
5391 get_scalar_src_reg(s, sn[0], &src_sign[0], &src[0], &src_scalar[0]);
5392 get_scalar_src_reg(s, sn[1], &src_sign[1], &src[1], &src_scalar[1]);
5393
5394 printf("src0 sign: %d reg: %d scalar: %d\n", src_sign[0], src[0],
5395 src_scalar[0]);
5396 printf("src1 sign: %d reg: %d scalar: %d\n", src_sign[1], src[1],
5397 src_scalar[1]);
5398 break;
5399
5400
5401 case 34: /* BIN */
5402 switch (ptn->children[0]->prod_applied) {
5403 case 36: /* ADD */
5404 opcode = VP_OPCODE_ADD;
5405 break;
5406 case 37: /* DP3 */
5407 opcode = VP_OPCODE_DP3;
5408 break;
5409 case 38: /* DP4 */
5410 opcode = VP_OPCODE_DP4;
5411 break;
5412 case 39: /* DPH */
5413 opcode = VP_OPCODE_DPH;
5414 break;
5415 case 40: /* DST */
5416 opcode = VP_OPCODE_DST;
5417 break;
5418 case 41: /* MAX */
5419 opcode = VP_OPCODE_MAX;
5420 break;
5421 case 42: /* MIN */
5422 opcode = VP_OPCODE_MIN;
5423 break;
5424 case 43: /* MUL */
5425 opcode = VP_OPCODE_MUL;
5426 break;
5427 case 44: /* SGE */
5428 opcode = VP_OPCODE_SGE;
5429 break;
5430 case 45: /* SLT */
5431 opcode = VP_OPCODE_SLT;
5432 break;
5433 case 46: /* SUB */
5434 opcode = VP_OPCODE_SUB;
5435 break;
5436 case 47: /* XPD */
5437 opcode = VP_OPCODE_XPD;
5438 break;
5439 }
5440
5441 printf("opcode: %d\n", opcode);
5442
5443 /* maskedDstReg */
5444 dn = ptn->children[1];
5445 get_masked_dst_reg(s, dn, &dst, dst_mask);
5446 printf("dst: %d mask: %d %d %d %d\n", dst, dst_mask[0], dst_mask[1],
5447 dst_mask[2], dst_mask[3]);
5448
5449 /* sn are scalarSrcReg's */
5450 sn[0] = ptn->children[2]->children[0];
5451 sn[1] = ptn->children[2]->children[1];
5452
5453 get_swizzle_src_reg(s, sn[0], &src_sign[0], &src[0], src_swz[0]);
5454 get_swizzle_src_reg(s, sn[1], &src_sign[1], &src[1], src_swz[1]);
5455
5456 printf("src0 sign: %d reg: %d swz: %d %d %d %d\n",
5457 src_sign[0], src[0], src_swz[0][0], src_swz[0][1], src_swz[0][2],
5458 src_swz[0][3]);
5459 printf("src1 sign: %d reg: %d swz: %d %d %d %d\n", src_sign[1], src[1],
5460 src_swz[1][0], src_swz[1][1], src_swz[1][2], src_swz[1][3]);
5461 break;
5462
5463 case 48: /* TRI */
5464 opcode = VP_OPCODE_MAD;
5465
5466 printf("opcode: %d\n", opcode);
5467
5468 /* maskedDstReg */
5469 dn = ptn->children[1];
5470 get_masked_dst_reg(s, dn, &dst, dst_mask);
5471 printf("dst: %d mask: %d %d %d %d\n", dst, dst_mask[0], dst_mask[1],
5472 dst_mask[2], dst_mask[3]);
5473
5474 /* sn are scalarSrcReg's */
5475 sn[0] = ptn->children[2]->children[0];
5476 sn[1] = ptn->children[2]->children[1]->children[0];
5477 sn[2] = ptn->children[2]->children[1]->children[1];
5478
5479 get_swizzle_src_reg(s, sn[0], &src_sign[0], &src[0], src_swz[0]);
5480 get_swizzle_src_reg(s, sn[1], &src_sign[1], &src[1], src_swz[1]);
5481 get_swizzle_src_reg(s, sn[2], &src_sign[2], &src[2], src_swz[2]);
5482
5483 printf("src0 sign: %d reg: %d swz: %d %d %d %d\n",
5484 src_sign[0], src[0], src_swz[0][0], src_swz[0][1], src_swz[0][2],
5485 src_swz[0][3]);
5486 printf("src1 sign: %d reg: %d swz: %d %d %d %d\n", src_sign[1], src[1],
5487 src_swz[1][0], src_swz[1][1], src_swz[1][2], src_swz[1][3]);
5488 printf("src2 sign: %d reg: %d swz: %d %d %d %d\n", src_sign[2], src[2],
5489 src_swz[2][0], src_swz[2][1], src_swz[2][2], src_swz[2][3]);
5490
5491 }
5492
5493 for (a = 0; a < 4; a++) {
5494 if (!ptn->children[a])
5495 return;
5496 parse_tree_generate_opcodes(s, ptn->children[a]);
5497 }
5498}
5499
5500/**
5501 * When we go to examine the parse tree to generate opcodes, things are not exactly pretty to deal with.
5502 * Parameters, constants, matricies, attribute bindings, and the like are represented by large numbers
5503 * of nodes.
5504 *
5505 * In order to keep the code generation code cleaner, we make a recursive pass over the parse tree and 'roll up' these deep
5506 * derivations of the attribs, and replace them with a single token, BINDING_TOKEN. The token attribute for
5507 * BINDING_TOKEN is a index in the 'binding table' where all the relavant info on the chunk of state is stored,
5508 * e.g its type.
5509 *
5510 * For example, the string 'vertex.color.secondary' is represented by 4 productions, and 4 nodes in the parse
5511 * tree. The token at the root of this derivation is NT_VTX_ATTRIB_BINDING_TOKEN. After this folding,
5512 * the token at the root is BINDING_TOKEN, and s->binds[token_attr_at_the_root].type = ATTRIB_COLOR_SECONDARY.
5513 *
5514 * \param s The parse state
5515 * \param ptn The root parse tree node to start folding bindings
5516 */
5517static void
5518parse_tree_fold_bindings(parse_state * s, parse_tree_node * ptn)
5519{
5520 GLint a, b;
5521 GLint eat_children, bind_type, bind_idx, bind_row, bind_nrows;
5522 GLfloat bind_vals[4];
5523 parse_tree_node *ptmp;
5524
5525 eat_children = 0;
5526 bind_row = 0;
5527 bind_nrows = 1;
5528 bind_vals[0] = bind_vals[1] = bind_vals[2] = bind_vals[3];
5529 switch (ptn->prod_applied) {
5530 /* vertex */
5531 case 121:
5532 eat_children = 1;
5533 bind_idx = 0;
5534 switch (ptn->children[0]->prod_applied) {
5535 case 122: /* position */
5536 bind_type = ATTRIB_POSITION;
5537 break;
5538 case 123: /* weight */
5539 bind_type = ATTRIB_WEIGHT;
5540 if (ptn->children[0]->children[0]->prod_applied == 132) {
5541 bind_idx =
5542 s->ints.data[ptn->children[0]->children[0]->children[0]->
5543 children[0]->tok_attr];
5544 }
5545 break;
5546 case 124: /* normal */
5547 bind_type = ATTRIB_NORMAL;
5548 break;
5549 case 125: /* color */
5550 bind_type = ATTRIB_COLOR_PRIMARY;
5551 if (ptn->children[0]->children[0]->prod_applied == 306) {
5552 if (ptn->children[0]->children[0]->children[0]->prod_applied ==
5553 309)
5554 bind_type = ATTRIB_COLOR_SECONDARY;
5555 }
5556 break;
5557 case 126: /* fogcoord */
5558 bind_type = ATTRIB_FOGCOORD;
5559 break;
5560 case 127: /* texcoord */
5561 bind_type = ATTRIB_TEXCOORD;
5562 if (ptn->children[0]->children[0]->prod_applied == 311) {
5563 bind_idx =
5564 s->ints.data[ptn->children[0]->children[0]->children[0]->
5565 children[0]->tok_attr];
5566 }
5567 break;
5568 case 128: /* matrixindex */
5569 bind_type = ATTRIB_MATRIXINDEX;
5570 bind_idx =
5571 s->ints.data[ptn->children[0]->children[0]->children[0]->
5572 tok_attr];
5573 break;
5574 case 129: /* attrib */
5575 bind_type = ATTRIB_ATTRIB;
5576 bind_idx =
5577 s->ints.data[ptn->children[0]->children[0]->children[0]->
5578 tok_attr];
5579 break;
5580 }
5581 break;
5582
5583 /* state */
5584 case 154:
5585 case 172: /* material */
5586 eat_children = 2;
5587 bind_idx = 0;
5588 ptmp = ptn->children[0]->children[0];
5589
5590 a = 0;
5591 if (ptmp->prod_applied == 182) {
5592 a = 1;
5593 b = 0;
5594 }
5595 else
5596 if ((ptmp->prod_applied == 183)
5597 && (ptmp->children[0]->prod_applied == 305)) {
5598 a = 1;
5599 b = 1;
5600 }
5601
5602 /* no explicit face, or explicit front */
5603 if (a) {
5604 switch (ptmp->children[b]->prod_applied) {
5605 case 184: /* ambient */
5606 bind_type = MATERIAL_FRONT_AMBIENT;
5607 break;
5608 case 185: /* diffuse */
5609 bind_type = MATERIAL_FRONT_DIFFUSE;
5610 break;
5611 case 186: /* specular */
5612 bind_type = MATERIAL_FRONT_SPECULAR;
5613 break;
5614 case 187: /* emission */
5615 bind_type = MATERIAL_FRONT_EMISSION;
5616 break;
5617 case 188: /* shininess */
5618 bind_type = MATERIAL_FRONT_SHININESS;
5619 break;
5620 }
5621 }
5622 /* has explicit back face */
5623 else {
5624 switch (ptmp->children[1]->prod_applied) {
5625 case 184: /* ambient */
5626 bind_type = MATERIAL_BACK_AMBIENT;
5627 break;
5628 case 185: /* diffuse */
5629 bind_type = MATERIAL_BACK_DIFFUSE;
5630 break;
5631 case 186: /* specular */
5632 bind_type = MATERIAL_BACK_SPECULAR;
5633 break;
5634 case 187: /* emission */
5635 bind_type = MATERIAL_BACK_EMISSION;
5636 break;
5637 case 188: /* shininess */
5638 bind_type = MATERIAL_BACK_SHININESS;
5639 break;
5640 }
5641 }
5642 break;
5643 case 155:
5644 case 173: /* light */
5645 eat_children = 2;
5646 bind_idx = 0;
5647 printf("FOLDING LIGHT!\n");
5648 ptmp = ptn->children[0];
5649 bind_idx = s->ints.data[ptmp->children[0]->children[0]->tok_attr];
5650 switch (ptmp->children[1]->children[0]->prod_applied) {
5651 case 191: /* ambient */
5652 bind_type = LIGHT_AMBIENT;
5653 break;
5654 case 192: /* diffuse */
5655 bind_type = LIGHT_DIFFUSE;
5656 break;
5657 case 193: /* specular */
5658 bind_type = LIGHT_SPECULAR;
5659 break;
5660 case 194: /* position */
5661 bind_type = LIGHT_POSITION;
5662 break;
5663 case 195: /* attenuation */
5664 bind_type = LIGHT_ATTENUATION;
5665 break;
5666 case 196: /* spot */
5667 bind_type = LIGHT_SPOT_DIRECTION;
5668 break;
5669 case 197: /* half */
5670 bind_type = LIGHT_HALF;
5671 break;
5672 }
5673 break;
5674
5675 case 156:
5676 case 174: /* lightmodel */
5677 eat_children = 2;
5678 bind_idx = 0;
5679
5680 ptmp = ptn->children[0];
5681 switch (ptmp->prod_applied) {
5682 case 201: /* ambient */
5683 bind_type = LIGHTMODEL_AMBIENT;
5684 break;
5685 case 202: /* scenecolor */
5686 bind_type = LIGHTMODEL_FRONT_SCENECOLOR;
5687 break;
5688 case 203: /* foo.scenecolor */
5689 if (ptmp->children[0]->prod_applied == 304)
5690 bind_type = LIGHTMODEL_FRONT_SCENECOLOR;
5691 else
5692 bind_type = LIGHTMODEL_BACK_SCENECOLOR;
5693 }
5694 break;
5695 case 157:
5696 case 175: /* lightprod */
5697 eat_children = 2;
5698 bind_idx = 0;
5699
5700 ptmp = ptn->children[0];
5701 bind_idx = s->ints.data[ptmp->children[0]->children[0]->tok_attr];
5702 /* No explicit face */
5703 if (ptmp->children[1]->children[0]->prod_applied == 206) {
5704 a = 1; /* front */
5705 b = 0; /* 0-th child */
5706 }
5707 else
5708 if ((ptmp->children[1]->children[0]->prod_applied == 207) &&
5709 (ptmp->children[1]->children[0]->children[0]->prod_applied ==
5710 304)) {
5711 a = 1; /* front */
5712 b = 1; /* 1-th child */
5713 }
5714 else {
5715 a = 0;
5716 b = 1;
5717 }
5718 if (a) {
5719 switch (ptmp->children[1]->children[0]->children[b]->prod_applied) {
5720 case 208: /* ambient */
5721 bind_type = LIGHTPROD_FRONT_AMBIENT;
5722 break;
5723 case 209: /* diffuse */
5724 bind_type = LIGHTPROD_FRONT_DIFFUSE;
5725 break;
5726 case 210: /* specular */
5727 bind_type = LIGHTPROD_FRONT_SPECULAR;
5728 break;
5729 }
5730 }
5731 else {
5732 switch (ptmp->children[1]->children[0]->children[b]->prod_applied) {
5733 case 208: /* ambient */
5734 bind_type = LIGHTPROD_BACK_AMBIENT;
5735 break;
5736 case 209: /* diffuse */
5737 bind_type = LIGHTPROD_BACK_DIFFUSE;
5738 break;
5739 case 210: /* specular */
5740 bind_type = LIGHTPROD_BACK_SPECULAR;
5741 break;
5742 }
5743 }
5744 break;
5745 case 158:
5746 case 176: /* texgen */
5747 eat_children = 2;
5748 bind_idx = 0;
5749
5750 ptmp = ptn->children[0];
5751 if (ptmp->children[0]->prod_applied == 311)
5752 bind_idx =
5753 s->ints.data[ptmp->children[0]->children[0]->children[0]->
5754 tok_attr];
5755 ptmp = ptn->children[0]->children[1];
5756 if (ptmp->children[0]->prod_applied == 214)
5757 a = 1; /* eye */
5758 else
5759 a = 0; /* object */
5760 b = ptmp->children[1]->prod_applied - 216;
5761 if (a == 1) {
5762 switch (b) {
5763 case 0:
5764 bind_type = TEXGEN_EYE_S;
5765 break;
5766 case 1:
5767 bind_type = TEXGEN_EYE_T;
5768 break;
5769 case 2:
5770 bind_type = TEXGEN_EYE_R;
5771 break;
5772 case 3:
5773 bind_type = TEXGEN_EYE_Q;
5774 break;
5775 }
5776 }
5777 else {
5778 switch (b) {
5779 case 0:
5780 bind_type = TEXGEN_OBJECT_S;
5781 break;
5782 case 1:
5783 bind_type = TEXGEN_OBJECT_T;
5784 break;
5785 case 2:
5786 bind_type = TEXGEN_OBJECT_R;
5787 break;
5788 case 3:
5789 bind_type = TEXGEN_OBJECT_Q;
5790 break;
5791 }
5792 }
5793 break;
5794 case 159:
5795 case 177: /* fog */
5796 eat_children = 2;
5797 bind_idx = 0;
5798
5799 ptmp = ptn->children[0];
5800 if (ptmp->children[0]->prod_applied == 221)
5801 bind_type = FOG_COLOR;
5802 else
5803 bind_type = FOG_PARAMS;
5804 break;
5805 case 160:
5806 case 178: /* clip */
5807 eat_children = 2;
5808 bind_idx = 0;
5809
5810 ptmp = ptn->children[0];
5811 bind_idx = s->ints.data[ptmp->children[0]->children[0]->tok_attr];
5812 bind_type = CLIP_PLANE;
5813 break;
5814 case 161:
5815 case 179: /* point */
5816 eat_children = 2;
5817 bind_idx = 0;
5818
5819 ptmp = ptn->children[0];
5820 if (ptmp->children[0]->prod_applied == 227)
5821 bind_type = POINT_SIZE;
5822 else
5823 bind_type = POINT_ATTENUATION;
5824 break;
5825
5826 case 162: /* matrix rows/whole matrix */
5827 eat_children = 2;
5828 bind_idx = 0;
5829 {
5830 parse_tree_node *mname;
5831 GLint mod = 0;
5832 GLint name = 0;
5833
5834 mname = ptn->children[0];
5835 switch (mname->prod_applied) {
5836 case 238: /* modelview */
5837 name = 0;
5838 if (mname->children[0]->prod_applied == 245)
5839 bind_idx =
5840 s->ints.data[mname->children[0]->children[0]->children[0]->
5841 tok_attr];
5842 break;
5843 case 239: /* projection */
5844 name = 1;
5845 break;
5846 case 240: /* mvp */
5847 name = 2;
5848 break;
5849 case 241: /* texture */
5850 if (mname->children[0]->prod_applied == 311)
5851 bind_idx =
5852 s->ints.data[mname->children[0]->children[0]->children[0]->
5853 tok_attr];
5854 name = 3;
5855 break;
5856 case 242: /* palette */
5857 bind_idx =
5858 s->ints.data[mname->children[0]->children[0]->tok_attr];
5859 name = 4;
5860 break;
5861 case 243: /* program */
5862 bind_idx =
5863 s->ints.data[mname->children[0]->children[0]->tok_attr];
5864 name = 5;
5865 break;
5866 }
5867
5868 ptmp = ptn->children[1];
5869 if (ptmp->prod_applied == 316) {
5870 bind_type = name_and_mod_to_matrixrows(name, mod);
5871 bind_row = 0;
5872 bind_nrows = 4;
5873 }
5874 else {
5875 if (ptmp->children[0]->prod_applied == 164) {
5876 switch (ptmp->children[0]->children[0]->prod_applied) {
5877 case 234: /* inverse */
5878 mod = 1;
5879 break;
5880 case 235: /* transpose */
5881 mod = 3;
5882 break;
5883 case 236: /* invtrans */
5884 mod = 2;
5885 break;
5886 }
5887 if (ptmp->children[0]->children[1]->prod_applied == 166) {
5888 bind_type = name_and_mod_to_matrixrows(name, mod);
5889 bind_row = 0;
5890 bind_nrows = 4;
5891 }
5892 else { /* prod 167 */
5893
5894 bind_type = name_and_mod_to_matrixrows(name, mod);
5895 bind_row =
5896 s->ints.data[ptmp->children[0]->children[1]->
5897 children[0]->children[0]->children[0]->
5898 tok_attr];
5899 if (ptmp->children[0]->children[1]->children[0]->
5900 children[1]->prod_applied == 169)
5901 bind_nrows = 1;
5902 else {
5903 bind_nrows =
5904 s->ints.data[ptmp->children[0]->children[1]->
5905 children[0]->children[1]->children[0]->
5906 children[0]->tok_attr] - bind_row + 1;
5907 }
5908 }
5909 }
5910 else { /* prod 165 */
5911
5912 bind_type = name_and_mod_to_matrixrows(name, mod);
5913
5914 bind_row =
5915 s->ints.data[ptmp->children[0]->children[0]->children[0]->
5916 tok_attr];
5917 if (ptmp->children[0]->children[1]->prod_applied == 169)
5918 bind_nrows = 1;
5919 else
5920 bind_nrows =
5921 s->ints.data[ptmp->children[0]->children[1]->
5922 children[0]->children[0]->tok_attr] -
5923 bind_row + 1;
5924 }
5925 }
5926 }
5927
5928 printf("folding matrixrows: %d %d %d %d\n", bind_type, bind_idx,
5929 bind_row, bind_nrows);
5930 break;
5931
5932 case 180: /* matrix row */
5933 eat_children = 2;
5934 bind_idx = 0;
5935
5936 {
5937 GLint mod;
5938 parse_tree_node *mname, *mrow;
5939
5940 ptmp = ptn->children[0];
5941 mname = ptmp->children[0];
5942 mod = 0;
5943 if (ptmp->children[1]->children[0]->prod_applied == 232) {
5944 mrow =
5945 ptmp->children[1]->children[0]->children[1]->children[0]->
5946 children[0];
5947 switch (ptmp->children[1]->children[0]->children[0]->prod_applied) {
5948 case 234:
5949 mod = 1; /* inverse */
5950 break;
5951 case 235:
5952 mod = 2; /* transpose */
5953 break;
5954 case 236:
5955 mod = 3; /* invtrans */
5956 break;
5957 }
5958 }
5959 else {
5960 mrow = ptmp->children[1]->children[0]->children[0]->children[0];
5961 }
5962 bind_row = s->ints.data[mrow->tok_attr];
5963
5964 switch (mname->prod_applied) {
5965 case 238: /* modelview */
5966 if (mname->children[0]->prod_applied == 245) {
5967 bind_idx =
5968 s->ints.data[mname->children[0]->children[0]->children[0]->
5969 tok_attr];
5970 }
5971 switch (mod) {
5972 case 0:
5973 bind_type = MATRIXROW_MODELVIEW;
5974 break;
5975 case 1:
5976 bind_type = MATRIXROW_MODELVIEW_INVERSE;
5977 break;
5978 case 2:
5979 bind_type = MATRIXROW_MODELVIEW_TRANSPOSE;
5980 break;
5981 case 3:
5982 bind_type = MATRIXROW_MODELVIEW_INVTRANS;
5983 }
5984 break;
5985
5986 case 239: /* projection */
5987 switch (mod) {
5988 case 0:
5989 bind_type = MATRIXROW_PROJECTION;
5990 break;
5991 case 1:
5992 bind_type = MATRIXROW_PROJECTION_INVERSE;
5993 break;
5994 case 2:
5995 bind_type = MATRIXROW_PROJECTION_TRANSPOSE;
5996 break;
5997 case 3:
5998 bind_type = MATRIXROW_PROJECTION_INVTRANS;
5999 }
6000 break;
6001
6002 case 240: /* mvp */
6003 switch (mod) {
6004 case 0:
6005 bind_type = MATRIXROW_MVP;
6006 break;
6007 case 1:
6008 bind_type = MATRIXROW_MVP_INVERSE;
6009 break;
6010 case 2:
6011 bind_type = MATRIXROW_MVP_TRANSPOSE;
6012 break;
6013 case 3:
6014 bind_type = MATRIXROW_MVP_INVTRANS;
6015 }
6016 break;
6017
6018 case 241: /* texture */
6019 if (mname->children[0]->prod_applied == 311) {
6020 bind_idx =
6021 s->ints.data[mname->children[0]->children[0]->children[0]->
6022 tok_attr];
6023 }
6024 switch (mod) {
6025 case 0:
6026 bind_type = MATRIXROW_TEXTURE;
6027 break;
6028 case 1:
6029 bind_type = MATRIXROW_TEXTURE_INVERSE;
6030 break;
6031 case 2:
6032 bind_type = MATRIXROW_TEXTURE_TRANSPOSE;
6033 break;
6034 case 3:
6035 bind_type = MATRIXROW_TEXTURE_INVTRANS;
6036 }
6037 break;
6038
6039 case 242: /* palette */
6040 bind_idx =
6041 s->ints.data[mname->children[0]->children[0]->tok_attr];
6042 switch (mod) {
6043 case 0:
6044 bind_type = MATRIXROW_PALETTE;
6045 break;
6046 case 1:
6047 bind_type = MATRIXROW_PALETTE_INVERSE;
6048 break;
6049 case 2:
6050 bind_type = MATRIXROW_PALETTE_TRANSPOSE;
6051 break;
6052 case 3:
6053 bind_type = MATRIXROW_PALETTE_INVTRANS;
6054 }
6055 break;
6056
6057 case 243: /* program */
6058 bind_idx =
6059 s->ints.data[mname->children[0]->children[0]->tok_attr];
6060 switch (mod) {
6061 case 0:
6062 bind_type = MATRIXROW_PROGRAM;
6063 break;
6064 case 1:
6065 bind_type = MATRIXROW_PROGRAM_INVERSE;
6066 break;
6067 case 2:
6068 bind_type = MATRIXROW_PROGRAM_TRANSPOSE;
6069 break;
6070 case 3:
6071 bind_type = MATRIXROW_PROGRAM_INVTRANS;
6072 }
6073 break;
6074 }
6075 }
6076 break;
6077
6078 /* program (single) */
6079 case 249:
6080 eat_children = 1;
6081 bind_idx = 0;
6082 switch (ptn->children[0]->prod_applied) {
6083 case 250: /* env */
6084 bind_type = PROGRAM_ENV_SINGLE;
6085 break;
6086 case 251: /* local */
6087 bind_type = PROGRAM_LOCAL_SINGLE;
6088 break;
6089 }
6090 bind_idx =
6091 s->ints.data[ptn->children[0]->children[0]->children[0]->
6092 children[0]->tok_attr];
6093 break;
6094
6095 /* program (multi) */
6096 case 252:
6097 eat_children = 1;
6098 bind_idx = 0;
6099 switch (ptn->children[0]->prod_applied) {
6100 case 253: /* env */
6101 case 254: /* local */
6102 if (ptn->children[0]->prod_applied == 253)
6103 bind_type = PROGRAM_ENV_MULTI;
6104 else
6105 bind_type = PROGRAM_LOCAL_MULTI;
6106
6107 ptmp = ptn->children[0]->children[0]->children[0];
6108 bind_idx = bind_row =
6109 s->ints.data[ptmp->children[0]->children[0]->tok_attr];
6110 bind_nrows = 1;
6111
6112 ptmp = ptn->children[0]->children[0]->children[0]->children[1];
6113 if ((ptmp->prod_applied == 257) || (ptmp->prod_applied == 262))
6114 bind_nrows =
6115 s->ints.data[ptmp->children[0]->children[0]->tok_attr] -
6116 bind_idx;
6117 break;
6118 }
6119 break;
6120
6121#define FOLD_FLOAT_CONSTANT(float_ptr, bind_vals_idx, sign) \
6122 if (float_ptr->tok == 49) /* GLfloat */ {\
6123 bind_vals[bind_vals_idx] = sign * s->floats.data[float_ptr->tok_attr];\
6124 }\
6125 else /* GLint */ {\
6126 bind_vals[bind_vals_idx] = sign * s->ints.data[float_ptr->tok_attr];\
6127 }
6128
6129#define FOLD_SIGNED_FLOAT_CONSTANT(sf_ptr, bind_vals_idx) \
6130 {\
6131 GLfloat __mul = 1.;\
6132 if (sf_ptr->children[0]->prod_applied == 282) \
6133 __mul = -1.;\
6134 FOLD_FLOAT_CONSTANT(sf_ptr->children[1], bind_vals_idx, __mul);\
6135 }
6136
6137 /* const scalar decl */
6138 case 271:
6139 eat_children = 1;
6140 bind_idx = 0;
6141 bind_type = CONSTANT;
6142
6143 FOLD_SIGNED_FLOAT_CONSTANT(ptn->children[0], 0);
6144#if 0
6145 {
6146 GLfloat mul = 1.;
6147 if (ptn->children[0]->children[0]->prod_applied == 282) {
6148 mul = -1;
6149 }
6150
6151 FOLD_FLOAT_CONSTANT(ptn->children[0]->children[1], 0, mul);
6152 }
6153#endif
6154 break;
6155
6156 /* const vector */
6157 case 273:
6158 eat_children = 1;
6159 bind_idx = 0;
6160 bind_type = CONSTANT;
6161
6162 FOLD_SIGNED_FLOAT_CONSTANT(ptn->children[0], 0);
6163 if (ptn->children[1]->prod_applied == 275) {
6164 FOLD_SIGNED_FLOAT_CONSTANT(ptn->children[1]->children[0], 1);
6165 if (ptn->children[1]->children[1]->prod_applied == 277) {
6166 FOLD_SIGNED_FLOAT_CONSTANT(ptn->children[1]->children[1]->
6167 children[0], 2);
6168 if (ptn->children[1]->children[1]->children[1]->prod_applied ==
6169 279) {
6170 FOLD_SIGNED_FLOAT_CONSTANT(ptn->children[1]->children[1]->
6171 children[1]->children[0], 3);
6172 }
6173 }
6174 }
6175 break;
6176
6177 /* result */
6178 case 289:
6179 eat_children = 1;
6180 bind_idx = 0;
6181 switch (ptn->children[0]->prod_applied) {
6182 case 290: /* position */
6183 bind_type = RESULT_POSITION;
6184 break;
6185 case 291: /* fogcoord */
6186 bind_type = RESULT_FOGCOORD;
6187 break;
6188 case 292: /* pointsize */
6189 bind_type = RESULT_POINTSIZE;
6190 break;
6191 case 293: /* color */
6192 bind_type = RESULT_COLOR_FRONT_PRIMARY;
6193 ptmp = ptn->children[0]->children[0]->children[0];
6194 if (ptmp->prod_applied == 297) {
6195 if (ptmp->children[0]->prod_applied == 298) { /* front */
6196 if (ptmp->children[0]->children[0]->prod_applied == 301) {
6197 if (ptmp->children[0]->children[0]->children[0]->prod_applied == 303) /* secondary */
6198 bind_type = RESULT_COLOR_FRONT_SECONDARY;
6199 }
6200 }
6201 else { /* back */
6202
6203 bind_type = RESULT_COLOR_BACK_PRIMARY;
6204 if (ptmp->children[0]->children[0]->prod_applied == 301) {
6205 if (ptmp->children[0]->children[0]->children[0]->prod_applied == 303) /* secondary */
6206 bind_type = RESULT_COLOR_BACK_SECONDARY;
6207 }
6208
6209 }
6210 }
6211 break;
6212 case 294: /* texcoord */
6213 bind_type = RESULT_TEXCOORD;
6214 if (ptn->children[0]->children[0]->prod_applied == 311) {
6215 bind_idx =
6216 s->ints.data[ptn->children[0]->children[0]->children[0]->
6217 children[0]->tok_attr];
6218 }
6219 break;
6220 }
6221 break;
6222 }
6223
6224 /* Mmmmm... baaaaby */
6225 if (eat_children) {
6226 if (eat_children == 2)
6227 parse_tree_free_children(ptn->children[0]);
6228 else
6229 parse_tree_free_children(ptn);
6230
6231 /* Insert the binding into the binding table */
6232 ptn->tok = BINDING_TOKEN;
6233 ptn->tok_attr =
6234 binding_table_add(&s->binds, bind_type, bind_idx, bind_row,
6235 bind_nrows, bind_vals);
6236
6237 printf("Got binding %d %d %d %d at pos %d in bind tab [%f %f %f %f]\n",
6238 bind_type, bind_idx, bind_row, bind_nrows, ptn->tok_attr,
6239 bind_vals[0], bind_vals[1], bind_vals[2], bind_vals[3]);
6240 }
6241
6242
6243 for (a = 0; a < 4; a++) {
6244 if (!ptn->children[a])
6245 return;
6246
6247 parse_tree_fold_bindings(s, ptn->children[a]);
6248 }
6249}
6250
6251/**
6252 * After we have figured out what mess of parse tree actually represents GL state (or constants, or
6253 * whatnot), we have to line up variables with the state. For example, a line something like
6254 *
6255 * OUTPUT foo = result.position;
6256 *
6257 * We would have 'foo' in the identifier table at some position foo_idx, and 'result.position' in the
6258 * binding table at some position res_pos_idx. To set things up such that 'foo' is associated with
6259 * the result position state, we need to set ident[foo_idx].attr = res_pos_idx so we can generate
6260 * opcodes without going bonkers.
6261 *
6262 * This function works on OUTPUT, ATTRIB, and PARAM single bindings. PARAM array bindings are handled in
6263 * parse_tree_assign_param_arrays().
6264 *
6265 * \param s The parse state
6266 * \param ptn The root of the parse tree from which to start lining up state and variables
6267 */
6268static void
6269parse_tree_assign_bindings(parse_state * s, parse_tree_node * ptn)
6270{
6271 GLint a;
6272 parse_tree_node *var_name, *attr_item;
6273
6274 /* OUTPUT, ATTRIB */
6275 if ((ptn->prod_applied == 288) || (ptn->prod_applied == 120)) {
6276 var_name = ptn->children[0]->children[0];
6277 attr_item = ptn->children[1];
6278
6279 if (attr_item->tok != BINDING_TOKEN) {
6280 fprintf(stderr,
6281 "sanity check: trying to bind an output variable to something funky!\n");
6282 return;
6283 }
6284
6285 s->idents.attr[var_name->tok_attr] = attr_item->tok_attr;
6286 printf("result: %s bound to %d\n", s->idents.data[var_name->tok_attr],
6287 s->binds.type[s->idents.attr[var_name->tok_attr]]);
6288 return;
6289 }
6290
6291 /* stateSingleItemDecl */
6292 if (ptn->prod_applied == 134) {
6293 var_name = ptn->children[0]->children[0];
6294 if (ptn->children[1]->prod_applied == 135) {
6295 if (ptn->children[1]->children[0]->prod_applied == 139) {
6296 if (ptn->children[1]->children[0]->children[0]->prod_applied ==
6297 144)
6298 attr_item =
6299 ptn->children[1]->children[0]->children[0]->children[0]->
6300 children[0];
6301 else if (ptn->children[1]->children[0]->children[0]->
6302 prod_applied == 145)
6303 attr_item =
6304 ptn->children[1]->children[0]->children[0]->children[0];
6305 else
6306 attr_item =
6307 ptn->children[1]->children[0]->children[0]->children[0]->
6308 children[0];
6309
6310 if (attr_item->tok != BINDING_TOKEN) {
6311 fprintf(stderr,
6312 "sanity check: trying to bind an param variable (%s) to something funky! [%d]\n",
6313 s->idents.data[var_name->tok_attr], attr_item->tok);
6314 exit(1);
6315 }
6316
6317 s->idents.attr[var_name->tok_attr] = attr_item->tok_attr;
6318 printf("result: %s bound to %d\n",
6319 s->idents.data[var_name->tok_attr],
6320 s->binds.type[s->idents.attr[var_name->tok_attr]]);
6321 return;
6322 }
6323 }
6324
6325 }
6326
6327 /* else, recurse on all our children */
6328 for (a = 0; a < 4; a++) {
6329 if (!ptn->children[a])
6330 return;
6331
6332 parse_tree_assign_bindings(s, ptn->children[a]);
6333 }
6334
6335}
6336
6337/**
6338 * This handles lining up PARAM arrays with variables, much like parse_tree_assign_bindings().
6339 *
6340 * In parse_tree_assign_bindings, we set the identifier attr to the index into the binding table of
6341 * the bound state.
6342 *
6343 * Here, instead, we allocate a slot in the 'array table' to stick the bound state into. Instead
6344 * of an index into the binding table, the identifier attr now holds the index into the array table.
6345 *
6346 * \param s The parse state
6347 * \param pnt The root parse tree node to handle arrays from
6348 *
6349 */
6350static void
6351parse_tree_assign_param_arrays(parse_state * s, parse_tree_node * ptn)
6352{
6353 GLint a, is_mult, array_len;
6354 parse_tree_node *var_name, *binding, *arraysize, *ptmp;
6355
6356 /* If we're a param */
6357 if (ptn->prod_applied == 134) {
6358 /* establish name */
6359 var_name = ptn->children[0];
6360
6361 /* param_statement2 */
6362 binding = ptn->children[1];
6363 if (binding->prod_applied == 136) {
6364 /* optarraysize */
6365 arraysize = binding->children[0];
6366
6367 is_mult = 0;
6368
6369 /* foo[3] */
6370 if (arraysize->prod_applied == 138) {
6371 debug_token(s, var_name->children[0]->tok,
6372 var_name->children[0]->tok_attr);
6373 debug_token(s, arraysize->children[0]->tok,
6374 arraysize->children[0]->tok_attr);
6375 printf("\n");
6376 is_mult = 1;
6377 }
6378 else
6379 /* foo[] */
6380 if (arraysize->prod_applied == 137) {
6381 arraysize = NULL;
6382 printf("How do I init a PARAM array like foo[]?? \n");
6383 is_mult = 1;
6384 }
6385
6386 if (!is_mult)
6387 return;
6388
6389 s->idents.attr[var_name->tok_attr] = array_table_new(&s->arrays);
6390
6391 binding = binding->children[1]->children[0];
6392 ptmp = binding->children[0];
6393 array_len = 0;
6394
6395 if (ptmp->prod_applied == 150) { /* state */
6396 printf("matrix 0 [state]:\n");
6397 printf("%d %d\n", ptmp->children[0]->children[0]->tok,
6398 ptmp->children[0]->children[0]->tok_attr);
6399 array_table_add_data(&s->arrays,
6400 s->idents.attr[var_name->tok_attr],
6401 ptmp->children[0]->children[0]->tok_attr);
6402 array_len +=
6403 s->binds.num_rows[ptmp->children[0]->children[0]->tok_attr];
6404 }
6405 else if (ptmp->prod_applied == 151) { /* program */
6406 printf("matrix 0 [program]:\n");
6407 printf("%d %d\n", ptmp->children[0]->tok,
6408 ptmp->children[0]->tok_attr);
6409 array_table_add_data(&s->arrays,
6410 s->idents.attr[var_name->tok_attr],
6411 ptmp->children[0]->tok_attr);
6412 array_len += s->binds.num_rows[ptmp->children[0]->tok_attr];
6413 }
6414 else { /* constant */
6415
6416 printf("matrix 0 [constant]:\n");
6417 printf("%d %d\n", ptmp->children[0]->children[0]->tok,
6418 ptmp->children[0]->children[0]->tok_attr);
6419 array_table_add_data(&s->arrays,
6420 s->idents.attr[var_name->tok_attr],
6421 ptmp->children[0]->children[0]->tok_attr);
6422 array_len +=
6423 s->binds.num_rows[ptmp->children[0]->children[0]->tok_attr];
6424 }
6425 binding = binding->children[1];
6426
6427 while (binding->prod_applied != 143) {
6428 ptmp = binding->children[0]->children[0];
6429 printf("mat: %d\n", ptmp->prod_applied);
6430 if (ptmp->prod_applied == 150) { /* state */
6431 printf("matrix %d:\n", array_len);
6432 printf("%d %d\n", ptmp->children[0]->children[0]->tok,
6433 ptmp->children[0]->children[0]->tok_attr);
6434 array_table_add_data(&s->arrays,
6435 s->idents.attr[var_name->tok_attr],
6436 ptmp->children[0]->children[0]->tok_attr);
6437 array_len +=
6438 s->binds.num_rows[ptmp->children[0]->children[0]->tok_attr];
6439 }
6440 else if (ptmp->prod_applied == 151) { /* program */
6441 printf("matrix %d [program]:\n", array_len);
6442 printf("%d %d\n", ptmp->children[0]->tok,
6443 ptmp->children[0]->tok_attr);
6444 array_table_add_data(&s->arrays,
6445 s->idents.attr[var_name->tok_attr],
6446 ptmp->children[0]->tok_attr);
6447 array_len += s->binds.num_rows[ptmp->children[0]->tok_attr];
6448 }
6449 else { /* constant */
6450
6451 printf("matrix %d [constant]:\n", array_len);
6452 printf("%d %d\n", ptmp->children[0]->children[0]->tok,
6453 ptmp->children[0]->children[0]->tok_attr);
6454 array_table_add_data(&s->arrays,
6455 s->idents.attr[var_name->tok_attr],
6456 ptmp->children[0]->children[0]->tok_attr);
6457 array_len +=
6458 s->binds.num_rows[ptmp->children[0]->children[0]->tok_attr];
6459 }
6460 binding = binding->children[0]->children[1];
6461 }
6462
6463 /* XXX: have to compare the requested size, and the actual
6464 * size, and fix up any inconsistancies
6465 */
6466 if (arraysize) {
6467 printf("matrix wants to get %d rows\n",
6468 s->ints.data[arraysize->children[0]->tok_attr]);
6469 }
6470 printf("matrix num rows: %d\n", array_len);
6471 }
6472
6473 return;
6474 }
6475
6476 /* Else, recurse on all our children */
6477 for (a = 0; a < 4; a++) {
6478 if (!ptn->children[a])
6479 return;
6480
6481 parse_tree_assign_param_arrays(s, ptn->children[a]);
6482 }
6483
6484}
6485
6486/* XXX: This needs to be written properly. */
6487/**
6488 * Here we allocate 'registers' for all of the various variables and bound state.
6489 *
6490 * The 'register' number is given by the reg_num field in the binding table. Note that this field
6491 * is not stored in the identifier table. If it were, we would need a different mechanism for handling
6492 * implicit bindings.
6493 *
6494 * However, after some discussion with Brian, implicit bindings may be handled by grabbing state
6495 * directly from Mesa's state structs. This might be a little hairy here, maybe not.. Implicit
6496 * bindings are those in the binding table that are not pointed to by any ident.attr or array.data
6497 *
6498 * This should also do various error checking, like the multiple vertex attrib error, or 'too many bindings'
6499 * error.
6500 *
6501 * \param s The parse state
6502 */
6503static void
6504assign_regs(parse_state * s)
6505{
6506 GLint a;
6507 GLfloat foo[4];
6508
6509 for (a = 0; a < s->idents.len; a++) {
6510 if (s->idents.type[a] == TYPE_TEMP) {
6511 s->idents.attr[a] =
6512 binding_table_add(&s->binds, TYPE_TEMP, 0, 0, 0, foo);
6513 }
6514 }
6515}
6516
6517/**
6518 * Parse/compile the 'str' returning the compiled 'program'.
6519 * ctx->Program.ErrorPos will be -1 if successful. Otherwise, ErrorPos
6520 * indicates the position of the error in 'str'.
6521 */
6522void
6523_mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target,
6524 const GLubyte * string, GLsizei len,
6525 struct vertex_program *program)
6526{
6527 GLubyte *our_string;
6528 parse_state *state;
6529
6530 printf("len: %d\n", len);
6531
6532 /* XXX: How do I handle these errors? */
6533 if (len < 10)
6534 return;
6535 if (_mesa_strncmp(string, "!!ARBvp1.0", 10))
6536 return;
6537
6538 /* Make a null-terminated copy of the program string */
6539 our_string = (GLubyte *) MALLOC(len + 1);
6540 if (!our_string) {
6541 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
6542 return;
6543 }
6544 MEMCPY(our_string, string, len);
6545 our_string[len] = 0;
6546
6547 state = parse_state_init(our_string + 10, strlen(our_string) - 10);
6548
6549 if (parse(state) == ARB_VP_SUCESS) {
6550 printf("parse sucess!\n");
6551 }
6552 else {
6553 printf("*** error\n");
6554 parse_state_cleanup(state);
6555 return;
6556 }
6557
6558 /* First, we 'fold' bindings from a big mess of productions and
6559 * tokens into one BINDING_TOKEN, which points to an entry
6560 * in the binding sym table that holds all of the relevant
6561 * info for the binding destination.
6562 */
6563 parse_tree_fold_bindings(state, state->pt_head);
6564
6565 /* Now, for each type of binding, walk the parse tree and stick
6566 * the index into the binding sym table
6567 */
6568 parse_tree_assign_bindings(state, state->pt_head);
6569
6570 /* XXX: this still needs a' fixin to get folded bindings
6571 * -- it does? wtf do I mean? */
6572 parse_tree_assign_param_arrays(state, state->pt_head);
6573
6574 /* XXX: Now, assign registers. For this, we'll need to create
6575 * bindings for all temps (and what else?? )
6576 */
6577 assign_regs(state);
6578
6579 /* Ok, now generate code */
6580 parse_tree_generate_opcodes(state, state->pt_head);
6581
6582 /* Just for testing.. */
6583 program->Base.Target = target;
6584 if (program->Base.String) {
6585 FREE(program->Base.String);
6586 }
6587 program->Base.String = our_string;
6588 program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
6589
6590 if (program->Instructions) {
6591 FREE(program->Instructions);
6592 }
6593
6594 program->Instructions =
6595 (struct vp_instruction *) _mesa_malloc(sizeof(struct vp_instruction));
6596 program->Instructions[0].Opcode = VP_OPCODE_END;
6597 program->InputsRead = 0;
6598 program->OutputsWritten = 0;
6599 program->IsPositionInvariant = 0;
6600
6601 parse_state_cleanup(state);
6602
6603 /* TODO:
6604 * - handle implicit state grabbing & register allocation like discussed
6605 * - implicit param declarations -- see above
6606 *
6607 * - variable bindings -- ADDRESS
6608 * - deal with explicit array sizes & size mismatches
6609 * - shuddup all my debugging crap
6610 * - grep for XXX
6611 * - multiple vtx attrib binding error
6612 * - What do I do on look ahead for prod 54 & 55? (see arbvp_grammar.txt)
6613 * - misc errors
6614 * - check integer ranges
6615 * - check array index ranges
6616 * - check variable counts
6617 * - param register allocation
6618 * - exercise swizzles and masks
6619 * - error handling
6620 * - generate opcodes
6621 * + Get addres registers for relative offsets in PARAM arrays
6622 * + Properly encode implicit PARAMs and ATTRIBs.
6623 * + ARL
6624 * + SWZ
6625 * + actually emit Mesa opcodes
6626 * - segfaults while freeing stuff
6627 * - OPTION
6628 */
6629}