Initial checking of new ARB_frag/vertex program parser
authorKarl Rasche <karlrasche@gmail.com>
Wed, 19 Nov 2003 13:15:13 +0000 (13:15 +0000)
committerKarl Rasche <karlrasche@gmail.com>
Wed, 19 Nov 2003 13:15:13 +0000 (13:15 +0000)
src/mesa/main/arbfragparse.c
src/mesa/main/arbvertparse.c
src/mesa/main/extensions.c
src/mesa/main/mtypes.h
src/mesa/main/nvvertexec.c

index 39aa1c38306a6b04e0c032e4b197a2d41e34755f..eb7d0c24a665aa63c80a72f962e1a9359f5f8d2c 100644 (file)
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#define DEBUG_FP 0
 
 /**
  * \file arbfragparse.c
  * ARB_fragment_program parser.
- * \author 
+ * \author Karl Rasche
  */
 
 #include "glheader.h"
 #include "imports.h"
 #include "macros.h"
 #include "mtypes.h"
+#include "arbparse.h"
 #include "arbfragparse.h"
 
+static void
+debug_fp_inst(GLint num, struct fp_instruction *fp)
+{
+   GLint a;
+   fprintf(stderr, "PROGRAM_OUTPUT: 0x%x\n",    PROGRAM_OUTPUT);
+   fprintf(stderr, "PROGRAM_INPUT: 0x%x\n",     PROGRAM_INPUT);
+   fprintf(stderr, "PROGRAM_TEMPORARY: 0x%x\n", PROGRAM_TEMPORARY);
+
+   for (a=0; a<num; a++) {
+      switch (fp[a].Opcode) {
+         case FP_OPCODE_END:
+            fprintf(stderr, "FP_OPCODE_END"); break;
+
+         case  FP_OPCODE_ABS:
+            fprintf(stderr, "FP_OPCODE_ABS"); break;
+
+         case  FP_OPCODE_ADD:
+            fprintf(stderr, "FP_OPCODE_ADD"); break;
+
+         case  FP_OPCODE_CMP:
+            fprintf(stderr, "FP_OPCODE_CMP"); break;
+
+         case  FP_OPCODE_COS:
+            fprintf(stderr, "FP_OPCODE_COS"); break;
+
+         case  FP_OPCODE_DP3:
+            fprintf(stderr, "FP_OPCODE_DP3"); break;
+
+         case  FP_OPCODE_DP4:
+            fprintf(stderr, "FP_OPCODE_DP4"); break;
+
+         case  FP_OPCODE_DPH:
+            fprintf(stderr, "FP_OPCODE_DPH"); break;
+
+         case  FP_OPCODE_DST:
+            fprintf(stderr, "FP_OPCODE_DST"); break;
+
+         case  FP_OPCODE_EX2:
+            fprintf(stderr, "FP_OPCODE_EX2"); break;
+
+         case  FP_OPCODE_FLR:
+            fprintf(stderr, "FP_OPCODE_FLR"); break;
+
+         case  FP_OPCODE_FRC:
+            fprintf(stderr, "FP_OPCODE_FRC"); break;
+
+         case  FP_OPCODE_KIL:
+            fprintf(stderr, "FP_OPCODE_KIL"); break;
+
+         case  FP_OPCODE_LG2:
+            fprintf(stderr, "FP_OPCODE_LG2"); break;
+
+         case  FP_OPCODE_LIT:
+            fprintf(stderr, "FP_OPCODE_LIT"); break;
+
+         case  FP_OPCODE_LRP:
+            fprintf(stderr, "FP_OPCODE_LRP"); break;
+
+         case  FP_OPCODE_MAD:
+            fprintf(stderr, "FP_OPCODE_MAD"); break;
+
+         case  FP_OPCODE_MAX:
+            fprintf(stderr, "FP_OPCODE_MAX"); break;
+
+         case  FP_OPCODE_MIN:
+            fprintf(stderr, "FP_OPCODE_MIN"); break;
+
+         case  FP_OPCODE_MOV:
+            fprintf(stderr, "FP_OPCODE_MOV"); break;
+
+         case  FP_OPCODE_MUL:
+            fprintf(stderr, "FP_OPCODE_MUL"); break;
+
+         case  FP_OPCODE_POW:
+            fprintf(stderr, "FP_OPCODE_POW"); break;
+
+         case  FP_OPCODE_RCP:
+            fprintf(stderr, "FP_OPCODE_RCP"); break;
+
+         case  FP_OPCODE_RSQ:
+            fprintf(stderr, "FP_OPCODE_RSQ"); break;
+
+         case  FP_OPCODE_SCS:
+            fprintf(stderr, "FP_OPCODE_SCS"); break;
+
+         case  FP_OPCODE_SIN:
+            fprintf(stderr, "FP_OPCODE_SIN"); break;
+
+         case  FP_OPCODE_SLT:
+            fprintf(stderr, "FP_OPCODE_SLT"); break;
+
+         case  FP_OPCODE_SUB:
+            fprintf(stderr, "FP_OPCODE_SUB"); break;
+
+         case  FP_OPCODE_SWZ:
+            fprintf(stderr, "FP_OPCODE_SWZ"); break;
+
+         case  FP_OPCODE_TEX:
+            fprintf(stderr, "FP_OPCODE_TEX"); break;
+
+         case  FP_OPCODE_TXB:
+            fprintf(stderr, "FP_OPCODE_TXB"); break;
+
+         case  FP_OPCODE_TXP:
+            fprintf(stderr, "FP_OPCODE_TXP"); break;
+
+         case  FP_OPCODE_X2D:
+            fprintf(stderr, "FP_OPCODE_XPD"); break;
+      }
+
+      fprintf(stderr, " D(0x%x:%d:%d%d%d%d) ", 
+         fp[a].DstReg.File, fp[a].DstReg.Index,
+         fp[a].DstReg.WriteMask[0], fp[a].DstReg.WriteMask[1], 
+         fp[a].DstReg.WriteMask[2], fp[a].DstReg.WriteMask[3]); 
+                                                
+      fprintf(stderr, "S1(0x%x:%d:%d%d%d%d) ", fp[a].SrcReg[0].File, fp[a].SrcReg[0].Index,
+         fp[a].SrcReg[0].Swizzle[0],
+         fp[a].SrcReg[0].Swizzle[1],
+         fp[a].SrcReg[0].Swizzle[2],
+         fp[a].SrcReg[0].Swizzle[3]);
+
+      fprintf(stderr, "S2(0x%x:%d:%d%d%d%d) ", fp[a].SrcReg[1].File, fp[a].SrcReg[1].Index,
+        fp[a].SrcReg[1].Swizzle[0],
+        fp[a].SrcReg[1].Swizzle[1],
+        fp[a].SrcReg[1].Swizzle[2],
+        fp[a].SrcReg[1].Swizzle[3]);
+
+      fprintf(stderr, "S3(0x%x:%d:%d%d%d%d)",  fp[a].SrcReg[2].File, fp[a].SrcReg[2].Index,
+        fp[a].SrcReg[2].Swizzle[0],
+        fp[a].SrcReg[2].Swizzle[1],
+        fp[a].SrcReg[2].Swizzle[2],
+        fp[a].SrcReg[2].Swizzle[3]);
+
+      fprintf(stderr, "\n");
+   }
+}
 
 void
 _mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target,
                                  const GLubyte * str, GLsizei len,
                                  struct fragment_program *program)
 {
+   GLuint retval;
+   struct arb_program ap;
+       
+   retval = _mesa_parse_arb_program(ctx, str, len, &ap);
+
+   /* XXX: Parse error. Cleanup things and return */   
+   if (retval)
+   {
+      return;
+   }
+
+   /* XXX: Eh.. we parsed something that wasn't a fragment program. doh! */
+   if (ap.type != GL_FRAGMENT_PROGRAM_ARB)
+   {
+      return;      
+   }
+
+#if DEBUG_FP
+   debug_fp_inst(ap.Base.NumInstructions, ap.FPInstructions);
+#endif
 
+   /* copy the relvant contents of the arb_program struct into the 
+    * fragment_program struct
+    */
+   program->Base.NumInstructions = ap.Base.NumInstructions;
+   program->Base.NumTemporaries  = ap.Base.NumTemporaries;
+   program->Base.NumParameters   = ap.Base.NumParameters;
+   program->Base.NumAttributes   = ap.Base.NumAttributes;
+   program->Base.NumAddressRegs  = ap.Base.NumAddressRegs;
+       
+   program->Instructions   = ap.FPInstructions;
+   program->InputsRead     = ap.InputsRead;
+   program->OutputsWritten = ap.OutputsWritten;
+   for  (retval=0; retval<MAX_TEXTURE_IMAGE_UNITS; retval++)
+      program->TexturesUsed[retval] = ap.TexturesUsed[retval];
+   program->NumAluInstructions = ap.NumAluInstructions;
+   program->NumTexInstructions = ap.NumTexInstructions;
+   program->NumTexIndirections = ap.NumTexIndirections;
+   program->Parameters         = ap.Parameters;
 }
index 3d1153b76bab6e22766dd718516b29ef9a0efa47..0df17f370afa28957abecf7e940f527feaea8968 100644 (file)
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/**
- * \file arbvertparse.c
- * ARB_vertex_program parser.
- * \author Karl Rasche
- */
-
-#include "glheader.h"
-#include "context.h"
-#include "hash.h"
-#include "imports.h"
-#include "macros.h"
-#include "mtypes.h"
-#include "nvprogram.h"
-#include "nvvertparse.h"
-#include "nvvertprog.h"
-
-#include "arbvertparse.h"
-
-/**
- * Overview:
- *
- * This is a simple top-down predictive parser. In a nutshell, there are two key
- * elements to a predictive parser. First, is the 'look ahead' symbol. This is simply 
- * the next token in the input stream. The other component is a stack of symbols. 
- *
- * Given the grammar, we can derive a look ahead table. This is just a 2D array, 
- * where one axis is the non-terminal on top of the stack and the other axis is 
- * the look ahead. Each entry in the array is the production to apply when the pair
- * of stack symbol & look ahead is encountered. If no production is listed at 
- * a given entry in the table, a parse error occurs if this combination
- * is seen.
- *
- * Since we want to drive the parsing from a couple of huge tables, we have to
- * save some information later on for processing (e.g. for code generation).
- * For this, we explicitly recreate the parse tree representing the derivation. 
- * We can then make several passes over the parse tree to perform all additional 
- * processing, and we can be sure the the parse is valid.
- *   
- * The stack is initialized by pushing the start symbol onto it. The look ahead
- * symbol is initially the first token in the program string. 
- *
- * If there is a non-terminal symbol on top of the stack, the look ahead table 
- * is consulted to find if a production exists for the top of the stack
- * and the look ahead.
- * 
- * When we find a matching production, we pop the non-terminal off the top of 
- * the stack (the LHS of the production), and push the tokens on the RHS of 
- * the production onto the stack. Note that we store a pointer to the parse_tree_node
- * containing the LHS token on the stack. This way, we can setup the children in 
- * the parse tree as we apply the production.
- *   
- * If there is a terminal symbol on top of the stack, we compare it with the
- * look ahead symbol. If they match, or we don't care about the value of the
- * terminal (e.g. we know its an integer, but don't necessairly care what 
- * integer), the terminal symbol is popped off the stack and the look ahead 
- * is advanced.
- *
- * There are a few special nasty cases of productions for which we make special 
- * cases. These aren't found in the production/look-ahead tables, but listed 
- * out explicitly.
- * 
- * After the parse tree has been constructed, we make several recusive passes 
- * over it to perform various tasks.
- *  
- * The first pass is made to clean up the state bindings.  This is done in 
- * parse_tree_fold_bindings(). The goal is to reduce the big mess of a parse tree
- * created by strings such as:
- * 
- *           result.color.secondary
- *
- * and roll them up into one token and fill out some information in a symbol table.
- * In this case, the token at the root of the derivation becomes BINDING_TOKEN,
- * and the token attribute is an index into the binding table where this state
- * is held.
- *
- * The next two passes go about associating variables with BINDING_TOKENs. This 
- * takes care of the cases like:
- *
- *           OUTPUT foo = result.color.secondary;
- *
- * by inserting the index in the binding table for result.color.secondary into 
- * the attr field in the identifier table where the 'foo' variable sits. 
- * The second such pass deals with setting up arrays of program parameters, 
- * while the first only deals with scalars.
- * 
- * We then examine all the information on variables and state that we have 
- * gathered, and layout which 'register' each variable or bit-of-state should use.
- *  
- *
- * Finally, we make a recursive pass of the parse tree and generate opcodes 
- * for Mesa to interpret while executing the program.
- * 
- * It should be noted that each input/stack token has two parts, an 'identifier' 
- * and an 'attribute'. The identifier tells what class the token is, e.g. INTEGER_TOKEN,
- * or NT_PROGRAM_SINGLE_ITEM_TOKEN. For some tokens, e.g. INTEGER_TOKEN, ID_TOKEN,
- * FLOAT_TOKEN, or BINDING_TOKEN, the attribute for the token is an index into a table
- * giving various properties about the token.
- * 
- */
-
-/**
- * Here are all of the structs used to hold parse state and symbol
- * tables used.
- *
- * All strings which are not reserved words, floats, ints, or misc
- * puncuation (ie .) are considered to be [potential] identifiers.
- * When we encounter such a string while lex'ing, insert it into 
- * the id symbol table, shown below. 
- *
- * Sometime later, we'll initialize the variable types for identifiers
- * which really are variables. This gets shoved into the 'type' field.
- *
- * For variables, we'll need additional info (e.g. state it is bound to,
- * variable we're aliased to, etc). This is stored in the 'attr' field.
- *     - For alias variables, the attr is the idx in the id table of
- *        the variable we are bound to.
- *     - For other variables, we need a whole mess of info. This can be 
- *        found in the binding symbol table, below. In this case, the
- *        attr field is the idx into the binding table that describes us.
- *     - For uninitialized ids, attr is -1.
- *
- * The data field holds the string of the id.
- *
- * len is the number of identifiers in the table.
- */
-typedef struct st_id_table
-{
-   GLint len;
-   GLint *type;
-   GLint *attr;
-   GLubyte **data;
-}
-id_table;
-
-/**
- * For PARAM arrays, we need to record the contents for use when
- * laying out registers and loading state. 
- *
- * len is the number of arrays in the table.
- *
- * num_elements[i] is the number of items in array i. In other words, this
- * is the number of registers it would require when allocating.
- *
- * data[i][n] is the state bound to element n in array i. It is an idx into
- * the binding table
- */
-typedef struct st_array_table
-{
-   GLint len;
-   GLint *num_elements;
-   GLint **data;
-}
-array_table;
-
-/**
- * For holding all of the data used to describe an identifier, we have the catch
- * all binding symbol table.
- *
- * len is the number of bound items;
- *
- * type[i] tells what we are binding too, e.g. ATTRIB_POSITION, FOG_COLOR, or CONSTANT
- *
- * offset[i] gives the matrix number for matrix bindings, e.g. MATRIXROWS_MODELVIEW.
- * Alternativly, it gives the number of the first parameter for PROGRAM_ENV_* and 
- * PROGRAM_LOCAL_*.
- *
- * num_rows[i] gives the number of rows for multiple matrix rows, or the number 
- * of parameters in a env/local array.
- *
- * consts gives the 4-GLfloat constant value for bindings of type CONSTANT
- *
- * reg_num gives the register number which this binding is held in.
- */
-typedef struct st_binding_table
-{
-   GLint len;
-   GLint *type;
-   GLint *offset;
-   GLint *row;
-   GLint *num_rows;
-   GLfloat **consts;
-   GLint *reg_num;
-}
-binding_table;
-
-/**
- * Integers and floats are stored here. 
- */
-typedef struct st_int_table
-{
-   GLint len;
-   GLint *data;
-}
-int_table;
-
-typedef struct st_float_table
-{
-   GLint len;
-   GLdouble *data;
-}
-float_table;
-
-/**
- * To avoid writing tons of mindless parser code, the parsing is driven by
- * a few big tables of rules, plus a few special cases. However, this means
- * that we have to do all of our analysis outside of the parsing step.
- *
- * So, the parser will contruct a parse tree describing the program string
- * which we can then operate on to do things like code generation.
- *
- * This struct represents a node in the parse tree.
- *
- * If tok is a non-terminal token, tok_attr is not relevant.
- * If tok is BINDING_TOKEN, tok_attr is the index into the binding table.
- * if tok is INTEGER_TOKEN or FLOAT_TOKEN, tok_attr is the index in the integer/GLfloat table
- *
- * prod_applied is the production number applied to this token in the derivation of
- * the program string. See arbvp_grammar.txt for a listing of the productions, and
- * their numbers.
- */
-typedef struct st_parse_tree_node
-{
-   GLint tok, tok_attr, is_terminal;
-   GLint prod_applied;
-   struct st_parse_tree_node *children[4];
-}
-parse_tree_node;
-
-/** This stores tokens that we lex out 
- */
-typedef struct st_token_list
-{
-   GLint tok, tok_attr;
-   parse_tree_node *pt;
-
-   struct st_token_list *next;
-}
-token_list;
-
-/**
- * This holds all of the productions in the grammar. 
- *
- * lhs is a non-terminal token, e.g. NT_PROGRAM_TOKEN.
- * rhs is either NULL_TOKEN, another non-terminal token, or a terminal token.
- *     In some cases, we need the RHS to be a certain value, e.g. for the dst reg write masks.
- *     For this, key is used to specify the string. If we don't care about the key, just
- *     specify "".
- *     Int/floats are slightly different, "-1" specifies 'we don't care'.
- *
- * lhs is not very useful here, but is is convient for sanity sake when specifing productions.
- */
-typedef struct st_prod_table
-{
-   GLint lhs;
-   GLint rhs[4];
-   char *key[4];
-}
-prod_table;
-
-/**
- * This holds the look ahead table to drive the parser. We examine the token on 
- * the top of the stack, as well as the next token in the input stream (the look ahead).
- * We then match this against the table, and apply the approprate production. If nothing
- * matches, we have a parse error.
- *
- * Here, LHS is the (non-terminal) token to match against the top of the stack.
- *
- * la is the token to match against the look ahead.
- *
- * If la is ID_TOKEN, we have to match a given keyword (e.g. 'ambient'). This is specified in 
- * la_kw.
- *
- * prod_idx is the idx into the prod_table of the production that we are to apply if this
- * rule matches.
- */
-typedef struct st_look_ahead_table
-{
-   GLint lhs;
-   GLint la;
-   char *la_kw;
-   GLint prod_idx;
-}
-look_ahead_table;
-
-/**
- * This is the general catch-all for the parse state 
- */
-typedef struct st_parse_state
-{
-   char *str;
-   GLint len;
-
-   /* lex stuff ------ */
-   GLint start_pos, curr_pos;
-   GLint curr_state;
-   /* ---------------- */
-
-   id_table idents;
-   int_table ints;
-   float_table floats;
-   binding_table binds;
-   array_table arrays;
-
-   token_list *stack_head, *stack_free_list;
-
-   parse_tree_node *pt_head;
-}
-parse_state;
-
-/* local prototypes */
-static GLint float_table_add(float_table * tab, const char *str, GLint start,
-                            GLint end);
-static GLint int_table_add(int_table * tab, const char *str, GLint start,
-                          GLint end);
-static GLint id_table_add(id_table * tab, const char *str, GLint start,
-                         GLint end);
-static void parse_tree_free_children(parse_tree_node * ptn);
-
-/** 
- * Here we have a ton of defined terms that we use to identify productions, 
- * terminals, and nonterminals.
- */
-
-/**
- * Terminal tokens
- */
-#define EOF_TOKEN              0
-#define ID_TOKEN                       1
-#define ABS_TOKEN                      2
-#define ADD_TOKEN                      3
-#define ADDRESS_TOKEN  4
-#define ALIAS_TOKEN            5
-#define ARL_TOKEN                      6
-#define ATTRIB_TOKEN           7
-
-#define DP3_TOKEN                      8
-#define DP4_TOKEN                      9
-#define DPH_TOKEN                      10
-#define DST_TOKEN                      11
-
-#define END_TOKEN                      12
-#define EX2_TOKEN                      13
-#define EXP_TOKEN                      14
-
-#define FLR_TOKEN                      15
-#define FRC_TOKEN                      16
-
-#define LG2_TOKEN                      17
-#define LIT_TOKEN                      18
-#define LOG_TOKEN                      19
-
-#define MAD_TOKEN                      20
-#define MAX_TOKEN                      21
-#define MIN_TOKEN                      22
-#define MOV_TOKEN                      23
-#define MUL_TOKEN                      24
-
-#define OPTION_TOKEN    25
-#define OUTPUT_TOKEN           26
-
-#define PARAM_TOKEN            27
-#define POW_TOKEN                      28
-
-#define RCP_TOKEN                      29
-#define RSQ_TOKEN                      30
-
-#define SGE_TOKEN                      31
-#define SLT_TOKEN                      32
-#define SUB_TOKEN                      33
-#define SWZ_TOKEN                      34
-
-#define TEMP_TOKEN             35
-
-#define XPD_TOKEN                      36
-
-#define SEMICOLON_TOKEN        37
-#define COMMA_TOKEN            38
-#define PLUS_TOKEN             39
-#define MINUS_TOKEN            40
-#define PERIOD_TOKEN           41
-#define DOTDOT_TOKEN           42
-#define LBRACKET_TOKEN 43
-#define RBRACKET_TOKEN 44
-#define LBRACE_TOKEN           45
-#define RBRACE_TOKEN           46
-#define EQUAL_TOKEN            47
-
-#define INTEGER_TOKEN  48
-#define FLOAT_TOKEN            49
-
-#define PROGRAM_TOKEN  50
-#define RESULT_TOKEN           51
-#define STATE_TOKEN            52
-#define VERTEX_TOKEN           53
-
-#define NULL_TOKEN             54
-
-#define BINDING_TOKEN  55
-
-/** 
- * Non-terminal tokens
- */
-#define NT_PROGRAM_TOKEN                                       100
-#define NT_OPTION_SEQUENCE_TOKEN                       101
-#define NT_OPTION_SEQUENCE2_TOKEN              102
-#define NT_OPTION_TOKEN                                                103
-#define NT_STATEMENT_SEQUENCE_TOKEN            104
-#define NT_STATEMENT_SEQUENCE2_TOKEN   105
-#define NT_STATEMENT_TOKEN                                     106
-
-#define NT_INSTRUCTION_TOKEN                           107
-#define NT_ARL_INSTRUCTION_TOKEN                       108
-#define NT_VECTOROP_INSTRUCTION_TOKEN  109
-#define NT_VECTOROP_TOKEN                                      110
-#define NT_SCALAROP_INSTRUCTION_TOKEN  111
-#define NT_SCALAROP_TOKEN                                      112
-#define NT_BINSCOP_INSTRUCTION_TOKEN   113
-#define NT_BINSCOP_INSTRUCTION2_TOKEN  114
-#define NT_BINSCOP_TOKEN                                       115
-#define NT_BINOP_INSTRUCTION_TOKEN             116
-#define NT_BINOP_INSTRUCTION2_TOKEN            117
-#define NT_BINOP_TOKEN                                         118
-#define NT_TRIOP_INSTRUCTION_TOKEN             119
-#define NT_TRIOP_INSTRUCTION2_TOKEN            120
-#define NT_TRIOP_INSTRUCTION3_TOKEN            121
-#define NT_TRIOP_TOKEN                                         122
-#define NT_SWZ_INSTRUCTION_TOKEN                       123
-#define NT_SWZ_INSTRUCTION2_TOKEN              124
-
-#define NT_SCALAR_SRC_REG_TOKEN                        130
-#define NT_SWIZZLE_SRC_REG_TOKEN                       131
-#define NT_MASKED_DST_REG_TOKEN                        132
-#define NT_MASKED_ADDR_REG_TOKEN                       133
-#define NT_EXTENDED_SWIZZLE_TOKEN              134
-#define NT_EXTENDED_SWIZZLE2_TOKEN             135
-#define NT_EXT_SWIZ_COMP_TOKEN                 136
-#define NT_EXT_SWIZ_SEL_TOKEN                          137
-#define NT_SRC_REG_TOKEN                                       138
-#define NT_DST_REG_TOKEN                                       139
-#define NT_VERTEX_ATTRIB_REG_TOKEN             140
-
-#define NT_TEMPORARY_REG_TOKEN                         150
-#define NT_PROG_PARAM_REG_TOKEN                        151
-#define NT_PROG_PARAM_SINGLE_TOKEN             152
-#define NT_PROG_PARAM_ARRAY_TOKEN              153
-#define NT_PROG_PARAM_ARRAY_MEM_TOKEN  154
-#define NT_PROG_PARAM_ARRAY_ABS_TOKEN  155
-#define NT_PROG_PARAM_ARRAY_REL_TOKEN  156
-
-#define NT_ADDR_REG_REL_OFFSET_TOKEN   157
-#define NT_ADDR_REG_POS_OFFSET_TOKEN   158
-#define NT_ADDR_REG_NEG_OFFSET_TOKEN   159
-
-#define NT_VERTEX_RESULT_REG_TOKEN             160
-#define NT_ADDR_REG_TOKEN                                      161
-#define NT_ADDR_COMPONENT_TOKEN                        162
-#define NT_ADDR_WRITE_MASK_TOKEN                       163
-#define NT_SCALAR_SUFFIX_TOKEN                 164
-#define NT_SWIZZLE_SUFFIX_TOKEN                        165
-
-#define NT_COMPONENT_TOKEN                                     166
-#define NT_OPTIONAL_MASK_TOKEN                 167
-#define NT_OPTIONAL_MASK2_TOKEN                        168
-#define NT_NAMING_STATEMENT_TOKEN              169
-
-#define NT_ATTRIB_STATEMENT_TOKEN              170
-#define NT_VTX_ATTRIB_BINDING_TOKEN            171
-#define NT_VTX_ATTRIB_ITEM_TOKEN                       172
-#define NT_VTX_ATTRIB_NUM_TOKEN                        173
-#define NT_VTX_OPT_WEIGHT_NUM_TOKEN            174
-#define NT_VTX_WEIGHT_NUM_TOKEN                        175
-#define NT_PARAM_STATEMENT_TOKEN                       176
-#define NT_PARAM_STATEMENT2_TOKEN              177
-#define NT_OPT_ARRAY_SIZE_TOKEN                        178
-#define NT_PARAM_SINGLE_INIT_TOKEN             179
-#define NT_PARAM_MULTIPLE_INIT_TOKEN   180
-#define NT_PARAM_MULT_INIT_LIST_TOKEN  181
-#define NT_PARAM_MULT_INIT_LIST2_TOKEN 182
-#define NT_PARAM_SINGLE_ITEM_DECL_TOKEN 183
-#define NT_PARAM_SINGLE_ITEM_USE_TOKEN 184
-#define NT_PARAM_MULTIPLE_ITEM_TOKEN   185
-#define NT_STATE_MULTIPLE_ITEM_TOKEN   186
-#define NT_STATE_MULTIPLE_ITEM2_TOKEN  187
-#define NT_FOO_TOKEN                                                   188
-#define NT_FOO2_TOKEN                                          189
-#define NT_FOO3_TOKEN                                          190
-#define NT_FOO35_TOKEN                                         191
-#define NT_FOO4_TOKEN                                          192
-#define NT_STATE_SINGLE_ITEM_TOKEN             193
-#define NT_STATE_SINGLE_ITEM2_TOKEN            194
-#define NT_STATE_MATERIAL_ITEM_TOKEN   195
-#define NT_STATE_MATERIAL_ITEM2_TOKEN  196
-#define NT_STATE_MAT_PROPERTY_TOKEN            197
-#define NT_STATE_LIGHT_ITEM_TOKEN              198
-#define NT_STATE_LIGHT_ITEM2_TOKEN             199
-#define NT_STATE_LIGHT_PROPERTY_TOKEN  200
-#define NT_STATE_SPOT_PROPERTY_TOKEN   201
-#define NT_STATE_LIGHT_MODEL_ITEM_TOKEN 202
-#define NT_STATE_LMOD_PROPERTY_TOKEN    203
-#define NT_STATE_LMOD_PROPERTY2_TOKEN   204
-
-#define NT_STATE_LIGHT_PROD_ITEM_TOKEN    207
-#define NT_STATE_LIGHT_PROD_ITEM15_TOKEN       208
-#define NT_STATE_LIGHT_PROD_ITEM2_TOKEN        209
-#define NT_STATE_LPROD_PROPERTY_TOKEN  210
-#define NT_STATE_LIGHT_NUMBER_TOKEN            211
-#define NT_STATE_TEX_GEN_ITEM_TOKEN            212
-#define NT_STATE_TEX_GEN_ITEM2_TOKEN   213
-#define NT_STATE_TEX_GEN_TYPE_TOKEN            214
-#define NT_STATE_TEX_GEN_COORD_TOKEN   215
-#define NT_STATE_FOG_ITEM_TOKEN                        216
-#define NT_STATE_FOG_PROPERTY_TOKEN            217
-
-#define NT_STATE_CLIP_PLANE_ITEM_TOKEN 218
-#define NT_STATE_CLIP_PLANE_ITEM2_TOKEN        219
-#define NT_STATE_CLIP_PLANE_NUM_TOKEN  220
-#define NT_STATE_POINT_ITEM_TOKEN              221
-#define NT_STATE_POINT_PROPERTY_TOKEN  222
-#define NT_STATE_MATRIX_ROW_TOKEN              223
-#define NT_STATE_MATRIX_ROW15_TOKEN            224
-#define NT_STATE_MATRIX_ROW2_TOKEN             225
-#define NT_STATE_MATRIX_ROW3_TOKEN             226
-#define NT_STATE_MAT_MODIFIER_TOKEN            227
-#define NT_STATE_MATRIX_ROW_NUM_TOKEN  228
-#define NT_STATE_MATRIX_NAME_TOKEN             229
-#define NT_STATE_OPT_MOD_MAT_NUM_TOKEN 230
-#define NT_STATE_MOD_MAT_NUM_TOKEN             231
-#define NT_STATE_PALETTE_MAT_NUM_TOKEN 232
-#define NT_STATE_PROGRAM_MAT_NUM_TOKEN 233
-
-#define NT_PROGRAM_SINGLE_ITEM_TOKEN   234
-#define NT_PROGRAM_SINGLE_ITEM2_TOKEN  235
-#define NT_PROGRAM_MULTIPLE_ITEM_TOKEN 236
-#define NT_PROGRAM_MULTIPLE_ITEM2_TOKEN        237
-#define NT_PROG_ENV_PARAMS_TOKEN                       238
-#define NT_PROG_ENV_PARAM_NUMS_TOKEN   239
-#define NT_PROG_ENV_PARAM_NUMS2_TOKEN  240
-#define NT_PROG_ENV_PARAM_TOKEN                        250
-#define NT_PROG_LOCAL_PARAMS_TOKEN             251
-#define NT_PROG_LOCAL_PARAM_NUMS_TOKEN 252
-#define NT_PROG_LOCAL_PARAM_NUMS2_TOKEN        253
-#define NT_PROG_LOCAL_PARAM_TOKEN              254
-#define NT_PROG_ENV_PARAM_NUM_TOKEN            255
-#define NT_PROG_LOCAL_PARAM_NUM_TOKEN  256
-
-#define NT_PARAM_CONST_DECL_TOKEN              257
-#define NT_PARAM_CONST_USE_TOKEN                       258
-#define NT_PARAM_CONST_SCALAR_DECL_TOKEN       259
-#define NT_PARAM_CONST_SCALAR_USE_TOKEN        260
-#define NT_PARAM_CONST_VECTOR_TOKEN            261
-#define NT_PARAM_CONST_VECTOR2_TOKEN   262
-#define NT_PARAM_CONST_VECTOR3_TOKEN   263
-#define NT_PARAM_CONST_VECTOR4_TOKEN   264
-
-#define NT_SIGNED_FLOAT_CONSTANT_TOKEN 265
-#define NT_FLOAT_CONSTANT_TOKEN                        266
-#define NT_OPTIONAL_SIGN_TOKEN                 267
-
-#define NT_TEMP_STATEMENT_TOKEN                        268
-#define NT_ADDRESS_STATEMENT_TOKEN             269
-#define NT_VAR_NAME_LIST_TOKEN                 270
-#define NT_OUTPUT_STATEMENT_TOKEN              271
-#define NT_RESULT_BINDING_TOKEN                        272
-#define NT_RESULT_BINDING2_TOKEN                       273
-#define NT_RESULT_COL_BINDING_TOKEN            274
-#define NT_RESULT_COL_BINDING2_TOKEN   275
-#define NT_RESULT_COL_BINDING3_TOKEN   276
-#define NT_RESULT_COL_BINDING4_TOKEN   277
-#define NT_RESULT_COL_BINDING5_TOKEN   278
-
-#define NT_OPT_FACE_TYPE2_TOKEN                        279
-#define NT_OPT_COLOR_TYPE_TOKEN                        280
-#define NT_OPT_COLOR_TYPE2_TOKEN                       281
-#define NT_OPT_TEX_COORD_NUM_TOKEN             282
-#define NT_TEX_COORD_NUM_TOKEN                 283
-
-#define NT_ALIAS_STATEMENT_TOKEN                       284
-#define NT_ESTABLISH_NAME_TOKEN                        285
-#define NT_ESTABLISHED_NAME_TOKEN              286
-
-#define NT_SWIZZLE_SUFFIX2_TOKEN                       287
-#define NT_COMPONENT4_TOKEN                            288
-
-/**
- * FSA States for lex
- *
- * XXX: These can be turned into enums 
- */
-#define STATE_BASE             0
-#define STATE_IDENT            1
-
-#define STATE_A                        2
-#define STATE_AB                       3
-#define STATE_ABS                      4
-#define STATE_AD                       5
-#define STATE_ADD                      6
-#define STATE_ADDR             7
-#define STATE_ADDRE            8
-#define STATE_ADDRES           9
-#define STATE_ADDRESS  10
-#define STATE_AL                       11
-#define STATE_ALI                      12
-#define STATE_ALIA             13
-#define STATE_ALIAS            14
-#define STATE_AR                       15
-#define STATE_ARL                      16
-#define STATE_AT                       17
-#define STATE_ATT                      18
-#define STATE_ATTR             19
-#define STATE_ATTRI            20
-#define STATE_ATTRIB           21
-
-#define STATE_D                        22
-#define STATE_DP                       23
-#define STATE_DP3                      24
-#define STATE_DP4                      25
-#define STATE_DPH                      26
-#define STATE_DS                       27
-#define STATE_DST                      28
-
-#define STATE_E                        29
-#define STATE_EN                       30
-#define STATE_END                      31
-#define STATE_EX                       32
-#define STATE_EX2                      33
-#define STATE_EXP                      34
-
-#define STATE_F                        35
-#define STATE_FL                       36
-#define STATE_FLR                      37
-#define STATE_FR                       38
-#define STATE_FRC                      39
-
-#define STATE_L                        40
-#define STATE_LG                       41
-#define STATE_LG2                      42
-#define STATE_LI                       43
-#define STATE_LIT                      44
-#define STATE_LO                       45
-#define STATE_LOG                      46
-
-#define STATE_M                        47
-#define STATE_MA                       48
-#define STATE_MAD                      49
-#define STATE_MAX                      50
-#define STATE_MI                       51
-#define STATE_MIN                      52
-#define STATE_MO                       53
-#define STATE_MOV                      54
-#define STATE_MU                       55
-#define STATE_MUL                      56
-
-#define STATE_O                        57
-#define STATE_OP                       58
-#define STATE_OPT                      59
-#define STATE_OPTI             60
-#define STATE_OPTIO            61
-#define STATE_OPTION           62
-#define STATE_OU                       63
-#define STATE_OUT                      64
-#define STATE_OUTP             65
-#define STATE_OUTPU            66
-#define STATE_OUTPUT           67
-
-#define STATE_P                        68
-#define STATE_PA                       69
-#define STATE_PAR                      70
-#define STATE_PARA             71
-#define STATE_PARAM            72
-#define STATE_PO                       73
-#define STATE_POW                      74
-
-#define STATE_R                        75
-#define STATE_RC                       76
-#define STATE_RCP                      77
-#define STATE_RS                       78
-#define STATE_RSQ                      79
-
-#define STATE_S                        80
-#define STATE_SG                       81
-#define STATE_SGE                      82
-#define STATE_SL                       83
-#define STATE_SLT                      84
-#define STATE_SU                       85
-#define STATE_SUB                      86
-#define STATE_SW                       87
-#define STATE_SWZ                      88
-
-#define STATE_T                        89
-#define STATE_TE                       90
-#define STATE_TEM                      91
-#define STATE_TEMP             92
-
-#define STATE_X                        93
-#define STATE_XP                       94
-#define STATE_XPD                      95
-
-#define STATE_N1                       96
-#define STATE_N2                       97
-#define STATE_N3                       98
-#define STATE_N4                       99
-#define STATE_N5                       100
-#define STATE_N6                       101
-#define STATE_N7                       102
-
-#define STATE_COMMENT  103
-
-/* LC == lower case, as in 'program' */
-#define STATE_LC_P             104
-#define STATE_LC_PR            105
-#define STATE_LC_PRO           106
-#define STATE_LC_PROG  107
-#define STATE_LC_PROGR 108
-#define STATE_LC_PROGRA        109
-
-#define STATE_LC_R             110
-#define STATE_LC_RE            111
-#define STATE_LC_RES           112
-#define STATE_LC_RESU  113
-#define STATE_LC_RESUL 114
-#define STATE_LC_RESULT        115
-
-#define STATE_LC_S             116
-#define STATE_LC_ST            117
-#define STATE_LC_STA           118
-#define STATE_LC_STAT  119
-#define STATE_LC_STATE 120
-
-#define STATE_LC_V                     121
-#define STATE_LC_VE                    122
-#define STATE_LC_VER                   123
-#define STATE_LC_VERT          124
-#define STATE_LC_VERTE         125
-#define STATE_LC_VERTEX                126
-#define STATE_LC_PROGRAM       127
-
-/**
- * Error codes 
- */
-#define ARB_VP_ERROR                   -1
-#define ARB_VP_SUCESS           0
-
-/** 
- * Variable types 
- */
-#define TYPE_NONE                              0
-#define TYPE_ATTRIB                    1
-#define TYPE_PARAM                     2
-#define TYPE_PARAM_SINGLE      3
-#define TYPE_PARAM_ARRAY       4
-#define TYPE_TEMP                              5
-#define TYPE_ADDRESS                   6
-#define TYPE_OUTPUT                    7
-#define TYPE_ALIAS                     8
-
-/** 
- * Vertex Attrib Bindings
- */
-#define ATTRIB_POSITION                                1
-#define ATTRIB_WEIGHT                          2
-#define ATTRIB_NORMAL                          3
-#define ATTRIB_COLOR_PRIMARY           4
-#define ATTRIB_COLOR_SECONDARY 5
-#define ATTRIB_FOGCOORD                                6
-#define ATTRIB_TEXCOORD                                7
-#define ATTRIB_MATRIXINDEX                     8
-#define ATTRIB_ATTRIB                          9
-
-/** 
- * Result Bindings
- */
-#define RESULT_POSITION                                                10
-#define RESULT_FOGCOORD                                                11
-#define RESULT_POINTSIZE                                       12
-#define RESULT_COLOR_FRONT_PRIMARY             13
-#define RESULT_COLOR_FRONT_SECONDARY   14
-#define RESULT_COLOR_BACK_PRIMARY              15
-#define RESULT_COLOR_BACK_SECONDARY            16
-#define RESULT_TEXCOORD                                                17
-
-/** 
- * Material Property Bindings
- */
-#define MATERIAL_FRONT_AMBIENT                 18
-#define MATERIAL_FRONT_DIFFUSE                 19
-#define MATERIAL_FRONT_SPECULAR                        20
-#define MATERIAL_FRONT_EMISSION                        21
-#define MATERIAL_FRONT_SHININESS                       22
-#define MATERIAL_BACK_AMBIENT                          23
-#define MATERIAL_BACK_DIFFUSE                          24
-#define MATERIAL_BACK_SPECULAR                 25
-#define MATERIAL_BACK_EMISSION                 26
-#define MATERIAL_BACK_SHININESS                        27
-
-/** 
- * Light Property Bindings
- */
-#define LIGHT_AMBIENT                                          28
-#define LIGHT_DIFFUSE                                          29
-#define LIGHT_SPECULAR                                         30
-#define LIGHT_POSITION                                         31
-#define LIGHT_ATTENUATION                                      32
-#define LIGHT_SPOT_DIRECTION                           33
-#define LIGHT_HALF                                                     34
-#define LIGHTMODEL_AMBIENT                                     35
-#define LIGHTMODEL_FRONT_SCENECOLOR            36
-#define LIGHTMODEL_BACK_SCENECOLOR             37
-#define LIGHTPROD_FRONT_AMBIENT                        38
-#define LIGHTPROD_FRONT_DIFFUSE                        39
-#define LIGHTPROD_FRONT_SPECULAR                       40
-#define LIGHTPROD_BACK_AMBIENT                 41
-#define LIGHTPROD_BACK_DIFFUSE                 42
-#define LIGHTPROD_BACK_SPECULAR                        43
-
-/**
- * Texgen Property Bindings
- */
-#define TEXGEN_EYE_S                                                   44
-#define TEXGEN_EYE_T                                                   45
-#define TEXGEN_EYE_R                                                   46
-#define TEXGEN_EYE_Q                                                   47
-#define TEXGEN_OBJECT_S                                                48
-#define TEXGEN_OBJECT_T                                                49
-#define TEXGEN_OBJECT_R                                                50
-#define TEXGEN_OBJECT_Q                                                51
-
-/**
- * Fog Property Bindings
- */
-#define FOG_COLOR                                                              52
-#define FOG_PARAMS                                                     53
-
-/** 
- * Clip Property Bindings
- */
-#define CLIP_PLANE                                                     54
-
-/** 
- * Point Property Bindings
- */
-#define POINT_SIZE                                                     55
-#define POINT_ATTENUATION                                      56
-
-/**
- * Matrix Row Property Bindings
- */
-#define MATRIXROW_MODELVIEW                                    57
-#define MATRIXROW_MODELVIEW_INVERSE                    58
-#define MATRIXROW_MODELVIEW_INVTRANS           59
-#define MATRIXROW_MODELVIEW_TRANSPOSE          60
-#define MATRIXROW_PROJECTION                                   61
-#define MATRIXROW_PROJECTION_INVERSE           62
-#define MATRIXROW_PROJECTION_INVTRANS          63
-#define MATRIXROW_PROJECTION_TRANSPOSE         64
-#define MATRIXROW_MVP                                                  65
-#define MATRIXROW_MVP_INVERSE                                  66
-#define MATRIXROW_MVP_INVTRANS                         67
-#define MATRIXROW_MVP_TRANSPOSE                                68
-#define MATRIXROW_TEXTURE                                              69
-#define MATRIXROW_TEXTURE_INVERSE                      70
-#define MATRIXROW_TEXTURE_INVTRANS                     71
-#define MATRIXROW_TEXTURE_TRANSPOSE                    72
-#define MATRIXROW_PALETTE                                              73
-#define MATRIXROW_PALETTE_INVERSE                      74
-#define MATRIXROW_PALETTE_INVTRANS                     75
-#define MATRIXROW_PALETTE_TRANSPOSE                    76
-#define MATRIXROW_PROGRAM                                              77
-#define MATRIXROW_PROGRAM_INVERSE                      78
-#define MATRIXROW_PROGRAM_INVTRANS                     79
-#define MATRIXROW_PROGRAM_TRANSPOSE                    80
-
-#define MATRIXROWS_MODELVIEW                                   81
-#define MATRIXROWS_MODELVIEW_INVERSE           82
-#define MATRIXROWS_MODELVIEW_INVTRANS          83
-#define MATRIXROWS_MODELVIEW_TRANSPOSE         84
-#define MATRIXROWS_PROJECTION                                  85
-#define MATRIXROWS_PROJECTION_INVERSE          86
-#define MATRIXROWS_PROJECTION_INVTRANS         87
-#define MATRIXROWS_PROJECTION_TRANSPOSE        88
-#define MATRIXROWS_MVP                                                 89
-#define MATRIXROWS_MVP_INVERSE                         90
-#define MATRIXROWS_MVP_INVTRANS                                91
-#define MATRIXROWS_MVP_TRANSPOSE                               92
-#define MATRIXROWS_TEXTURE                                             93
-#define MATRIXROWS_TEXTURE_INVERSE                     94
-#define MATRIXROWS_TEXTURE_INVTRANS                    95
-#define MATRIXROWS_TEXTURE_TRANSPOSE           96
-#define MATRIXROWS_PALETTE                                             97
-#define MATRIXROWS_PALETTE_INVERSE                     98
-#define MATRIXROWS_PALETTE_INVTRANS                    99
-#define MATRIXROWS_PALETTE_TRANSPOSE           100
-#define MATRIXROWS_PROGRAM                                             101
-#define MATRIXROWS_PROGRAM_INVERSE                     102
-#define MATRIXROWS_PROGRAM_INVTRANS                    103
-#define MATRIXROWS_PROGRAM_TRANSPOSE           104
-
-#define PROGRAM_ENV_SINGLE                                     105
-#define PROGRAM_LOCAL_SINGLE                           106
-#define PROGRAM_ENV_MULTI                                      107
-#define PROGRAM_LOCAL_MULTI                            108
-
-#define CONSTANT                                                               109
-
-
-
-
-#define IS_WHITESPACE(c)       (c == ' ') || (c == '\t') || (c == '\n')
-#define IS_IDCHAR(c)                   ((c >= 'A') && (c <= 'Z')) || \
-                                                                       ((c >= 'a') && (c <= 'z')) || \
-                                                                       (c == '_') || (c == '$')
-#define IS_DIGIT(c)                    (c >= '0') && (c <= '9')
-#define IS_CD(c)                               (IS_DIGIT(c)) || (IS_IDCHAR(c))
-
-#define ADV_TO_STATE(state) s->curr_state = state; s->curr_pos++;
-
-#define ADV_OR_FALLBACK(c, state) if (curr == c) { \
-                                     ADV_TO_STATE(state); \
-                                  } else {\
-                                     if (IS_CD(curr)) { \
-                                        ADV_TO_STATE(STATE_IDENT); \
-                                     } else \
-                                        s->curr_state = 1;\
-                                  }
-
-#define FINISH(tok) *token = tok; s->start_pos = s->curr_pos; s->curr_state = STATE_BASE; return ARB_VP_SUCESS;
-#define ADV_AND_FINISH(tok) *token = tok; s->start_pos = s->curr_pos+1; s->curr_pos++; \
-                                                                                                                       s->curr_state = STATE_BASE; return ARB_VP_SUCESS;
-
-#define FINISH_OR_FALLBACK(tok) if (IS_CD(curr)) {\
-                                   ADV_TO_STATE(STATE_IDENT); \
-                                } else { \
-                                   FINISH(tok)\
-                                }
-
-#define NO_KW {"", "", "", ""}
-#define NULL2 NULL_TOKEN, NULL_TOKEN
-#define NULL3 NULL_TOKEN, NULL2
-#define NULL4 NULL2, NULL2
-
-/* This uglyness is the production table. See the prod_table struct definition for a description */
-prod_table ptab[] = {
-   {NT_PROGRAM_TOKEN,
-        {NT_OPTION_SEQUENCE_TOKEN, NT_STATEMENT_SEQUENCE_TOKEN, END_TOKEN, NULL_TOKEN}, NO_KW},
-   {NT_OPTION_SEQUENCE_TOKEN,  {NT_OPTION_SEQUENCE2_TOKEN, NULL3},                      NO_KW},
-   {NT_OPTION_SEQUENCE2_TOKEN, {NT_OPTION_TOKEN, NT_OPTION_SEQUENCE2_TOKEN, NULL2},     NO_KW},
-   {NT_OPTION_SEQUENCE2_TOKEN, {NULL4},                                                 NO_KW},
-   {NT_OPTION_TOKEN,           {OPTION_TOKEN, ID_TOKEN, SEMICOLON_TOKEN, NULL_TOKEN},   NO_KW},
-    
-
-   /* 5: */
-   {NT_STATEMENT_SEQUENCE_TOKEN,  {NT_STATEMENT_SEQUENCE2_TOKEN, NULL3},                     NO_KW},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, {NT_STATEMENT_TOKEN, NT_STATEMENT_SEQUENCE2_TOKEN, NULL2}, NO_KW},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, {NULL4},                                                   NO_KW},
-   {NT_STATEMENT_TOKEN, {NT_INSTRUCTION_TOKEN, SEMICOLON_TOKEN, NULL2},                      NO_KW},
-   {NT_STATEMENT_TOKEN, {NT_NAMING_STATEMENT_TOKEN, SEMICOLON_TOKEN, NULL2},                 NO_KW},
-
-   /* 10: */
-   {NT_INSTRUCTION_TOKEN, {NT_ARL_INSTRUCTION_TOKEN, NULL3},      NO_KW},
-   {NT_INSTRUCTION_TOKEN, {NT_VECTOROP_INSTRUCTION_TOKEN, NULL3}, NO_KW},
-   {NT_INSTRUCTION_TOKEN, {NT_SCALAROP_INSTRUCTION_TOKEN, NULL3}, NO_KW},
-   {NT_INSTRUCTION_TOKEN, {NT_BINSCOP_INSTRUCTION_TOKEN, NULL3},  NO_KW},
-   {NT_INSTRUCTION_TOKEN, {NT_BINOP_INSTRUCTION_TOKEN, NULL3},    NO_KW},
-
-   /* 15: */
-   {NT_INSTRUCTION_TOKEN,          {NT_TRIOP_INSTRUCTION_TOKEN, NULL3},      NO_KW},
-   {NT_INSTRUCTION_TOKEN,          {NT_SWZ_INSTRUCTION_TOKEN, NULL3},        NO_KW},
-   {NT_ARL_INSTRUCTION_TOKEN,      {ARL_TOKEN, NT_MASKED_ADDR_REG_TOKEN, 
-                                                                                                 COMMA_TOKEN, NT_SCALAR_SRC_REG_TOKEN}, NO_KW},
-   {NT_VECTOROP_INSTRUCTION_TOKEN, {NT_VECTOROP_TOKEN, NT_MASKED_DST_REG_TOKEN, COMMA_TOKEN,
-                                     NT_SWIZZLE_SRC_REG_TOKEN},              NO_KW},
-   {NT_VECTOROP_TOKEN,             {ABS_TOKEN, NULL3},                       NO_KW},
-
-   /* 20: */
-   {NT_VECTOROP_TOKEN,             {FLR_TOKEN, NULL3}, NO_KW},
-   {NT_VECTOROP_TOKEN,             {FRC_TOKEN, NULL3}, NO_KW},
-   {NT_VECTOROP_TOKEN,             {LIT_TOKEN, NULL3}, NO_KW},
-   {NT_VECTOROP_TOKEN,             {MOV_TOKEN, NULL3}, NO_KW},
-   {NT_SCALAROP_INSTRUCTION_TOKEN, {NT_SCALAROP_TOKEN, NT_MASKED_DST_REG_TOKEN, COMMA_TOKEN,
-                             NT_SCALAR_SRC_REG_TOKEN}, NO_KW},
-
-   /* 25: */
-   {NT_SCALAROP_TOKEN, {EX2_TOKEN, NULL3}, NO_KW},
-   {NT_SCALAROP_TOKEN, {EXP_TOKEN, NULL3}, NO_KW},
-   {NT_SCALAROP_TOKEN, {LG2_TOKEN, NULL3}, NO_KW},
-   {NT_SCALAROP_TOKEN, {LOG_TOKEN, NULL3}, NO_KW},
-   {NT_SCALAROP_TOKEN, {RCP_TOKEN, NULL3}, NO_KW},
-
-   /* 30: */
-   {NT_SCALAROP_TOKEN, {RSQ_TOKEN, NULL3},         NO_KW},
-   {NT_BINSCOP_INSTRUCTION_TOKEN,
-                       {NT_BINSCOP_TOKEN, NT_MASKED_DST_REG_TOKEN, NT_BINSCOP_INSTRUCTION2_TOKEN,
-                         NULL_TOKEN},              NO_KW},
-   {NT_BINSCOP_INSTRUCTION2_TOKEN,
-                       {COMMA_TOKEN, NT_SCALAR_SRC_REG_TOKEN, COMMA_TOKEN,
-                         NT_SCALAR_SRC_REG_TOKEN}, NO_KW},
-   {NT_BINSCOP_TOKEN,  {POW_TOKEN, NULL3},         NO_KW},
-   {NT_BINOP_INSTRUCTION_TOKEN,
-                       {NT_BINOP_TOKEN, NT_MASKED_DST_REG_TOKEN, NT_BINOP_INSTRUCTION2_TOKEN,
-                         NULL_TOKEN},              NO_KW},
-
-   /* 35: */
-   {NT_BINOP_INSTRUCTION2_TOKEN,
-                       {COMMA_TOKEN, NT_SWIZZLE_SRC_REG_TOKEN, COMMA_TOKEN,
-                        NT_SWIZZLE_SRC_REG_TOKEN}, NO_KW},
-   {NT_BINOP_TOKEN,    {ADD_TOKEN, NULL3},         NO_KW},
-   {NT_BINOP_TOKEN,    {DP3_TOKEN, NULL3},         NO_KW},
-   {NT_BINOP_TOKEN,    {DP4_TOKEN, NULL3},         NO_KW},
-   {NT_BINOP_TOKEN,    {DPH_TOKEN, NULL3},         NO_KW},
-
-   /* 40: */
-   {NT_BINOP_TOKEN, {DST_TOKEN, NULL3}, NO_KW},
-   {NT_BINOP_TOKEN, {MAX_TOKEN, NULL3}, NO_KW},
-   {NT_BINOP_TOKEN, {MIN_TOKEN, NULL3}, NO_KW},
-   {NT_BINOP_TOKEN, {MUL_TOKEN, NULL3}, NO_KW},
-   {NT_BINOP_TOKEN, {SGE_TOKEN, NULL3}, NO_KW},
-
-   /* 45: */
-   {NT_BINOP_TOKEN, {SLT_TOKEN, NULL3}, NO_KW},
-   {NT_BINOP_TOKEN, {SUB_TOKEN, NULL3}, NO_KW},
-   {NT_BINOP_TOKEN, {XPD_TOKEN, NULL3}, NO_KW},
-   {NT_TRIOP_INSTRUCTION_TOKEN,
-                    {NT_TRIOP_TOKEN, NT_MASKED_DST_REG_TOKEN, NT_TRIOP_INSTRUCTION2_TOKEN,
-                      NULL_TOKEN},      NO_KW},
-   {NT_TRIOP_INSTRUCTION2_TOKEN,
-                    {COMMA_TOKEN, NT_SWIZZLE_SRC_REG_TOKEN, NT_TRIOP_INSTRUCTION3_TOKEN,
-                      NULL_TOKEN},      NO_KW},
-
-   /* 50: */
-   {NT_TRIOP_INSTRUCTION3_TOKEN,
-                     {COMMA_TOKEN, NT_SWIZZLE_SRC_REG_TOKEN, COMMA_TOKEN,
-                       NT_SWIZZLE_SRC_REG_TOKEN}, NO_KW},
-   {NT_TRIOP_TOKEN,  {MAD_TOKEN, NULL3},          NO_KW},
-   {NT_SWZ_INSTRUCTION_TOKEN,
-                     {SWZ_TOKEN, NT_MASKED_DST_REG_TOKEN, NT_SWZ_INSTRUCTION2_TOKEN,
-                       NULL_TOKEN},               NO_KW},
-   {NT_SWZ_INSTRUCTION2_TOKEN,
-                     {COMMA_TOKEN, NT_SRC_REG_TOKEN, COMMA_TOKEN, NT_EXTENDED_SWIZZLE_TOKEN},
-                                                  NO_KW},
-   {NT_SCALAR_SRC_REG_TOKEN,
-                     {NT_OPTIONAL_SIGN_TOKEN, NT_SRC_REG_TOKEN, NT_SCALAR_SUFFIX_TOKEN,
-                       NULL_TOKEN},               NO_KW},
-
-   /* 55 */
-   {NT_SWIZZLE_SRC_REG_TOKEN,
-                      {NT_OPTIONAL_SIGN_TOKEN, NT_SRC_REG_TOKEN, NT_SWIZZLE_SUFFIX_TOKEN,
-                        NULL_TOKEN},                                        NO_KW},
-   {NT_MASKED_DST_REG_TOKEN,
-                      {NT_DST_REG_TOKEN, NT_OPTIONAL_MASK_TOKEN, NULL2},    NO_KW},
-   {NT_MASKED_ADDR_REG_TOKEN,
-                      {NT_ADDR_REG_TOKEN, NT_ADDR_WRITE_MASK_TOKEN, NULL2}, NO_KW},
-   {NT_EXTENDED_SWIZZLE_TOKEN,
-                      {NT_EXT_SWIZ_COMP_TOKEN, COMMA_TOKEN, NT_EXT_SWIZ_COMP_TOKEN,
-                        NT_EXTENDED_SWIZZLE2_TOKEN},                        NO_KW},
-   {NT_EXTENDED_SWIZZLE2_TOKEN,
-                      {COMMA_TOKEN, NT_EXT_SWIZ_COMP_TOKEN, COMMA_TOKEN,
-                        NT_EXT_SWIZ_COMP_TOKEN},                            NO_KW},
-
-   /* 60 */
-   {NT_EXT_SWIZ_COMP_TOKEN,{NT_OPTIONAL_SIGN_TOKEN, NT_EXT_SWIZ_SEL_TOKEN, NULL2},
-                                                                NO_KW},
-   {NT_EXT_SWIZ_SEL_TOKEN, {INTEGER_TOKEN, NULL3},              {"0", "", "", ""}},
-   {NT_EXT_SWIZ_SEL_TOKEN, {INTEGER_TOKEN, NULL3},              {"1", "", "", ""}},
-   {NT_EXT_SWIZ_SEL_TOKEN, {NT_COMPONENT_TOKEN, NULL3},         NO_KW},
-   {NT_SRC_REG_TOKEN,      {NT_VERTEX_ATTRIB_REG_TOKEN, NULL3}, NO_KW},
-
-   /* 65: */
-   {NT_SRC_REG_TOKEN,           {NT_TEMPORARY_REG_TOKEN, NULL3},     NO_KW},
-   {NT_SRC_REG_TOKEN,           {NT_PROG_PARAM_REG_TOKEN, NULL3},    NO_KW},
-   {NT_DST_REG_TOKEN,           {NT_TEMPORARY_REG_TOKEN, NULL3},     NO_KW},
-   {NT_DST_REG_TOKEN,           {NT_VERTEX_RESULT_REG_TOKEN, NULL3}, NO_KW},
-   {NT_VERTEX_ATTRIB_REG_TOKEN, {NT_ESTABLISHED_NAME_TOKEN, NULL3},  NO_KW},
-
-   /* 70: */
-   {NT_VERTEX_ATTRIB_REG_TOKEN, {NT_VTX_ATTRIB_BINDING_TOKEN, NULL3},    NO_KW},
-   {NT_TEMPORARY_REG_TOKEN,     {NT_ESTABLISHED_NAME_TOKEN, NULL3},      NO_KW},
-   {NT_PROG_PARAM_REG_TOKEN,    {NT_PROG_PARAM_SINGLE_TOKEN, NULL3},     NO_KW},
-   {NT_PROG_PARAM_REG_TOKEN,
-                                {NT_PROG_PARAM_ARRAY_TOKEN, LBRACKET_TOKEN, NT_PROG_PARAM_ARRAY_MEM_TOKEN,
-                                  RBRACKET_TOKEN},                       NO_KW},
-   {NT_PROG_PARAM_REG_TOKEN,    {NT_PARAM_SINGLE_ITEM_USE_TOKEN, NULL3}, NO_KW},
-
-   /* 75: */
-   {NT_PROG_PARAM_SINGLE_TOKEN,    {NT_ESTABLISHED_NAME_TOKEN, NULL3},     NO_KW},
-   {NT_PROG_PARAM_ARRAY_TOKEN,     {NT_ESTABLISHED_NAME_TOKEN, NULL3},     NO_KW},
-   {NT_PROG_PARAM_ARRAY_MEM_TOKEN, {NT_PROG_PARAM_ARRAY_ABS_TOKEN, NULL3}, NO_KW},
-   {NT_PROG_PARAM_ARRAY_MEM_TOKEN, {NT_PROG_PARAM_ARRAY_REL_TOKEN, NULL3}, NO_KW},
-                                                                           /* -1 matches all */
-   {NT_PROG_PARAM_ARRAY_ABS_TOKEN, {INTEGER_TOKEN, NULL3},                 {"-1", "", "", ""}},        
-
-
-   /* 80: */
-   {NT_PROG_PARAM_ARRAY_REL_TOKEN,
-              {NT_ADDR_REG_TOKEN, NT_ADDR_COMPONENT_TOKEN, NT_ADDR_REG_REL_OFFSET_TOKEN,
-                NULL_TOKEN},                                      NO_KW},
-   {NT_ADDR_REG_REL_OFFSET_TOKEN, {NULL4},                        NO_KW},
-   {NT_ADDR_REG_REL_OFFSET_TOKEN,
-              {PLUS_TOKEN, NT_ADDR_REG_POS_OFFSET_TOKEN, NULL2},  NO_KW},
-   {NT_ADDR_REG_REL_OFFSET_TOKEN,
-              {MINUS_TOKEN, NT_ADDR_REG_NEG_OFFSET_TOKEN, NULL2}, NO_KW},
-   {NT_ADDR_REG_POS_OFFSET_TOKEN, {INTEGER_TOKEN, NULL3},         {"-1", "", "", ""}},
-
-   /* 85: */
-   {NT_ADDR_REG_NEG_OFFSET_TOKEN, {INTEGER_TOKEN, NULL3},             {"-1", "", "", ""}},
-   {NT_VERTEX_RESULT_REG_TOKEN,   {NT_ESTABLISHED_NAME_TOKEN, NULL3}, NO_KW},
-   {NT_VERTEX_RESULT_REG_TOKEN,   {NT_RESULT_BINDING_TOKEN, NULL3},   NO_KW},
-   {NT_ADDR_REG_TOKEN,            {NT_ESTABLISHED_NAME_TOKEN, NULL3}, NO_KW},
-   {NT_ADDR_COMPONENT_TOKEN,      {PERIOD_TOKEN, ID_TOKEN, NULL2},    {"", "x", "", ""}},
-    
-   /* 90: */
-   {NT_ADDR_WRITE_MASK_TOKEN, {PERIOD_TOKEN, ID_TOKEN, NULL2},            {"", "x", "", ""}},
-   {NT_SCALAR_SUFFIX_TOKEN,   {PERIOD_TOKEN, NT_COMPONENT_TOKEN, NULL2},  {"", "x", "", ""}},
-   {NT_SWIZZLE_SUFFIX_TOKEN,  {NULL4},                                    NO_KW},
-   {NT_COMPONENT_TOKEN,       {ID_TOKEN, NULL3},                          {"x", "", "", ""}},
-   {NT_COMPONENT_TOKEN,       {ID_TOKEN, NULL3},                          {"y", "", "", ""}},
-
-   /* 95: */
-   {NT_COMPONENT_TOKEN,      {ID_TOKEN, NULL3},                              {"z", "", "", ""}},
-   {NT_COMPONENT_TOKEN,      {ID_TOKEN, NULL3},                              {"w", "", "", ""}},
-   {NT_OPTIONAL_MASK_TOKEN,  {PERIOD_TOKEN, NT_OPTIONAL_MASK2_TOKEN, NULL2}, NO_KW},
-   {NT_OPTIONAL_MASK_TOKEN,  {NULL4},                                        NO_KW},
-   {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3},                              {"x", "", "", ""}},
-
-   /* 100: */
-   {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"y", "", "", ""}},
-   {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"xy", "", "", ""}},
-   {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"z", "", "", ""}},
-   {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"xz", "", "", ""}},
-   {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"yz", "", "", ""}},
-
-   /* 105: */
-   {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"xyz", "", "", ""}},
-   {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"w", "", "", ""}},
-   {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"xw", "", "", ""}},
-   {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"yw", "", "", ""}},
-   {NT_OPTIONAL_MASK2_TOKEN, {ID_TOKEN, NULL3}, {"xyw", "", "", ""}},
-
-   /* 110: */
-   {NT_OPTIONAL_MASK2_TOKEN,  {ID_TOKEN, NULL3}, {"zw", "", "", ""}},
-   {NT_OPTIONAL_MASK2_TOKEN,  {ID_TOKEN, NULL3}, {"xzw", "", "", ""}},
-   {NT_OPTIONAL_MASK2_TOKEN,  {ID_TOKEN, NULL3}, {"yzw", "", "", ""}},
-   {NT_OPTIONAL_MASK2_TOKEN,  {ID_TOKEN, NULL3}, {"xyzw", "", "", ""}},
-   {NT_NAMING_STATEMENT_TOKEN, {NT_ATTRIB_STATEMENT_TOKEN, NULL3}, NO_KW},
-
-   /* 115: */
-   {NT_NAMING_STATEMENT_TOKEN, {NT_PARAM_STATEMENT_TOKEN, NULL3},   NO_KW},
-   {NT_NAMING_STATEMENT_TOKEN, {NT_TEMP_STATEMENT_TOKEN, NULL3},    NO_KW},
-   {NT_NAMING_STATEMENT_TOKEN, {NT_ADDRESS_STATEMENT_TOKEN, NULL3}, NO_KW},
-   {NT_NAMING_STATEMENT_TOKEN, {NT_OUTPUT_STATEMENT_TOKEN, NULL3},  NO_KW},
-   {NT_NAMING_STATEMENT_TOKEN, {NT_ALIAS_STATEMENT_TOKEN, NULL3},   NO_KW},
-
-   /* 120: */
-   {NT_ATTRIB_STATEMENT_TOKEN,
-           {ATTRIB_TOKEN, NT_ESTABLISH_NAME_TOKEN, EQUAL_TOKEN, NT_VTX_ATTRIB_BINDING_TOKEN}, NO_KW},
-   {NT_VTX_ATTRIB_BINDING_TOKEN,
-           {VERTEX_TOKEN, PERIOD_TOKEN, NT_VTX_ATTRIB_ITEM_TOKEN, NULL_TOKEN},                NO_KW},
-   {NT_VTX_ATTRIB_ITEM_TOKEN, {ID_TOKEN, NULL3},                             {"position", "", "", ""}},
-   {NT_VTX_ATTRIB_ITEM_TOKEN, {ID_TOKEN, NT_VTX_OPT_WEIGHT_NUM_TOKEN, NULL2},{"weight", "", "", ""}},
-   {NT_VTX_ATTRIB_ITEM_TOKEN, {ID_TOKEN, NULL3},                             {"normal", "", "", ""}},
-
-   /* 125: */
-   {NT_VTX_ATTRIB_ITEM_TOKEN, {ID_TOKEN, NT_OPT_COLOR_TYPE_TOKEN, NULL2},
-                                                 {"color", "", "", ""}},
-   {NT_VTX_ATTRIB_ITEM_TOKEN, {ID_TOKEN, NULL3}, {"fogcoord", "", "", ""}},
-   {NT_VTX_ATTRIB_ITEM_TOKEN, {ID_TOKEN, NT_OPT_TEX_COORD_NUM_TOKEN, NULL2},
-                                                 {"texcoord", "", "", ""}},
-   {NT_VTX_ATTRIB_ITEM_TOKEN,
-                              {ID_TOKEN, LBRACKET_TOKEN, NT_VTX_WEIGHT_NUM_TOKEN, RBRACKET_TOKEN},
-                                                 {"matrixindex", "", "", ""}},
-   {NT_VTX_ATTRIB_ITEM_TOKEN,
-                              {ID_TOKEN, LBRACKET_TOKEN, NT_VTX_ATTRIB_NUM_TOKEN, RBRACKET_TOKEN},
-                                                 {"attrib", "", "", ""}},
-
-   /* 130: */
-   {NT_VTX_ATTRIB_NUM_TOKEN,     {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
-   {NT_VTX_OPT_WEIGHT_NUM_TOKEN, {NULL4},                NO_KW},
-   {NT_VTX_OPT_WEIGHT_NUM_TOKEN, {LBRACKET_TOKEN, NT_VTX_WEIGHT_NUM_TOKEN, RBRACKET_TOKEN, NULL_TOKEN},
-                                                         NO_KW},
-   {NT_VTX_WEIGHT_NUM_TOKEN,     {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
-   {NT_PARAM_STATEMENT_TOKEN,
-                                 {PARAM_TOKEN, NT_ESTABLISH_NAME_TOKEN, NT_PARAM_STATEMENT2_TOKEN,
-                                   NULL_TOKEN},          NO_KW},
-
-   /* 135: */
-   {NT_PARAM_STATEMENT2_TOKEN,  {NT_PARAM_SINGLE_INIT_TOKEN, NULL3},     NO_KW},
-   {NT_PARAM_STATEMENT2_TOKEN,  {LBRACKET_TOKEN, NT_OPT_ARRAY_SIZE_TOKEN, RBRACKET_TOKEN,
-                                    NT_PARAM_MULTIPLE_INIT_TOKEN},       NO_KW},
-   {NT_OPT_ARRAY_SIZE_TOKEN,    {NULL4},                                 NO_KW},
-   {NT_OPT_ARRAY_SIZE_TOKEN,    {INTEGER_TOKEN, NULL3},                  {"-1", "", "", ""}},
-   {NT_PARAM_SINGLE_INIT_TOKEN, {EQUAL_TOKEN, NT_PARAM_SINGLE_ITEM_DECL_TOKEN, NULL2}, 
-                                                                                       NO_KW},
-    
-
-   /* 140: */
-   {NT_PARAM_MULTIPLE_INIT_TOKEN,
-                     {EQUAL_TOKEN, LBRACE_TOKEN, NT_PARAM_MULT_INIT_LIST_TOKEN, RBRACE_TOKEN},
-                                              NO_KW},
-   {NT_PARAM_MULT_INIT_LIST_TOKEN,
-                     {NT_PARAM_MULTIPLE_ITEM_TOKEN, NT_PARAM_MULT_INIT_LIST2_TOKEN, NULL2},
-                                              NO_KW},
-   {NT_PARAM_MULT_INIT_LIST2_TOKEN,
-                     {COMMA_TOKEN, NT_PARAM_MULT_INIT_LIST_TOKEN, NULL2}, 
-                                                                                NO_KW},
-   {NT_PARAM_MULT_INIT_LIST2_TOKEN,  {NULL4}, NO_KW},
-   {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, {NT_STATE_SINGLE_ITEM_TOKEN, NULL3},
-                                              NO_KW},
-
-   /* 145: */
-   {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, {NT_PROGRAM_SINGLE_ITEM_TOKEN, NULL3}, NO_KW},
-   {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, {NT_PARAM_CONST_DECL_TOKEN, NULL3},    NO_KW},
-   {NT_PARAM_SINGLE_ITEM_USE_TOKEN, {NT_STATE_SINGLE_ITEM_TOKEN, NULL3},    NO_KW},
-   {NT_PARAM_SINGLE_ITEM_USE_TOKEN, {NT_PROGRAM_SINGLE_ITEM_TOKEN, NULL3},  NO_KW},
-   {NT_PARAM_SINGLE_ITEM_USE_TOKEN, {NT_PARAM_CONST_USE_TOKEN, NULL3},      NO_KW},
-
-   /* 150: */
-   {NT_PARAM_MULTIPLE_ITEM_TOKEN, {NT_STATE_MULTIPLE_ITEM_TOKEN, NULL3},    NO_KW},
-   {NT_PARAM_MULTIPLE_ITEM_TOKEN, {NT_PROGRAM_MULTIPLE_ITEM_TOKEN, NULL3},  NO_KW},
-   {NT_PARAM_MULTIPLE_ITEM_TOKEN, {NT_PARAM_CONST_DECL_TOKEN, NULL3},       NO_KW},
-   {NT_STATE_MULTIPLE_ITEM_TOKEN,
-        {STATE_TOKEN, PERIOD_TOKEN, NT_STATE_MULTIPLE_ITEM2_TOKEN, NULL_TOKEN},
-                                                                            NO_KW},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_MATERIAL_ITEM_TOKEN, NULL3},   NO_KW},
-
-   /* 155: */
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_LIGHT_ITEM_TOKEN, NULL3},       NO_KW},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_LIGHT_MODEL_ITEM_TOKEN, NULL3}, NO_KW},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_LIGHT_PROD_ITEM_TOKEN, NULL3},  NO_KW},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_TEX_GEN_ITEM_TOKEN, NULL3},     NO_KW},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_FOG_ITEM_TOKEN, NULL3},         NO_KW},
-
-   /* 160: */
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_CLIP_PLANE_ITEM_TOKEN, NULL3},  NO_KW},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, {NT_STATE_POINT_ITEM_TOKEN, NULL3},       NO_KW},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN,
-                  {ID_TOKEN, PERIOD_TOKEN, NT_STATE_MATRIX_NAME_TOKEN, NT_FOO_TOKEN},
-                                                               {"matrix", "", "", ""}},
-   {NT_FOO_TOKEN, {PERIOD_TOKEN, NT_FOO2_TOKEN, NULL2},                      NO_KW},
-   {NT_FOO2_TOKEN, {NT_STATE_MAT_MODIFIER_TOKEN, NT_FOO3_TOKEN, NULL2},      NO_KW},
-
-   /* 165: */
-   {NT_FOO2_TOKEN,  {ID_TOKEN, LBRACKET_TOKEN, NT_STATE_MATRIX_ROW_NUM_TOKEN, NT_FOO4_TOKEN},
-                             {"row", "", "", ""}},
-   {NT_FOO3_TOKEN,  {NULL4}, NO_KW},
-   {NT_FOO3_TOKEN,  {PERIOD_TOKEN, ID_TOKEN, LBRACKET_TOKEN, NT_FOO35_TOKEN},
-                            {"", "row", "", ""}},
-   {NT_FOO35_TOKEN, {NT_STATE_MATRIX_ROW_NUM_TOKEN, NT_FOO4_TOKEN, NULL2},
-                            NO_KW},
-   {NT_FOO4_TOKEN,  {RBRACKET_TOKEN, NULL3}, NO_KW},
-
-   /* 170: */
-   {NT_FOO4_TOKEN, {DOTDOT_TOKEN, NT_STATE_MATRIX_ROW_NUM_TOKEN, RBRACKET_TOKEN, NULL_TOKEN},
-                     NO_KW},
-   {NT_STATE_SINGLE_ITEM_TOKEN,
-                   {STATE_TOKEN, PERIOD_TOKEN, NT_STATE_SINGLE_ITEM2_TOKEN, NULL_TOKEN},
-                     NO_KW},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_MATERIAL_ITEM_TOKEN, NULL3},
-                     NO_KW},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_LIGHT_ITEM_TOKEN, NULL3}, 
-                                   NO_KW},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_LIGHT_MODEL_ITEM_TOKEN, NULL3},
-                     NO_KW},
-
-   /* 175: */
-   {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_LIGHT_PROD_ITEM_TOKEN, NULL3}, NO_KW},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_TEX_GEN_ITEM_TOKEN, NULL3},    NO_KW},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_FOG_ITEM_TOKEN, NULL3},        NO_KW},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_CLIP_PLANE_ITEM_TOKEN, NULL3}, NO_KW},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_POINT_ITEM_TOKEN, NULL3},      NO_KW},
-
-   /* 180: */
-   {NT_STATE_SINGLE_ITEM2_TOKEN, {NT_STATE_MATRIX_ROW_TOKEN, NULL3}, NO_KW},
-   {NT_STATE_MATERIAL_ITEM_TOKEN,
-         {ID_TOKEN, PERIOD_TOKEN, NT_STATE_MATERIAL_ITEM2_TOKEN, NULL_TOKEN},
-                                                                     {"material", "", "", ""}},
-   {NT_STATE_MATERIAL_ITEM2_TOKEN, {NT_STATE_MAT_PROPERTY_TOKEN, NULL3},
-                                                                     NO_KW},
-   {NT_STATE_MATERIAL_ITEM2_TOKEN,
-         {PERIOD_TOKEN, NT_OPT_FACE_TYPE2_TOKEN, PERIOD_TOKEN,
-            NT_STATE_MAT_PROPERTY_TOKEN},                            NO_KW},
-   {NT_STATE_MAT_PROPERTY_TOKEN, {ID_TOKEN, NULL3},                  {"ambient", "", "", ""}},
-
-   /* 185 */
-   {NT_STATE_MAT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"diffuse", "", "", ""}},
-   {NT_STATE_MAT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"specular", "", "", ""}},
-   {NT_STATE_MAT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"emission", "", "", ""}},
-   {NT_STATE_MAT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"shininess", "", "", ""}},
-   {NT_STATE_LIGHT_ITEM_TOKEN,
-                                 {ID_TOKEN, LBRACKET_TOKEN, NT_STATE_LIGHT_NUMBER_TOKEN,
-                      NT_STATE_LIGHT_ITEM2_TOKEN},  {"light", "", "", ""}},
-
-   /* 190: */
-   {NT_STATE_LIGHT_ITEM2_TOKEN, {RBRACKET_TOKEN, PERIOD_TOKEN, NT_STATE_LIGHT_PROPERTY_TOKEN, NULL_TOKEN},
-                                                      NO_KW},
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"ambient", "", "", ""}},
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"diffuse", "", "", ""}},
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"specular", "", "", ""}},
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"position", "", "", ""}},
-
-   /* 195: */
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"attenuation", "", "", ""}},
-   {NT_STATE_LIGHT_PROPERTY_TOKEN,
-               {ID_TOKEN, PERIOD_TOKEN, NT_STATE_SPOT_PROPERTY_TOKEN, NULL_TOKEN},
-                                                      {"spot", "", "", ""}},
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"half", "", "", ""}},
-   {NT_STATE_SPOT_PROPERTY_TOKEN,  {ID_TOKEN, NULL3}, {"direction", "", "", ""}},
-   {NT_STATE_LIGHT_MODEL_ITEM_TOKEN,
-     {ID_TOKEN, NT_STATE_LMOD_PROPERTY_TOKEN, NULL2}, {"lightmodel", "", "", ""}},
-                                                    
-   /* 200: */
-   {NT_STATE_LMOD_PROPERTY_TOKEN,  {PERIOD_TOKEN, NT_STATE_LMOD_PROPERTY2_TOKEN, NULL2}, NO_KW},
-   {NT_STATE_LMOD_PROPERTY2_TOKEN, {ID_TOKEN, NULL3}, {"ambient", "", "", ""}},
-   {NT_STATE_LMOD_PROPERTY2_TOKEN, {ID_TOKEN, NULL3}, {"scenecolor", "", "", ""}},
-   {NT_STATE_LMOD_PROPERTY2_TOKEN,
-                 {NT_OPT_FACE_TYPE2_TOKEN, PERIOD_TOKEN, ID_TOKEN, NULL_TOKEN},
-                                                      {"scenecolor", "", "", ""}},
-   {NT_STATE_LIGHT_PROD_ITEM_TOKEN,
-                 {ID_TOKEN, LBRACKET_TOKEN, NT_STATE_LIGHT_NUMBER_TOKEN,
-                   NT_STATE_LIGHT_PROD_ITEM15_TOKEN}, {"lightprod", "", "", ""}},
-
-   /* 205: */
-   {NT_STATE_LIGHT_PROD_ITEM15_TOKEN,
-    {RBRACKET_TOKEN, PERIOD_TOKEN, NT_STATE_LIGHT_PROD_ITEM2_TOKEN, NULL_TOKEN},        NO_KW},
-   {NT_STATE_LIGHT_PROD_ITEM2_TOKEN, {NT_STATE_LPROD_PROPERTY_TOKEN, NULL3},            NO_KW},
-   {NT_STATE_LIGHT_PROD_ITEM2_TOKEN,
-   {NT_OPT_FACE_TYPE2_TOKEN, PERIOD_TOKEN, NT_STATE_LPROD_PROPERTY_TOKEN, NULL_TOKEN},  NO_KW},
-   {NT_STATE_LPROD_PROPERTY_TOKEN, {ID_TOKEN, NULL3},  {"diffuse", "", "", ""}},
-   {NT_STATE_LPROD_PROPERTY_TOKEN, {ID_TOKEN, NULL3},  {"ambient", "", "", ""}},
-    
-   /* 210: */
-   {NT_STATE_LPROD_PROPERTY_TOKEN, {ID_TOKEN, NULL3},    {"specular", "", "", ""}},
-   {NT_STATE_LIGHT_NUMBER_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
-   {NT_STATE_TEX_GEN_ITEM_TOKEN, {ID_TOKEN, NT_OPT_TEX_COORD_NUM_TOKEN, 
-              NT_STATE_TEX_GEN_ITEM2_TOKEN, NULL_TOKEN}, {"texgen", "", "", ""}},
-   {NT_STATE_TEX_GEN_ITEM2_TOKEN,{PERIOD_TOKEN, NT_STATE_TEX_GEN_TYPE_TOKEN, PERIOD_TOKEN,
-                          NT_STATE_TEX_GEN_COORD_TOKEN}, NO_KW},
-   {NT_STATE_TEX_GEN_TYPE_TOKEN, {ID_TOKEN, NULL3},      {"eye", "", "", ""}},
-
-   /* 215: */
-   {NT_STATE_TEX_GEN_TYPE_TOKEN,  {ID_TOKEN, NULL3}, {"object", "", "", ""}},
-   {NT_STATE_TEX_GEN_COORD_TOKEN, {ID_TOKEN, NULL3}, {"s", "", "", ""}},
-   {NT_STATE_TEX_GEN_COORD_TOKEN, {ID_TOKEN, NULL3}, {"t", "", "", ""}},
-   {NT_STATE_TEX_GEN_COORD_TOKEN, {ID_TOKEN, NULL3}, {"r", "", "", ""}},
-   {NT_STATE_TEX_GEN_COORD_TOKEN, {ID_TOKEN, NULL3}, {"q", "", "", ""}},
-
-   /* 220: */
-   {NT_STATE_FOG_ITEM_TOKEN,     {ID_TOKEN, PERIOD_TOKEN, NT_STATE_FOG_PROPERTY_TOKEN, NULL_TOKEN},
-                                                    {"fog", "","",""}},
-   {NT_STATE_FOG_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"color", "", "", ""}},
-   {NT_STATE_FOG_PROPERTY_TOKEN, {ID_TOKEN, NULL3}, {"params", "", "", ""}},
-   {NT_STATE_CLIP_PLANE_ITEM_TOKEN,
-                {ID_TOKEN, LBRACKET_TOKEN, NT_STATE_CLIP_PLANE_NUM_TOKEN,
-                  NT_STATE_CLIP_PLANE_ITEM2_TOKEN}, {"clip", "", "", ""}},
-   {NT_STATE_CLIP_PLANE_ITEM2_TOKEN,
-                {RBRACKET_TOKEN, PERIOD_TOKEN, ID_TOKEN, NULL_TOKEN}, 
-                                                                            {"", "", "plane", ""}},
-                                                                                                                                        
-   /* 225: */
-   {NT_STATE_CLIP_PLANE_NUM_TOKEN,{INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
-   {NT_STATE_POINT_ITEM_TOKEN,    {ID_TOKEN, PERIOD_TOKEN, NT_STATE_POINT_PROPERTY_TOKEN, NULL_TOKEN},
-                                                          {"point", "", "", ""}},
-   {NT_STATE_POINT_PROPERTY_TOKEN, {ID_TOKEN, NULL3},     {"size", "", "", ""}},
-   {NT_STATE_POINT_PROPERTY_TOKEN, {ID_TOKEN, NULL3},     {"attenuation", "", "", ""}},
-   {NT_STATE_MATRIX_ROW_TOKEN,     {ID_TOKEN, PERIOD_TOKEN, NT_STATE_MATRIX_NAME_TOKEN,
-                            NT_STATE_MATRIX_ROW15_TOKEN}, {"matrix", "", "", ""}},
-
-   /* 230: */
-   {NT_STATE_MATRIX_ROW15_TOKEN, {PERIOD_TOKEN, NT_STATE_MATRIX_ROW2_TOKEN, NULL2}, NO_KW},
-   {NT_STATE_MATRIX_ROW2_TOKEN,  {ID_TOKEN, LBRACKET_TOKEN, 
-                           NT_STATE_MATRIX_ROW_NUM_TOKEN, RBRACKET_TOKEN},         
-                                                                       {"row", "", "", ""}},
-   {NT_STATE_MATRIX_ROW2_TOKEN, {NT_STATE_MAT_MODIFIER_TOKEN, PERIOD_TOKEN, ID_TOKEN,
-                           NT_STATE_MATRIX_ROW3_TOKEN}, 
-                                                                       {"", "", "row", ""}},
-   {NT_STATE_MATRIX_ROW3_TOKEN, {LBRACKET_TOKEN, NT_STATE_MATRIX_ROW_NUM_TOKEN, RBRACKET_TOKEN,
-                          NULL_TOKEN}, NO_KW},
-   {NT_STATE_MAT_MODIFIER_TOKEN, {ID_TOKEN, NULL3}, {"inverse", "", "", ""}},
-
-   /* 235: */
-   {NT_STATE_MAT_MODIFIER_TOKEN,   {ID_TOKEN, NULL3},      {"transpose", "", "", ""}},
-   {NT_STATE_MAT_MODIFIER_TOKEN,   {ID_TOKEN, NULL3},      {"invtrans", "", "", ""}},
-   {NT_STATE_MATRIX_ROW_NUM_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
-   {NT_STATE_MATRIX_NAME_TOKEN,    {ID_TOKEN, NT_STATE_OPT_MOD_MAT_NUM_TOKEN, NULL2},
-                                                                         {"modelview", "", "", ""}},
-   {NT_STATE_MATRIX_NAME_TOKEN, {ID_TOKEN, NULL3},         {"projection", "", "", ""}},
-
-   /* 240: */
-   {NT_STATE_MATRIX_NAME_TOKEN, {ID_TOKEN, NULL3}, {"mvp", "", "", ""}},
-   {NT_STATE_MATRIX_NAME_TOKEN, {ID_TOKEN, NT_OPT_TEX_COORD_NUM_TOKEN, NULL2},
-                                                   {"texture", "", "", ""}},
-   {NT_STATE_MATRIX_NAME_TOKEN, {ID_TOKEN, LBRACKET_TOKEN, NT_STATE_PALETTE_MAT_NUM_TOKEN,
-                                  RBRACKET_TOKEN}, {"palette", "", "", ""}},
-   {NT_STATE_MATRIX_NAME_TOKEN, {PROGRAM_TOKEN, LBRACKET_TOKEN, NT_STATE_PROGRAM_MAT_NUM_TOKEN,
-                                  RBRACKET_TOKEN}, NO_KW},
-   {NT_STATE_OPT_MOD_MAT_NUM_TOKEN, {NULL4},       NO_KW},
-
-   /* 245: */
-   {NT_STATE_OPT_MOD_MAT_NUM_TOKEN,
-    {LBRACKET_TOKEN, NT_STATE_MOD_MAT_NUM_TOKEN, RBRACKET_TOKEN, NULL_TOKEN}, NO_KW},
-   {NT_STATE_MOD_MAT_NUM_TOKEN, {INTEGER_TOKEN, NULL3},                       {"-1", "", "", ""}},
-   {NT_STATE_PALETTE_MAT_NUM_TOKEN, {INTEGER_TOKEN, NULL3},                   {"-1", "", "", ""}},
-   {NT_STATE_PROGRAM_MAT_NUM_TOKEN, {INTEGER_TOKEN, NULL3},                   {"-1", "", "", ""}},
-   {NT_PROGRAM_SINGLE_ITEM_TOKEN, 
-     {PROGRAM_TOKEN, PERIOD_TOKEN, NT_PROGRAM_SINGLE_ITEM2_TOKEN, NULL_TOKEN}, NO_KW},
-
-   /* 250: */
-   {NT_PROGRAM_SINGLE_ITEM2_TOKEN, {NT_PROG_ENV_PARAM_TOKEN, NULL3},            NO_KW},
-   {NT_PROGRAM_SINGLE_ITEM2_TOKEN, {NT_PROG_LOCAL_PARAM_TOKEN, NULL3},          NO_KW},
-   {NT_PROGRAM_MULTIPLE_ITEM_TOKEN,
-    {PROGRAM_TOKEN, PERIOD_TOKEN, NT_PROGRAM_MULTIPLE_ITEM2_TOKEN, NULL_TOKEN}, NO_KW},
-   {NT_PROGRAM_MULTIPLE_ITEM2_TOKEN, {NT_PROG_ENV_PARAMS_TOKEN, NULL3},         NO_KW},
-   {NT_PROGRAM_MULTIPLE_ITEM2_TOKEN, {NT_PROG_LOCAL_PARAMS_TOKEN, NULL3},       NO_KW},
-
-   /* 255: */
-   {NT_PROG_ENV_PARAMS_TOKEN, {ID_TOKEN, LBRACKET_TOKEN, NT_PROG_ENV_PARAM_NUMS_TOKEN, RBRACKET_TOKEN},
-                                   {"env", "", "", ""}},
-   {NT_PROG_ENV_PARAM_NUMS_TOKEN, {NT_PROG_ENV_PARAM_NUM_TOKEN, NT_PROG_ENV_PARAM_NUMS2_TOKEN, NULL2},
-                                   NO_KW},
-   {NT_PROG_ENV_PARAM_NUMS2_TOKEN, {DOTDOT_TOKEN, NT_PROG_ENV_PARAM_NUM_TOKEN, NULL2}, NO_KW},
-   {NT_PROG_ENV_PARAM_NUMS2_TOKEN, {NULL4},                                            NO_KW},
-   {NT_PROG_ENV_PARAM_TOKEN,
-     {ID_TOKEN, LBRACKET_TOKEN, NT_PROG_ENV_PARAM_NUM_TOKEN, RBRACKET_TOKEN},
-                                   {"env", "", "", ""}},
-
-   /* 260: */
-   {NT_PROG_LOCAL_PARAMS_TOKEN, {ID_TOKEN, LBRACKET_TOKEN, NT_PROG_LOCAL_PARAM_NUMS_TOKEN,
-                  RBRACKET_TOKEN}, {"local", "", "", ""}},
-   {NT_PROG_LOCAL_PARAM_NUMS_TOKEN,
-    {NT_PROG_LOCAL_PARAM_NUM_TOKEN, NT_PROG_LOCAL_PARAM_NUMS2_TOKEN, NULL2},
-                                   NO_KW},
-   {NT_PROG_LOCAL_PARAM_NUMS2_TOKEN, {DOTDOT_TOKEN, NT_PROG_LOCAL_PARAM_NUM_TOKEN, NULL2}, NO_KW},
-   {NT_PROG_LOCAL_PARAM_NUMS2_TOKEN, {NULL4},                                              NO_KW},
-   {NT_PROG_LOCAL_PARAM_TOKEN, {ID_TOKEN, LBRACKET_TOKEN, NT_PROG_LOCAL_PARAM_NUM_TOKEN, RBRACKET_TOKEN},
-                                   {"local", "", "", ""}},
-
-   /* 265: */
-   {NT_PROG_ENV_PARAM_NUM_TOKEN, {INTEGER_TOKEN, NULL3},   {"-1", "", "", ""}},
-   {NT_PROG_LOCAL_PARAM_NUM_TOKEN, {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
-   {NT_PARAM_CONST_DECL_TOKEN, {NT_PARAM_CONST_SCALAR_DECL_TOKEN, NULL3}, NO_KW},
-   {NT_PARAM_CONST_DECL_TOKEN, {NT_PARAM_CONST_VECTOR_TOKEN, NULL3},      NO_KW},
-   {NT_PARAM_CONST_USE_TOKEN, {NT_PARAM_CONST_SCALAR_USE_TOKEN, NULL3},   NO_KW},
-    
-   /* 270: */
-   {NT_PARAM_CONST_USE_TOKEN,         {NT_PARAM_CONST_VECTOR_TOKEN, NULL3},    NO_KW},
-   {NT_PARAM_CONST_SCALAR_DECL_TOKEN, {NT_SIGNED_FLOAT_CONSTANT_TOKEN, NULL3}, NO_KW},
-   {NT_PARAM_CONST_SCALAR_USE_TOKEN,  {FLOAT_TOKEN, NULL3}, {"-1", "", "", ""}},
-   {NT_PARAM_CONST_VECTOR_TOKEN, {LBRACE_TOKEN, NT_SIGNED_FLOAT_CONSTANT_TOKEN,
-                                    NT_PARAM_CONST_VECTOR2_TOKEN, NULL_TOKEN}, NO_KW},
-   {NT_PARAM_CONST_VECTOR2_TOKEN,{RBRACE_TOKEN, NULL3},                        NO_KW},
-
-   /* 275: */
-   {NT_PARAM_CONST_VECTOR2_TOKEN, {COMMA_TOKEN, NT_SIGNED_FLOAT_CONSTANT_TOKEN,
-                                    NT_PARAM_CONST_VECTOR3_TOKEN, NULL_TOKEN}, NO_KW},
-   {NT_PARAM_CONST_VECTOR3_TOKEN, {RBRACE_TOKEN, NULL3},                       NO_KW},
-   {NT_PARAM_CONST_VECTOR3_TOKEN, {COMMA_TOKEN, NT_SIGNED_FLOAT_CONSTANT_TOKEN,
-                                    NT_PARAM_CONST_VECTOR4_TOKEN, NULL_TOKEN}, NO_KW},
-   {NT_PARAM_CONST_VECTOR4_TOKEN, {RBRACE_TOKEN, NULL3},                       NO_KW},
-   {NT_PARAM_CONST_VECTOR4_TOKEN, {COMMA_TOKEN, NT_SIGNED_FLOAT_CONSTANT_TOKEN, 
-                                                                                                               RBRACE_TOKEN, NULL_TOKEN},           NO_KW},
-
-   /* 280: */
-   {NT_SIGNED_FLOAT_CONSTANT_TOKEN, {NT_OPTIONAL_SIGN_TOKEN, FLOAT_TOKEN, NULL2}, 
-                                                  {"", "-1", "", ""}},
-   {NT_OPTIONAL_SIGN_TOKEN, {NULL4},              NO_KW},
-   {NT_OPTIONAL_SIGN_TOKEN, {MINUS_TOKEN, NULL3}, NO_KW},
-   {NT_OPTIONAL_SIGN_TOKEN, {PLUS_TOKEN, NULL3},  NO_KW},
-   {NT_TEMP_STATEMENT_TOKEN, {TEMP_TOKEN, NT_VAR_NAME_LIST_TOKEN, NULL2},
-                                                  NO_KW},
-
-   /* 285: */
-   {NT_ADDRESS_STATEMENT_TOKEN, {ADDRESS_TOKEN, NT_VAR_NAME_LIST_TOKEN, NULL2}, NO_KW},
-   {NT_VAR_NAME_LIST_TOKEN,     {NT_ESTABLISH_NAME_TOKEN, NULL3},               NO_KW},
-   {NT_VAR_NAME_LIST_TOKEN,     {NT_ESTABLISH_NAME_TOKEN, COMMA_TOKEN, NT_VAR_NAME_LIST_TOKEN,
-                                  NULL_TOKEN},                                  NO_KW},
-   {NT_OUTPUT_STATEMENT_TOKEN,  {OUTPUT_TOKEN, NT_ESTABLISH_NAME_TOKEN, EQUAL_TOKEN,
-                                  NT_RESULT_BINDING_TOKEN},                     NO_KW},
-   {NT_RESULT_BINDING_TOKEN,    {RESULT_TOKEN, PERIOD_TOKEN, NT_RESULT_BINDING2_TOKEN, NULL_TOKEN},
-                                                                                NO_KW},
-
-   /* 290: */
-   {NT_RESULT_BINDING2_TOKEN, {ID_TOKEN, NULL3},                    {"position", "", "", ""}},
-   {NT_RESULT_BINDING2_TOKEN, {ID_TOKEN, NULL3},                    {"fogcoord", "", "", ""}},
-   {NT_RESULT_BINDING2_TOKEN, {ID_TOKEN, NULL3},                    {"pointsize", "", "", ""}},
-   {NT_RESULT_BINDING2_TOKEN, {NT_RESULT_COL_BINDING_TOKEN, NULL3}, NO_KW},
-   {NT_RESULT_BINDING2_TOKEN, {ID_TOKEN, NT_OPT_TEX_COORD_NUM_TOKEN, NULL2},
-                                                                    {"texcoord", "", "", ""}},
-
-   /* 295: */
-   {NT_RESULT_COL_BINDING_TOKEN, {ID_TOKEN, NT_RESULT_COL_BINDING2_TOKEN, NULL2}, {"color", "", "", ""}},
-   {NT_RESULT_COL_BINDING2_TOKEN, {NULL4},                                        NO_KW},
-   {NT_RESULT_COL_BINDING2_TOKEN, {PERIOD_TOKEN, NT_RESULT_COL_BINDING3_TOKEN, NULL2}, NO_KW},
-   {NT_RESULT_COL_BINDING3_TOKEN, {ID_TOKEN, NT_RESULT_COL_BINDING4_TOKEN, NULL2}, {"front", "", "", ""}},
-   {NT_RESULT_COL_BINDING3_TOKEN, {ID_TOKEN, NT_RESULT_COL_BINDING4_TOKEN, NULL2}, {"back", "", "", ""}},
-    
-   /* 300: */
-   {NT_RESULT_COL_BINDING4_TOKEN, {NULL4},           NO_KW},
-   {NT_RESULT_COL_BINDING4_TOKEN, {PERIOD_TOKEN, NT_RESULT_COL_BINDING5_TOKEN, NULL2}, NO_KW},
-   {NT_RESULT_COL_BINDING5_TOKEN, {ID_TOKEN, NULL3}, {"primary", "", "", ""}},
-   {NT_RESULT_COL_BINDING5_TOKEN, {ID_TOKEN, NULL3}, {"secondary", "", "", ""}},
-   {NT_OPT_FACE_TYPE2_TOKEN,      {ID_TOKEN, NULL3}, {"front", "", "", ""}},
-
-   /* 305: */
-   {NT_OPT_FACE_TYPE2_TOKEN, {ID_TOKEN, NULL3},  {"back", "", "", ""}},
-   {NT_OPT_COLOR_TYPE_TOKEN, {PERIOD_TOKEN, NT_OPT_COLOR_TYPE2_TOKEN, NULL2}, NO_KW},
-   {NT_OPT_COLOR_TYPE_TOKEN, {NULL4},            NO_KW},
-   {NT_OPT_COLOR_TYPE2_TOKEN, {ID_TOKEN, NULL3}, {"primary", "", "", ""}},
-   {NT_OPT_COLOR_TYPE2_TOKEN, {ID_TOKEN, NULL3}, {"secondary", "", "", ""}},
-
-   /* 310: */
-   {NT_OPT_TEX_COORD_NUM_TOKEN, {NULL4},                                  NO_KW},
-   {NT_OPT_TEX_COORD_NUM_TOKEN,
-    {LBRACKET_TOKEN, NT_TEX_COORD_NUM_TOKEN, RBRACKET_TOKEN, NULL_TOKEN}, NO_KW},
-   {NT_TEX_COORD_NUM_TOKEN,     {INTEGER_TOKEN, NULL3}, {"-1", "", "", ""}},
-   {NT_ALIAS_STATEMENT_TOKEN,   {ALIAS_TOKEN, NT_ESTABLISH_NAME_TOKEN, EQUAL_TOKEN,
-                             NT_ESTABLISHED_NAME_TOKEN}, NO_KW},
-   {NT_ESTABLISH_NAME_TOKEN, {ID_TOKEN, NULL3},          {"-1", "", "", ""}},
-
-   /* 315: */
-   {NT_ESTABLISHED_NAME_TOKEN, {ID_TOKEN, NULL3},           {"-1", "", "", ""}},
-   {NT_FOO_TOKEN,              {NULL4},                     NO_KW},
-   {NT_SWIZZLE_SUFFIX_TOKEN, {PERIOD_TOKEN, NT_SWIZZLE_SUFFIX2_TOKEN, NULL2},
-                                                            NO_KW},
-   {NT_SWIZZLE_SUFFIX2_TOKEN, {NT_COMPONENT_TOKEN, NULL3},  NO_KW},
-   {NT_SWIZZLE_SUFFIX2_TOKEN, {NT_COMPONENT4_TOKEN, NULL3}, NO_KW},
-};
-
-/* This is the look ahead table. See the look_ahead_table struct def for a description */
-look_ahead_table latab[] = {
-   {NT_PROGRAM_TOKEN, ABS_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, ADD_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, ADDRESS_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, ALIAS_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, ARL_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, ATTRIB_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, DP3_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, DP4_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, DPH_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, DST_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, END_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, EOF_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, EX2_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, EXP_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, FLR_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, FRC_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, LIT_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, LG2_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, LOG_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, MAD_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, MAX_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, MIN_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, MOV_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, MUL_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, OPTION_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, OUTPUT_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, PARAM_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, POW_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, RCP_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, RSQ_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, SGE_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, SLT_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, SUB_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, SWZ_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, XPD_TOKEN, "", 0},
-   {NT_PROGRAM_TOKEN, TEMP_TOKEN, "", 0},
-
-   {NT_OPTION_SEQUENCE_TOKEN, ABS_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, ADD_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, ADDRESS_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, ALIAS_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, ARL_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, ATTRIB_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, DP3_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, DP4_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, DPH_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, DST_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, END_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, EX2_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, EXP_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, FLR_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, FRC_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, LIT_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, LG2_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, LOG_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, MAD_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, MAX_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, MIN_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, MOV_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, MUL_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, OPTION_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, OUTPUT_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, PARAM_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, POW_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, RCP_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, RSQ_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, SGE_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, SLT_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, SUB_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, SWZ_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, XPD_TOKEN, "", 1},
-   {NT_OPTION_SEQUENCE_TOKEN, TEMP_TOKEN, "", 1},
-
-   {NT_OPTION_SEQUENCE2_TOKEN, OPTION_TOKEN, "", 2},
-
-   {NT_OPTION_SEQUENCE2_TOKEN, ABS_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, ADD_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, ADDRESS_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, ALIAS_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, ARL_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, ATTRIB_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, DP3_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, DP4_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, DPH_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, DST_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, END_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, EX2_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, EXP_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, FLR_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, FRC_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, LIT_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, LG2_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, LOG_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, MAD_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, MAX_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, MIN_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, MOV_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, MUL_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, OUTPUT_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, PARAM_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, POW_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, RCP_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, RSQ_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, SGE_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, SLT_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, SUB_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, SWZ_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, XPD_TOKEN, "", 3},
-   {NT_OPTION_SEQUENCE2_TOKEN, TEMP_TOKEN, "", 3},
-
-   {NT_OPTION_TOKEN, OPTION_TOKEN, "", 4},
-
-   {NT_STATEMENT_SEQUENCE_TOKEN, ABS_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, ADD_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, ADDRESS_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, ALIAS_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, ARL_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, ATTRIB_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, DP3_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, DP4_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, DPH_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, DST_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, END_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, EX2_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, EXP_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, FLR_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, FRC_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, LIT_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, LG2_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, LOG_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, MAD_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, MAX_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, MIN_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, MOV_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, MUL_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, OUTPUT_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, PARAM_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, POW_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, RCP_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, RSQ_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, SGE_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, SLT_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, SUB_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, SWZ_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, XPD_TOKEN, "", 5},
-   {NT_STATEMENT_SEQUENCE_TOKEN, TEMP_TOKEN, "", 5},
-
-   {NT_STATEMENT_SEQUENCE2_TOKEN, ABS_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, ADD_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, ADDRESS_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, ALIAS_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, ARL_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, ATTRIB_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, DP3_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, DP4_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, DPH_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, DST_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, EX2_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, EXP_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, FLR_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, FRC_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, LIT_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, LG2_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, LOG_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, MAD_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, MAX_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, MIN_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, MOV_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, MUL_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, OUTPUT_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, PARAM_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, POW_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, RCP_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, RSQ_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, SGE_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, SLT_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, SUB_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, SWZ_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, XPD_TOKEN, "", 6},
-   {NT_STATEMENT_SEQUENCE2_TOKEN, TEMP_TOKEN, "", 6},
-
-   {NT_STATEMENT_SEQUENCE2_TOKEN, END_TOKEN, "", 7},
-
-
-   {NT_STATEMENT_TOKEN, ABS_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, ADD_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, ARL_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, DP3_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, DP4_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, DPH_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, DST_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, EX2_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, EXP_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, FLR_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, FRC_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, LIT_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, LG2_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, LOG_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, MAD_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, MAX_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, MIN_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, MOV_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, MUL_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, POW_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, RCP_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, RSQ_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, SGE_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, SLT_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, SUB_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, SWZ_TOKEN, "", 8},
-   {NT_STATEMENT_TOKEN, XPD_TOKEN, "", 8},
-
-   {NT_STATEMENT_TOKEN, ADDRESS_TOKEN, "", 9},
-   {NT_STATEMENT_TOKEN, ALIAS_TOKEN, "", 9},
-   {NT_STATEMENT_TOKEN, ATTRIB_TOKEN, "", 9},
-   {NT_STATEMENT_TOKEN, OUTPUT_TOKEN, "", 9},
-   {NT_STATEMENT_TOKEN, PARAM_TOKEN, "", 9},
-   {NT_STATEMENT_TOKEN, TEMP_TOKEN, "", 9},
-
-   {NT_INSTRUCTION_TOKEN, ARL_TOKEN, "", 10},
-
-   {NT_INSTRUCTION_TOKEN, ABS_TOKEN, "", 11},
-   {NT_INSTRUCTION_TOKEN, FLR_TOKEN, "", 11},
-   {NT_INSTRUCTION_TOKEN, FRC_TOKEN, "", 11},
-   {NT_INSTRUCTION_TOKEN, LIT_TOKEN, "", 11},
-   {NT_INSTRUCTION_TOKEN, MOV_TOKEN, "", 11},
-
-   {NT_INSTRUCTION_TOKEN, EX2_TOKEN, "", 12},
-   {NT_INSTRUCTION_TOKEN, EXP_TOKEN, "", 12},
-   {NT_INSTRUCTION_TOKEN, LG2_TOKEN, "", 12},
-   {NT_INSTRUCTION_TOKEN, LOG_TOKEN, "", 12},
-   {NT_INSTRUCTION_TOKEN, RCP_TOKEN, "", 12},
-   {NT_INSTRUCTION_TOKEN, RSQ_TOKEN, "", 12},
-
-   {NT_INSTRUCTION_TOKEN, POW_TOKEN, "", 13},
-
-   {NT_INSTRUCTION_TOKEN, ADD_TOKEN, "", 14},
-   {NT_INSTRUCTION_TOKEN, DP3_TOKEN, "", 14},
-   {NT_INSTRUCTION_TOKEN, DP4_TOKEN, "", 14},
-   {NT_INSTRUCTION_TOKEN, DPH_TOKEN, "", 14},
-   {NT_INSTRUCTION_TOKEN, DST_TOKEN, "", 14},
-   {NT_INSTRUCTION_TOKEN, MAX_TOKEN, "", 14},
-   {NT_INSTRUCTION_TOKEN, MIN_TOKEN, "", 14},
-   {NT_INSTRUCTION_TOKEN, MUL_TOKEN, "", 14},
-   {NT_INSTRUCTION_TOKEN, SGE_TOKEN, "", 14},
-   {NT_INSTRUCTION_TOKEN, SLT_TOKEN, "", 14},
-   {NT_INSTRUCTION_TOKEN, SUB_TOKEN, "", 14},
-   {NT_INSTRUCTION_TOKEN, XPD_TOKEN, "", 14},
-
-   {NT_INSTRUCTION_TOKEN, MAD_TOKEN, "", 15},
-
-   {NT_INSTRUCTION_TOKEN, SWZ_TOKEN, "", 16},
-
-   {NT_ARL_INSTRUCTION_TOKEN, ARL_TOKEN, "", 17},
-
-   {NT_VECTOROP_INSTRUCTION_TOKEN, ABS_TOKEN, "", 18},
-   {NT_VECTOROP_INSTRUCTION_TOKEN, FLR_TOKEN, "", 18},
-   {NT_VECTOROP_INSTRUCTION_TOKEN, FRC_TOKEN, "", 18},
-   {NT_VECTOROP_INSTRUCTION_TOKEN, LIT_TOKEN, "", 18},
-   {NT_VECTOROP_INSTRUCTION_TOKEN, MOV_TOKEN, "", 18},
-
-   {NT_VECTOROP_TOKEN, ABS_TOKEN, "", 19},
-
-   {NT_VECTOROP_TOKEN, FLR_TOKEN, "", 20},
-
-   {NT_VECTOROP_TOKEN, FRC_TOKEN, "", 21},
-
-   {NT_VECTOROP_TOKEN, LIT_TOKEN, "", 22},
-
-   {NT_VECTOROP_TOKEN, MOV_TOKEN, "", 23},
-
-   {NT_SCALAROP_INSTRUCTION_TOKEN, EX2_TOKEN, "", 24},
-   {NT_SCALAROP_INSTRUCTION_TOKEN, EXP_TOKEN, "", 24},
-   {NT_SCALAROP_INSTRUCTION_TOKEN, LG2_TOKEN, "", 24},
-   {NT_SCALAROP_INSTRUCTION_TOKEN, LOG_TOKEN, "", 24},
-   {NT_SCALAROP_INSTRUCTION_TOKEN, RCP_TOKEN, "", 24},
-   {NT_SCALAROP_INSTRUCTION_TOKEN, RSQ_TOKEN, "", 24},
-
-   {NT_SCALAROP_TOKEN, EX2_TOKEN, "", 25},
-
-   {NT_SCALAROP_TOKEN, EXP_TOKEN, "", 26},
-
-   {NT_SCALAROP_TOKEN, LG2_TOKEN, "", 27},
-
-   {NT_SCALAROP_TOKEN, LOG_TOKEN, "", 28},
-
-   {NT_SCALAROP_TOKEN, RCP_TOKEN, "", 29},
-
-   {NT_SCALAROP_TOKEN, RSQ_TOKEN, "", 30},
-
-   {NT_BINSCOP_INSTRUCTION_TOKEN, POW_TOKEN, "", 31},
-
-   {NT_BINSCOP_INSTRUCTION2_TOKEN, COMMA_TOKEN, "", 32},
-
-   {NT_BINSCOP_TOKEN, POW_TOKEN, "", 33},
-
-   {NT_BINOP_INSTRUCTION_TOKEN, ADD_TOKEN, "", 34},
-   {NT_BINOP_INSTRUCTION_TOKEN, DP3_TOKEN, "", 34},
-   {NT_BINOP_INSTRUCTION_TOKEN, DP4_TOKEN, "", 34},
-   {NT_BINOP_INSTRUCTION_TOKEN, DPH_TOKEN, "", 34},
-   {NT_BINOP_INSTRUCTION_TOKEN, DST_TOKEN, "", 34},
-   {NT_BINOP_INSTRUCTION_TOKEN, MAX_TOKEN, "", 34},
-   {NT_BINOP_INSTRUCTION_TOKEN, MIN_TOKEN, "", 34},
-   {NT_BINOP_INSTRUCTION_TOKEN, MUL_TOKEN, "", 34},
-   {NT_BINOP_INSTRUCTION_TOKEN, SGE_TOKEN, "", 34},
-   {NT_BINOP_INSTRUCTION_TOKEN, SLT_TOKEN, "", 34},
-   {NT_BINOP_INSTRUCTION_TOKEN, SUB_TOKEN, "", 34},
-   {NT_BINOP_INSTRUCTION_TOKEN, XPD_TOKEN, "", 34},
-
-   {NT_BINOP_INSTRUCTION2_TOKEN, COMMA_TOKEN, "", 35},
-
-   {NT_BINOP_TOKEN, ADD_TOKEN, "", 36},
-   {NT_BINOP_TOKEN, DP3_TOKEN, "", 37},
-   {NT_BINOP_TOKEN, DP4_TOKEN, "", 38},
-   {NT_BINOP_TOKEN, DPH_TOKEN, "", 39},
-   {NT_BINOP_TOKEN, DST_TOKEN, "", 40},
-   {NT_BINOP_TOKEN, MAX_TOKEN, "", 41},
-   {NT_BINOP_TOKEN, MIN_TOKEN, "", 42},
-   {NT_BINOP_TOKEN, MUL_TOKEN, "", 43},
-   {NT_BINOP_TOKEN, SGE_TOKEN, "", 44},
-   {NT_BINOP_TOKEN, SLT_TOKEN, "", 45},
-   {NT_BINOP_TOKEN, SUB_TOKEN, "", 46},
-   {NT_BINOP_TOKEN, XPD_TOKEN, "", 47},
-
-   {NT_TRIOP_INSTRUCTION_TOKEN, MAD_TOKEN, "", 48},
-   {NT_TRIOP_INSTRUCTION2_TOKEN, COMMA_TOKEN, "", 49},
-   {NT_TRIOP_INSTRUCTION3_TOKEN, COMMA_TOKEN, "", 50},
-
-   {NT_TRIOP_TOKEN, MAD_TOKEN, "", 51},
-   {NT_SWZ_INSTRUCTION_TOKEN, SWZ_TOKEN, "", 52},
-   {NT_SWZ_INSTRUCTION2_TOKEN, COMMA_TOKEN, "", 53},
-
-   {NT_SCALAR_SRC_REG_TOKEN, PLUS_TOKEN, "", 54},
-   {NT_SCALAR_SRC_REG_TOKEN, MINUS_TOKEN, "", 54},
-   {NT_SCALAR_SRC_REG_TOKEN, VERTEX_TOKEN, "", 54},
-   {NT_SCALAR_SRC_REG_TOKEN, STATE_TOKEN, "", 54},
-   {NT_SCALAR_SRC_REG_TOKEN, PROGRAM_TOKEN, "", 54},
-   {NT_SCALAR_SRC_REG_TOKEN, LBRACE_TOKEN, "", 54},
-   {NT_SCALAR_SRC_REG_TOKEN, FLOAT_TOKEN, "-1", 54},
-   {NT_SCALAR_SRC_REG_TOKEN, INTEGER_TOKEN, "-1", 54},
-   {NT_SCALAR_SRC_REG_TOKEN, ID_TOKEN, "-1", 54},
-
-   {NT_SWIZZLE_SRC_REG_TOKEN, PLUS_TOKEN, "", 55},
-   {NT_SWIZZLE_SRC_REG_TOKEN, MINUS_TOKEN, "", 55},
-   {NT_SWIZZLE_SRC_REG_TOKEN, VERTEX_TOKEN, "", 55},
-   {NT_SWIZZLE_SRC_REG_TOKEN, STATE_TOKEN, "", 55},
-   {NT_SWIZZLE_SRC_REG_TOKEN, PROGRAM_TOKEN, "", 55},
-   {NT_SWIZZLE_SRC_REG_TOKEN, LBRACE_TOKEN, "", 55},
-   {NT_SWIZZLE_SRC_REG_TOKEN, FLOAT_TOKEN, "-1", 55},
-   {NT_SWIZZLE_SRC_REG_TOKEN, INTEGER_TOKEN, "-1", 55},
-   {NT_SWIZZLE_SRC_REG_TOKEN, ID_TOKEN, "-1", 55},
-
-   {NT_MASKED_DST_REG_TOKEN, ID_TOKEN, "-1", 56},
-   {NT_MASKED_DST_REG_TOKEN, RESULT_TOKEN, "", 56},
-   {NT_MASKED_ADDR_REG_TOKEN, ID_TOKEN, "-1", 57},
-
-   {NT_EXTENDED_SWIZZLE_TOKEN, PLUS_TOKEN, "", 58},
-   {NT_EXTENDED_SWIZZLE_TOKEN, MINUS_TOKEN, "", 58},
-   {NT_EXTENDED_SWIZZLE_TOKEN, INTEGER_TOKEN, "0", 58},
-   {NT_EXTENDED_SWIZZLE_TOKEN, INTEGER_TOKEN, "1", 58},
-   {NT_EXTENDED_SWIZZLE_TOKEN, ID_TOKEN, "x", 58},
-   {NT_EXTENDED_SWIZZLE_TOKEN, ID_TOKEN, "y", 58},
-   {NT_EXTENDED_SWIZZLE_TOKEN, ID_TOKEN, "z", 58},
-   {NT_EXTENDED_SWIZZLE_TOKEN, ID_TOKEN, "w", 58},
-
-   {NT_EXTENDED_SWIZZLE2_TOKEN, COMMA_TOKEN, "", 59},
-
-   {NT_EXT_SWIZ_COMP_TOKEN, PLUS_TOKEN, "", 60},
-   {NT_EXT_SWIZ_COMP_TOKEN, MINUS_TOKEN, "", 60},
-   {NT_EXT_SWIZ_COMP_TOKEN, INTEGER_TOKEN, "0", 60},
-   {NT_EXT_SWIZ_COMP_TOKEN, INTEGER_TOKEN, "1", 60},
-   {NT_EXT_SWIZ_COMP_TOKEN, ID_TOKEN, "x", 60},
-   {NT_EXT_SWIZ_COMP_TOKEN, ID_TOKEN, "y", 60},
-   {NT_EXT_SWIZ_COMP_TOKEN, ID_TOKEN, "z", 60},
-   {NT_EXT_SWIZ_COMP_TOKEN, ID_TOKEN, "w", 60},
-
-   {NT_EXT_SWIZ_SEL_TOKEN, INTEGER_TOKEN, "0", 61},
-   {NT_EXT_SWIZ_SEL_TOKEN, INTEGER_TOKEN, "1", 62},
-   {NT_EXT_SWIZ_SEL_TOKEN, ID_TOKEN, "x", 63},
-   {NT_EXT_SWIZ_SEL_TOKEN, ID_TOKEN, "y", 63},
-   {NT_EXT_SWIZ_SEL_TOKEN, ID_TOKEN, "z", 63},
-   {NT_EXT_SWIZ_SEL_TOKEN, ID_TOKEN, "w", 63},
-
-   /* Special case for 64 - 68 */
-
-   {NT_DST_REG_TOKEN, RESULT_TOKEN, "", 68},
-   {NT_VERTEX_ATTRIB_REG_TOKEN, ID_TOKEN, "-1", 69},
-   {NT_VERTEX_ATTRIB_REG_TOKEN, VERTEX_TOKEN, "", 70},
-   {NT_TEMPORARY_REG_TOKEN, ID_TOKEN, "-1", 71},
-
-   /* Special case for 72 - 73 */
-
-   {NT_PROG_PARAM_REG_TOKEN, STATE_TOKEN, "", 74},
-   {NT_PROG_PARAM_REG_TOKEN, PROGRAM_TOKEN, "", 74},
-   {NT_PROG_PARAM_REG_TOKEN, LBRACE_TOKEN, "", 74},
-   {NT_PROG_PARAM_REG_TOKEN, FLOAT_TOKEN, "-1", 74},
-
-   {NT_PROG_PARAM_SINGLE_TOKEN, ID_TOKEN, "-1", 75},
-   {NT_PROG_PARAM_ARRAY_TOKEN, ID_TOKEN, "-1", 76},
-   {NT_PROG_PARAM_ARRAY_MEM_TOKEN, INTEGER_TOKEN, "-1", 77},
-   {NT_PROG_PARAM_ARRAY_MEM_TOKEN, ID_TOKEN, "-1", 78},
-   {NT_PROG_PARAM_ARRAY_ABS_TOKEN, INTEGER_TOKEN, "-1", 79},
-   {NT_PROG_PARAM_ARRAY_REL_TOKEN, ID_TOKEN, "-1", 80},
-
-   {NT_ADDR_REG_REL_OFFSET_TOKEN, RBRACKET_TOKEN, "", 81},
-   {NT_ADDR_REG_REL_OFFSET_TOKEN, PLUS_TOKEN, "", 82},
-   {NT_ADDR_REG_REL_OFFSET_TOKEN, MINUS_TOKEN, "", 83},
-   {NT_ADDR_REG_POS_OFFSET_TOKEN, INTEGER_TOKEN, "-1", 84},
-   {NT_ADDR_REG_NEG_OFFSET_TOKEN, INTEGER_TOKEN, "-1", 85},
-
-
-   {NT_VERTEX_RESULT_REG_TOKEN, ID_TOKEN, "-1", 86},
-   {NT_VERTEX_RESULT_REG_TOKEN, RESULT_TOKEN, "", 87},
-   {NT_ADDR_REG_TOKEN, ID_TOKEN, "-1", 88},
-   {NT_ADDR_COMPONENT_TOKEN, PERIOD_TOKEN, "", 89},
-   {NT_ADDR_WRITE_MASK_TOKEN, PERIOD_TOKEN, "", 90},
-
-   {NT_SCALAR_SUFFIX_TOKEN, PERIOD_TOKEN, "", 91},
-
-   {NT_SWIZZLE_SUFFIX_TOKEN, COMMA_TOKEN, "", 92},
-   {NT_SWIZZLE_SUFFIX_TOKEN, SEMICOLON_TOKEN, "", 92},
-   {NT_SWIZZLE_SUFFIX_TOKEN, PERIOD_TOKEN, "", 317},
-
-   {NT_COMPONENT_TOKEN, ID_TOKEN, "x", 93},
-   {NT_COMPONENT_TOKEN, ID_TOKEN, "y", 94},
-   {NT_COMPONENT_TOKEN, ID_TOKEN, "z", 95},
-   {NT_COMPONENT_TOKEN, ID_TOKEN, "w", 96},
-
-   {NT_OPTIONAL_MASK_TOKEN, PERIOD_TOKEN, "", 97},
-   {NT_OPTIONAL_MASK_TOKEN, COMMA_TOKEN, "", 98},
-
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "x", 99},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "y", 100},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xy", 101},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "z", 102},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xz", 103},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "yz", 104},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xyz", 105},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "w", 106},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xw", 107},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "yw", 108},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xyw", 109},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "zw", 110},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xzw", 111},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "yzw", 112},
-   {NT_OPTIONAL_MASK2_TOKEN, ID_TOKEN, "xyzw", 113},
-
-
-   {NT_NAMING_STATEMENT_TOKEN, ATTRIB_TOKEN, "", 114},
-   {NT_NAMING_STATEMENT_TOKEN, PARAM_TOKEN, "", 115},
-   {NT_NAMING_STATEMENT_TOKEN, TEMP_TOKEN, "", 116},
-   {NT_NAMING_STATEMENT_TOKEN, ADDRESS_TOKEN, "", 117},
-   {NT_NAMING_STATEMENT_TOKEN, OUTPUT_TOKEN, "", 118},
-   {NT_NAMING_STATEMENT_TOKEN, ALIAS_TOKEN, "", 119},
-
-   {NT_ATTRIB_STATEMENT_TOKEN, ATTRIB_TOKEN, "", 120},
-   {NT_VTX_ATTRIB_BINDING_TOKEN, VERTEX_TOKEN, "", 121},
-
-   {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "position", 122},
-   {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "weight", 123},
-   {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "normal", 124},
-   {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "color", 125},
-   {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "fogcoord", 126},
-   {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "texcoord", 127},
-   {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "matrixindex", 128},
-   {NT_VTX_ATTRIB_ITEM_TOKEN, ID_TOKEN, "attrib", 129},
-
-   {NT_VTX_ATTRIB_NUM_TOKEN, INTEGER_TOKEN, "-1", 130},
-   {NT_VTX_OPT_WEIGHT_NUM_TOKEN, SEMICOLON_TOKEN, "", 131},
-   {NT_VTX_OPT_WEIGHT_NUM_TOKEN, COMMA_TOKEN, "", 131},
-   {NT_VTX_OPT_WEIGHT_NUM_TOKEN, PERIOD_TOKEN, "", 131},
-   {NT_VTX_OPT_WEIGHT_NUM_TOKEN, LBRACKET_TOKEN, "", 132},
-
-   {NT_VTX_WEIGHT_NUM_TOKEN, INTEGER_TOKEN, "-1", 133},
-   {NT_PARAM_STATEMENT_TOKEN, PARAM_TOKEN, "", 134},
-   {NT_PARAM_STATEMENT2_TOKEN, EQUAL_TOKEN, "", 135},
-   {NT_PARAM_STATEMENT2_TOKEN, LBRACKET_TOKEN, "", 136},
-
-   {NT_OPT_ARRAY_SIZE_TOKEN, RBRACKET_TOKEN, "", 137},
-   {NT_OPT_ARRAY_SIZE_TOKEN, INTEGER_TOKEN, "-1", 138},
-
-   {NT_PARAM_SINGLE_INIT_TOKEN, EQUAL_TOKEN, "", 139},
-   {NT_PARAM_MULTIPLE_INIT_TOKEN, EQUAL_TOKEN, "", 140},
-
-   {NT_PARAM_MULT_INIT_LIST_TOKEN, STATE_TOKEN, "", 141},
-   {NT_PARAM_MULT_INIT_LIST_TOKEN, PROGRAM_TOKEN, "", 141},
-   {NT_PARAM_MULT_INIT_LIST_TOKEN, PLUS_TOKEN, "", 141},
-   {NT_PARAM_MULT_INIT_LIST_TOKEN, MINUS_TOKEN, "", 141},
-   {NT_PARAM_MULT_INIT_LIST_TOKEN, FLOAT_TOKEN, "-1", 141},
-   {NT_PARAM_MULT_INIT_LIST_TOKEN, INTEGER_TOKEN, "-1", 141},
-   {NT_PARAM_MULT_INIT_LIST_TOKEN, LBRACE_TOKEN, "", 141},
-
-
-   {NT_PARAM_MULT_INIT_LIST2_TOKEN, COMMA_TOKEN, "", 142},
-   {NT_PARAM_MULT_INIT_LIST2_TOKEN, RBRACE_TOKEN, "", 143},
-
-
-   {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, STATE_TOKEN, "", 144},
-   {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, PROGRAM_TOKEN, "", 145},
-   {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, PLUS_TOKEN, "", 146},
-   {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, MINUS_TOKEN, "", 146},
-   {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, FLOAT_TOKEN, "-1", 146},
-   {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, INTEGER_TOKEN, "-1", 146},
-   {NT_PARAM_SINGLE_ITEM_DECL_TOKEN, LBRACE_TOKEN, "", 146},
-
-
-   {NT_PARAM_SINGLE_ITEM_USE_TOKEN, STATE_TOKEN, "", 147},
-   {NT_PARAM_SINGLE_ITEM_USE_TOKEN, PROGRAM_TOKEN, "", 148},
-   {NT_PARAM_SINGLE_ITEM_USE_TOKEN, LBRACE_TOKEN, "", 149},
-   {NT_PARAM_SINGLE_ITEM_USE_TOKEN, FLOAT_TOKEN, "-1", 149},
-   {NT_PARAM_SINGLE_ITEM_USE_TOKEN, INTEGER_TOKEN, "-1", 149},
-
-   {NT_PARAM_MULTIPLE_ITEM_TOKEN, STATE_TOKEN, "", 150},
-   {NT_PARAM_MULTIPLE_ITEM_TOKEN, PROGRAM_TOKEN, "", 151},
-   {NT_PARAM_MULTIPLE_ITEM_TOKEN, PLUS_TOKEN, "", 152},
-   {NT_PARAM_MULTIPLE_ITEM_TOKEN, MINUS_TOKEN, "", 152},
-   {NT_PARAM_MULTIPLE_ITEM_TOKEN, FLOAT_TOKEN, "-1", 152},
-   {NT_PARAM_MULTIPLE_ITEM_TOKEN, INTEGER_TOKEN, "-1", 152},
-   {NT_PARAM_MULTIPLE_ITEM_TOKEN, LBRACE_TOKEN, "", 152},
-
-   {NT_STATE_MULTIPLE_ITEM_TOKEN, STATE_TOKEN, "", 153},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "material", 154},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "light", 155},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "lightmodel", 156},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "lightprod", 157},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "texgen", 158},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "fog", 159},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "clip", 160},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "point", 161},
-   {NT_STATE_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "matrix", 162},
-
-   {NT_FOO_TOKEN, PERIOD_TOKEN, "", 163},
-   {NT_FOO_TOKEN, COMMA_TOKEN, "", 316},
-   {NT_FOO_TOKEN, RBRACE_TOKEN, "", 316},
-   {NT_FOO2_TOKEN, ID_TOKEN, "inverse", 164},
-   {NT_FOO2_TOKEN, ID_TOKEN, "transpose", 164},
-   {NT_FOO2_TOKEN, ID_TOKEN, "invtrans", 164},
-   {NT_FOO2_TOKEN, ID_TOKEN, "row", 165},
-   {NT_FOO3_TOKEN, COMMA_TOKEN, "", 166},
-   {NT_FOO3_TOKEN, RBRACE_TOKEN, "", 166},
-   {NT_FOO3_TOKEN, PERIOD_TOKEN, "", 167},
-
-   {NT_FOO35_TOKEN, INTEGER_TOKEN, "-1", 168},
-   {NT_FOO4_TOKEN, RBRACKET_TOKEN, "", 169},
-   {NT_FOO4_TOKEN, DOTDOT_TOKEN, "", 170},
-
-   {NT_STATE_SINGLE_ITEM_TOKEN, STATE_TOKEN, "", 171},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "material", 172},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "light", 173},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "lightmodel", 174},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "lightprod", 175},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "texgen", 176},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "fog", 177},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "clip", 178},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "point", 179},
-   {NT_STATE_SINGLE_ITEM2_TOKEN, ID_TOKEN, "matrix", 180},
-
-
-   {NT_STATE_MATERIAL_ITEM_TOKEN, ID_TOKEN, "material", 181},
-   {NT_STATE_MATERIAL_ITEM2_TOKEN, ID_TOKEN, "ambient", 182},
-   {NT_STATE_MATERIAL_ITEM2_TOKEN, ID_TOKEN, "diffuse", 182},
-   {NT_STATE_MATERIAL_ITEM2_TOKEN, ID_TOKEN, "specular", 182},
-   {NT_STATE_MATERIAL_ITEM2_TOKEN, ID_TOKEN, "emission", 182},
-   {NT_STATE_MATERIAL_ITEM2_TOKEN, ID_TOKEN, "shininess", 182},
-
-   {NT_STATE_MATERIAL_ITEM2_TOKEN, PERIOD_TOKEN, "", 183},
-   {NT_STATE_MAT_PROPERTY_TOKEN, ID_TOKEN, "ambient", 184},
-   {NT_STATE_MAT_PROPERTY_TOKEN, ID_TOKEN, "diffuse", 185},
-   {NT_STATE_MAT_PROPERTY_TOKEN, ID_TOKEN, "specular", 186},
-   {NT_STATE_MAT_PROPERTY_TOKEN, ID_TOKEN, "emission", 187},
-   {NT_STATE_MAT_PROPERTY_TOKEN, ID_TOKEN, "shininess", 188},
-
-
-   {NT_STATE_LIGHT_ITEM_TOKEN, ID_TOKEN, "light", 189},
-   {NT_STATE_LIGHT_ITEM2_TOKEN, RBRACKET_TOKEN, "", 190},
-
-
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "ambient", 191},
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "diffuse", 192},
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "specular", 193},
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "position", 194},
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "attenuation", 195},
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "spot", 196},
-   {NT_STATE_LIGHT_PROPERTY_TOKEN, ID_TOKEN, "half", 197},
-
-   {NT_STATE_SPOT_PROPERTY_TOKEN, ID_TOKEN, "direction", 198},
-   {NT_STATE_LIGHT_MODEL_ITEM_TOKEN, ID_TOKEN, "lightmodel", 199},
-
-
-   {NT_STATE_LMOD_PROPERTY_TOKEN, PERIOD_TOKEN, "", 200},
-   {NT_STATE_LMOD_PROPERTY2_TOKEN, ID_TOKEN, "ambient", 201},
-   {NT_STATE_LMOD_PROPERTY2_TOKEN, ID_TOKEN, "scenecolor", 202},
-   {NT_STATE_LMOD_PROPERTY2_TOKEN, ID_TOKEN, "front", 203},
-   {NT_STATE_LMOD_PROPERTY2_TOKEN, ID_TOKEN, "back", 203},
-
-
-   {NT_STATE_LIGHT_PROD_ITEM_TOKEN, ID_TOKEN, "lightprod", 204},
-   {NT_STATE_LIGHT_PROD_ITEM15_TOKEN, RBRACKET_TOKEN, "", 205},
-   {NT_STATE_LIGHT_PROD_ITEM2_TOKEN, ID_TOKEN, "ambient", 206},
-   {NT_STATE_LIGHT_PROD_ITEM2_TOKEN, ID_TOKEN, "diffuse", 206},
-   {NT_STATE_LIGHT_PROD_ITEM2_TOKEN, ID_TOKEN, "specular", 206},
-   {NT_STATE_LIGHT_PROD_ITEM2_TOKEN, ID_TOKEN, "front", 207},
-   {NT_STATE_LIGHT_PROD_ITEM2_TOKEN, ID_TOKEN, "back", 207},
-
-   {NT_STATE_LPROD_PROPERTY_TOKEN, ID_TOKEN, "ambient", 208},
-   {NT_STATE_LPROD_PROPERTY_TOKEN, ID_TOKEN, "diffuse", 209},
-   {NT_STATE_LPROD_PROPERTY_TOKEN, ID_TOKEN, "specular", 210},
-
-   {NT_STATE_LIGHT_NUMBER_TOKEN, INTEGER_TOKEN, "-1", 211},
-   {NT_STATE_TEX_GEN_ITEM_TOKEN, ID_TOKEN, "texgen", 212},
-   {NT_STATE_TEX_GEN_ITEM2_TOKEN, PERIOD_TOKEN, "", 213},
-   {NT_STATE_TEX_GEN_TYPE_TOKEN, ID_TOKEN, "eye", 214},
-   {NT_STATE_TEX_GEN_TYPE_TOKEN, ID_TOKEN, "object", 215},
-
-
-   {NT_STATE_TEX_GEN_COORD_TOKEN, ID_TOKEN, "s", 216},
-   {NT_STATE_TEX_GEN_COORD_TOKEN, ID_TOKEN, "t", 217},
-   {NT_STATE_TEX_GEN_COORD_TOKEN, ID_TOKEN, "r", 218},
-   {NT_STATE_TEX_GEN_COORD_TOKEN, ID_TOKEN, "q", 219},
-
-   {NT_STATE_FOG_ITEM_TOKEN, ID_TOKEN, "fog", 220},
-
-   {NT_STATE_FOG_PROPERTY_TOKEN, ID_TOKEN, "color", 221},
-   {NT_STATE_FOG_PROPERTY_TOKEN, ID_TOKEN, "params", 222},
-
-   {NT_STATE_CLIP_PLANE_ITEM_TOKEN, ID_TOKEN, "clip", 223},
-   {NT_STATE_CLIP_PLANE_ITEM2_TOKEN, RBRACKET_TOKEN, "", 224},
-   {NT_STATE_CLIP_PLANE_NUM_TOKEN, INTEGER_TOKEN, "-1", 225},
-   {NT_STATE_POINT_ITEM_TOKEN, ID_TOKEN, "point", 226},
-   {NT_STATE_POINT_PROPERTY_TOKEN, ID_TOKEN, "size", 227},
-   {NT_STATE_POINT_PROPERTY_TOKEN, ID_TOKEN, "attenuation", 228},
-
-
-   {NT_STATE_MATRIX_ROW_TOKEN, ID_TOKEN, "matrix", 229},
-   {NT_STATE_MATRIX_ROW15_TOKEN, PERIOD_TOKEN, "", 230},
-   {NT_STATE_MATRIX_ROW2_TOKEN, ID_TOKEN, "row", 231},
-   {NT_STATE_MATRIX_ROW2_TOKEN, ID_TOKEN, "inverse", 232},
-   {NT_STATE_MATRIX_ROW2_TOKEN, ID_TOKEN, "transpose", 232},
-   {NT_STATE_MATRIX_ROW2_TOKEN, ID_TOKEN, "invtrans", 232},
-   {NT_STATE_MATRIX_ROW3_TOKEN, LBRACKET_TOKEN, "", 233},
-
-   {NT_STATE_MAT_MODIFIER_TOKEN, ID_TOKEN, "inverse", 234},
-   {NT_STATE_MAT_MODIFIER_TOKEN, ID_TOKEN, "transpose", 235},
-   {NT_STATE_MAT_MODIFIER_TOKEN, ID_TOKEN, "invtrans", 236},
-   {NT_STATE_MATRIX_ROW_NUM_TOKEN, INTEGER_TOKEN, "-1", 237},
-
-
-   {NT_STATE_MATRIX_NAME_TOKEN, ID_TOKEN, "modelview", 238},
-   {NT_STATE_MATRIX_NAME_TOKEN, ID_TOKEN, "projection", 239},
-   {NT_STATE_MATRIX_NAME_TOKEN, ID_TOKEN, "mvp", 240},
-   {NT_STATE_MATRIX_NAME_TOKEN, ID_TOKEN, "texture", 241},
-   {NT_STATE_MATRIX_NAME_TOKEN, ID_TOKEN, "palette", 242},
-   {NT_STATE_MATRIX_NAME_TOKEN, PROGRAM_TOKEN, "", 243},
-
-   {NT_STATE_OPT_MOD_MAT_NUM_TOKEN, PERIOD_TOKEN, "", 244},
-   {NT_STATE_OPT_MOD_MAT_NUM_TOKEN, COMMA_TOKEN, "", 244},
-   {NT_STATE_OPT_MOD_MAT_NUM_TOKEN, RBRACE_TOKEN, "", 244},
-   {NT_STATE_OPT_MOD_MAT_NUM_TOKEN, LBRACKET_TOKEN, "", 245},
-
-   {NT_STATE_MOD_MAT_NUM_TOKEN, INTEGER_TOKEN, "-1", 246},
-   {NT_STATE_PALETTE_MAT_NUM_TOKEN, INTEGER_TOKEN, "-1", 247},
-   {NT_STATE_PROGRAM_MAT_NUM_TOKEN, INTEGER_TOKEN, "-1", 248},
-
-   {NT_PROGRAM_SINGLE_ITEM_TOKEN, PROGRAM_TOKEN, "", 249},
-   {NT_PROGRAM_SINGLE_ITEM2_TOKEN, ID_TOKEN, "env", 250},
-   {NT_PROGRAM_SINGLE_ITEM2_TOKEN, ID_TOKEN, "local", 251},
-
-
-   {NT_PROGRAM_MULTIPLE_ITEM_TOKEN, PROGRAM_TOKEN, "", 252},
-   {NT_PROGRAM_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "env", 253},
-   {NT_PROGRAM_MULTIPLE_ITEM2_TOKEN, ID_TOKEN, "local", 254},
-   {NT_PROG_ENV_PARAMS_TOKEN, ID_TOKEN, "env", 255},
-   {NT_PROG_ENV_PARAM_NUMS_TOKEN, INTEGER_TOKEN, "-1", 256},
-   {NT_PROG_ENV_PARAM_NUMS2_TOKEN, DOTDOT_TOKEN, "", 257},
-   {NT_PROG_ENV_PARAM_NUMS2_TOKEN, RBRACKET_TOKEN, "", 258},
-   {NT_PROG_ENV_PARAM_TOKEN, ID_TOKEN, "env", 259},
-
-   {NT_PROG_LOCAL_PARAMS_TOKEN, ID_TOKEN, "local", 260},
-   {NT_PROG_LOCAL_PARAM_NUMS_TOKEN, INTEGER_TOKEN, "-1", 261},
-   {NT_PROG_LOCAL_PARAM_NUMS2_TOKEN, DOTDOT_TOKEN, "", 262},
-   {NT_PROG_LOCAL_PARAM_NUMS2_TOKEN, RBRACKET_TOKEN, "", 263},
-   {NT_PROG_LOCAL_PARAM_TOKEN, ID_TOKEN, "local", 264},
-   {NT_PROG_ENV_PARAM_NUM_TOKEN, INTEGER_TOKEN, "-1", 265},
-   {NT_PROG_LOCAL_PARAM_NUM_TOKEN, INTEGER_TOKEN, "-1", 266},
-   {NT_PARAM_CONST_DECL_TOKEN, PLUS_TOKEN, "", 267},
-   {NT_PARAM_CONST_DECL_TOKEN, MINUS_TOKEN, "", 267},
-   {NT_PARAM_CONST_DECL_TOKEN, FLOAT_TOKEN, "-1", 267},
-   {NT_PARAM_CONST_DECL_TOKEN, INTEGER_TOKEN, "-1", 267},
-   {NT_PARAM_CONST_DECL_TOKEN, LBRACE_TOKEN, "", 268},
-
-   {NT_PARAM_CONST_USE_TOKEN, FLOAT_TOKEN, "-1", 269},
-   {NT_PARAM_CONST_USE_TOKEN, INTEGER_TOKEN, "-1", 269},
-   {NT_PARAM_CONST_USE_TOKEN, LBRACE_TOKEN, "", 270},
-
-
-   {NT_PARAM_CONST_SCALAR_DECL_TOKEN, PLUS_TOKEN, "", 271},
-   {NT_PARAM_CONST_SCALAR_DECL_TOKEN, MINUS_TOKEN, "", 271},
-   {NT_PARAM_CONST_SCALAR_DECL_TOKEN, FLOAT_TOKEN, "-1", 271},
-   {NT_PARAM_CONST_SCALAR_DECL_TOKEN, INTEGER_TOKEN, "-1", 271},
-
-   {NT_PARAM_CONST_SCALAR_USE_TOKEN, FLOAT_TOKEN, "-1", 272},
-   {NT_PARAM_CONST_SCALAR_USE_TOKEN, INTEGER_TOKEN, "-1", 272},
-   {NT_PARAM_CONST_VECTOR_TOKEN, LBRACE_TOKEN, "", 273},
-   {NT_PARAM_CONST_VECTOR2_TOKEN, RBRACE_TOKEN, "", 274},
-   {NT_PARAM_CONST_VECTOR2_TOKEN, COMMA_TOKEN, "", 275},
-   {NT_PARAM_CONST_VECTOR3_TOKEN, RBRACE_TOKEN, "", 276},
-   {NT_PARAM_CONST_VECTOR3_TOKEN, COMMA_TOKEN, "", 277},
-   {NT_PARAM_CONST_VECTOR4_TOKEN, RBRACE_TOKEN, "", 278},
-   {NT_PARAM_CONST_VECTOR4_TOKEN, COMMA_TOKEN, "", 279},
-
-   {NT_SIGNED_FLOAT_CONSTANT_TOKEN, PLUS_TOKEN, "", 280},
-   {NT_SIGNED_FLOAT_CONSTANT_TOKEN, MINUS_TOKEN, "", 280},
-   {NT_SIGNED_FLOAT_CONSTANT_TOKEN, FLOAT_TOKEN, "-1", 280},
-   {NT_SIGNED_FLOAT_CONSTANT_TOKEN, INTEGER_TOKEN, "-1", 280},
-
-   {NT_OPTIONAL_SIGN_TOKEN, FLOAT_TOKEN, "-1", 281},
-   {NT_OPTIONAL_SIGN_TOKEN, INTEGER_TOKEN, "0", 281},
-   {NT_OPTIONAL_SIGN_TOKEN, INTEGER_TOKEN, "1", 281},
-   {NT_OPTIONAL_SIGN_TOKEN, INTEGER_TOKEN, "-1", 281},
-   {NT_OPTIONAL_SIGN_TOKEN, ID_TOKEN, "-1", 281},
-   {NT_OPTIONAL_SIGN_TOKEN, STATE_TOKEN, "", 281},
-   {NT_OPTIONAL_SIGN_TOKEN, PROGRAM_TOKEN, "", 281},
-   {NT_OPTIONAL_SIGN_TOKEN, VERTEX_TOKEN, "", 281},
-   {NT_OPTIONAL_SIGN_TOKEN, LBRACE_TOKEN, "", 281},
-
-
-   {NT_OPTIONAL_SIGN_TOKEN, MINUS_TOKEN, "", 282},
-   {NT_OPTIONAL_SIGN_TOKEN, PLUS_TOKEN, "", 283},
-
-   {NT_TEMP_STATEMENT_TOKEN, TEMP_TOKEN, "", 284},
-   {NT_ADDRESS_STATEMENT_TOKEN, ADDRESS_TOKEN, "", 285},
-
-   /* Special case 286-7 */
-
-   {NT_OUTPUT_STATEMENT_TOKEN, OUTPUT_TOKEN, "", 288},
-   {NT_RESULT_BINDING_TOKEN, RESULT_TOKEN, "", 289},
-   {NT_RESULT_BINDING2_TOKEN, ID_TOKEN, "position", 290},
-   {NT_RESULT_BINDING2_TOKEN, ID_TOKEN, "fogcoord", 291},
-   {NT_RESULT_BINDING2_TOKEN, ID_TOKEN, "pointsize", 292},
-   {NT_RESULT_BINDING2_TOKEN, ID_TOKEN, "color", 293},
-   {NT_RESULT_BINDING2_TOKEN, ID_TOKEN, "texcoord", 294},
-
-   {NT_RESULT_COL_BINDING_TOKEN, ID_TOKEN, "color", 295},
-
-   /* Special case 296-7 */
-
-   {NT_RESULT_COL_BINDING3_TOKEN, ID_TOKEN, "front", 298},
-   {NT_RESULT_COL_BINDING3_TOKEN, ID_TOKEN, "back", 299},
-
-   /* Special case 300-301 */
-
-   {NT_RESULT_COL_BINDING5_TOKEN, ID_TOKEN, "primary", 302},
-   {NT_RESULT_COL_BINDING5_TOKEN, ID_TOKEN, "secondary", 303},
-   {NT_OPT_FACE_TYPE2_TOKEN, ID_TOKEN, "front", 304},
-   {NT_OPT_FACE_TYPE2_TOKEN, ID_TOKEN, "back", 305},
-
-   /* Special case 306-7 */
-
-   {NT_OPT_COLOR_TYPE2_TOKEN, ID_TOKEN, "primary", 308},
-   {NT_OPT_COLOR_TYPE2_TOKEN, ID_TOKEN, "secondary", 309},
-
-   {NT_OPT_TEX_COORD_NUM_TOKEN, PERIOD_TOKEN, "", 310},
-   {NT_OPT_TEX_COORD_NUM_TOKEN, SEMICOLON_TOKEN, "", 310},
-   {NT_OPT_TEX_COORD_NUM_TOKEN, COMMA_TOKEN, "", 310},
-   {NT_OPT_TEX_COORD_NUM_TOKEN, RBRACE_TOKEN, "", 310},
-   {NT_OPT_TEX_COORD_NUM_TOKEN, LBRACKET_TOKEN, "", 311},
-
-   {NT_TEX_COORD_NUM_TOKEN, INTEGER_TOKEN, "-1", 312},
-
-   /* Special case for 313 to get aliasing correct */
-
-   {NT_ESTABLISH_NAME_TOKEN, ID_TOKEN, "-1", 314},
-   {NT_ESTABLISHED_NAME_TOKEN, ID_TOKEN, "-1", 315},
-
-   /* Special case for 318-9 */
-};
-
-static GLint nprods = sizeof(ptab) / sizeof(prod_table);
-static GLint nlas = sizeof(latab) / sizeof(look_ahead_table);
-
-/** 
- * This is a gigantic FSA to recognize the keywords put forth in the
- * GL_ARB_vertex_program spec. 
- *
- * All other tokens are deemed 'identifiers', and shoved into the 
- * identifier symbol table (as opposed to the GLint and GLfloat symbol tables)
- *
- * \param s                            The parse state
- * \param token                The next token seen is returned in this value
- * \param token_attr   The token attribute for the next token is returned here. This
- *                    is the index into the approprate symbol table if token is INTEGER_TOKEN,
- *                    FLOAT_TOKEN, or ID_TOKEN
- *                   
- * \return ARB_VP_ERROR on lex error, ARB_VP_SUCESS on sucess
- */
-static GLint
-get_next_token(parse_state * s, GLint * token, GLint * token_attr)
-{
-   GLubyte curr;
-
-   while (s->start_pos < s->len) {
-      curr = s->str[s->curr_pos];
-
-      switch (s->curr_state) {
-        /* Default state */
-      case STATE_BASE:
-        if (IS_WHITESPACE(curr)) {
-           s->start_pos++;
-           s->curr_pos++;
-        }
-        else {
-           if (IS_IDCHAR(curr)) {
-              switch (curr) {
-              case 'A':
-                 ADV_TO_STATE(STATE_A);
-                 break;
-
-              case 'D':
-                 ADV_TO_STATE(STATE_D);
-                 break;
-
-              case 'E':
-                 ADV_TO_STATE(STATE_E);
-                 break;
-
-              case 'F':
-                 ADV_TO_STATE(STATE_F);
-                 break;
-
-              case 'L':
-                 ADV_TO_STATE(STATE_L);
-                 break;
-
-              case 'M':
-                 ADV_TO_STATE(STATE_M);
-                 break;
-
-              case 'O':
-                 ADV_TO_STATE(STATE_O);
-                 break;
-
-              case 'P':
-                 ADV_TO_STATE(STATE_P);
-                 break;
-
-              case 'R':
-                 ADV_TO_STATE(STATE_R);
-                 break;
-
-              case 'S':
-                 ADV_TO_STATE(STATE_S);
-                 break;
-
-              case 'T':
-                 ADV_TO_STATE(STATE_T);
-                 break;
-
-              case 'X':
-                 ADV_TO_STATE(STATE_X);
-                 break;
-
-              case 'p':
-                 ADV_TO_STATE(STATE_LC_P);
-                 break;
-
-              case 'r':
-                 ADV_TO_STATE(STATE_LC_R);
-                 break;
-
-              case 's':
-                 ADV_TO_STATE(STATE_LC_S);
-                 break;
-
-              case 'v':
-                 ADV_TO_STATE(STATE_LC_V);
-                 break;
-
-              default:
-                 s->curr_state = 1;
-                 s->start_pos = s->curr_pos;
-                 s->curr_pos++;
-              }
-           }
-           else if (IS_DIGIT(curr)) {
-              ADV_TO_STATE(STATE_N4);
-           }
-           else {
-              switch (curr) {
-              case '#':
-                 ADV_TO_STATE(STATE_COMMENT);
-                 break;
-              case ';':
-                 ADV_AND_FINISH(SEMICOLON_TOKEN);
-                 break;
-              case ',':
-                 ADV_AND_FINISH(COMMA_TOKEN);
-                 break;
-              case '+':
-                 ADV_AND_FINISH(PLUS_TOKEN);
-                 break;
-              case '-':
-                 ADV_AND_FINISH(MINUS_TOKEN);
-                 break;
-              case '[':
-                 ADV_AND_FINISH(LBRACKET_TOKEN);
-                 break;
-              case ']':
-                 ADV_AND_FINISH(RBRACKET_TOKEN);
-                 break;
-              case '{':
-                 ADV_AND_FINISH(LBRACE_TOKEN);
-                 break;
-              case '}':
-                 ADV_AND_FINISH(RBRACE_TOKEN);
-                 break;
-              case '=':
-                 ADV_AND_FINISH(EQUAL_TOKEN);
-                 break;
-
-              case '.':
-                 ADV_TO_STATE(STATE_N1);
-                 break;
-
-              default:
-                 return ARB_VP_ERROR;
-                 break;
-              }
-           }
-        }
-        break;
-
-
-        /* Main identifier state */
-      case STATE_IDENT:
-        if (IS_CD(curr)) {
-           s->curr_pos++;
-        }
-        else {
-           *token = ID_TOKEN;
-           *token_attr =
-              id_table_add(&s->idents, s->str, s->start_pos, s->curr_pos);
-
-           s->curr_state = 0;
-           s->start_pos = s->curr_pos;
-           return ARB_VP_SUCESS;
-        }
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the A* keywords
-         */
-      case STATE_A:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case 'B':
-              ADV_TO_STATE(STATE_AB);
-              break;
-           case 'D':
-              ADV_TO_STATE(STATE_AD);
-              break;
-           case 'L':
-              ADV_TO_STATE(STATE_AL);
-              break;
-           case 'R':
-              ADV_TO_STATE(STATE_AR);
-              break;
-           case 'T':
-              ADV_TO_STATE(STATE_AT);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_AB:
-        ADV_OR_FALLBACK('S', STATE_ABS);
-        break;
-
-      case STATE_ABS:
-        FINISH_OR_FALLBACK(ABS_TOKEN);
-        break;
-
-      case STATE_AD:
-        ADV_OR_FALLBACK('D', STATE_ADD);
-        break;
-
-      case STATE_ADD:
-        if (curr == 'R') {
-           ADV_TO_STATE(STATE_ADDR);
-        }
-        else if (IS_CD(curr)) {
-           ADV_TO_STATE(STATE_IDENT);
-        }
-        else {
-           FINISH(ADD_TOKEN);
-        }
-        break;
-
-      case STATE_ADDR:
-        ADV_OR_FALLBACK('E', STATE_ADDRE);
-        break;
-
-      case STATE_ADDRE:
-        ADV_OR_FALLBACK('S', STATE_ADDRES);
-        break;
-
-      case STATE_ADDRES:
-        ADV_OR_FALLBACK('S', STATE_ADDRESS);
-        break;
-
-      case STATE_ADDRESS:
-        FINISH_OR_FALLBACK(ADDRESS_TOKEN);
-        break;
-
-      case STATE_AL:
-        ADV_OR_FALLBACK('I', STATE_ALI);
-        break;
-
-      case STATE_ALI:
-        ADV_OR_FALLBACK('A', STATE_ALIA);
-        break;
-
-      case STATE_ALIA:
-        ADV_OR_FALLBACK('S', STATE_ALIAS);
-        break;
-
-      case STATE_ALIAS:
-        FINISH_OR_FALLBACK(ALIAS_TOKEN);
-        break;
-
-      case STATE_AR:
-        ADV_OR_FALLBACK('L', STATE_ARL);
-        break;
-
-      case STATE_ARL:
-        FINISH_OR_FALLBACK(ARL_TOKEN);
-        break;
-
-      case STATE_AT:
-        ADV_OR_FALLBACK('T', STATE_ATT);
-        break;
-
-      case STATE_ATT:
-        ADV_OR_FALLBACK('R', STATE_ATTR);
-        break;
-
-      case STATE_ATTR:
-        ADV_OR_FALLBACK('I', STATE_ATTRI);
-        break;
-
-      case STATE_ATTRI:
-        ADV_OR_FALLBACK('B', STATE_ATTRIB);
-        break;
-
-      case STATE_ATTRIB:
-        FINISH_OR_FALLBACK(ATTRIB_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the D* keywords
-         */
-      case STATE_D:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case 'P':
-              ADV_TO_STATE(STATE_DP);
-              break;
-           case 'S':
-              ADV_TO_STATE(STATE_DS);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_DP:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case '3':
-              ADV_TO_STATE(STATE_DP3);
-              break;
-           case '4':
-              ADV_TO_STATE(STATE_DP4);
-              break;
-           case 'H':
-              ADV_TO_STATE(STATE_DPH);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_DP3:
-        FINISH_OR_FALLBACK(DP3_TOKEN);
-        break;
-
-      case STATE_DP4:
-        FINISH_OR_FALLBACK(DP4_TOKEN);
-        break;
-
-      case STATE_DPH:
-        FINISH_OR_FALLBACK(DPH_TOKEN);
-        break;
-
-      case STATE_DS:
-        ADV_OR_FALLBACK('T', STATE_DST);
-        break;
-
-      case STATE_DST:
-        FINISH_OR_FALLBACK(DST_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the E* keywords
-         */
-      case STATE_E:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case 'N':
-              ADV_TO_STATE(STATE_EN);
-              break;
-           case 'X':
-              ADV_TO_STATE(STATE_EX);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_EN:
-        ADV_OR_FALLBACK('D', STATE_END);
-        break;
-
-      case STATE_END:
-        FINISH_OR_FALLBACK(END_TOKEN);
-        break;
-
-      case STATE_EX:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case '2':
-              ADV_TO_STATE(STATE_EX2);
-              break;
-           case 'P':
-              ADV_TO_STATE(STATE_EXP);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_EX2:
-        FINISH_OR_FALLBACK(EX2_TOKEN);
-        break;
-
-      case STATE_EXP:
-        FINISH_OR_FALLBACK(EXP_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the F* keywords
-         */
-      case STATE_F:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case 'L':
-              ADV_TO_STATE(STATE_FL);
-              break;
-           case 'R':
-              ADV_TO_STATE(STATE_FR);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_FL:
-        ADV_OR_FALLBACK('R', STATE_FLR);
-        break;
-
-      case STATE_FLR:
-        FINISH_OR_FALLBACK(FLR_TOKEN);
-        break;
-
-      case STATE_FR:
-        ADV_OR_FALLBACK('C', STATE_FRC);
-        break;
-
-      case STATE_FRC:
-        FINISH_OR_FALLBACK(FRC_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the L* keywords
-         */
-      case STATE_L:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case 'G':
-              ADV_TO_STATE(STATE_LG);
-              break;
-           case 'I':
-              ADV_TO_STATE(STATE_LI);
-              break;
-           case 'O':
-              ADV_TO_STATE(STATE_LO);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_LG:
-        ADV_OR_FALLBACK('2', STATE_LG2);
-        break;
-
-      case STATE_LG2:
-        FINISH_OR_FALLBACK(LG2_TOKEN);
-        break;
-
-      case STATE_LI:
-        ADV_OR_FALLBACK('T', STATE_LIT);
-        break;
-
-      case STATE_LIT:
-        FINISH_OR_FALLBACK(LIT_TOKEN);
-        break;
-
-      case STATE_LO:
-        ADV_OR_FALLBACK('G', STATE_LOG);
-        break;
-
-      case STATE_LOG:
-        FINISH_OR_FALLBACK(LOG_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the M* keywords
-         */
-      case STATE_M:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case 'A':
-              ADV_TO_STATE(STATE_MA);
-              break;
-           case 'I':
-              ADV_TO_STATE(STATE_MI);
-              break;
-           case 'O':
-              ADV_TO_STATE(STATE_MO);
-              break;
-           case 'U':
-              ADV_TO_STATE(STATE_MU);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_MA:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case 'D':
-              ADV_TO_STATE(STATE_MAD);
-              break;
-           case 'X':
-              ADV_TO_STATE(STATE_MAX);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_MAD:
-        FINISH_OR_FALLBACK(MAD_TOKEN);
-        break;
-
-      case STATE_MAX:
-        FINISH_OR_FALLBACK(MAX_TOKEN);
-        break;
-
-      case STATE_MI:
-        ADV_OR_FALLBACK('N', STATE_MIN);
-        break;
-
-      case STATE_MIN:
-        FINISH_OR_FALLBACK(MIN_TOKEN);
-        break;
-
-      case STATE_MO:
-        ADV_OR_FALLBACK('V', STATE_MOV);
-        break;
-
-      case STATE_MOV:
-        FINISH_OR_FALLBACK(MOV_TOKEN);
-        break;
-
-      case STATE_MU:
-        ADV_OR_FALLBACK('L', STATE_MUL);
-        break;
-
-      case STATE_MUL:
-        FINISH_OR_FALLBACK(MUL_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the O* keywords
-         */
-      case STATE_O:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case 'P':
-              ADV_TO_STATE(STATE_OP);
-              break;
-           case 'U':
-              ADV_TO_STATE(STATE_OU);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_OP:
-        ADV_OR_FALLBACK('T', STATE_OPT);
-        break;
-
-      case STATE_OPT:
-        ADV_OR_FALLBACK('I', STATE_OPTI);
-        break;
-
-      case STATE_OPTI:
-        ADV_OR_FALLBACK('O', STATE_OPTIO);
-        break;
-
-      case STATE_OPTIO:
-        ADV_OR_FALLBACK('N', STATE_OPTION);
-        break;
-
-      case STATE_OPTION:
-        FINISH_OR_FALLBACK(OPTION_TOKEN);
-        break;
-
-      case STATE_OU:
-        ADV_OR_FALLBACK('T', STATE_OUT);
-        break;
-
-      case STATE_OUT:
-        ADV_OR_FALLBACK('P', STATE_OUTP);
-        break;
-
-      case STATE_OUTP:
-        ADV_OR_FALLBACK('U', STATE_OUTPU);
-        break;
-
-      case STATE_OUTPU:
-        ADV_OR_FALLBACK('T', STATE_OUTPUT);
-        break;
-
-      case STATE_OUTPUT:
-        FINISH_OR_FALLBACK(OUTPUT_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the P* keywords
-         */
-      case STATE_P:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case 'A':
-              ADV_TO_STATE(STATE_PA);
-              break;
-           case 'O':
-              ADV_TO_STATE(STATE_PO);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_PA:
-        ADV_OR_FALLBACK('R', STATE_PAR);
-        break;
-
-      case STATE_PAR:
-        ADV_OR_FALLBACK('A', STATE_PARA);
-        break;
-
-      case STATE_PARA:
-        ADV_OR_FALLBACK('M', STATE_PARAM);
-        break;
-
-      case STATE_PARAM:
-        FINISH_OR_FALLBACK(PARAM_TOKEN);
-        break;
-
-      case STATE_PO:
-        ADV_OR_FALLBACK('W', STATE_POW);
-        break;
-
-      case STATE_POW:
-        FINISH_OR_FALLBACK(POW_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the R* keywords
-         */
-      case STATE_R:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case 'C':
-              ADV_TO_STATE(STATE_RC);
-              break;
-           case 'S':
-              ADV_TO_STATE(STATE_RS);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_RC:
-        ADV_OR_FALLBACK('P', STATE_RCP);
-        break;
-
-      case STATE_RCP:
-        FINISH_OR_FALLBACK(RCP_TOKEN);
-        break;
-
-      case STATE_RS:
-        ADV_OR_FALLBACK('Q', STATE_RSQ);
-        break;
-
-      case STATE_RSQ:
-        FINISH_OR_FALLBACK(RSQ_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the S* keywords
-         */
-      case STATE_S:
-        if (IS_CD(curr)) {
-           switch (curr) {
-           case 'G':
-              ADV_TO_STATE(STATE_SG);
-              break;
-           case 'L':
-              ADV_TO_STATE(STATE_SL);
-              break;
-           case 'U':
-              ADV_TO_STATE(STATE_SU);
-              break;
-           case 'W':
-              ADV_TO_STATE(STATE_SW);
-              break;
-           default:
-              ADV_TO_STATE(STATE_IDENT);
-              break;
-           }
-        }
-        else {
-           s->curr_state = 1;
-        }
-        break;
-
-      case STATE_SG:
-        ADV_OR_FALLBACK('E', STATE_SGE);
-        break;
-
-      case STATE_SGE:
-        FINISH_OR_FALLBACK(SGE_TOKEN);
-        break;
-
-      case STATE_SL:
-        ADV_OR_FALLBACK('T', STATE_SLT);
-        break;
-
-      case STATE_SLT:
-        FINISH_OR_FALLBACK(SLT_TOKEN);
-        break;
-
-      case STATE_SU:
-        ADV_OR_FALLBACK('B', STATE_SUB);
-        break;
-
-      case STATE_SUB:
-        FINISH_OR_FALLBACK(SUB_TOKEN);
-        break;
-
-      case STATE_SW:
-        ADV_OR_FALLBACK('Z', STATE_SWZ);
-        break;
-
-      case STATE_SWZ:
-        FINISH_OR_FALLBACK(SWZ_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the T* keywords
-         */
-      case STATE_T:
-        ADV_OR_FALLBACK('E', STATE_TE);
-        break;
-
-      case STATE_TE:
-        ADV_OR_FALLBACK('M', STATE_TEM);
-        break;
-
-      case STATE_TEM:
-        ADV_OR_FALLBACK('P', STATE_TEMP);
-        break;
-
-      case STATE_TEMP:
-        FINISH_OR_FALLBACK(TEMP_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the X* keywords
-         */
-      case STATE_X:
-        ADV_OR_FALLBACK('P', STATE_XP);
-        break;
-
-      case STATE_XP:
-        ADV_OR_FALLBACK('D', STATE_XPD);
-        break;
-
-      case STATE_XPD:
-        FINISH_OR_FALLBACK(XPD_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the p* keywords
-         */
-      case STATE_LC_P:
-        ADV_OR_FALLBACK('r', STATE_LC_PR);
-        break;
-
-      case STATE_LC_PR:
-        ADV_OR_FALLBACK('o', STATE_LC_PRO);
-        break;
-
-      case STATE_LC_PRO:
-        ADV_OR_FALLBACK('g', STATE_LC_PROG);
-        break;
-
-      case STATE_LC_PROG:
-        ADV_OR_FALLBACK('r', STATE_LC_PROGR);
-        break;
-
-      case STATE_LC_PROGR:
-        ADV_OR_FALLBACK('a', STATE_LC_PROGRA);
-        break;
-
-      case STATE_LC_PROGRA:
-        ADV_OR_FALLBACK('m', STATE_LC_PROGRAM);
-        break;
-
-      case STATE_LC_PROGRAM:
-        FINISH_OR_FALLBACK(PROGRAM_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the r* keywords
-         */
-      case STATE_LC_R:
-        ADV_OR_FALLBACK('e', STATE_LC_RE);
-        break;
-
-      case STATE_LC_RE:
-        ADV_OR_FALLBACK('s', STATE_LC_RES);
-        break;
-
-      case STATE_LC_RES:
-        ADV_OR_FALLBACK('u', STATE_LC_RESU);
-        break;
-
-      case STATE_LC_RESU:
-        ADV_OR_FALLBACK('l', STATE_LC_RESUL);
-        break;
-
-      case STATE_LC_RESUL:
-        ADV_OR_FALLBACK('t', STATE_LC_RESULT);
-        break;
-
-      case STATE_LC_RESULT:
-        FINISH_OR_FALLBACK(RESULT_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the s* keywords
-         */
-      case STATE_LC_S:
-        ADV_OR_FALLBACK('t', STATE_LC_ST);
-        break;
-
-      case STATE_LC_ST:
-        ADV_OR_FALLBACK('a', STATE_LC_STA);
-        break;
-
-      case STATE_LC_STA:
-        ADV_OR_FALLBACK('t', STATE_LC_STAT);
-        break;
-
-      case STATE_LC_STAT:
-        ADV_OR_FALLBACK('e', STATE_LC_STATE);
-        break;
-
-      case STATE_LC_STATE:
-        FINISH_OR_FALLBACK(STATE_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the v* keywords
-         */
-      case STATE_LC_V:
-        ADV_OR_FALLBACK('e', STATE_LC_VE);
-        break;
-
-      case STATE_LC_VE:
-        ADV_OR_FALLBACK('r', STATE_LC_VER);
-        break;
-
-      case STATE_LC_VER:
-        ADV_OR_FALLBACK('t', STATE_LC_VERT);
-        break;
-
-      case STATE_LC_VERT:
-        ADV_OR_FALLBACK('e', STATE_LC_VERTE);
-        break;
-
-      case STATE_LC_VERTE:
-        ADV_OR_FALLBACK('x', STATE_LC_VERTEX);
-        break;
-
-      case STATE_LC_VERTEX:
-        FINISH_OR_FALLBACK(VERTEX_TOKEN);
-        break;
-
-        /* -----------------------------------------------------
-         *  Beginning of the number & comment FSAs
-         */
-      case STATE_N1:
-        if (curr == '.') {
-           ADV_TO_STATE(STATE_N2);
-        }
-        else if (IS_DIGIT(curr)) {
-           ADV_TO_STATE(STATE_N3);
-        }
-        else {
-           /*ADV_AND_FINISH(PERIOD_TOKEN);                                 */
-           FINISH(PERIOD_TOKEN);
-        }
-        break;
-
-      case STATE_N2:
-#if 1
-        /*ADV_AND_FINISH(DOTDOT_TOKEN);*/
-        FINISH(DOTDOT_TOKEN);
-#else
-        FINISH(PERIOD_TOKEN);
-#endif
-        break;
-
-      case STATE_N3:
-        if (IS_DIGIT(curr)) {
-           ADV_TO_STATE(STATE_N3);
-        }
-        else if ((curr == 'E') || (curr == 'e')) {
-           ADV_TO_STATE(STATE_N5);
-        }
-        else if (curr == '.') {
-           /* Blech! we have something like 1.. -> have to backup */
-           s->curr_pos -= 1;
-           *token_attr =
-              int_table_add(&s->ints, s->str, s->start_pos, s->curr_pos);
-           FINISH(INTEGER_TOKEN);
-        }
-        else {
-           *token_attr =
-              float_table_add(&s->floats, s->str, s->start_pos, s->curr_pos);
-           /*ADV_AND_FINISH(FLOAT_TOKEN);*/
-           FINISH(FLOAT_TOKEN);
-        }
-        break;
-
-      case STATE_N4:
-        if (IS_DIGIT(curr)) {
-           ADV_TO_STATE(STATE_N4);
-        }
-        else if ((curr == 'E') || (curr == 'e')) {
-           ADV_TO_STATE(STATE_N5);
-        }
-        else if (curr == '.') {
-           ADV_TO_STATE(STATE_N3);
-        }
-        else {
-           *token_attr =
-              int_table_add(&s->ints, s->str, s->start_pos, s->curr_pos);
-           /*ADV_AND_FINISH(INTEGER_TOKEN);*/
-           FINISH(INTEGER_TOKEN);
-        }
-        break;
-
-      case STATE_N5:
-        if (IS_DIGIT(curr)) {
-           ADV_TO_STATE(STATE_N6);
-        }
-        else if ((curr == '+') || (curr == '-')) {
-           ADV_TO_STATE(STATE_N7)
-        }
-        else {
-           return ARB_VP_ERROR;
-        }
-        break;
-
-      case STATE_N6:
-        if (IS_DIGIT(curr)) {
-           ADV_TO_STATE(STATE_N6);
-        }
-        else {
-           *token_attr =
-              float_table_add(&s->floats, s->str, s->start_pos, s->curr_pos);
-           /*ADV_AND_FINISH(FLOAT_TOKEN);*/
-           FINISH(FLOAT_TOKEN);
-        }
-        break;
-
-      case STATE_N7:
-        if (IS_DIGIT(curr)) {
-           ADV_TO_STATE(STATE_N6);
-        }
-        else {
-           return ARB_VP_ERROR;
-        }
-
-        break;
-
-      case STATE_COMMENT:
-        if ((curr == '\n') || (curr == '\r')) {
-           s->start_pos = s->curr_pos + 1;
-           s->curr_pos++;
-           s->curr_state = 0;
-        }
-        else {
-           ADV_TO_STATE(STATE_COMMENT);
-        }
-      }
-   }
-
-   *token = EOF_TOKEN;
-   return ARB_VP_SUCESS;
-}
-
-/**
- * This does the same as get_next_token(), but it does not advance the 
- * position pointers (Err, rather it does, but then it resets them)
- *
- * \param s          The parse state
- * \param token      The next token seen is returned in this value
- * \param token_attr   The token attribute for the next token is returned here. This
- *                    is the index into the approprate symbol table if token is INTEGER_TOKEN,
- *                    FLOAT_TOKEN, or ID_TOKEN
- * \param how_many   How many tokens to peek ahead
- *                   
- * \return ARB_VP_ERROR on lex error, ARB_VP_SUCESS on sucess
- */
-static GLint
-peek_next_token(parse_state * s, GLint * token, GLint * token_attr,
-               GLint how_many)
-{
-   GLint tmp_state = s->curr_state;
-   GLint tmp_sp = s->start_pos;
-   GLint tmp_cp = s->curr_pos;
-   GLint a, retval;
-
-   for (a = 0; a < how_many; a++) {
-      retval = get_next_token(s, token, token_attr);
-
-      if (retval == ARB_VP_ERROR)
-        return retval;
-   }
-
-   s->curr_state = tmp_state;
-   s->start_pos = tmp_sp;
-   s->curr_pos = tmp_cp;
-
-   return retval;
-}
-
-/**
- * Print out the value of a token
- */
-static void
-debug_token(parse_state * state, GLint t, GLint ta)
-{
-   switch (t) {
-   case EOF_TOKEN:
-      printf("EOF\n");
-      break;
-   case ID_TOKEN:
-      printf("|%s|  ", state->idents.data[ta]);
-      break;
-   case INTEGER_TOKEN:
-      printf("|%d|  ", state->ints.data[ta]);
-      break;
-   case FLOAT_TOKEN:
-      printf("|%f|  ", state->floats.data[ta]);
-      break;
-
-   case ABS_TOKEN:
-      printf("ABS  ");
-      break;
-   case ADD_TOKEN:
-      printf("ADD  ");
-      break;
-   case ADDRESS_TOKEN:
-      printf("ADDRESS  ");
-      break;
-   case ALIAS_TOKEN:
-      printf("ALIAS  ");
-      break;
-   case ARL_TOKEN:
-      printf("ARL  ");
-      break;
-   case ATTRIB_TOKEN:
-      printf("ATTRIB  ");
-      break;
-
-   case DP3_TOKEN:
-      printf("DP3  ");
-      break;
-   case DP4_TOKEN:
-      printf("DP4  ");
-      break;
-   case DPH_TOKEN:
-      printf("DPH  ");
-      break;
-   case DST_TOKEN:
-      printf("DST  ");
-      break;
-
-   case END_TOKEN:
-      printf("END  ");
-      break;
-   case EX2_TOKEN:
-      printf("EX2  ");
-      break;
-   case EXP_TOKEN:
-      printf("EXP  ");
-      break;
-
-   case FLR_TOKEN:
-      printf("FLR  ");
-      break;
-   case FRC_TOKEN:
-      printf("FRC  ");
-      break;
-
-   case LG2_TOKEN:
-      printf("LG2  ");
-      break;
-   case LIT_TOKEN:
-      printf("LIT  ");
-      break;
-   case LOG_TOKEN:
-      printf("LOG  ");
-      break;
-
-   case MAD_TOKEN:
-      printf("MAD  ");
-      break;
-   case MAX_TOKEN:
-      printf("MAX  ");
-      break;
-   case MIN_TOKEN:
-      printf("MIN  ");
-      break;
-   case MOV_TOKEN:
-      printf("MOV  ");
-      break;
-   case MUL_TOKEN:
-      printf("MUL  ");
-      break;
-
-   case OPTION_TOKEN:
-      printf("OPTION  ");
-      break;
-   case OUTPUT_TOKEN:
-      printf("OUTPUT  ");
-      break;
-
-   case PARAM_TOKEN:
-      printf("PARAM  ");
-      break;
-   case POW_TOKEN:
-      printf("POW  ");
-      break;
-
-   case RCP_TOKEN:
-      printf("RCP  ");
-      break;
-   case RSQ_TOKEN:
-      printf("RSQ  ");
-      break;
-
-   case SGE_TOKEN:
-      printf("SGE  ");
-      break;
-   case SLT_TOKEN:
-      printf("SLT  ");
-      break;
-   case SUB_TOKEN:
-      printf("SUB  ");
-      break;
-   case SWZ_TOKEN:
-      printf("SWZ  ");
-      break;
-
-   case TEMP_TOKEN:
-      printf("TEMP  ");
-      break;
-
-   case XPD_TOKEN:
-      printf("XPD  ");
-      break;
-
-   case SEMICOLON_TOKEN:
-      printf(";  ");
-      break;
-   case COMMA_TOKEN:
-      printf(",  ");
-      break;
-   case PLUS_TOKEN:
-      printf("+  ");
-      break;
-   case MINUS_TOKEN:
-      printf("-  ");
-      break;
-   case PERIOD_TOKEN:
-      printf(".  ");
-      break;
-   case DOTDOT_TOKEN:
-      printf("..  ");
-      break;
-   case LBRACKET_TOKEN:
-      printf("[  ");
-      break;
-   case RBRACKET_TOKEN:
-      printf("]  ");
-      break;
-   case LBRACE_TOKEN:
-      printf("{  ");
-      break;
-   case RBRACE_TOKEN:
-      printf("}  ");
-      break;
-   case EQUAL_TOKEN:
-      printf("=  ");
-      break;
-
-   case PROGRAM_TOKEN:
-      printf("program ");
-      break;
-   case RESULT_TOKEN:
-      printf("result ");
-      break;
-   case STATE_TOKEN:
-      printf("state ");
-      break;
-   case VERTEX_TOKEN:
-      printf("vertex ");
-      break;
-   default:
-      printf("Unknown token type %d\n", t);
-   }
-}
-
-/**
- * Setup the state used by the parser / lex 
- *
- * \param str  The program string, with the !!ARBvp1.0 token stripped off
- * \param len  The lenght of the given string
- *
- * \return             A parse_state struct to keep track of all the things we need while parsing
- */
-static parse_state *
-parse_state_init(GLubyte * str, GLint len)
-{
-   parse_state *s = (parse_state *) _mesa_malloc(sizeof(parse_state));
-
-   s->str = _mesa_strdup((char *) str);
-   s->len = len;
-   s->curr_pos = 0;
-   s->start_pos = 0;
-
-   s->curr_state = 0;
-
-   s->idents.len = 0;
-   s->idents.data = NULL;
-
-   s->ints.len = 0;
-   s->ints.data = NULL;
-
-   s->floats.len = 0;
-   s->floats.data = NULL;
-   printf("%s\n", s->str);
-
-   s->binds.len = 0;
-   s->binds.type = NULL;
-   s->binds.offset = NULL;
-   s->binds.row = NULL;
-   s->binds.consts = NULL;
-
-   s->arrays.len = 0;
-   s->arrays.num_elements = NULL;
-   s->arrays.data = NULL;
-
-   s->stack_head = NULL;
-   s->stack_free_list = NULL;
-
-   s->pt_head = NULL;
-
-   return s;
-}
-
-/**
- * This frees all the things we hold while parsing.
- *
- * \param s            The struct created by parse_state_init()
- */
-static void
-parse_state_cleanup(parse_state * s)
-{
-   GLint a;
-   token_list *tl, *next;
-
-   /* Free our copy of the string [Mesa has its own] */
-   _mesa_free(s->str);
-
-   /* Free all the tables ident, int, float, bind, mat */
-   _mesa_free(s->idents.type);
-   _mesa_free(s->idents.attr);
-   for (a = 0; a < s->idents.len; a++)
-      _mesa_free(s->idents.data[a]);
-
-   _mesa_free(s->ints.data);
-   _mesa_free(s->floats.data);
-
-   _mesa_free(s->arrays.num_elements);
-   for (a = 0; a < s->arrays.len; a++)
-      _mesa_free(s->arrays.data[a]);
-
-   _mesa_free(s->binds.type);
-   _mesa_free(s->binds.offset);
-   _mesa_free(s->binds.row);
-   _mesa_free(s->binds.num_rows);
-   _mesa_free(s->binds.reg_num);
-#if 0
-   for (a = 0; a < s->binds.len; a++) {
-      printf("6: %d/%d\n", a, s->binds.len - 1);
-      _mesa_free(s->binds.consts[a]);
-   }
-#endif
-
-   /* Free the stack */
-   tl = s->stack_head;
-   while (tl) {
-      next = tl->next;
-      free(tl);
-      tl = next;
-   }
-   tl = s->stack_free_list;
-   while (tl) {
-      next = tl->next;
-      free(tl);
-      tl = next;
-   }
-   printf("freed stack free list\n");
-
-#if 0
-   /* Free the parse tree */
-   parse_tree_free_children(s->pt_head);
-   printf("freed parse_tree\n");
-#endif
-   free(s);
-   printf("freed state\n");
-}
-
-/**
- *     Alloc a new node for a parse tree.
- *
- *     \return An empty node to fill and stick into the parse tree
- */
-static parse_tree_node *
-parse_tree_node_init(void)
-{
-   GLint a;
-   parse_tree_node *pt;
-
-   pt = (parse_tree_node *) _mesa_malloc(sizeof(parse_tree_node));
-   pt->tok = -1;
-   pt->tok_attr = -1;
-   pt->is_terminal = 0;
-   pt->prod_applied = -1;
-
-   for (a = 0; a < 4; a++)
-      pt->children[a] = NULL;
-
-   return pt;
-}
-
-/**
- * We maintain a stack of nonterminals used for predictive parsing. To keep
- * from thrashing malloc/free, we keep a free list of token_list structs
- * to be used for this stack. This function is called to refill the free
- * list, when we try to grab a new token_list struct, and find that there are none
- * available
- *
- * \param s    The parse state
- */
-static void
-_fill_free_list(parse_state * s)
-{
-   GLint a;
-   token_list *tl;
-
-   if (s->stack_free_list)
-      return;
-
-   for (a = 0; a < 20; a++) {
-      tl = (token_list *) _mesa_malloc(sizeof(token_list));
-
-      tl->next = s->stack_free_list;
-      s->stack_free_list = tl;
-   }
-}
-
-/**
- * Peek at the head of the nonterminal stack,
- *
- * \param s          The parse state
- * \param token      Return for the nonterminal token on the top of the stack
- * \param token_attr Return for the the token attribute on the top of the stack
- *
- * \return ARB_VP_ERROR on an empty stack [not necessarily a bad thing], else ARB_VP_SUCESS
- */
-static GLint
-_stack_peek(parse_state * s, GLint * token, GLint * token_attr)
-{
-   if (!s->stack_head) {
-      fprintf(stderr, "ACK! Empty stack on peek!\n");
-      return ARB_VP_ERROR;
-   }
-
-   *token = s->stack_head->tok;
-   *token_attr = s->stack_head->tok_attr;
-
-   return ARB_VP_SUCESS;
-}
-
-/**
- * Remove the token at the head of the nonterminal stack
- * \param s          The parse state
- * \param token      Return for the nonterminal token on the top of the stack
- * \param token_attr Return for the the token attribute on the top of the stack
- * \param ptn        Return for a pointer to the place in the parse tree where 
- *                    the token lives
- *
- * \return           ARB_VP_ERROR on an empty stack [not necessarily a bad thing], else ARB_VP_SUCESS
- */
-static GLint
-_stack_pop(parse_state * s, GLint * token, GLint * token_attr,
-          parse_tree_node ** ptn)
-{
-   token_list *tl;
-
-   if (!s->stack_head) {
-      fprintf(stderr, "ACK! Empty stack!\n");
-      return ARB_VP_ERROR;
-   }
-
-   *token = s->stack_head->tok;
-   *token_attr = s->stack_head->tok_attr;
-   if (ptn)
-      *ptn = s->stack_head->pt;
-   tl = s->stack_head;
-
-   s->stack_head = tl->next;
-   tl->next = s->stack_free_list;
-   s->stack_free_list = tl;
-
-   return ARB_VP_SUCESS;
-}
-
-/**
- * Put a token, its attribute, and the the parse tree node where the token is stored, onto
- * the parse stack.
- * 
- * \param s          The parse state
- * \param token      Return for the nonterminal token on the top of the stack
- * \param token_attr Return for the the token attribute on the top of the stack
- * \param ptn        Return for a pointer to the place in the parse tree where 
- *                    the token lives
- *
- * \return           ARB_VP_ERROR on out of memory while allocing more storage for the stack,
- *                    else ARB_VP_SUCESS
- */
-static GLint
-_stack_push(parse_state * s, GLint token, GLint token_attr,
-           parse_tree_node * ptn)
-{
-   token_list *tl;
-
-   if (!s->stack_free_list) {
-      _fill_free_list(s);
-      if (!s->stack_free_list) {
-        fprintf(stderr, "ACK! Error filling stack free list\n");
-        return ARB_VP_ERROR;
-      }
-   }
-
-   tl = s->stack_free_list;
-
-   s->stack_free_list = tl->next;
-
-   tl->tok = token;
-   tl->tok_attr = token_attr;
-   tl->pt = ptn;
-   tl->next = s->stack_head;
-
-   s->stack_head = tl;
-
-   return ARB_VP_SUCESS;
-}
-
-/**
- * Allocate a new entry in the array table
- *
- * \param tab   The array table to add a new element too
- *
- * \return      The index into the array table where the new element is.
- */
-static GLint
-array_table_new(array_table * tab)
-{
-   GLint idx;
-   if (tab->len == 0) {
-      tab->num_elements = (GLint *) _mesa_malloc(sizeof(GLint));
-      tab->data = (GLint **) _mesa_malloc(sizeof(GLint *));
-      idx = 0;
-   }
-   else {
-      tab->num_elements =
-        (GLint *) _mesa_realloc(tab->num_elements, tab->len * sizeof(GLint),
-                                (tab->len + 1) * sizeof(GLint));
-      tab->data =
-        (GLint **) _mesa_realloc(tab->data, tab->len * sizeof(GLint *),
-                                 (tab->len + 1) * sizeof(GLint *));
-      idx = tab->len;
-   }
-
-   tab->len++;
-   tab->num_elements[idx] = 0;
-   tab->data[idx] = NULL;
-
-   return idx;
-}
-
-/**
- * Add a new element to a array in a array table
- *
- * \param tab   The array table
- * \param idx   The index into the array table of the array we want to append an item onto
- * \param data  The program parameter that goes into the idx-th array 
- */
-static void
-array_table_add_data(array_table * tab, GLint idx, GLint data)
-{
-   if ((idx < 0) || (idx >= tab->len)) {
-      printf("Bad matrix index %d!\n", idx);
-      return;
-   }
-
-   if (tab->data[idx] == NULL) {
-      tab->data[idx] = (GLint *) _mesa_malloc(sizeof(GLint));
-   }
-   else {
-      tab->data[idx] =
-        (GLint *) _mesa_realloc(tab->data[idx],
-                                tab->num_elements[idx] * sizeof(GLint),
-                                (tab->num_elements[idx] +
-                                 1) * sizeof(GLint));
-   }
-
-   tab->data[idx][tab->num_elements[idx]] = data;
-   tab->num_elements[idx]++;
-}
-
-
-/**
- * This adds a new entry into the binding table. 
- *
- * \param tab    The binding table
- * \param type   The type of the state
- * \param offset For matrix bindings, e.g. MATRIXROWS_MODELVIEW, this gives the matrix number. 
- *               For PROGRAM_ENV_* and PROGRAM_LOCAL_* bindings, this gives the number of the first parameter
- *               
- * \param row    For MATRIXROWS bindings, this is the first row in the matrix we're bound to
- * \param nrows  For MATRIXROWS bindings, this is the number of rows of the matrix we have. 
- *               For PROGRAM_ENV/LOCAL bindings, this is the number of parameters in the array we're bound to
- * \param values For CONSTANT bindings, these are the constant values we're bound to
- * \return       The index into the binding table where this state is bound
- */
-static GLint
-binding_table_add(binding_table * tab, GLint type, GLint offset, GLint row,
-                 GLint nrows, GLfloat * values)
-{
-   GLint key, a;
-
-   key = tab->len;
-
-   /* test for existance */
-   for (a = 0; a < tab->len; a++) {
-      if ((tab->type[a] == type) && (tab->offset[a] == offset)
-         && (tab->row[a] == row) && (tab->num_rows[a] == nrows) &&
-         (fabs(tab->consts[a][0] - values[0]) < .0001) &&
-         (fabs(tab->consts[a][1] - values[1]) < .0001) &&
-         (fabs(tab->consts[a][2] - values[2]) < .0001) &&
-         (fabs(tab->consts[a][3] - values[3]) < .0001))
-        return a;
-   }
-
-   if (tab->len == 0) {
-      tab->type = (GLint *) _mesa_malloc(sizeof(GLint));
-      tab->offset = (GLint *) _mesa_malloc(sizeof(GLint));
-      tab->row = (GLint *) _mesa_malloc(sizeof(GLint));
-      tab->num_rows = (GLint *) _mesa_malloc(sizeof(GLint));
-      tab->consts = (GLfloat **) _mesa_malloc(sizeof(GLfloat *));
-      tab->consts[0] = (GLfloat *) _mesa_malloc(4 * sizeof(GLfloat));
-      tab->reg_num = (GLint *) _mesa_malloc(sizeof(GLint));
-   }
-   else {
-      tab->type =
-        (GLint *) _mesa_realloc(tab->type, tab->len * sizeof(GLint),
-                                (tab->len + 1) * sizeof(GLint));
-      tab->offset =
-        (GLint *) _mesa_realloc(tab->offset, tab->len * sizeof(GLint),
-                                (tab->len + 1) * sizeof(GLint));
-      tab->row =
-        (GLint *) _mesa_realloc(tab->row, tab->len * sizeof(GLint),
-                                (tab->len + 1) * sizeof(GLint));
-      tab->num_rows =
-        (GLint *) _mesa_realloc(tab->num_rows, tab->len * sizeof(GLint),
-                                (tab->len + 1) * sizeof(GLint));
-      tab->consts =
-        (GLfloat **) _mesa_realloc(tab->consts, tab->len * sizeof(GLfloat),
-                                   (tab->len + 1) * sizeof(GLfloat *));
-      tab->consts[tab->len] = (GLfloat *) _mesa_malloc(4 * sizeof(GLfloat));
-      tab->reg_num =
-        (GLint *) _mesa_realloc(tab->reg_num, tab->len * sizeof(GLint),
-                                (tab->len + 1) * sizeof(GLint));
-   }
-
-   tab->type[key] = type;
-   tab->offset[key] = offset;
-   tab->row[key] = row;                /*key;*/
-   tab->num_rows[key] = nrows;
-   tab->reg_num[key] = 0;
-   _mesa_memcpy(tab->consts[key], values, 4 * sizeof(GLfloat));
-   tab->len++;
-
-   return key;
-}
-
-/** 
- * Given a string and a start/end point, add a string into the float
- * symbol table (and convert it into a float)
- *
- * If we already have this GLfloat in the table, don't bother
- * adding another, just return the key to the existing one
- *
- * \param tab     The float table
- * \param str     The string containing the float
- * \param start   The starting position of the float in str
- * \param end     The ending position of the float in str
- *
- * \return        The index of the float, after we insert it, in the float table
- */
-static GLint
-float_table_add(float_table *tab, const char *str, GLint start, GLint end)
-{
-   GLint key, a;
-   GLubyte *newstr;
-
-   key = tab->len;
-
-   newstr = (GLubyte *) _mesa_malloc(end - start + 2);
-   _mesa_memset(newstr, 0, end - start + 2);
-   _mesa_memcpy(newstr, str + start, end - start);
-
-   /* test for existance */
-   for (a = 0; a < tab->len; a++) {
-      if (tab->data[a] == atof((char *) newstr)) {
-        _mesa_free(newstr);
-        return a;
-      }
-   }
-
-   if (tab->len == 0) {
-      tab->data = (GLdouble *) _mesa_malloc(sizeof(GLdouble));
-   }
-   else {
-      tab->data =
-        (GLdouble *) _mesa_realloc(tab->data, tab->len * sizeof(GLdouble),
-                                   (tab->len + 1) * sizeof(GLdouble));
-   }
-
-   tab->data[key] = atof((char *) newstr);
-   tab->len++;
-
-   _mesa_free(newstr);
-   return key;
-}
-
-/** 
- * Given a string and a start/end point, add a string into the int
- * symbol table (and convert it into a int)
- *
- * If we already have this int in the table, don't bother
- * adding another, just return the key to the existing one
- *
- * \param tab     The int table
- * \param str     The string containing the int
- * \param start   The starting position of the int in str
- * \param end     The ending position of the int in str
- *
- * \return        The index of the int, after we insert it, in the int table
- */
-static GLint
-int_table_add(int_table * tab, const char *str, GLint start, GLint end)
-{
-   GLint key, a;
-   char *newstr;
-
-   key = tab->len;
-
-   newstr = (char *) _mesa_malloc(end - start + 2);
-   _mesa_memset(newstr, 0, end - start + 2);
-   _mesa_memcpy(newstr, str + start, end - start);
-
-   for (a = 0; a < tab->len; a++) {
-      if (tab->data[a] == _mesa_atoi(newstr)) {
-        _mesa_free(newstr);
-        return a;
-      }
-   }
-
-   if (tab->len == 0) {
-      tab->data = (GLint *) _mesa_malloc(sizeof(GLint));
-   }
-   else {
-      tab->data =
-        (GLint *) _mesa_realloc(tab->data, tab->len * sizeof(GLint),
-                                (tab->len + 1) * sizeof(GLint));
-   }
-
-   tab->data[key] = _mesa_atoi(newstr);
-   tab->len++;
-
-   _mesa_free(newstr);
-   return key;
-}
-
-/**
- * Insert an identifier into the identifier symbol table
- * 
- * If we already have this id in the table, don't bother
- * adding another, just return the key to the existing one
- *
- * If we already have this id in the table, and it has been
- * initialized to an ALIAS, return what the alias points
- * to, not the alias var
- *
- * \param tab    The ID table
- * \param str    The string containing the id
- * \param start  The position in str where the id begins
- * \param end    The position in str where the id ends
- *
- * \return       either:
- *                1) The index into the id table where the id is
- *                2) The index into the id table where the alias of id, if we already have id
- *                     in the table, and it has been initialized to type ALIAS
- */
-static GLint
-id_table_add(id_table * tab, const char * str, GLint start, GLint end)
-{
-   GLint key, a;
-   GLubyte *newstr;
-
-   key = tab->len;
-
-   if (tab->len == 0) {
-      tab->data = (GLubyte **) _mesa_malloc(sizeof(GLubyte *));
-      tab->type = (GLint *) _mesa_malloc(sizeof(GLint));
-      tab->attr = (GLint *) _mesa_malloc(sizeof(GLint));
-   }
-   else {
-      tab->data =
-        (GLubyte **) _mesa_realloc(tab->data, tab->len * sizeof(GLubyte *),
-                                   (tab->len + 1) * sizeof(GLubyte *));
-      tab->type =
-        (GLint *) _mesa_realloc(tab->type, tab->len * sizeof(GLint),
-                                (tab->len + 1) * sizeof(GLint));
-      tab->attr =
-        (GLint *) _mesa_realloc(tab->attr, tab->len * sizeof(GLint),
-                                (tab->len + 1) * sizeof(GLint));
-   }
-
-   /*tab->type[key] = TYPE_NONE;*/
-
-   newstr = (GLubyte *) _mesa_malloc((end - start + 2) * sizeof(GLubyte));
-   _mesa_memset(newstr, 0, end - start + 2);
-   _mesa_memcpy(newstr, str + start, end - start);
-
-   for (a = 0; a < tab->len; a++) {
-      /* aha! we found it in the table */
-      if (!_mesa_strcmp((char *) tab->data[a], (char *) newstr)) {
-        _mesa_free(newstr);
-
-        key = a;
-        while ((tab->type[key] == TYPE_ALIAS) && (tab->attr[key] != -1)) {
-           printf("----------- %s is an alias, renaming to %s\n",
-                  tab->data[key], tab->data[tab->attr[key]]);
-           key = tab->attr[key];
-        }
-
-        return key;
-      }
-   }
-
-   /* oh, we really have a new id */
-   tab->data[key] = newstr;
-   tab->type[key] = TYPE_NONE;
-   tab->attr[key] = -1;
-   tab->len++;
-
-   return key;
-}
-
-/*#define SHOW_STEPS 1*/
-
-
-/**
- * Apply the specified production number to the parse state. This handles
- * looking at the production table and sticking new tokens onto the 
- * parse stack. 
- *
- * It also handles the construction of the parse tree
- *
- * \param s   The parse state
- * \param num The production number to apply [the idx in the production table]
- *
- */
-static void
-apply_production(parse_state * s, int num)
-{
-   GLint a, str_key, stack_tok, stack_tok_attr;
-   GLint tok, nnptr = 0;
-   parse_tree_node *ptn;
-   parse_tree_node *pt_ptr_new[4];
-
-   (void) _stack_pop(s, &stack_tok, &stack_tok_attr, &ptn);
-   /*printf("apply prod %d\n", num); */
-
-   ptn->prod_applied = num;
-   for (a = 3; a >= 0; a--) {
-      str_key = 0;
-      tok = ptab[num].rhs[a];
-
-      if (tok == NULL_TOKEN)
-        continue;
-
-      /* If we are pushing an identifier or a number, we need to translate the string literal
-       * in the production table into an entry in the approprate symbol table
-       */
-      if (tok == ID_TOKEN) {
-        str_key = id_table_add(&s->idents, ptab[num].key[a], 0,
-                        _mesa_strlen(ptab[num].key[a]));
-      }
-      else if (tok == INTEGER_TOKEN) {
-        str_key = int_table_add(&s->ints, ptab[num].key[a], 0,
-                         _mesa_strlen(ptab[num].key[a]));
-      }
-      else if (tok == FLOAT_TOKEN) {
-        str_key = float_table_add(&s->floats, ptab[num].key[a], 0,
-                           _mesa_strlen(ptab[num].key[a]));
-      }
-
-      /* "-1" is a wildcard flag, accept any id/float/int */
-      if ((!_mesa_strcmp(ptab[num].key[a], "-1")) &&
-         ((tok == FLOAT_TOKEN) || (tok == INTEGER_TOKEN)
-          || (tok == ID_TOKEN))) {
-        pt_ptr_new[nnptr] = parse_tree_node_init();
-        pt_ptr_new[nnptr]->is_terminal = 0;
-        pt_ptr_new[nnptr]->tok = tok;
-        pt_ptr_new[nnptr]->tok_attr = str_key;
-        nnptr++;
-        _stack_push(s, ptab[num].rhs[a], str_key, pt_ptr_new[nnptr - 1]);
-      }
-      else if (tok >= NT_PROGRAM_TOKEN) {
-        pt_ptr_new[nnptr] = parse_tree_node_init();
-        pt_ptr_new[nnptr]->is_terminal = 0;
-        pt_ptr_new[nnptr]->tok = tok;
-        nnptr++;
-        _stack_push(s, ptab[num].rhs[a], str_key, pt_ptr_new[nnptr - 1]);
-      }
-      else
-        _stack_push(s, ptab[num].rhs[a], str_key, NULL);
-   }
-
-   tok = 0;
-   if (ptn) {
-      /*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]); */
-
-      for (a = nnptr - 1; a >= 0; a--) {
-        ptn->children[tok] = pt_ptr_new[a];
-        /*printf("%x->children[%d] = %x\n", ptn, tok, pt_ptr_new[a]); */
-        tok++;
-      }
-   }
-}
-
-/**
- * Here we initialize a bunch of variables to a given type (e.g. TEMP). 
- *
- * We stick the variable type into the 0-th element in the var_queue array, followed by var_queue_size
- * indicies into the identifier table which designate the variables we are to init.
- * 
- * \param s              The parse state
- * \param var_queue      The queue of variables to initialize. The first element in the array is variable
- *                        type. It is followed by var_queue_size indicies into the identifier table 
- *                        who we are supposed to init to type var_queue[0].
- * \param var_queue_size The number of variables listed in var_queue[].
- *
- * \return               ARB_VP_ERROR if we have already initilized a variable in var_queue, otherwise
- *                        ARB_VP_SUCESS
- */
-static GLint
-init_vars(parse_state * s, GLint * var_queue, GLint var_queue_size)
-{
-   GLint a;
-
-   a = 1;
-   while (a < var_queue_size) {
-      /* Make sure we haven't already init'd this var. This will
-       * catch multiple definations of the same symbol
-       */
-      if (s->idents.type[var_queue[a]] != TYPE_NONE) {
-        printf("%s already init'd! (%d)\n", s->idents.data[var_queue[a]],
-               s->idents.type[var_queue[a]]);
-        return ARB_VP_ERROR;
-      }
-
-      s->idents.type[var_queue[a]] = var_queue[0];
-      s->idents.attr[var_queue[a]] = -1;
-      a++;
-   }
-
-   return ARB_VP_SUCESS;
-}
-
-/**
- * The main parsing loop. This applies productions and builds the parse tree.
- *
- * \param s    The parse state
- *
- * \return ARB_VP_ERROR on a parse error, else ARB_VP_SUCESS
- */
-static GLint
-parse(parse_state * s)
-{
-   GLint input_tok, input_tok_attr;
-   GLint stack_tok, stack_tok_attr;
-   GLint peek_tok, peek_tok_attr, ret;
-   GLint idx, str_key;
-   GLint var_queue_size = 0;
-   GLint *var_queue;
-   parse_tree_node *ptn, *ptn2;
-
-   /* This should be MAX_VAR + 1 */
-   var_queue = (GLint *) _mesa_malloc(1000 * sizeof(int));
-
-   s->stack_head = NULL;
-
-   /* init the system by pushing the start symbol onto the stack */
-   ptn = parse_tree_node_init();
-   ptn->is_terminal = 0;
-   ptn->tok = NT_PROGRAM_TOKEN;
-   s->pt_head = ptn;
-   _stack_push(s, NT_PROGRAM_TOKEN, 0, ptn);
-
-   /* and get the first token */
-   if (get_next_token(s, &input_tok, &input_tok_attr) == ARB_VP_ERROR) {
-      fprintf(stderr, "LEX ERROR!!\n");
-      return ARB_VP_ERROR;
-   }
-
-   while (1) {
-      GLint la, is_nonterm;
-
-      /* If the stack is empty, and we've eaten all the input, we're done */
-      if ((_stack_peek(s, &stack_tok, &stack_tok_attr) == ARB_VP_ERROR) &&
-         (input_tok == EOF_TOKEN))
-        break;
-
-#ifdef SHOW_STEPS
-      printf("stack: %d input: ", stack_tok);
-      debug_token(s, input_tok, input_tok_attr);
-      printf("\n");
-#endif
-
-      /* We [may] have a non-terminal on top of the stack, apply
-       * productions!
-       */
-      switch (stack_tok) {
-        /* Special case non-terminals */
-
-        /* productions 64-66 */
-      case NT_SRC_REG_TOKEN:
-        if ((input_tok == VERTEX_TOKEN) ||
-            ((input_tok == ID_TOKEN)
-             && (s->idents.type[input_tok_attr] == TYPE_ATTRIB))) {
-           apply_production(s, 64);
-        }
-        else
-           if ((input_tok == ID_TOKEN)
-               && (s->idents.type[input_tok_attr] == TYPE_TEMP)) {
-           apply_production(s, 65);
-        }
-        else
-           if ((input_tok == STATE_TOKEN) ||
-               (input_tok == PROGRAM_TOKEN) ||
-               (input_tok == LBRACE_TOKEN) ||
-               (input_tok == FLOAT_TOKEN) ||
-               (input_tok == INTEGER_TOKEN) ||
-               ((input_tok == ID_TOKEN)
-                && (s->idents.type[input_tok_attr] == TYPE_PARAM_SINGLE))
-               || ((input_tok == ID_TOKEN)
-                   && (s->idents.type[input_tok_attr] ==
-                       TYPE_PARAM_ARRAY))) {
-           apply_production(s, 66);
-        }
-        else {
-           return ARB_VP_ERROR;
-        }
-        break;
-
-        /* productions 67-68 */
-      case NT_DST_REG_TOKEN:
-        /* We can only write to result.*, TEMP vars, or OUTPUT vars */
-        if (input_tok == RESULT_TOKEN) {
-           apply_production(s, 68);
-        }
-        else if (input_tok == ID_TOKEN) {
-           if (s->idents.type[input_tok_attr] == TYPE_TEMP) {
-              apply_production(s, 67);
-           }
-           else if (s->idents.type[input_tok_attr] == TYPE_OUTPUT) {
-              apply_production(s, 68);
-           }
-           else {
-              return ARB_VP_ERROR;
-           }
-        }
-        else {
-           return ARB_VP_ERROR;
-        }
-        break;
-
-        /* productions 72-4 */
-      case NT_PROG_PARAM_REG_TOKEN:
-        if ((input_tok == ID_TOKEN)
-            && (s->idents.type[input_tok_attr] == TYPE_PARAM_SINGLE)) {
-           apply_production(s, 72);
-        }
-        else
-           if ((input_tok == ID_TOKEN)
-               && (s->idents.type[input_tok_attr] == TYPE_PARAM_ARRAY)) {
-           apply_production(s, 73);
-        }
-        else
-           if ((input_tok == STATE_TOKEN) ||
-               (input_tok == PROGRAM_TOKEN) ||
-               (input_tok == FLOAT_TOKEN) ||
-               (input_tok == INTEGER_TOKEN) || (input_tok == LBRACE_TOKEN)) {
-           apply_production(s, 74);
-        }
-        else {
-           return ARB_VP_ERROR;
-        }
-        break;
-
-        /* productions 286-7 */
-      case NT_VAR_NAME_LIST_TOKEN:
-        ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
-
-        var_queue[var_queue_size] = input_tok_attr;
-        var_queue_size++;
-
-        if ((ret == ARB_VP_ERROR) || (peek_tok != COMMA_TOKEN)) {
-           apply_production(s, 286);
-
-           /* Dump the var_queue & assign types */
-           if (init_vars(s, var_queue, var_queue_size) == ARB_VP_ERROR)
-              return ARB_VP_ERROR;
-        }
-        else {
-           apply_production(s, 287);
-        }
-        break;
-
-        /* productions 296-7 */
-      case NT_RESULT_COL_BINDING2_TOKEN:
-        if ((input_tok == SEMICOLON_TOKEN) || (input_tok == COMMA_TOKEN)) {
-           apply_production(s, 296);
-        }
-        else if (input_tok == PERIOD_TOKEN) {
-           ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
-           if ((peek_tok == ID_TOKEN) &&
-               ((!_mesa_strcmp((char *) s->idents.data[peek_tok_attr], "back")) ||
-                (!_mesa_strcmp((char *) s->idents.data[peek_tok_attr], "front")))) {
-              apply_production(s, 297);
-           }
-           else {
-              apply_production(s, 296);
-           }
-        }
-        else {
-           return ARB_VP_ERROR;
-        }
-        break;
-
-        /* productions 300-1 */
-      case NT_RESULT_COL_BINDING4_TOKEN:
-        if ((input_tok == SEMICOLON_TOKEN) || (input_tok == COMMA_TOKEN)) {
-           apply_production(s, 300);
-        }
-        else if (input_tok == PERIOD_TOKEN) {
-           ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
-           if ((ret == ARB_VP_SUCESS) && (peek_tok == ID_TOKEN) &&
-               ((!_mesa_strcmp((char *) s->idents.data[peek_tok_attr], "primary")) ||
-                (!_mesa_strcmp((char *) s->idents.data[peek_tok_attr], "secondary"))))
-           {
-              apply_production(s, 301);
-           }
-           else {
-              apply_production(s, 300);
-           }
-        }
-        else {
-           return ARB_VP_ERROR;
-        }
-        break;
-
-        /* productions 306-7 */
-      case NT_OPT_COLOR_TYPE_TOKEN:
-        if ((input_tok == SEMICOLON_TOKEN) || (input_tok == COMMA_TOKEN)) {
-           apply_production(s, 307);
-        }
-        else if (input_tok == PERIOD_TOKEN) {
-           ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
-           if ((ret == ARB_VP_SUCESS) && (peek_tok == ID_TOKEN) &&
-               ((!_mesa_strcmp((char *) s->idents.data[peek_tok_attr], "primary")) ||
-                (!_mesa_strcmp((char *) s->idents.data[peek_tok_attr], "secondary"))))
-           {
-              apply_production(s, 306);
-           }
-           else {
-              apply_production(s, 307);
-           }
-        }
-        else {
-           return ARB_VP_ERROR;
-        }
-        break;
-
-        /* production 313 -- Do this so we can mangle IDs as they are 
-         *                                              added into the ID table for the lex
-         */
-      case NT_ALIAS_STATEMENT_TOKEN:
-        if (input_tok == ALIAS_TOKEN) {
-           GLint alias_to;
-
-           apply_production(s, 313);
-
-           /* stack ALIAS */
-           var_queue_size = 1;
-           var_queue[0] = TYPE_ALIAS;
-           ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
-           var_queue[var_queue_size] = peek_tok_attr;
-           var_queue_size++;
-
-           if (init_vars(s, var_queue, var_queue_size) == ARB_VP_ERROR)
-              return ARB_VP_ERROR;
-
-           /* Now, peek ahead and see what we are aliasing _to_ */
-           alias_to = peek_tok_attr;
-           ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 3);
-           if (ret == ARB_VP_SUCESS) {
-              s->idents.attr[alias_to] = peek_tok_attr;
-           }
-           else
-              return ARB_VP_ERROR;
-        }
-        else {
-           return ARB_VP_ERROR;
-        }
-        break;
-
-        /* productions 314 (ESTABLISH_NAME) duplicates are caught by the ID symbol table */
-
-        /* productions 315 */
-      case NT_ESTABLISHED_NAME_TOKEN:
-        if (input_tok == ID_TOKEN) {
-           if (s->idents.type[input_tok_attr] == TYPE_NONE) {
-              printf("Trying to use variable %s before initializing!\n",
-                     s->idents.data[input_tok_attr]);
-              return ARB_VP_ERROR;
-           }
-           else {
-              apply_production(s, 315);
-           }
-        }
-        else {
-           return ARB_VP_ERROR;
-        }
-        break;
-
-
-        /* productions 318-9 */
-      case NT_SWIZZLE_SUFFIX2_TOKEN:
-        if (_mesa_strlen((char *) s->idents.data[input_tok_attr]) == 1) {
-           apply_production(s, 318);
-        }
-        else if (_mesa_strlen((char *) s->idents.data[input_tok_attr]) == 4) {
-           apply_production(s, 319);
-        }
-        else {
-           return ARB_VP_ERROR;
-        }
-        break;
-
-        /* 4-component swizzle mask -- this is a total hack */
-#define IS_SWZ_CMP(foo) ((foo == 'x') || (foo == 'y') || (foo == 'z') || (foo == 'w'))
-      case NT_COMPONENT4_TOKEN:
-        {
-           GLubyte *str = s->idents.data[input_tok_attr];
-
-           if (IS_SWZ_CMP(str[0]) && IS_SWZ_CMP(str[1]) && IS_SWZ_CMP(str[2])
-               && IS_SWZ_CMP(str[3])) {
-              _stack_pop(s, &stack_tok, &stack_tok_attr, &ptn);
-               /*                                              _stack_push(s, input_tok, input_tok_attr, NULL);*/
-
-              ptn2 = parse_tree_node_init();
-              ptn2->tok = input_tok;
-              ptn2->tok_attr = input_tok_attr;
-              ptn2->is_terminal = 1;
-              ptn->children[0] = ptn2;
-              _stack_push(s, input_tok, input_tok_attr, ptn2);
-           }
-           else {
-              return ARB_VP_ERROR;
-           }
-        }
-        break;
-
-        /* Handle general non-terminals using tables, and terminals */
-      default:
-        is_nonterm = 0;
-        for (la = 0; la < nlas; la++) {
-           if (latab[la].lhs != stack_tok)
-              continue;
-
-           if (latab[la].la != input_tok)
-              continue;
-
-           if (input_tok == ID_TOKEN) {
-              str_key =
-                 id_table_add(&s->idents, latab[la].la_kw, 0,
-                              _mesa_strlen(latab[la].la_kw));
-              if ((str_key != input_tok_attr)
-                  && (_mesa_strcmp(latab[la].la_kw, "-1")))
-                 continue;
-           }
-           else if (input_tok == INTEGER_TOKEN) {
-              if ((s->ints.data[input_tok_attr] !=
-                   _mesa_atoi(latab[la].la_kw))
-                  && (_mesa_atoi(latab[la].la_kw) != -1)) {
-                 continue;
-              }
-           }
-           else if (input_tok == FLOAT_TOKEN) {
-              if ((s->floats.data[input_tok_attr] != atof(latab[la].la_kw))
-                  && (atof(latab[la].la_kw) != -1))
-                 continue;
-           }
-           idx = latab[la].prod_idx;
-
-           /* Here we stack identifiers onto the var_queue */
-           switch (idx) {
-              /* setup ATTRIB */
-           case 120:
-              var_queue_size = 1;
-              var_queue[0] = TYPE_ATTRIB;
-              ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
-              var_queue[var_queue_size] = peek_tok_attr;
-              var_queue_size++;
-
-              if (init_vars(s, var_queue, var_queue_size) == ARB_VP_ERROR)
-                 return ARB_VP_ERROR;
-              break;
-
-              /* stack PARAM */
-           case 134:
-              var_queue_size = 1;
-              var_queue[0] = TYPE_PARAM;
-
-              ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
-              var_queue[var_queue_size] = peek_tok_attr;
-              var_queue_size++;
-
-              break;
-
-           case 135:
-              var_queue[0] = TYPE_PARAM_SINGLE;
-
-              if (init_vars(s, var_queue, var_queue_size) == ARB_VP_ERROR)
-                 return ARB_VP_ERROR;
-              break;
-
-           case 136:
-              var_queue[0] = TYPE_PARAM_ARRAY;
-
-              if (init_vars(s, var_queue, var_queue_size) == ARB_VP_ERROR)
-                 return ARB_VP_ERROR;
-              break;
-
-              /* stack TEMP */
-           case 284:
-              var_queue_size = 1;
-              var_queue[0] = TYPE_TEMP;
-              break;
-
-              /* stack ADDRESS */
-           case 285:
-              var_queue_size = 1;
-              var_queue[0] = TYPE_ADDRESS;
-              break;
-
-              /* stack OUTPUT */
-           case 288:
-              var_queue_size = 1;
-              var_queue[0] = TYPE_OUTPUT;
-              ret = peek_next_token(s, &peek_tok, &peek_tok_attr, 1);
-              var_queue[var_queue_size] = peek_tok_attr;
-              var_queue_size++;
-
-              if (init_vars(s, var_queue, var_queue_size) == ARB_VP_ERROR)
-                 return ARB_VP_ERROR;
-              break;
-
-
-              /* stack opts for varNameList  -- see above */
-
-           }
-
-           /* finally.. we match! apply the production */
-           if ((idx < 0) || (idx >= nprods)) {
-              fprintf(stderr,
-                      "Prod IDX of %d in look ahead table [%d] is horked!\n",
-                      idx, la);
-              exit(1);
-           }
-
-           apply_production(s, idx);
-           is_nonterm = 1;
-           break;
-        }
-
-        if (!is_nonterm) {
-           if ((stack_tok == EOF_TOKEN) && (s->stack_head == NULL))
-              return ARB_VP_SUCESS;
-
-           if ((input_tok == stack_tok) ||
-               ((stack_tok == FLOAT_TOKEN)
-                && (input_tok == INTEGER_TOKEN))) {
-              /* XXX: Need to check values for int/id/GLfloat tokens here -- yes! */
-
-              _stack_pop(s, &stack_tok, &stack_tok_attr, &ptn);
-              if ((ptn)
-                  && ((stack_tok == FLOAT_TOKEN)
-                      || (stack_tok == INTEGER_TOKEN)
-                      || (stack_tok == ID_TOKEN))) {
-                 ptn->is_terminal = 1;
-                 ptn->tok = input_tok;
-                 ptn->tok_attr = input_tok_attr;
-              }
-
-              if (get_next_token(s, &input_tok, &input_tok_attr) ==
-                  ARB_VP_ERROR) {
-                 fprintf(stderr, "PARSE ERROR!!\n");
-                 return ARB_VP_ERROR;
-              }
-           }
-           else {
-              fprintf(stderr, "PARSE ERROR!\n");
-              return ARB_VP_ERROR;
-           }
-        }
-        break;
-      }
-   }
-
-   return ARB_VP_SUCESS;
-
-
-}
-
-/**
- * Print out the parse tree from a given point. Just for debugging.
- *
- * \param s    The parse state
- * \param ptn  The root to start printing from
- */
-static void
-print_parse_tree(parse_state * s, parse_tree_node * ptn)
-{
-   GLint a;
-
-   /* If we're terminal, prGLint and exit */
-   if (ptn->is_terminal) {
-      debug_token(s, ptn->tok, ptn->tok_attr);
-      printf("\n");
-      return;
-   }
-
-   /* Else, recurse on all our children */
-   for (a = 0; a < 4; a++) {
-      if (!ptn->children[a])
-        return;
-
-      print_parse_tree(s, ptn->children[a]);
-   }
-}
-
-/**
- * Free all of the children of a given parse tree node. 
- *
- * \param ptn    The root node whose children we recursively free
- */
-static void
-parse_tree_free_children(parse_tree_node * ptn)
-{
-   GLint a;
-
-   if (!ptn)
-      return;
-   if (!ptn->children[0])
-      return;
-
-   for (a = 0; a < 4; a++) {
-      if (ptn->children[a]) {
-        parse_tree_free_children(ptn->children[a]);
-        _mesa_free(ptn->children[a]);
-        ptn->children[a] = NULL;
-      }
-   }
-}
-
-/**
- * Given the name of a matrix, and a modifier, expand into a binding type.
- *
- * names:  0 -- modelview
- *         1 -- projection
- *         2 -- mvp
- *         3 -- texture
- *         4 -- palette
- *         5 -- program
- *
- * mods:   0 -- normal
- *         1 -- inverse
- *         2 -- invtrans
- *         3 -- transpose
- *
- * \param name  The number of the matrix type
- * \param mod   The number of the matrix modifier
- *
- * \return The binding state corresponding to name & mod
- */
-static GLint
-name_and_mod_to_matrixrows(GLint name, GLint mod)
-{
-   switch (name) {
-   case 0:                     /* modelview */
-      switch (mod) {
-      case 0:
-        return MATRIXROWS_MODELVIEW;
-      case 1:
-        return MATRIXROWS_MODELVIEW_INVERSE;
-      case 2:
-        return MATRIXROWS_MODELVIEW_INVTRANS;
-      case 3:
-        return MATRIXROWS_MODELVIEW_TRANSPOSE;
-      }
-      break;
-   case 1:                     /* projection */
-      switch (mod) {
-      case 0:
-        return MATRIXROWS_PROJECTION;
-      case 1:
-        return MATRIXROWS_PROJECTION_INVERSE;
-      case 2:
-        return MATRIXROWS_PROJECTION_INVTRANS;
-      case 3:
-        return MATRIXROWS_PROJECTION_TRANSPOSE;
-      }
-
-      break;
-   case 2:                     /* mvp */
-      switch (mod) {
-      case 0:
-        return MATRIXROWS_MVP;
-      case 1:
-        return MATRIXROWS_MVP_INVERSE;
-      case 2:
-        return MATRIXROWS_MVP_INVTRANS;
-      case 3:
-        return MATRIXROWS_MVP_TRANSPOSE;
-      }
-
-      break;
-   case 3:                     /* texture */
-      switch (mod) {
-      case 0:
-        return MATRIXROWS_TEXTURE;
-      case 1:
-        return MATRIXROWS_TEXTURE_INVERSE;
-      case 2:
-        return MATRIXROWS_TEXTURE_INVTRANS;
-      case 3:
-        return MATRIXROWS_TEXTURE_TRANSPOSE;
-      }
-      break;
-   case 4:                     /* palette */
-      switch (mod) {
-      case 0:
-        return MATRIXROWS_PALETTE;
-      case 1:
-        return MATRIXROWS_PALETTE_INVERSE;
-      case 2:
-        return MATRIXROWS_PALETTE_INVTRANS;
-      case 3:
-        return MATRIXROWS_PALETTE_TRANSPOSE;
-      }
-      break;
-   case 5:                     /* program */
-      switch (mod) {
-      case 0:
-        return MATRIXROWS_PROGRAM;
-      case 1:
-        return MATRIXROWS_PROGRAM_INVERSE;
-      case 2:
-        return MATRIXROWS_PROGRAM_INVTRANS;
-      case 3:
-        return MATRIXROWS_PROGRAM_TRANSPOSE;
-      }
-      break;
-   }
-
-   return 0;
-}
-
-/**
- * This takes a node in the parse tree for an OPTIONAL_MASK token
- * being derived into a write mask for a register. 
- *
- * This will expand the production number into a 4-component
- * write mask.
- *
- * \param mask_node  The parse tree node for the optional_mask non-termina
- * \param mask       4-component write mask
- */
-static void
-get_optional_mask(parse_tree_node * mask_node, GLint * mask)
-{
-   if (mask_node->prod_applied == 97) {
-      switch (mask_node->children[0]->prod_applied) {
-      case 99:                 /* x  */
-        mask[0] = 1;
-        mask[1] = 0;
-        mask[2] = 0;
-        mask[3] = 0;
-        break;
-
-      case 100:                /* y */
-        mask[0] = 0;
-        mask[1] = 1;
-        mask[2] = 0;
-        mask[3] = 0;
-        break;
-
-      case 101:                /* xy */
-        mask[0] = 1;
-        mask[1] = 1;
-        mask[2] = 0;
-        mask[3] = 0;
-        break;
-
-      case 102:                /* z */
-        mask[0] = 0;
-        mask[1] = 0;
-        mask[2] = 1;
-        mask[3] = 0;
-        break;
-
-      case 103:                /* xz */
-        mask[0] = 1;
-        mask[1] = 0;
-        mask[2] = 1;
-        mask[3] = 0;
-        break;
-
-      case 104:                /* yz */
-        mask[0] = 0;
-        mask[1] = 1;
-        mask[2] = 1;
-        mask[3] = 0;
-        break;
-
-      case 105:                /* xyz */
-        mask[0] = 1;
-        mask[1] = 1;
-        mask[2] = 1;
-        mask[3] = 0;
-        break;
-
-      case 106:                /* w */
-        mask[0] = 0;
-        mask[1] = 0;
-        mask[2] = 0;
-        mask[3] = 1;
-        break;
-
-      case 107:                /* xw */
-        mask[0] = 1;
-        mask[1] = 0;
-        mask[2] = 0;
-        mask[3] = 1;
-        break;
-
-      case 108:                /* yw */
-        mask[0] = 0;
-        mask[1] = 1;
-        mask[2] = 0;
-        mask[3] = 1;
-        break;
-
-      case 109:                /* xyw */
-        mask[0] = 1;
-        mask[1] = 1;
-        mask[2] = 0;
-        mask[3] = 1;
-        break;
-
-      case 110:                /* zw */
-        mask[0] = 0;
-        mask[1] = 0;
-        mask[2] = 1;
-        mask[3] = 1;
-        break;
-
-      case 111:                /* xzw */
-        mask[0] = 1;
-        mask[1] = 0;
-        mask[2] = 1;
-        mask[3] = 1;
-        break;
-
-      case 112:                /* yzw */
-        mask[0] = 0;
-        mask[1] = 1;
-        mask[2] = 1;
-        mask[3] = 1;
-        break;
-
-      case 113:                /* xyzw */
-        mask[0] = 1;
-        mask[1] = 1;
-        mask[2] = 1;
-        mask[3] = 1;
-        break;
-      }
-   }
-}
-
-/**
- * Given a MASKED_DST_REG token in a parse tree node, figure out what 
- * register number and write mask the production results in.
- *
- * \param  s         The parse state
- * \param  mdr       The parse tree node
- * \param  dest      The destination register number
- * \param  dest_mask The 4-component write mask
- */
-static void
-get_masked_dst_reg(parse_state * s, parse_tree_node * mdr, GLint * dest,
-                  GLint * dest_mask)
-{
-   GLint a;
-
-   /* dest is a TEMP variable */
-   if (mdr->children[0]->prod_applied == 67) {
-      a = mdr->children[0]->children[0]->children[0]->children[0]->tok_attr;
-      *dest = s->binds.reg_num[s->idents.attr[a]];
-      printf("dst reg: %d (%s)\n", *dest, s->idents.data[a]);
-   }
-   else {
-      /* dest is a result variable */
-      if (mdr->children[0]->children[0]->prod_applied == 86) {
-        a = mdr->children[0]->children[0]->children[0]->children[0]->
-           tok_attr;
-        *dest = s->binds.reg_num[s->idents.attr[a]];
-        printf("dest reg: %d (%s)\n", *dest, s->idents.data[a]);
-      }
-      /* dest is an implicit binding to result/output state */
-      else {
-        a = mdr->children[0]->children[0]->children[0]->tok_attr;
-        *dest = s->binds.reg_num[a];
-        printf("dst: %d\n", *dest);
-      }
-   }
-
-   /* mdr->children[1] is the write mask */
-   get_optional_mask(mdr->children[1], dest_mask);
-}
-
-
-/**
- * Given a parse tree node with a swizzled src token, figure out the swizzle
- * mask.
- *
- * \param s       The parse state
- * \param ssr     The parse tree node
- * \param swz     The 4-component swizzle, 0 - x, 1 - y, 2 - z, 3 - w
- */
-static void
-get_src_swizzle(parse_state * s, parse_tree_node * ssr, GLint * swz)
-{
-   GLint a;
-   GLubyte *c;
-
-   if (ssr->prod_applied == 317) {
-      if (ssr->children[0]->prod_applied == 318) {     /* single component */
-        switch (ssr->children[0]->children[0]->prod_applied) {
-        case 93:               /* x */
-           for (a = 0; a < 4; a++)
-              swz[a] = 0;
-           break;
-
-        case 94:               /* y */
-           for (a = 0; a < 4; a++)
-              swz[a] = 1;
-           break;
-
-        case 95:               /* z */
-           for (a = 0; a < 4; a++)
-              swz[a] = 2;
-           break;
-
-        case 96:               /* w */
-           for (a = 0; a < 4; a++)
-              swz[a] = 3;
-           break;
-        }
-      }
-      else {                   /* 4-component */
-
-        c = s->idents.data[ssr->children[0]->children[0]->children[0]->
-                           tok_attr];
-        for (a = 0; a < 4; a++) {
-           switch (c[a]) {
-           case 'x':
-              swz[a] = 0;
-              break;
-           case 'y':
-              swz[a] = 1;
-              break;
-           case 'z':
-              swz[a] = 2;
-              break;
-           case 'w':
-              swz[a] = 3;
-              break;
-           }
-        }
-      }
-   }
-}
-
-
-/**
- * Given a parse tree node for a src register with an optional sign, figure out
- * what register the src maps to, and what the sign is
- *
- * \param s     The parse state
- * \param ssr   The parse tree node to work from
- * \param sign  The sign (1 or -1)
- * \param ssrc  The src register number
- */
-static void
-get_optional_sign_and_src_reg(parse_state * s, parse_tree_node * ssr,
-                             int *sign, int *ssrc)
-{
-   GLint a;
-
-   /* ssr->children[0] is the optionalSign  */
-   if (ssr->children[0]->prod_applied == 282) {        /* - */
-      *sign = -1;
-   }
-
-   /* ssr->children[1] is the srcReg        */
-
-   /* The src is a vertex attrib */
-   if (ssr->children[1]->prod_applied == 64) {
-      if (ssr->children[1]->children[0]->prod_applied == 69) { /* variable */
-        a = ssr->children[1]->children[0]->children[0]->children[0]->
-           tok_attr;
-        *ssrc = s->binds.reg_num[s->idents.attr[a]];
-        printf("src reg: %d (%s)\n", *ssrc, s->idents.data[a]);
-      }
-      else {                   /* implicit binding */
-
-        a = ssr->children[1]->children[0]->children[0]->tok_attr;
-        *ssrc = s->binds.reg_num[a];
-        printf("src reg: %d %d (implicit binding)\n",
-               *ssrc, s->binds.type[a]);
-      }
-   }
-   else
-      /* The src is a temp variable */
-   if (ssr->children[1]->prod_applied == 65) {
-      a = ssr->children[1]->children[0]->children[0]->children[0]->tok_attr;
-      *ssrc = s->binds.reg_num[s->idents.attr[a]];
-      printf("src reg: %d (%s)\n", *ssrc, s->idents.data[a]);
-   }
-   /* The src is a param */
-   else {
-      /* We have a single item */
-      if (ssr->children[1]->children[0]->prod_applied == 72) {
-        a = ssr->children[1]->children[0]->children[0]->children[0]->
-           children[0]->tok_attr;
-        *ssrc = s->binds.reg_num[s->idents.attr[a]];
-        printf("src reg: %d (%s)\n", *ssrc, s->idents.data[a]);
-      }
-      else
-        /* We have an array of items */
-      if (ssr->children[1]->children[0]->prod_applied == 73) {
-        a = ssr->children[1]->children[0]->children[0]->children[0]->
-           children[0]->tok_attr;
-        *ssrc = s->binds.reg_num[s->idents.attr[a]];
-
-        /* We have an absolute offset into the array */
-        if (ssr->children[1]->children[0]->children[1]->prod_applied == 77) {
-           /* Ok, are array will be layed out fully in registers, so we can compute the reg */
-           printf("array base: %s\n", s->idents.data[a]);
-           a = ssr->children[1]->children[0]->children[1]->children[0]->
-              children[0]->tok_attr;
-           printf("array absolute offset: %d\n", s->ints.data[a]);
-           *ssrc += s->ints.data[a];
-        }
-        /* Otherwise, we have to grab the offset register */
-        else {                 /* progParamArrayRel */
-
-           /* XXX: We don't know the offset, so we have to grab the offset register # */
-        }
-      }
-      /* Otherwise, we have an implicit binding */
-      else {                   /* paramSingleItemUse */
-
-        if (ssr->children[1]->children[0]->children[0]->prod_applied == 148) { /* programSingleItem */
-           a = ssr->children[1]->children[0]->children[0]->children[0]->
-              tok_attr;
-        }
-        else {
-           a = ssr->children[1]->children[0]->children[0]->children[0]->
-              children[0]->tok_attr;
-        }
-        *ssrc = s->binds.reg_num[a];
-        printf("src reg: %d %d (implicit binding)\n", *ssrc,
-               s->binds.type[a]);
-      }
-   }
-}
-
+#define DEBUG_VP 0
 
 /**
- * Figure out what register a src reg is in, as well as the swizzle mask and the 
- * sign
- *
- * \param s    The parse state
- * \param ssr  The swizzeled src reg parse tree node
- * \param sign The return value for the sign {1, -1}
- * \param ssrc The return value for the register number
- * \param swz  The 4-component swizzle mask
+ * \file arbvertparse.c
+ * ARB_vertex_program parser.
+ * \author Karl Rasche
  */
-static void
-get_swizzle_src_reg(parse_state * s, parse_tree_node * ssr, GLint * sign,
-                   GLint * ssrc, GLint * swz)
-{
-   get_optional_sign_and_src_reg(s, ssr, sign, ssrc);
 
-   /* ssr->children[2] is the swizzleSuffix */
-   get_src_swizzle(s, ssr->children[2], swz);
-}
+#include "glheader.h"
+#include "context.h"
+#include "hash.h"
+#include "imports.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "nvprogram.h"
+#include "nvvertparse.h"
+#include "nvvertprog.h"
 
-/**
- *     Just like get_swizzle_src_reg, but find the scalar value to use from the register instead
- *     of the swizzle mask
- *
- * \param s       The parse state
- * \param ssr     The swizzeled src reg parse tree node
- * \param sign    The return value for the sign {1, -1}
- * \param ssrc    The return value for the register number
- * \param scalar  The 1-component scalar number
- */
-static void
-get_scalar_src_reg(parse_state * s, parse_tree_node * ssr, GLint * sign,
-                  GLint * ssrc, GLint * scalar)
-{
-   get_optional_sign_and_src_reg(s, ssr, sign, ssrc);
+#include "arbparse.h"
 
-   /* sn->children[2] is a scalarSuffix  */
-   switch (ssr->children[2]->children[0]->prod_applied) {
-   case 93:
-      *scalar = 0;
-      break;
-   case 94:
-      *scalar = 1;
-      break;
-   case 95:
-      *scalar = 2;
-      break;
-   case 96:
-      *scalar = 3;
-      break;
-   }
-}
 
-/**
- * Recursivly traverse the parse tree and generate Mesa opcodes 
- *
- * \param s    The parse state
- * \param ptn  The parse tree node to process
- */
-static void
-parse_tree_generate_opcodes(parse_state * s, parse_tree_node * ptn)
+static GLvoid
+debug_vp_inst(GLint num, struct vp_instruction *vp)
 {
    GLint a;
-   GLint opcode, dst, src[3];
-   GLint dst_mask[4], src_swz[3][4], src_scalar[3], src_sign[3];
-   parse_tree_node *dn, *sn[3];
-
-   src_sign[0] = src_sign[1] = src_sign[2] = 1;
-   for (a = 0; a < 4; a++) {
-      src_swz[0][a] = a;
-      src_swz[1][a] = a;
-      src_swz[2][a] = a;
-   }
-   src_scalar[0] = src_scalar[1] = src_scalar[2] = 0;
-   dst_mask[0] = dst_mask[1] = dst_mask[2] = dst_mask[3] = 1;
-
-   switch (ptn->prod_applied) {
-   case 17:                    /* ARL */
-      opcode = VP_OPCODE_ARL;
-
-      dn = ptn->children[0];
-      sn[0] = ptn->children[1];
-
-      /* dn is a maskedAddrReg */
-      /* dn->children[0] is an addrReg */
-      /* dn->children[1] is an addrWriteMask */
-      /* XXX: do this.. */
-      break;
-
-   case 18:                    /* VECTORop */
-      switch (ptn->children[0]->prod_applied) {
-      case 19:                 /* ABS */
-        opcode = VP_OPCODE_ABS;
-        break;
-      case 20:                 /* FLR */
-        opcode = VP_OPCODE_FLR;
-        break;
-      case 21:                 /* FRC */
-        opcode = VP_OPCODE_FRC;
-        break;
-      case 22:                 /* LIT */
-        opcode = VP_OPCODE_LIT;
-        break;
-      case 23:                 /* MOV */
-        opcode = VP_OPCODE_MOV;
-        break;
-      }
-      printf("opcode: %d\n", opcode);
-
-      /* dn is a maskedDstReg */
-      dn = ptn->children[1];
-
-      /* sn is a swizzleSrcReg */
-      sn[0] = ptn->children[2];
-
-      get_masked_dst_reg(s, dn, &dst, dst_mask);
-      printf("dst: %d mask: %d %d %d %d\n", dst, dst_mask[0], dst_mask[1],
-            dst_mask[2], dst_mask[3]);
-
-      get_swizzle_src_reg(s, sn[0], &src_sign[0], &src[0], src_swz[0]);
-
-      printf("src sign: %d reg: %d swz: %d %d %d %d\n",
-            src_sign[0], src[0], src_swz[0][0], src_swz[0][1], src_swz[0][2],
-            src_swz[0][3]);
-      break;
-
-   case 24:                    /* SCALARop */
-      switch (ptn->children[0]->prod_applied) {
-      case 25:                 /* EX2 */
-        opcode = VP_OPCODE_EX2;
-        break;
-      case 26:                 /* EXP */
-        opcode = VP_OPCODE_EXP;
-        break;
-      case 27:                 /* LG2 */
-        opcode = VP_OPCODE_LG2;
-        break;
-      case 28:                 /* LOG */
-        opcode = VP_OPCODE_LOG;
-        break;
-      case 29:                 /* RCP */
-        opcode = VP_OPCODE_RCP;
-        break;
-      case 30:                 /* RSQ */
-        opcode = VP_OPCODE_RSQ;
-        break;
-      }
-
-      printf("opcode: %d\n", opcode);
-      /* dn is a maskedDstReg */
-      dn = ptn->children[1];
-
-      get_masked_dst_reg(s, dn, &dst, dst_mask);
-      printf("dst: %d mask: %d %d %d %d\n", dst, dst_mask[0], dst_mask[1],
-            dst_mask[2], dst_mask[3]);
-
-      /* sn is a scalarSrcReg */
-      sn[0] = ptn->children[2];
-
-      get_scalar_src_reg(s, sn[0], &src_sign[0], &src[0], &src_scalar[0]);
-      printf("src sign: %d reg: %d scalar: %d\n", src_sign[0], src[0],
-            src_scalar[0]);
-      break;
-
-   case 31:                    /* BINSC */
-      opcode = VP_OPCODE_POW;
-
-      printf("opcode: %d\n", opcode);
-      /* maskedDstReg */
-      dn = ptn->children[1];
-      get_masked_dst_reg(s, dn, &dst, dst_mask);
-      printf("dst: %d mask: %d %d %d %d\n", dst, dst_mask[0], dst_mask[1],
-            dst_mask[2], dst_mask[3]);
-
-      /* sn are scalarSrcReg's */
-      sn[0] = ptn->children[2]->children[0];
-      sn[1] = ptn->children[2]->children[1];
-
-      get_scalar_src_reg(s, sn[0], &src_sign[0], &src[0], &src_scalar[0]);
-      get_scalar_src_reg(s, sn[1], &src_sign[1], &src[1], &src_scalar[1]);
-
-      printf("src0 sign: %d reg: %d scalar: %d\n", src_sign[0], src[0],
-            src_scalar[0]);
-      printf("src1 sign: %d reg: %d scalar: %d\n", src_sign[1], src[1],
-            src_scalar[1]);
-      break;
-
-
-   case 34:                    /* BIN */
-      switch (ptn->children[0]->prod_applied) {
-      case 36:                 /* ADD */
-        opcode = VP_OPCODE_ADD;
-        break;
-      case 37:                 /* DP3 */
-        opcode = VP_OPCODE_DP3;
-        break;
-      case 38:                 /* DP4 */
-        opcode = VP_OPCODE_DP4;
-        break;
-      case 39:                 /* DPH */
-        opcode = VP_OPCODE_DPH;
-        break;
-      case 40:                 /* DST */
-        opcode = VP_OPCODE_DST;
-        break;
-      case 41:                 /* MAX */
-        opcode = VP_OPCODE_MAX;
-        break;
-      case 42:                 /* MIN */
-        opcode = VP_OPCODE_MIN;
-        break;
-      case 43:                 /* MUL */
-        opcode = VP_OPCODE_MUL;
-        break;
-      case 44:                 /* SGE */
-        opcode = VP_OPCODE_SGE;
-        break;
-      case 45:                 /* SLT */
-        opcode = VP_OPCODE_SLT;
-        break;
-      case 46:                 /* SUB */
-        opcode = VP_OPCODE_SUB;
-        break;
-      case 47:                 /* XPD */
-        opcode = VP_OPCODE_XPD;
-        break;
-      }
-
-      printf("opcode: %d\n", opcode);
-
-      /* maskedDstReg */
-      dn = ptn->children[1];
-      get_masked_dst_reg(s, dn, &dst, dst_mask);
-      printf("dst: %d mask: %d %d %d %d\n", dst, dst_mask[0], dst_mask[1],
-            dst_mask[2], dst_mask[3]);
-
-      /* sn are scalarSrcReg's */
-      sn[0] = ptn->children[2]->children[0];
-      sn[1] = ptn->children[2]->children[1];
-
-      get_swizzle_src_reg(s, sn[0], &src_sign[0], &src[0], src_swz[0]);
-      get_swizzle_src_reg(s, sn[1], &src_sign[1], &src[1], src_swz[1]);
-
-      printf("src0 sign: %d reg: %d swz: %d %d %d %d\n",
-            src_sign[0], src[0], src_swz[0][0], src_swz[0][1], src_swz[0][2],
-            src_swz[0][3]);
-      printf("src1 sign: %d reg: %d swz: %d %d %d %d\n", src_sign[1], src[1],
-            src_swz[1][0], src_swz[1][1], src_swz[1][2], src_swz[1][3]);
-      break;
-
-   case 48:                    /* TRI */
-      opcode = VP_OPCODE_MAD;
-
-      printf("opcode: %d\n", opcode);
-
-      /* maskedDstReg */
-      dn = ptn->children[1];
-      get_masked_dst_reg(s, dn, &dst, dst_mask);
-      printf("dst: %d mask: %d %d %d %d\n", dst, dst_mask[0], dst_mask[1],
-            dst_mask[2], dst_mask[3]);
-
-      /* sn are scalarSrcReg's */
-      sn[0] = ptn->children[2]->children[0];
-      sn[1] = ptn->children[2]->children[1]->children[0];
-      sn[2] = ptn->children[2]->children[1]->children[1];
-
-      get_swizzle_src_reg(s, sn[0], &src_sign[0], &src[0], src_swz[0]);
-      get_swizzle_src_reg(s, sn[1], &src_sign[1], &src[1], src_swz[1]);
-      get_swizzle_src_reg(s, sn[2], &src_sign[2], &src[2], src_swz[2]);
-
-      printf("src0 sign: %d reg: %d swz: %d %d %d %d\n",
-            src_sign[0], src[0], src_swz[0][0], src_swz[0][1], src_swz[0][2],
-            src_swz[0][3]);
-      printf("src1 sign: %d reg: %d swz: %d %d %d %d\n", src_sign[1], src[1],
-            src_swz[1][0], src_swz[1][1], src_swz[1][2], src_swz[1][3]);
-      printf("src2 sign: %d reg: %d swz: %d %d %d %d\n", src_sign[2], src[2],
-            src_swz[2][0], src_swz[2][1], src_swz[2][2], src_swz[2][3]);
-
-   }
-
-   for (a = 0; a < 4; a++) {
-      if (!ptn->children[a])
-        return;
-      parse_tree_generate_opcodes(s, ptn->children[a]);
-   }
-}
-
-/**
- * When we go to examine the parse tree to generate opcodes, things are not exactly pretty to deal with.
- * Parameters, constants, matricies, attribute bindings, and the like are represented by large numbers
- * of nodes.
- *
- * In order to keep the code generation code cleaner, we make a recursive pass over the parse tree and 'roll up' these deep
- * derivations of the attribs, and replace them with a single token, BINDING_TOKEN. The token attribute for 
- * BINDING_TOKEN is a index in the 'binding table' where all the relavant info on the chunk of state is stored, 
- * e.g its type.
- *
- * For example, the string 'vertex.color.secondary' is represented by 4 productions, and 4 nodes in the parse
- * tree. The token at the root of this derivation is NT_VTX_ATTRIB_BINDING_TOKEN. After this folding, 
- * the token at the root is BINDING_TOKEN, and s->binds[token_attr_at_the_root].type = ATTRIB_COLOR_SECONDARY.
- *
- * \param s    The parse state
- * \param ptn  The root parse tree node to start folding bindings 
- */
-static void
-parse_tree_fold_bindings(parse_state * s, parse_tree_node * ptn)
-{
-   GLint a, b;
-   GLint eat_children, bind_type, bind_idx, bind_row, bind_nrows;
-   GLfloat bind_vals[4];
-   parse_tree_node *ptmp;
 
-   eat_children = 0;
-   bind_row = 0;
-   bind_nrows = 1;
-   bind_vals[0] = bind_vals[1] = bind_vals[2] = bind_vals[3] = 0.0f;
-   switch (ptn->prod_applied) {
-      /* vertex */
-   case 121:
-      eat_children = 1;
-      bind_idx = 0;
-      switch (ptn->children[0]->prod_applied) {
-      case 122:                /* position */
-        bind_type = ATTRIB_POSITION;
-        break;
-      case 123:                /* weight */
-        bind_type = ATTRIB_WEIGHT;
-        if (ptn->children[0]->children[0]->prod_applied == 132) {
-           bind_idx =
-              s->ints.data[ptn->children[0]->children[0]->children[0]->
-                           children[0]->tok_attr];
-        }
-        break;
-      case 124:                /* normal */
-        bind_type = ATTRIB_NORMAL;
-        break;
-      case 125:                /* color */
-        bind_type = ATTRIB_COLOR_PRIMARY;
-        if (ptn->children[0]->children[0]->prod_applied == 306) {
-           if (ptn->children[0]->children[0]->children[0]->prod_applied ==
-               309)
-              bind_type = ATTRIB_COLOR_SECONDARY;
-        }
-        break;
-      case 126:                /* fogcoord */
-        bind_type = ATTRIB_FOGCOORD;
-        break;
-      case 127:                /* texcoord */
-        bind_type = ATTRIB_TEXCOORD;
-        if (ptn->children[0]->children[0]->prod_applied == 311) {
-           bind_idx =
-              s->ints.data[ptn->children[0]->children[0]->children[0]->
-                           children[0]->tok_attr];
-        }
-        break;
-      case 128:                /* matrixindex */
-        bind_type = ATTRIB_MATRIXINDEX;
-        bind_idx =
-           s->ints.data[ptn->children[0]->children[0]->children[0]->
-                        tok_attr];
-        break;
-      case 129:                /* attrib */
-        bind_type = ATTRIB_ATTRIB;
-        bind_idx =
-           s->ints.data[ptn->children[0]->children[0]->children[0]->
-                        tok_attr];
-        break;
-      }
-      break;
-
-      /* state */
-   case 154:
-   case 172:                   /* material */
-      eat_children = 2;
-      bind_idx = 0;
-      ptmp = ptn->children[0]->children[0];
-
-      a = 0;
-      if (ptmp->prod_applied == 182) {
-        a = 1;
-        b = 0;
-      }
-      else
-        if ((ptmp->prod_applied == 183)
-            && (ptmp->children[0]->prod_applied == 305)) {
-        a = 1;
-        b = 1;
-      }
-
-      /* no explicit face, or explicit front */
-      if (a) {
-        switch (ptmp->children[b]->prod_applied) {
-        case 184:              /* ambient */
-           bind_type = MATERIAL_FRONT_AMBIENT;
-           break;
-        case 185:              /* diffuse */
-           bind_type = MATERIAL_FRONT_DIFFUSE;
-           break;
-        case 186:              /* specular */
-           bind_type = MATERIAL_FRONT_SPECULAR;
-           break;
-        case 187:              /* emission */
-           bind_type = MATERIAL_FRONT_EMISSION;
-           break;
-        case 188:              /* shininess */
-           bind_type = MATERIAL_FRONT_SHININESS;
-           break;
-        }
-      }
-      /* has explicit back face */
-      else {
-        switch (ptmp->children[1]->prod_applied) {
-        case 184:              /* ambient */
-           bind_type = MATERIAL_BACK_AMBIENT;
-           break;
-        case 185:              /* diffuse */
-           bind_type = MATERIAL_BACK_DIFFUSE;
-           break;
-        case 186:              /* specular */
-           bind_type = MATERIAL_BACK_SPECULAR;
-           break;
-        case 187:              /* emission */
-           bind_type = MATERIAL_BACK_EMISSION;
-           break;
-        case 188:              /* shininess */
-           bind_type = MATERIAL_BACK_SHININESS;
-           break;
-        }
-      }
-      break;
-   case 155:
-   case 173:                   /* light */
-      eat_children = 2;
-      bind_idx = 0;
-      printf("FOLDING LIGHT!\n");
-      ptmp = ptn->children[0];
-      bind_idx = s->ints.data[ptmp->children[0]->children[0]->tok_attr];
-      switch (ptmp->children[1]->children[0]->prod_applied) {
-      case 191:                /* ambient */
-        bind_type = LIGHT_AMBIENT;
-        break;
-      case 192:                /* diffuse */
-        bind_type = LIGHT_DIFFUSE;
-        break;
-      case 193:                /* specular */
-        bind_type = LIGHT_SPECULAR;
-        break;
-      case 194:                /* position */
-        bind_type = LIGHT_POSITION;
-        break;
-      case 195:                /* attenuation */
-        bind_type = LIGHT_ATTENUATION;
-        break;
-      case 196:                /* spot */
-        bind_type = LIGHT_SPOT_DIRECTION;
-        break;
-      case 197:                /* half */
-        bind_type = LIGHT_HALF;
-        break;
-      }
-      break;
-
-   case 156:
-   case 174:                   /* lightmodel */
-      eat_children = 2;
-      bind_idx = 0;
-
-      ptmp = ptn->children[0];
-      switch (ptmp->prod_applied) {
-      case 201:                /* ambient */
-        bind_type = LIGHTMODEL_AMBIENT;
-        break;
-      case 202:                /* scenecolor */
-        bind_type = LIGHTMODEL_FRONT_SCENECOLOR;
-        break;
-      case 203:                /* foo.scenecolor */
-        if (ptmp->children[0]->prod_applied == 304)
-           bind_type = LIGHTMODEL_FRONT_SCENECOLOR;
-        else
-           bind_type = LIGHTMODEL_BACK_SCENECOLOR;
-      }
-      break;
-   case 157:
-   case 175:                   /* lightprod */
-      eat_children = 2;
-      bind_idx = 0;
-
-      ptmp = ptn->children[0];
-      bind_idx = s->ints.data[ptmp->children[0]->children[0]->tok_attr];
-      /* No explicit face */
-      if (ptmp->children[1]->children[0]->prod_applied == 206) {
-        a = 1;                 /* front */
-        b = 0;                 /* 0-th child */
-      }
-      else
-        if ((ptmp->children[1]->children[0]->prod_applied == 207) &&
-            (ptmp->children[1]->children[0]->children[0]->prod_applied ==
-             304)) {
-        a = 1;                 /* front */
-        b = 1;                 /* 1-th child */
-      }
-      else {
-        a = 0;
-        b = 1;
-      }
-      if (a) {
-        switch (ptmp->children[1]->children[0]->children[b]->prod_applied) {
-        case 208:              /* ambient */
-           bind_type = LIGHTPROD_FRONT_AMBIENT;
-           break;
-        case 209:              /* diffuse */
-           bind_type = LIGHTPROD_FRONT_DIFFUSE;
-           break;
-        case 210:              /* specular */
-           bind_type = LIGHTPROD_FRONT_SPECULAR;
-           break;
-        }
-      }
-      else {
-        switch (ptmp->children[1]->children[0]->children[b]->prod_applied) {
-        case 208:              /* ambient */
-           bind_type = LIGHTPROD_BACK_AMBIENT;
-           break;
-        case 209:              /* diffuse */
-           bind_type = LIGHTPROD_BACK_DIFFUSE;
-           break;
-        case 210:              /* specular */
-           bind_type = LIGHTPROD_BACK_SPECULAR;
-           break;
-        }
-      }
-      break;
-   case 158:
-   case 176:                   /* texgen */
-      eat_children = 2;
-      bind_idx = 0;
-
-      ptmp = ptn->children[0];
-      if (ptmp->children[0]->prod_applied == 311)
-        bind_idx =
-           s->ints.data[ptmp->children[0]->children[0]->children[0]->
-                        tok_attr];
-      ptmp = ptn->children[0]->children[1];
-      if (ptmp->children[0]->prod_applied == 214)
-        a = 1;                 /* eye */
-      else
-        a = 0;                 /* object */
-      b = ptmp->children[1]->prod_applied - 216;
-      if (a == 1) {
-        switch (b) {
-        case 0:
-           bind_type = TEXGEN_EYE_S;
-           break;
-        case 1:
-           bind_type = TEXGEN_EYE_T;
-           break;
-        case 2:
-           bind_type = TEXGEN_EYE_R;
-           break;
-        case 3:
-           bind_type = TEXGEN_EYE_Q;
-           break;
-        }
-      }
-      else {
-        switch (b) {
-        case 0:
-           bind_type = TEXGEN_OBJECT_S;
-           break;
-        case 1:
-           bind_type = TEXGEN_OBJECT_T;
-           break;
-        case 2:
-           bind_type = TEXGEN_OBJECT_R;
-           break;
-        case 3:
-           bind_type = TEXGEN_OBJECT_Q;
-           break;
-        }
-      }
-      break;
-   case 159:
-   case 177:                   /* fog */
-      eat_children = 2;
-      bind_idx = 0;
-
-      ptmp = ptn->children[0];
-      if (ptmp->children[0]->prod_applied == 221)
-        bind_type = FOG_COLOR;
-      else
-        bind_type = FOG_PARAMS;
-      break;
-   case 160:
-   case 178:                   /* clip */
-      eat_children = 2;
-      bind_idx = 0;
-
-      ptmp = ptn->children[0];
-      bind_idx = s->ints.data[ptmp->children[0]->children[0]->tok_attr];
-      bind_type = CLIP_PLANE;
-      break;
-   case 161:
-   case 179:                   /* point */
-      eat_children = 2;
-      bind_idx = 0;
-
-      ptmp = ptn->children[0];
-      if (ptmp->children[0]->prod_applied == 227)
-        bind_type = POINT_SIZE;
-      else
-        bind_type = POINT_ATTENUATION;
-      break;
-
-   case 162:                   /* matrix rows/whole matrix */
-      eat_children = 2;
-      bind_idx = 0;
-      {
-        parse_tree_node *mname;
-        GLint mod = 0;
-        GLint name = 0;
-
-        mname = ptn->children[0];
-        switch (mname->prod_applied) {
-        case 238:              /* modelview */
-           name = 0;
-           if (mname->children[0]->prod_applied == 245)
-              bind_idx =
-                 s->ints.data[mname->children[0]->children[0]->children[0]->
-                              tok_attr];
-           break;
-        case 239:              /* projection */
-           name = 1;
-           break;
-        case 240:              /* mvp */
-           name = 2;
-           break;
-        case 241:              /* texture */
-           if (mname->children[0]->prod_applied == 311)
-              bind_idx =
-                 s->ints.data[mname->children[0]->children[0]->children[0]->
-                              tok_attr];
-           name = 3;
-           break;
-        case 242:              /* palette */
-           bind_idx =
-              s->ints.data[mname->children[0]->children[0]->tok_attr];
-           name = 4;
-           break;
-        case 243:              /* program */
-           bind_idx =
-              s->ints.data[mname->children[0]->children[0]->tok_attr];
-           name = 5;
-           break;
-        }
-
-        ptmp = ptn->children[1];
-        if (ptmp->prod_applied == 316) {
-           bind_type = name_and_mod_to_matrixrows(name, mod);
-           bind_row = 0;
-           bind_nrows = 4;
-        }
-        else {
-           if (ptmp->children[0]->prod_applied == 164) {
-              switch (ptmp->children[0]->children[0]->prod_applied) {
-              case 234:        /* inverse */
-                 mod = 1;
-                 break;
-              case 235:        /* transpose */
-                 mod = 3;
-                 break;
-              case 236:        /* invtrans */
-                 mod = 2;
-                 break;
-              }
-              if (ptmp->children[0]->children[1]->prod_applied == 166) {
-                 bind_type = name_and_mod_to_matrixrows(name, mod);
-                 bind_row = 0;
-                 bind_nrows = 4;
-              }
-              else {           /* prod 167 */
-
-                 bind_type = name_and_mod_to_matrixrows(name, mod);
-                 bind_row =
-                    s->ints.data[ptmp->children[0]->children[1]->
-                                 children[0]->children[0]->children[0]->
-                                 tok_attr];
-                 if (ptmp->children[0]->children[1]->children[0]->
-                     children[1]->prod_applied == 169)
-                    bind_nrows = 1;
-                 else {
-                    bind_nrows =
-                       s->ints.data[ptmp->children[0]->children[1]->
-                                    children[0]->children[1]->children[0]->
-                                    children[0]->tok_attr] - bind_row + 1;
-                 }
-              }
-           }
-           else {              /* prod 165 */
-
-              bind_type = name_and_mod_to_matrixrows(name, mod);
-
-              bind_row =
-                 s->ints.data[ptmp->children[0]->children[0]->children[0]->
-                              tok_attr];
-              if (ptmp->children[0]->children[1]->prod_applied == 169)
-                 bind_nrows = 1;
-              else
-                 bind_nrows =
-                    s->ints.data[ptmp->children[0]->children[1]->
-                                 children[0]->children[0]->tok_attr] -
-                    bind_row + 1;
-           }
-        }
-      }
-
-      printf("folding matrixrows: %d %d %d %d\n", bind_type, bind_idx,
-            bind_row, bind_nrows);
-      break;
+   for (a=0; a<num; a++) {
+      switch (vp[a].Opcode) {
+         case VP_OPCODE_MOV:
+            fprintf(stderr, "VP_OPCODE_MOV"); break;
 
-   case 180:                   /* matrix row */
-      eat_children = 2;
-      bind_idx = 0;
+         case VP_OPCODE_LIT:
+            fprintf(stderr, "VP_OPCODE_LIT"); break;
 
-      {
-        GLint mod;
-        parse_tree_node *mname, *mrow;
+         case VP_OPCODE_RCP:
+            fprintf(stderr, "VP_OPCODE_RCP"); break;
 
-        ptmp = ptn->children[0];
-        mname = ptmp->children[0];
-        mod = 0;
-        if (ptmp->children[1]->children[0]->prod_applied == 232) {
-           mrow =
-              ptmp->children[1]->children[0]->children[1]->children[0]->
-              children[0];
-           switch (ptmp->children[1]->children[0]->children[0]->prod_applied) {
-           case 234:
-              mod = 1;         /* inverse */
-              break;
-           case 235:
-              mod = 2;         /* transpose */
-              break;
-           case 236:
-              mod = 3;         /* invtrans */
-              break;
-           }
-        }
-        else {
-           mrow = ptmp->children[1]->children[0]->children[0]->children[0];
-        }
-        bind_row = s->ints.data[mrow->tok_attr];
+         case VP_OPCODE_RSQ:
+            fprintf(stderr, "VP_OPCODE_RSQ"); break;
 
-        switch (mname->prod_applied) {
-        case 238:              /* modelview */
-           if (mname->children[0]->prod_applied == 245) {
-              bind_idx =
-                 s->ints.data[mname->children[0]->children[0]->children[0]->
-                              tok_attr];
-           }
-           switch (mod) {
-           case 0:
-              bind_type = MATRIXROW_MODELVIEW;
-              break;
-           case 1:
-              bind_type = MATRIXROW_MODELVIEW_INVERSE;
-              break;
-           case 2:
-              bind_type = MATRIXROW_MODELVIEW_TRANSPOSE;
-              break;
-           case 3:
-              bind_type = MATRIXROW_MODELVIEW_INVTRANS;
-           }
-           break;
+         case VP_OPCODE_EXP:
+            fprintf(stderr, "VP_OPCODE_EXP"); break;
 
-        case 239:              /* projection */
-           switch (mod) {
-           case 0:
-              bind_type = MATRIXROW_PROJECTION;
-              break;
-           case 1:
-              bind_type = MATRIXROW_PROJECTION_INVERSE;
-              break;
-           case 2:
-              bind_type = MATRIXROW_PROJECTION_TRANSPOSE;
-              break;
-           case 3:
-              bind_type = MATRIXROW_PROJECTION_INVTRANS;
-           }
-           break;
+         case VP_OPCODE_LOG:
+            fprintf(stderr, "VP_OPCODE_LOG"); break;
 
-        case 240:              /* mvp */
-           switch (mod) {
-           case 0:
-              bind_type = MATRIXROW_MVP;
-              break;
-           case 1:
-              bind_type = MATRIXROW_MVP_INVERSE;
-              break;
-           case 2:
-              bind_type = MATRIXROW_MVP_TRANSPOSE;
-              break;
-           case 3:
-              bind_type = MATRIXROW_MVP_INVTRANS;
-           }
-           break;
+         case VP_OPCODE_MUL:
+            fprintf(stderr, "VP_OPCODE_MUL"); break;
 
-        case 241:              /* texture */
-           if (mname->children[0]->prod_applied == 311) {
-              bind_idx =
-                 s->ints.data[mname->children[0]->children[0]->children[0]->
-                              tok_attr];
-           }
-           switch (mod) {
-           case 0:
-              bind_type = MATRIXROW_TEXTURE;
-              break;
-           case 1:
-              bind_type = MATRIXROW_TEXTURE_INVERSE;
-              break;
-           case 2:
-              bind_type = MATRIXROW_TEXTURE_TRANSPOSE;
-              break;
-           case 3:
-              bind_type = MATRIXROW_TEXTURE_INVTRANS;
-           }
-           break;
+         case VP_OPCODE_ADD:
+            fprintf(stderr, "VP_OPCODE_ADD"); break;
+                               
+         case VP_OPCODE_DP3:
+            fprintf(stderr, "VP_OPCODE_DP3"); break;
 
-        case 242:              /* palette */
-           bind_idx =
-              s->ints.data[mname->children[0]->children[0]->tok_attr];
-           switch (mod) {
-           case 0:
-              bind_type = MATRIXROW_PALETTE;
-              break;
-           case 1:
-              bind_type = MATRIXROW_PALETTE_INVERSE;
-              break;
-           case 2:
-              bind_type = MATRIXROW_PALETTE_TRANSPOSE;
-              break;
-           case 3:
-              bind_type = MATRIXROW_PALETTE_INVTRANS;
-           }
-           break;
+         case VP_OPCODE_DP4:
+            fprintf(stderr, "VP_OPCODE_DP4"); break;
 
-        case 243:              /* program */
-           bind_idx =
-              s->ints.data[mname->children[0]->children[0]->tok_attr];
-           switch (mod) {
-           case 0:
-              bind_type = MATRIXROW_PROGRAM;
-              break;
-           case 1:
-              bind_type = MATRIXROW_PROGRAM_INVERSE;
-              break;
-           case 2:
-              bind_type = MATRIXROW_PROGRAM_TRANSPOSE;
-              break;
-           case 3:
-              bind_type = MATRIXROW_PROGRAM_INVTRANS;
-           }
-           break;
-        }
-      }
-      break;
-
-      /* program (single) */
-   case 249:
-      eat_children = 1;
-      bind_idx = 0;
-      switch (ptn->children[0]->prod_applied) {
-      case 250:                /* env */
-        bind_type = PROGRAM_ENV_SINGLE;
-        break;
-      case 251:                /* local */
-        bind_type = PROGRAM_LOCAL_SINGLE;
-        break;
-      }
-      bind_idx =
-        s->ints.data[ptn->children[0]->children[0]->children[0]->
-                     children[0]->tok_attr];
-      break;
-
-      /* program (multi) */
-   case 252:
-      eat_children = 1;
-      bind_idx = 0;
-      switch (ptn->children[0]->prod_applied) {
-      case 253:                /* env */
-      case 254:                /* local */
-        if (ptn->children[0]->prod_applied == 253)
-           bind_type = PROGRAM_ENV_MULTI;
-        else
-           bind_type = PROGRAM_LOCAL_MULTI;
-
-        ptmp = ptn->children[0]->children[0]->children[0];
-        bind_idx = bind_row =
-           s->ints.data[ptmp->children[0]->children[0]->tok_attr];
-        bind_nrows = 1;
-
-        ptmp = ptn->children[0]->children[0]->children[0]->children[1];
-        if ((ptmp->prod_applied == 257) || (ptmp->prod_applied == 262))
-           bind_nrows =
-              s->ints.data[ptmp->children[0]->children[0]->tok_attr] -
-              bind_idx;
-        break;
-      }
-      break;
-
-#define FOLD_FLOAT_CONSTANT(float_ptr, bind_vals_idx, sign) \
-               if (float_ptr->tok == 49) /* GLfloat */ {\
-                       bind_vals[bind_vals_idx] = sign * (GLfloat) s->floats.data[float_ptr->tok_attr];\
-               }\
-               else /* GLint */ {\
-                       bind_vals[bind_vals_idx] = sign * s->ints.data[float_ptr->tok_attr];\
-               }
+         case VP_OPCODE_DST:
+            fprintf(stderr, "VP_OPCODE_DST"); break;
 
-#define FOLD_SIGNED_FLOAT_CONSTANT(sf_ptr, bind_vals_idx) \
-               {\
-                       GLfloat __mul = 1.0F;\
-                       if (sf_ptr->children[0]->prod_applied == 282) \
-                               __mul = -1.0F;\
-                       FOLD_FLOAT_CONSTANT(sf_ptr->children[1], bind_vals_idx, __mul);\
-               }
-
-      /* const scalar decl */
-   case 271:
-      eat_children = 1;
-      bind_idx = 0;
-      bind_type = CONSTANT;
-
-      FOLD_SIGNED_FLOAT_CONSTANT(ptn->children[0], 0);
-#if 0
-      {
-        GLfloat mul = 1.;
-        if (ptn->children[0]->children[0]->prod_applied == 282) {
-           mul = -1;
-        }
-
-        FOLD_FLOAT_CONSTANT(ptn->children[0]->children[1], 0, mul);
-      }
-#endif
-      break;
-
-      /* const vector */
-   case 273:
-      eat_children = 1;
-      bind_idx = 0;
-      bind_type = CONSTANT;
-
-      FOLD_SIGNED_FLOAT_CONSTANT(ptn->children[0], 0);
-      if (ptn->children[1]->prod_applied == 275) {
-        FOLD_SIGNED_FLOAT_CONSTANT(ptn->children[1]->children[0], 1);
-        if (ptn->children[1]->children[1]->prod_applied == 277) {
-           FOLD_SIGNED_FLOAT_CONSTANT(ptn->children[1]->children[1]->
-                                      children[0], 2);
-           if (ptn->children[1]->children[1]->children[1]->prod_applied ==
-               279) {
-              FOLD_SIGNED_FLOAT_CONSTANT(ptn->children[1]->children[1]->
-                                         children[1]->children[0], 3);
-           }
-        }
-      }
-      break;
+         case VP_OPCODE_MIN:
+            fprintf(stderr, "VP_OPCODE_MIN"); break;
 
-      /* result */
-   case 289:
-      eat_children = 1;
-      bind_idx = 0;
-      switch (ptn->children[0]->prod_applied) {
-      case 290:                /* position */
-        bind_type = RESULT_POSITION;
-        break;
-      case 291:                /* fogcoord */
-        bind_type = RESULT_FOGCOORD;
-        break;
-      case 292:                /* pointsize */
-        bind_type = RESULT_POINTSIZE;
-        break;
-      case 293:                /* color */
-        bind_type = RESULT_COLOR_FRONT_PRIMARY;
-        ptmp = ptn->children[0]->children[0]->children[0];
-        if (ptmp->prod_applied == 297) {
-           if (ptmp->children[0]->prod_applied == 298) {       /* front */
-              if (ptmp->children[0]->children[0]->prod_applied == 301) {
-                 if (ptmp->children[0]->children[0]->children[0]->prod_applied == 303) /* secondary */
-                    bind_type = RESULT_COLOR_FRONT_SECONDARY;
-              }
-           }
-           else {              /* back */
+         case VP_OPCODE_MAX:
+            fprintf(stderr, "VP_OPCODE_MAX"); break;
 
-              bind_type = RESULT_COLOR_BACK_PRIMARY;
-              if (ptmp->children[0]->children[0]->prod_applied == 301) {
-                 if (ptmp->children[0]->children[0]->children[0]->prod_applied == 303) /* secondary */
-                    bind_type = RESULT_COLOR_BACK_SECONDARY;
-              }
+         case VP_OPCODE_SLT:
+            fprintf(stderr, "VP_OPCODE_SLT"); break;
 
-           }
-        }
-        break;
-      case 294:                /* texcoord */
-        bind_type = RESULT_TEXCOORD;
-        if (ptn->children[0]->children[0]->prod_applied == 311) {
-           bind_idx =
-              s->ints.data[ptn->children[0]->children[0]->children[0]->
-                           children[0]->tok_attr];
-        }
-        break;
-      }
-      break;
-   }
+         case VP_OPCODE_SGE:
+            fprintf(stderr, "VP_OPCODE_SGE"); break;
 
-   /* Mmmmm... baaaaby */
-   if (eat_children) {
-      if (eat_children == 2)
-        parse_tree_free_children(ptn->children[0]);
-      else
-        parse_tree_free_children(ptn);
+         case VP_OPCODE_MAD:
+            fprintf(stderr, "VP_OPCODE_MAD"); break;
 
-      /* Insert the binding into the binding table */
-      ptn->tok = BINDING_TOKEN;
-      ptn->tok_attr =
-        binding_table_add(&s->binds, bind_type, bind_idx, bind_row,
-                          bind_nrows, bind_vals);
+         case VP_OPCODE_ARL:
+            fprintf(stderr, "VP_OPCODE_ARL"); break;
 
-      printf("Got binding %d %d %d %d at pos %d in bind tab [%f %f %f %f]\n",
-            bind_type, bind_idx, bind_row, bind_nrows, ptn->tok_attr,
-            bind_vals[0], bind_vals[1], bind_vals[2], bind_vals[3]);
-   }
+         case VP_OPCODE_DPH:
+            fprintf(stderr, "VP_OPCODE_DPH"); break;
 
+         case VP_OPCODE_RCC:
+            fprintf(stderr, "VP_OPCODE_RCC"); break;
 
-   for (a = 0; a < 4; a++) {
-      if (!ptn->children[a])
-        return;
+         case VP_OPCODE_SUB:
+            fprintf(stderr, "VP_OPCODE_SUB"); break;
 
-      parse_tree_fold_bindings(s, ptn->children[a]);
-   }
-}
+         case VP_OPCODE_ABS:
+            fprintf(stderr, "VP_OPCODE_ABS"); break;
 
-/**
- * After we have figured out what mess of parse tree actually represents GL state (or constants, or 
- * whatnot), we have to line up variables with the state.  For example, a line something like
- *
- *    OUTPUT foo = result.position;
- *
- * We would have 'foo' in the identifier table at some position foo_idx, and 'result.position' in the 
- * binding table at some position res_pos_idx. To set things up such that 'foo' is associated with 
- * the result position state, we need to set ident[foo_idx].attr = res_pos_idx so we can generate
- * opcodes without going bonkers.
- *
- * This function works on OUTPUT, ATTRIB, and PARAM single bindings. PARAM array bindings are handled in  
- * parse_tree_assign_param_arrays().
- *
- * \param  s   The parse state
- * \param  ptn The root of the parse tree from which to start lining up state and variables
- */
-static void
-parse_tree_assign_bindings(parse_state * s, parse_tree_node * ptn)
-{
-   GLint a;
-   parse_tree_node *var_name, *attr_item;
+         case VP_OPCODE_FLR:
+            fprintf(stderr, "VP_OPCODE_FLR"); break;
 
-   /* OUTPUT, ATTRIB */
-   if ((ptn->prod_applied == 288) || (ptn->prod_applied == 120)) {
-      var_name = ptn->children[0]->children[0];
-      attr_item = ptn->children[1];
+         case VP_OPCODE_FRC:
+            fprintf(stderr, "VP_OPCODE_FRC"); break;
 
-      if (attr_item->tok != BINDING_TOKEN) {
-        fprintf(stderr,
-                "sanity check: trying to bind an output variable to something funky!\n");
-        return;
-      }
+         case VP_OPCODE_EX2:
+            fprintf(stderr, "VP_OPCODE_EX2"); break;
 
-      s->idents.attr[var_name->tok_attr] = attr_item->tok_attr;
-      printf("result: %s bound to %d\n", s->idents.data[var_name->tok_attr],
-            s->binds.type[s->idents.attr[var_name->tok_attr]]);
-      return;
-   }
+         case VP_OPCODE_LG2:
+            fprintf(stderr, "VP_OPCODE_LG2"); break;
 
-   /* stateSingleItemDecl */
-   if (ptn->prod_applied == 134) {
-      var_name = ptn->children[0]->children[0];
-      if (ptn->children[1]->prod_applied == 135) {
-        if (ptn->children[1]->children[0]->prod_applied == 139) {
-           if (ptn->children[1]->children[0]->children[0]->prod_applied ==
-               144)
-              attr_item =
-                 ptn->children[1]->children[0]->children[0]->children[0]->
-                 children[0];
-           else if (ptn->children[1]->children[0]->children[0]->
-                    prod_applied == 145)
-              attr_item =
-                 ptn->children[1]->children[0]->children[0]->children[0];
-           else
-              attr_item =
-                 ptn->children[1]->children[0]->children[0]->children[0]->
-                 children[0];
+         case VP_OPCODE_POW:
+            fprintf(stderr, "VP_OPCODE_POW"); break;
 
-           if (attr_item->tok != BINDING_TOKEN) {
-              fprintf(stderr,
-                      "sanity check: trying to bind an param variable (%s) to something funky! [%d]\n",
-                      s->idents.data[var_name->tok_attr], attr_item->tok);
-              exit(1);
-           }
+         case VP_OPCODE_XPD:
+            fprintf(stderr, "VP_OPCODE_XPD"); break;
 
-           s->idents.attr[var_name->tok_attr] = attr_item->tok_attr;
-           printf("result: %s bound to %d\n",
-                  s->idents.data[var_name->tok_attr],
-                  s->binds.type[s->idents.attr[var_name->tok_attr]]);
-           return;
-        }
+         case VP_OPCODE_SWZ:
+            fprintf(stderr, "VP_OPCODE_SWZ"); break;
+                               
+         case VP_OPCODE_END:
+            fprintf(stderr, "VP_OPCODE_END"); break;
       }
 
-   }
-
-   /* else, recurse on all our children */
-   for (a = 0; a < 4; a++) {
-      if (!ptn->children[a])
-        return;
-
-      parse_tree_assign_bindings(s, ptn->children[a]);
-   }
-
-}
-
-/**
- * This handles lining up PARAM arrays with variables, much like parse_tree_assign_bindings().
- *
- * In parse_tree_assign_bindings, we set the identifier attr to the index into the binding table of 
- * the bound state.
- *
- * Here, instead, we allocate a slot in the 'array table' to stick the bound state into. Instead
- * of an index into the binding table, the identifier attr now holds the index into the array table.
- *
- * \param s   The parse state
- * \param pnt The root parse tree node to handle arrays from
- *
- */
-static void
-parse_tree_assign_param_arrays(parse_state * s, parse_tree_node * ptn)
-{
-   GLint a, is_mult, array_len;
-   parse_tree_node *var_name, *binding, *arraysize, *ptmp;
-
-   /* If we're a param */
-   if (ptn->prod_applied == 134) {
-      /* establish name */
-      var_name = ptn->children[0];
-
-      /* param_statement2 */
-      binding = ptn->children[1];
-      if (binding->prod_applied == 136) {
-        /* optarraysize */
-        arraysize = binding->children[0];
+      fprintf(stderr, " D(0x%x:%d:%d%d%d%d) ", vp[a].DstReg.File, vp[a].DstReg.Index,
+          vp[a].DstReg.WriteMask[0],
+          vp[a].DstReg.WriteMask[1],
+          vp[a].DstReg.WriteMask[2],
+          vp[a].DstReg.WriteMask[3]);
+               
+      fprintf(stderr, "S1(0x%x:%d:%d%d%d%d) ", vp[a].SrcReg[0].File, vp[a].SrcReg[0].Index,
+          vp[a].SrcReg[0].Swizzle[0],
+          vp[a].SrcReg[0].Swizzle[1],
+          vp[a].SrcReg[0].Swizzle[2],
+          vp[a].SrcReg[0].Swizzle[3]);
 
-        is_mult = 0;
+      fprintf(stderr, "S2(0x%x:%d:%d%d%d%d) ", vp[a].SrcReg[1].File, vp[a].SrcReg[1].Index,
+          vp[a].SrcReg[1].Swizzle[0],
+          vp[a].SrcReg[1].Swizzle[1],
+          vp[a].SrcReg[1].Swizzle[2],
+          vp[a].SrcReg[1].Swizzle[3]);
 
-        /* foo[3] */
-        if (arraysize->prod_applied == 138) {
-           debug_token(s, var_name->children[0]->tok,
-                       var_name->children[0]->tok_attr);
-           debug_token(s, arraysize->children[0]->tok,
-                       arraysize->children[0]->tok_attr);
-           printf("\n");
-           is_mult = 1;
-        }
-        else
-           /* foo[] */
-        if (arraysize->prod_applied == 137) {
-           arraysize = NULL;
-           printf("How do I init a PARAM array like foo[]?? \n");
-           is_mult = 1;
-        }
+      fprintf(stderr, "S3(0x%x:%d:%d%d%d%d)",  vp[a].SrcReg[2].File, vp[a].SrcReg[2].Index,    
+          vp[a].SrcReg[2].Swizzle[0],
+          vp[a].SrcReg[2].Swizzle[1],
+          vp[a].SrcReg[2].Swizzle[2],
+          vp[a].SrcReg[2].Swizzle[3]);
 
-        if (!is_mult)
-           return;
-
-        s->idents.attr[var_name->tok_attr] = array_table_new(&s->arrays);
-
-        binding = binding->children[1]->children[0];
-        ptmp = binding->children[0];
-        array_len = 0;
-
-        if (ptmp->prod_applied == 150) {       /* state */
-           printf("matrix 0 [state]:\n");
-           printf("%d %d\n", ptmp->children[0]->children[0]->tok,
-                  ptmp->children[0]->children[0]->tok_attr);
-           array_table_add_data(&s->arrays,
-                                s->idents.attr[var_name->tok_attr],
-                                ptmp->children[0]->children[0]->tok_attr);
-           array_len +=
-              s->binds.num_rows[ptmp->children[0]->children[0]->tok_attr];
-        }
-        else if (ptmp->prod_applied == 151) {  /* program */
-           printf("matrix 0 [program]:\n");
-           printf("%d %d\n", ptmp->children[0]->tok,
-                  ptmp->children[0]->tok_attr);
-           array_table_add_data(&s->arrays,
-                                s->idents.attr[var_name->tok_attr],
-                                ptmp->children[0]->tok_attr);
-           array_len += s->binds.num_rows[ptmp->children[0]->tok_attr];
-        }
-        else {                 /* constant */
-
-           printf("matrix 0 [constant]:\n");
-           printf("%d %d\n", ptmp->children[0]->children[0]->tok,
-                  ptmp->children[0]->children[0]->tok_attr);
-           array_table_add_data(&s->arrays,
-                                s->idents.attr[var_name->tok_attr],
-                                ptmp->children[0]->children[0]->tok_attr);
-           array_len +=
-              s->binds.num_rows[ptmp->children[0]->children[0]->tok_attr];
-        }
-        binding = binding->children[1];
-
-        while (binding->prod_applied != 143) {
-           ptmp = binding->children[0]->children[0];
-           printf("mat: %d\n", ptmp->prod_applied);
-           if (ptmp->prod_applied == 150) {    /* state */
-              printf("matrix %d:\n", array_len);
-              printf("%d %d\n", ptmp->children[0]->children[0]->tok,
-                     ptmp->children[0]->children[0]->tok_attr);
-              array_table_add_data(&s->arrays,
-                                   s->idents.attr[var_name->tok_attr],
-                                   ptmp->children[0]->children[0]->tok_attr);
-              array_len +=
-                 s->binds.num_rows[ptmp->children[0]->children[0]->tok_attr];
-           }
-           else if (ptmp->prod_applied == 151) {       /* program */
-              printf("matrix %d [program]:\n", array_len);
-              printf("%d %d\n", ptmp->children[0]->tok,
-                     ptmp->children[0]->tok_attr);
-              array_table_add_data(&s->arrays,
-                                   s->idents.attr[var_name->tok_attr],
-                                   ptmp->children[0]->tok_attr);
-              array_len += s->binds.num_rows[ptmp->children[0]->tok_attr];
-           }
-           else {              /* constant */
-
-              printf("matrix %d [constant]:\n", array_len);
-              printf("%d %d\n", ptmp->children[0]->children[0]->tok,
-                     ptmp->children[0]->children[0]->tok_attr);
-              array_table_add_data(&s->arrays,
-                                   s->idents.attr[var_name->tok_attr],
-                                   ptmp->children[0]->children[0]->tok_attr);
-              array_len +=
-                 s->binds.num_rows[ptmp->children[0]->children[0]->tok_attr];
-           }
-           binding = binding->children[0]->children[1];
-        }
-
-        /* XXX: have to compare the requested size, and the actual 
-         * size, and fix up any inconsistancies
-         */
-        if (arraysize) {
-           printf("matrix wants to get %d rows\n",
-                  s->ints.data[arraysize->children[0]->tok_attr]);
-        }
-        printf("matrix num rows: %d\n", array_len);
-      }
-
-      return;
-   }
-
-   /* Else, recurse on all our children */
-   for (a = 0; a < 4; a++) {
-      if (!ptn->children[a])
-        return;
-
-      parse_tree_assign_param_arrays(s, ptn->children[a]);
+      fprintf(stderr, "\n");
    }
-
 }
 
-/* XXX: This needs to be written properly. */
-/**
- * Here we allocate 'registers' for all of the various variables and bound state. 
- *
- * The 'register' number is given by the reg_num field in the binding table. Note that this field
- * is not stored in the identifier table. If it were, we would need a different mechanism for handling 
- * implicit bindings.
- *
- * However, after some discussion with Brian, implicit bindings may be handled by grabbing state
- * directly from Mesa's state structs. This might be a little hairy here, maybe not.. Implicit 
- * bindings are those in the binding table that are not pointed to by any ident.attr or array.data
- *
- * This should also do various error checking, like the multiple vertex attrib error, or 'too many bindings'
- * error.
- * 
- * \param s The parse state
- */
-static void
-assign_regs(parse_state * s)
-{
-   GLint a;
-   GLfloat foo[4];
-
-   for (a = 0; a < s->idents.len; a++) {
-      if (s->idents.type[a] == TYPE_TEMP) {
-        s->idents.attr[a] =
-           binding_table_add(&s->binds, TYPE_TEMP, 0, 0, 0, foo);
-      }
-   }
-}
 
-/**
- * Parse/compile the 'str' returning the compiled 'program'.
- * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
- * indicates the position of the error in 'str'.
- */
 void
 _mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target,
-                              const GLubyte * string, GLsizei len,
+                              const GLubyte * str, GLsizei len,
                               struct vertex_program *program)
 {
-   GLubyte *our_string;
-   parse_state *state;
-
-   /* XXX: How do I handle these errors? */
-   if (len < 10 || _mesa_strncmp((const char *) string, "!!ARBvp1.0", 10)) {
-      ctx->Program.ErrorPos = 0;
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramStringARB(bad header)");
-      return;
-   }
-
-   /* Make a null-terminated copy of the program string */
-   our_string = (GLubyte *) MALLOC(len + 1);
-   if (!our_string) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
-      return;
-   }
-   MEMCPY(our_string, string, len);
-   our_string[len] = 0;
-
-   state = parse_state_init(our_string + 10, _mesa_strlen((char *) our_string) - 10);
+   GLuint retval;
+   struct arb_program ap;
+       
+       retval = _mesa_parse_arb_program(ctx, str, len, &ap);
 
-   if (parse(state) == ARB_VP_SUCESS) {
-      printf("parse sucess!\n");
-   }
-   else {
-      printf("*** error\n");
-      parse_state_cleanup(state);
+   /* XXX: Parse error. Cleanup things and return */   
+   if (retval)
+   {
       return;
    }
 
-   /* First, we 'fold' bindings from a big mess of productions and 
-    * tokens into one BINDING_TOKEN, which points to an entry
-    * in the binding sym table that holds all of the relevant
-    * info for the binding destination.
-    */
-   parse_tree_fold_bindings(state, state->pt_head);
-
-   /* Now, for each type of binding, walk the parse tree and stick
-    * the index into the binding sym table 
-    */
-   parse_tree_assign_bindings(state, state->pt_head);
-
-   /* XXX: this still needs a' fixin to get folded bindings 
-    *                   -- it does? wtf do I mean? */
-   parse_tree_assign_param_arrays(state, state->pt_head);
-
-   /* XXX: Now, assign registers. For this, we'll need to create
-    * bindings for all temps (and what else?? )
-    */
-   assign_regs(state);
-
-   /* Ok, now generate code */
-   parse_tree_generate_opcodes(state, state->pt_head);
-
-   /* Just for testing.. */
-   program->Base.Target = target;
-   if (program->Base.String) {
-      FREE(program->Base.String);
-   }
-   program->Base.String = our_string;
-   program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
-
-   if (program->Instructions) {
-      FREE(program->Instructions);
+   /* XXX: Eh.. we parsed something that wasn't a vertex program. doh! */
+   if (ap.type != GL_VERTEX_PROGRAM_ARB)
+   {
+      return;      
    }
+       
+#if DEBUG_VP
+   debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions);
+#endif
 
-   program->Instructions =
-      (struct vp_instruction *) _mesa_malloc(sizeof(struct vp_instruction));
-   program->Instructions[0].Opcode = VP_OPCODE_END;
-   program->InputsRead = 0;
-   program->OutputsWritten = 0;
-   program->IsPositionInvariant = 0;
-
-   parse_state_cleanup(state);
-
-   /* TODO:
-    *    - handle implicit state grabbing & register allocation like discussed
-    *      - implicit param declarations -- see above
-    *
-    *      - variable bindings -- ADDRESS
-    *      - deal with explicit array sizes & size mismatches
-    *      - shuddup all my debugging crap
-    *      - grep for XXX
-    *      - multiple vtx attrib binding error
-    *      - What do I do on look ahead for prod 54 & 55? (see arbvp_grammar.txt)
-    *      - misc errors
-    *         - check integer ranges
-    *         - check array index ranges
-    *         - check variable counts
-    *      - param register allocation
-    *      - exercise swizzles and masks
-    *      - error handling
-    *      - generate opcodes
-    *          + Get addres registers for relative offsets in PARAM arrays 
-    *          + Properly encode implicit PARAMs and ATTRIBs.
-    *          + ARL
-    *          + SWZ
-    *          + actually emit Mesa opcodes
-    *      - segfaults while freeing stuff
-    *      - OPTION
+   /* copy the relvant contents of the arb_program struct into the 
+    * fragment_program struct
     */
+   program->Base.NumInstructions = ap.Base.NumInstructions;
+   program->Base.NumTemporaries  = ap.Base.NumTemporaries;
+   program->Base.NumParameters   = ap.Base.NumParameters;
+   program->Base.NumAttributes   = ap.Base.NumAttributes;
+   program->Base.NumAddressRegs  = ap.Base.NumAddressRegs;
+
+   program->Instructions   = ap.VPInstructions;
+   program->IsPositionInvariant = ap.HintPositionInvariant;
+   program->InputsRead     = ap.InputsRead;
+   program->OutputsWritten = ap.OutputsWritten;
+   program->Parameters     = ap.Parameters; 
 }
index fb67683a396d4c3fa94b60fd99d29149bf0468bb..05ae619ea2822f07e799e85bed930a8baf69724e 100644 (file)
@@ -281,9 +281,11 @@ void
 _mesa_enable_1_4_extensions(GLcontext *ctx)
 {
    ctx->Extensions.ARB_depth_texture = GL_TRUE;
+   ctx->Extensions.ARB_fragment_program = GL_TRUE;
    ctx->Extensions.ARB_shadow = GL_TRUE;
    ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
    ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
+   ctx->Extensions.ARB_vertex_program = GL_TRUE;
    ctx->Extensions.ARB_window_pos = GL_TRUE;
    ctx->Extensions.EXT_blend_color = GL_TRUE;
    ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
index 0a5c99546de5697599799ee26f51b11def18f8b5..a36a21825771433e90a0a305cc38e65707de980a 100644 (file)
@@ -1446,7 +1446,8 @@ enum register_file
    PROGRAM_ENV_PARAM,
    PROGRAM_NAMED_PARAM,
    PROGRAM_STATE_VAR,
-   PROGRAM_WRITE_ONLY
+   PROGRAM_WRITE_ONLY,
+       PROGRAM_ADDRESS
 };
 
 
@@ -1485,6 +1486,7 @@ struct vertex_program
    GLboolean IsPositionInvariant;  /* GL_NV_vertex_program1_1 */
    GLuint InputsRead;     /* Bitmask of which input regs are read */
    GLuint OutputsWritten; /* Bitmask of which output regs are written to */
+   struct program_parameter_list *Parameters; /**< array [NumParameters] */
 };
 
 
index 580d04abca599a1c233eec0484a4320718ce6521..f3034ea69911768c7b13c01a8fa60f95ddcafb67 100644 (file)
@@ -64,6 +64,23 @@ _mesa_init_vp_registers(GLcontext *ctx)
    }
 
    /* The program parameters aren't touched */
+       /* XXX: This should be moved to glBegin() time, but its safe (and slow!) 
+        *       here - Karl
+        */
+   if (ctx->VertexProgram.Current->Parameters) {
+
+      /* Grab the state */                       
+      _mesa_load_state_parameters(ctx, ctx->VertexProgram.Current->Parameters);
+
+               /* And copy it into the program state */
+      for (i=0; i<ctx->VertexProgram.Current->Parameters->NumParameters; i++) {
+         MEMCPY(ctx->VertexProgram.Parameters[i], 
+            &ctx->VertexProgram.Current->Parameters->Parameters[i].Values,     
+            4*sizeof(GLfloat));                                
+      }                                  
+                                 
+   }
+
 }
 
 
@@ -234,13 +251,11 @@ get_register_pointer( const struct vp_src_register *source,
             return state->Inputs[source->Index];
          case PROGRAM_LOCAL_PARAM:
             /* XXX fix */
-            return state->Temporaries[source->Index];
+            return state->Temporaries[source->Index]; 
          case PROGRAM_ENV_PARAM:
             return state->Parameters[source->Index];
          case PROGRAM_STATE_VAR:
-            /* XXX fix */
-            return NULL;
-            break;
+            return state->Parameters[source->Index];
          default:
             _mesa_problem(NULL,
                           "Bad source register file in fetch_vector4(vp)");