Added missing Copyrights.
authorMichal Krol <mjkrol@gmail.org>
Thu, 4 Mar 2004 13:07:52 +0000 (13:07 +0000)
committerMichal Krol <mjkrol@gmail.org>
Thu, 4 Mar 2004 13:07:52 +0000 (13:07 +0000)
src/mesa/shader/arbprogram.syn
src/mesa/shader/arbprogram_syn.h
src/mesa/shader/grammar.c
src/mesa/shader/grammar.h
src/mesa/shader/grammar_mesa.c
src/mesa/shader/grammar_mesa.h
src/mesa/shader/grammar_syn.h

index 0fc03e734ac6dde2dad8ee90dd39a83f195ce106..e6249abd30b11d605c31a3e8dcae004562566b49 100644 (file)
-.syntax program;\r
-\r
-/*\r
-   This value must be incremented every time emit code values or structure of the production\r
-   array changes. This value is placed at the beginning of the production array. The loader\r
-   compares the value with its REVISION value. If they do not match, the loader is not up\r
-   to date.\r
-*/\r
-.emtcode REVISION                                   0x07\r
-\r
-/* program type */\r
-.emtcode FRAGMENT_PROGRAM                           0x01\r
-.emtcode VERTEX_PROGRAM                             0x02\r
-\r
-/* program section */\r
-.emtcode OPTION                                     0x01\r
-.emtcode INSTRUCTION                                0x02\r
-.emtcode DECLARATION                                0x03\r
-.emtcode END                                        0x04\r
-\r
-/* GL_ARB_fragment_program option flags */\r
-.emtcode ARB_PRECISION_HINT_FASTEST                 0x01\r
-.emtcode ARB_PRECISION_HINT_NICEST                  0x02\r
-.emtcode ARB_FOG_EXP                                0x04\r
-.emtcode ARB_FOG_EXP2                               0x08\r
-.emtcode ARB_FOG_LINEAR                             0x10\r
-\r
-/* GL_ARB_vertex_program option flags */\r
-.emtcode ARB_POSITION_INVARIANT                     0x20\r
-\r
-/* GL_ARB_fragment_program_shadow option flags */\r
-.emtcode ARB_FRAGMENT_PROGRAM_SHADOW                0x40\r
-\r
-/* GL_ARB_fragment_program instruction class */\r
-.emtcode OP_ALU_INST                                0x00\r
-.emtcode OP_TEX_INST                                0x01\r
-\r
-/* GL_ARB_vertex_program instruction class */\r
-/*       OP_ALU_INST */\r
-\r
-/* GL_ARB_fragment_program instruction type */\r
-.emtcode OP_ALU_VECTOR                               0x00\r
-.emtcode OP_ALU_SCALAR                               0x01\r
-.emtcode OP_ALU_BINSC                                0x02\r
-.emtcode OP_ALU_BIN                                  0x03\r
-.emtcode OP_ALU_TRI                                  0x04\r
-.emtcode OP_ALU_SWZ                                  0x05\r
-.emtcode OP_TEX_SAMPLE                               0x06\r
-.emtcode OP_TEX_KIL                                  0x07\r
-\r
-/* GL_ARB_vertex_program instruction type */\r
-.emtcode OP_ALU_ARL                                  0x08\r
-/*       OP_ALU_VECTOR */\r
-/*       OP_ALU_SCALAR */\r
-/*       OP_ALU_BINSC */\r
-/*       OP_ALU_BIN */\r
-/*       OP_ALU_TRI */\r
-/*       OP_ALU_SWZ */\r
-\r
-/* GL_ARB_fragment_program instruction code */\r
-.emtcode OP_ABS                                     0x00\r
-.emtcode OP_ABS_SAT                                 0x1B\r
-.emtcode OP_FLR                                     0x09\r
-.emtcode OP_FLR_SAT                                 0x26\r
-.emtcode OP_FRC                                     0x0A\r
-.emtcode OP_FRC_SAT                                 0x27\r
-.emtcode OP_LIT                                     0x0C\r
-.emtcode OP_LIT_SAT                                 0x2A\r
-.emtcode OP_MOV                                     0x11\r
-.emtcode OP_MOV_SAT                                 0x30\r
-.emtcode OP_COS                                     0x1F\r
-.emtcode OP_COS_SAT                                 0x20\r
-.emtcode OP_EX2                                     0x07\r
-.emtcode OP_EX2_SAT                                 0x25\r
-.emtcode OP_LG2                                     0x0B\r
-.emtcode OP_LG2_SAT                                 0x29\r
-.emtcode OP_RCP                                     0x14\r
-.emtcode OP_RCP_SAT                                 0x33\r
-.emtcode OP_RSQ                                     0x15\r
-.emtcode OP_RSQ_SAT                                 0x34\r
-.emtcode OP_SIN                                     0x38\r
-.emtcode OP_SIN_SAT                                 0x39\r
-.emtcode OP_SCS                                     0x35\r
-.emtcode OP_SCS_SAT                                 0x36\r
-.emtcode OP_POW                                     0x13\r
-.emtcode OP_POW_SAT                                 0x32\r
-.emtcode OP_ADD                                     0x01\r
-.emtcode OP_ADD_SAT                                 0x1C\r
-.emtcode OP_DP3                                     0x03\r
-.emtcode OP_DP3_SAT                                 0x21\r
-.emtcode OP_DP4                                     0x04\r
-.emtcode OP_DP4_SAT                                 0x22\r
-.emtcode OP_DPH                                     0x05\r
-.emtcode OP_DPH_SAT                                 0x23\r
-.emtcode OP_DST                                     0x06\r
-.emtcode OP_DST_SAT                                 0x24\r
-.emtcode OP_MAX                                     0x0F\r
-.emtcode OP_MAX_SAT                                 0x2E\r
-.emtcode OP_MIN                                     0x10\r
-.emtcode OP_MIN_SAT                                 0x2F\r
-.emtcode OP_MUL                                     0x12\r
-.emtcode OP_MUL_SAT                                 0x31\r
-.emtcode OP_SGE                                     0x16\r
-.emtcode OP_SGE_SAT                                 0x37\r
-.emtcode OP_SLT                                     0x17\r
-.emtcode OP_SLT_SAT                                 0x3A\r
-.emtcode OP_SUB                                     0x18\r
-.emtcode OP_SUB_SAT                                 0x3B\r
-.emtcode OP_XPD                                     0x1A\r
-.emtcode OP_XPD_SAT                                 0x43\r
-.emtcode OP_CMP                                     0x1D\r
-.emtcode OP_CMP_SAT                                 0x1E\r
-.emtcode OP_LRP                                     0x2B\r
-.emtcode OP_LRP_SAT                                 0x2C\r
-.emtcode OP_MAD                                     0x0E\r
-.emtcode OP_MAD_SAT                                 0x2D\r
-.emtcode OP_SWZ                                     0x19\r
-.emtcode OP_SWZ_SAT                                 0x3C\r
-.emtcode OP_TEX                                     0x3D\r
-.emtcode OP_TEX_SAT                                 0x3E\r
-.emtcode OP_TXB                                     0x3F\r
-.emtcode OP_TXB_SAT                                 0x40\r
-.emtcode OP_TXP                                     0x41\r
-.emtcode OP_TXP_SAT                                 0x42\r
-.emtcode OP_KIL                                     0x28\r
-\r
-/* GL_ARB_vertex_program instruction code */\r
-.emtcode OP_ARL                                     0x02\r
-/*       OP_ABS */\r
-/*       OP_FLR */\r
-/*       OP_FRC */\r
-/*       OP_LIT */\r
-/*       OP_MOV */\r
-/*       OP_EX2 */\r
-.emtcode OP_EXP                                     0x08\r
-/*       OP_LG2 */\r
-.emtcode OP_LOG                                     0x0D\r
-/*       OP_RCP */\r
-/*       OP_RSQ */\r
-/*       OP_POW */\r
-/*       OP_ADD */\r
-/*       OP_DP3 */\r
-/*       OP_DP4 */\r
-/*       OP_DPH */\r
-/*       OP_DST */\r
-/*       OP_MAX */\r
-/*       OP_MIN */\r
-/*       OP_MUL */\r
-/*       OP_SGE */\r
-/*       OP_SLT */\r
-/*       OP_SUB */\r
-/*       OP_XPD */\r
-/*       OP_MAD */\r
-/*       OP_SWZ */\r
-\r
-/* fragment attribute binding */\r
-.emtcode FRAGMENT_ATTRIB_COLOR                      0x01\r
-.emtcode FRAGMENT_ATTRIB_TEXCOORD                   0x02\r
-.emtcode FRAGMENT_ATTRIB_FOGCOORD                   0x03\r
-.emtcode FRAGMENT_ATTRIB_POSITION                   0x04\r
-\r
-/* vertex attribute binding */\r
-.emtcode VERTEX_ATTRIB_POSITION                     0x01\r
-.emtcode VERTEX_ATTRIB_WEIGHT                       0x02\r
-.emtcode VERTEX_ATTRIB_NORMAL                       0x03\r
-.emtcode VERTEX_ATTRIB_COLOR                        0x04\r
-.emtcode VERTEX_ATTRIB_FOGCOORD                     0x05\r
-.emtcode VERTEX_ATTRIB_TEXCOORD                     0x06\r
-.emtcode VERTEX_ATTRIB_MATRIXINDEX                  0x07\r
-.emtcode VERTEX_ATTRIB_GENERIC                      0x08\r
-\r
-/* fragment result binding */\r
-.emtcode FRAGMENT_RESULT_COLOR                      0x01\r
-.emtcode FRAGMENT_RESULT_DEPTH                      0x02\r
-\r
-/* vertex result binding */\r
-.emtcode VERTEX_RESULT_POSITION                     0x01\r
-.emtcode VERTEX_RESULT_COLOR                        0x02\r
-.emtcode VERTEX_RESULT_FOGCOORD                     0x03\r
-.emtcode VERTEX_RESULT_POINTSIZE                    0x04\r
-.emtcode VERTEX_RESULT_TEXCOORD                     0x05\r
-\r
-/* texture target */\r
-.emtcode TEXTARGET_1D                               0x01\r
-.emtcode TEXTARGET_2D                               0x02\r
-.emtcode TEXTARGET_3D                               0x03\r
-.emtcode TEXTARGET_RECT                             0x04\r
-.emtcode TEXTARGET_CUBE                             0x05\r
-/* GL_ARB_fragment_program_shadow */\r
-.emtcode TEXTARGET_SHADOW1D                         0x06\r
-.emtcode TEXTARGET_SHADOW2D                         0x07\r
-.emtcode TEXTARGET_SHADOWRECT                       0x08\r
-\r
-/* face type */\r
-.emtcode FACE_FRONT                                 0x00\r
-.emtcode FACE_BACK                                  0x01\r
-\r
-/* color type */\r
-.emtcode COLOR_PRIMARY                              0x00\r
-.emtcode COLOR_SECONDARY                            0x01\r
-\r
-/* component */\r
-.emtcode COMPONENT_X                                0x00\r
-.emtcode COMPONENT_Y                                0x01\r
-.emtcode COMPONENT_Z                                0x02\r
-.emtcode COMPONENT_W                                0x03\r
-.emtcode COMPONENT_0                                0x04\r
-.emtcode COMPONENT_1                                0x05\r
-\r
-/* array index type */\r
-.emtcode ARRAY_INDEX_ABSOLUTE                       0x00\r
-.emtcode ARRAY_INDEX_RELATIVE                       0x01\r
-\r
-/* matrix name */\r
-.emtcode MATRIX_MODELVIEW                           0x01\r
-.emtcode MATRIX_PROJECTION                          0x02\r
-.emtcode MATRIX_MVP                                 0x03\r
-.emtcode MATRIX_TEXTURE                             0x04\r
-.emtcode MATRIX_PALETTE                             0x05\r
-.emtcode MATRIX_PROGRAM                             0x06\r
-\r
-/* matrix modifier */\r
-.emtcode MATRIX_MODIFIER_IDENTITY                   0x00\r
-.emtcode MATRIX_MODIFIER_INVERSE                    0x01\r
-.emtcode MATRIX_MODIFIER_TRANSPOSE                  0x02\r
-.emtcode MATRIX_MODIFIER_INVTRANS                   0x03\r
-\r
-/* constant type */\r
-.emtcode CONSTANT_SCALAR                            0x01\r
-.emtcode CONSTANT_VECTOR                            0x02\r
-\r
-/* program param type */\r
-.emtcode PROGRAM_PARAM_ENV                          0x01\r
-.emtcode PROGRAM_PARAM_LOCAL                        0x02\r
-\r
-/* register type */\r
-.emtcode REGISTER_ATTRIB                            0x01\r
-.emtcode REGISTER_PARAM                             0x02\r
-.emtcode REGISTER_RESULT                            0x03\r
-.emtcode REGISTER_ESTABLISHED_NAME                  0x04\r
-\r
-/* param binding */\r
-.emtcode PARAM_NULL                                 0x00\r
-.emtcode PARAM_ARRAY_ELEMENT                        0x01\r
-.emtcode PARAM_STATE_ELEMENT                        0x02\r
-.emtcode PARAM_PROGRAM_ELEMENT                      0x03\r
-.emtcode PARAM_PROGRAM_ELEMENTS                     0x04\r
-.emtcode PARAM_CONSTANT                             0x05\r
-\r
-/* param state property */\r
-.emtcode STATE_MATERIAL                             0x01\r
-.emtcode STATE_LIGHT                                0x02\r
-.emtcode STATE_LIGHT_MODEL                          0x03\r
-.emtcode STATE_LIGHT_PROD                           0x04\r
-.emtcode STATE_FOG                                  0x05\r
-.emtcode STATE_MATRIX_ROWS                          0x06\r
-/* GL_ARB_fragment_program */\r
-.emtcode STATE_TEX_ENV                              0x07\r
-.emtcode STATE_DEPTH                                0x08\r
-/* GL_ARB_vertex_program */\r
-.emtcode STATE_TEX_GEN                              0x09\r
-.emtcode STATE_CLIP_PLANE                           0x0A\r
-.emtcode STATE_POINT                                0x0B\r
-\r
-/* state material property */\r
-.emtcode MATERIAL_AMBIENT                           0x01\r
-.emtcode MATERIAL_DIFFUSE                           0x02\r
-.emtcode MATERIAL_SPECULAR                          0x03\r
-.emtcode MATERIAL_EMISSION                          0x04\r
-.emtcode MATERIAL_SHININESS                         0x05\r
-\r
-/* state light property */\r
-.emtcode LIGHT_AMBIENT                              0x01\r
-.emtcode LIGHT_DIFFUSE                              0x02\r
-.emtcode LIGHT_SPECULAR                             0x03\r
-.emtcode LIGHT_POSITION                             0x04\r
-.emtcode LIGHT_ATTENUATION                          0x05\r
-.emtcode LIGHT_HALF                                 0x06\r
-.emtcode LIGHT_SPOT_DIRECTION                       0x07\r
-\r
-/* state light model property */\r
-.emtcode LIGHT_MODEL_AMBIENT                        0x01\r
-.emtcode LIGHT_MODEL_SCENECOLOR                     0x02\r
-\r
-/* state light product property */\r
-.emtcode LIGHT_PROD_AMBIENT                         0x01\r
-.emtcode LIGHT_PROD_DIFFUSE                         0x02\r
-.emtcode LIGHT_PROD_SPECULAR                        0x03\r
-\r
-/* state texture environment property */\r
-.emtcode TEX_ENV_COLOR                              0x01\r
-\r
-/* state texture generation coord property */\r
-.emtcode TEX_GEN_EYE                                0x01\r
-.emtcode TEX_GEN_OBJECT                             0x02\r
-\r
-/* state fog property */\r
-.emtcode FOG_COLOR                                  0x01\r
-.emtcode FOG_PARAMS                                 0x02\r
-\r
-/* state depth property */\r
-.emtcode DEPTH_RANGE                                0x01\r
-\r
-/* state point parameters property */\r
-.emtcode POINT_SIZE                                 0x01\r
-.emtcode POINT_ATTENUATION                          0x02\r
-\r
-/* declaration */\r
-.emtcode ATTRIB                                     0x01\r
-.emtcode PARAM                                      0x02\r
-.emtcode TEMP                                       0x03\r
-.emtcode OUTPUT                                     0x04\r
-.emtcode ALIAS                                      0x05\r
-/* GL_ARB_vertex_program */\r
-.emtcode ADDRESS                                    0x06\r
-\r
-/* error messages */\r
-.errtext UNKNOWN_PROGRAM_SIGNATURE                  "1001: '$e_signature$': unknown program signature"\r
-.errtext MISSING_END_OR_INVALID_STATEMENT           "1002: '$e_statement$': invalid statement"\r
-.errtext CODE_AFTER_END                             "1003: '$e_statement$': code after 'END' keyword"\r
-.errtext INVALID_PROGRAM_OPTION                     "1004: '$e_identifier$': invalid program option"\r
-.errtext EXT_SWIZ_COMP_EXPECTED                     "1005: extended swizzle component expected but '$e_token$' found"\r
-.errtext TEX_TARGET_EXPECTED                        "1006: texture target expected but '$e_token$' found"\r
-.errtext TEXTURE_EXPECTED                           "1007: 'texture' expected but '$e_identifier$' found"\r
-.errtext SOURCE_REGISTER_EXPECTED                   "1008: source register expected but '$e_token$' found"\r
-.errtext DESTINATION_REGISTER_EXPECTED              "1009: destination register expected but '$e_token$' found"\r
-.errtext INVALID_ADDRESS_COMPONENT                  "1010: '$e_identifier$': invalid address component"\r
-.errtext INVALID_ADDRESS_WRITEMASK                  "1011: '$e_identifier$': invalid address writemask"\r
-.errtext INVALID_COMPONENT                          "1012: '$e_charordigit$': invalid component"\r
-.errtext INVALID_SUFFIX                             "1013: '$e_identifier$': invalid suffix"\r
-.errtext INVALID_WRITEMASK                          "1014: '$e_identifier$': invalid writemask"\r
-.errtext FRAGMENT_EXPECTED                          "1015: 'fragment' expected but '$e_identifier$' found"\r
-.errtext VERTEX_EXPECTED                            "1016: 'vertex' expected but '$e_identifier$' found"\r
-.errtext INVALID_FRAGMENT_PROPERTY                  "1017: '$e_identifier$': invalid fragment property"\r
-.errtext INVALID_VERTEX_PROPERTY                    "1018: '$e_identifier$': invalid vertex property"\r
-.errtext INVALID_STATE_PROPERTY                     "1019: '$e_identifier$': invalid state property"\r
-.errtext INVALID_MATERIAL_PROPERTY                  "1020: '$e_identifier$': invalid material property"\r
-.errtext INVALID_LIGHT_PROPERTY                     "1021: '$e_identifier$': invalid light property"\r
-.errtext INVALID_SPOT_PROPERTY                      "1022: '$e_identifier$': invalid spot property"\r
-.errtext INVALID_LIGHTMODEL_PROPERTY                "1023: '$e_identifier$': invalid light model property"\r
-.errtext INVALID_LIGHTPROD_PROPERTY                 "1024: '$e_identifier$': invalid light product property"\r
-.errtext INVALID_TEXENV_PROPERTY                    "1025: '$e_identifier$': invalid texture environment property"\r
-.errtext INVALID_TEXGEN_PROPERTY                    "1026: '$e_identifier$': invalid texture generating property"\r
-.errtext INVALID_TEXGEN_COORD                       "1027: '$e_identifier$': invalid texture generating coord"\r
-.errtext INVALID_FOG_PROPERTY                       "1028: '$e_identifier$': invalid fog property"\r
-.errtext INVALID_DEPTH_PROPERTY                     "1029: '$e_identifier$': invalid depth property"\r
-.errtext INVALID_CLIPPLANE_PROPERTY                 "1030: '$e_identifier$': invalid clip plane property"\r
-.errtext INVALID_POINT_PROPERTY                     "1031: '$e_identifier$': invalid point property"\r
-.errtext MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED   "1032: matrix row selector or modifier expected but '$e_token$' found"\r
-.errtext INVALID_MATRIX_NAME                        "1033: '$e_identifier$': invalid matrix name"\r
-.errtext INVALID_PROGRAM_PROPERTY                   "1034: '$e_identifier$': invalid program property"\r
-.errtext RESULT_EXPECTED                            "1035: 'result' expected but '$e_token$' found"\r
-.errtext INVALID_RESULT_PROPERTY                    "1036: '$e_identifier$': invalid result property"\r
-.errtext INVALID_FACE_PROPERTY                      "1037: '$e_identifier$': invalid face property"\r
-.errtext INVALID_COLOR_PROPERTY                     "1038: '$e_identifier$': invalid color property"\r
-.errtext IDENTIFIER_EXPECTED                        "1039: identifier expected but '$e_token$' found"\r
-.errtext RESERVED_KEYWORD                           "1040: use of reserved keyword as an identifier"\r
-.errtext INTEGER_EXPECTED                           "1041: integer value expected but '$e_token$' found"\r
-.errtext MISSING_SEMICOLON                          "1042: ';' expected but '$e_token$' found"\r
-.errtext MISSING_COMMA                              "1043: ',' expected but '$e_token$' found"\r
-.errtext MISSING_LBRACKET                           "1044: '[' expected but '$e_token$' found"\r
-.errtext MISSING_RBRACKET                           "1045: ']' expected but '$e_token$' found"\r
-.errtext MISSING_DOT                                "1046: '.' expected but '$e_token$' found"\r
-.errtext MISSING_EQUAL                              "1047: '=' expected but '$e_token$' found"\r
-.errtext MISSING_LBRACE                             "1048: '{' expected but '$e_token$' found"\r
-.errtext MISSING_RBRACE                             "1049: '}' expected but '$e_token$' found"\r
-.errtext MISSING_DOTDOT                             "1050: '..' expected but '$e_token$' found"\r
-.errtext MISSING_FRACTION_OR_EXPONENT               "1051: missing fraction part or exponent"\r
-.errtext MISSING_DOT_OR_EXPONENT                    "1052: missing '.' or exponent"\r
-.errtext EXPONENT_VALUE_EXPECTED                    "1053: exponent value expected"\r
-.errtext INTEGER_OUT_OF_RANGE                       "1054: integer value out of range"\r
-.errtext OPERATION_NEEDS_DESTINATION_VARIABLE       "1055: operation needs destination variable"\r
-.errtext OPERATION_NEEDS_SOURCE_VARIABLE            "1056: operation needs source variable"\r
-.errtext ADDRESS_REGISTER_EXPECTED                  "1057: address register expected but '$e_token$' found"\r
-.errtext ADDRESS_REGISTER_OR_INTEGER_EXPECTED       "1058: address register or integer literal expected but '$e_token$' found"\r
-\r
-/* extension presence condition registers */\r
-\r
-/* GL_ARB_vertex_blend */\r
-/* GL_EXT_vertex_weighting */\r
-.regbyte vertex_blend                               0x00\r
-\r
-/* GL_ARB_matrix_palette */\r
-.regbyte matrix_palette                             0x00\r
-\r
-/* GL_ARB_point_parameters */\r
-/* GL_EXT_point_parameters */\r
-.regbyte point_parameters                           0x01\r
-\r
-/* GL_EXT_secondary_color */\r
-.regbyte secondary_color                            0x01\r
-\r
-/* GL_EXT_fog_coord */\r
-.regbyte fog_coord                                  0x01\r
-\r
-/* GL_EXT_texture_rectangle */\r
-/* GL_NV_texture_rectangle */\r
-.regbyte texture_rectangle                          0x01\r
-\r
-/* GL_ARB_fragment_program_shadow */\r
-.regbyte fragment_program_shadow                    0x00\r
-\r
-/* option presence condition registers */\r
-/* they are all initially set to zero - when a particular OPTION is encountered, the appropriate */\r
-/* register is set to 1 to indicate that the OPTION was specified. */\r
-\r
-/* GL_ARB_fragment_program */\r
-.regbyte ARB_precision_hint_fastest                 0x00\r
-.regbyte ARB_precision_hint_nicest                  0x00\r
-.regbyte ARB_fog_exp                                0x00\r
-.regbyte ARB_fog_exp2                               0x00\r
-.regbyte ARB_fog_linear                             0x00\r
-\r
-/* GL_ARB_vertex_program */\r
-.regbyte ARB_position_invariant                     0x00\r
-\r
-/* GL_ARB_fragment_program_shadow */\r
-.regbyte ARB_fragment_program_shadow                0x00\r
-\r
-/* program target condition register */\r
-/* this syntax script deals with two program targets - VERTEX_PROGRAM and FRAGMENT_PROGRAM. */\r
-/* to distinguish between them we need a register that will store for us the current target. */\r
-/* the client will typically set the register to apropriate value before parsing a particular */\r
-/* program. the mapping between program targets and their values is listed below. */\r
-/* */\r
-/* program target               register value    */\r
-/* ---------------------------------------------- */\r
-/* FRAGMENT_PROGRAM             0x10              */\r
-/* VERTEX_PROGRAM               0x20              */\r
-/* */\r
-/* the initial value of the register is 0 to catch potential errors with not setting the register */\r
-/* with the proper value. */\r
-.regbyte program_target                             0x00\r
-\r
-/*\r
-    <program>              ::= <optionSequence> <statementSequence> "END"\r
-*/\r
-program\r
-    programs .error UNKNOWN_PROGRAM_SIGNATURE .emit REVISION;\r
-programs\r
-    .if (program_target == 0x10) frag_program_1_0 .emit FRAGMENT_PROGRAM .emit 0x01 .emit 0x00 .or\r
-    .if (program_target == 0x20) vert_program_1_0 .emit VERTEX_PROGRAM .emit 0x01 .emit 0x00;\r
-frag_program_1_0\r
-    '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'f' .and 'p' .and '1' .and '.' .and '0' .and\r
-    optional_space .and fp_optionSequence .and fp_statementSequence .and\r
-    "END" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and\r
-    '\0' .error CODE_AFTER_END;\r
-vert_program_1_0\r
-    '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'v' .and 'p' .and '1' .and '.' .and '0' .and\r
-    optional_space .and vp_optionSequence .and vp_statementSequence .and\r
-    "END" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and\r
-    '\0' .error CODE_AFTER_END;\r
-\r
-/*\r
-    <optionSequence>       ::= <optionSequence> <option>\r
-                             | ""\r
-*/\r
-fp_optionSequence\r
-    .loop fp_option;\r
-vp_optionSequence\r
-    .loop vp_option;\r
-\r
-/*\r
-    <option>               ::= "OPTION" <identifier> ";"\r
-\r
-NOTE: options ARB_precision_hint_nicest and ARB_precision_hint_fastest are exclusive. When one of\r
-      these options is encountered, the other one is automatically disabled.\r
-      the same applies to options ARB_fog_exp, ARB_fog_exp2 and ARB_fog_linear.\r
-*/\r
-fp_option\r
-    "OPTION" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and\r
-    fp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;\r
-vp_option\r
-    "OPTION" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and\r
-    vp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;\r
-fp_optionString\r
-    .if (ARB_precision_hint_nicest == 0x00) "ARB_precision_hint_fastest"\r
-        .emit ARB_PRECISION_HINT_FASTEST .load ARB_precision_hint_fastest 0x01 .or\r
-    .if (ARB_precision_hint_fastest == 0x00) "ARB_precision_hint_nicest"\r
-        .emit ARB_PRECISION_HINT_NICEST .load ARB_precision_hint_nicest 0x01 .or\r
-    fp_ARB_fog_exp .emit ARB_FOG_EXP .load ARB_fog_exp 0x01 .or\r
-    fp_ARB_fog_exp2 .emit ARB_FOG_EXP2 .load ARB_fog_exp2 0x01 .or\r
-    fp_ARB_fog_linear .emit ARB_FOG_LINEAR .load ARB_fog_linear 0x01 .or\r
-    .if (fragment_program_shadow != 0x00) "ARB_fragment_program_shadow"\r
-        .emit ARB_FRAGMENT_PROGRAM_SHADOW .load ARB_fragment_program_shadow 0x01;\r
-vp_optionString\r
-    "ARB_position_invariant" .emit ARB_POSITION_INVARIANT .load ARB_position_invariant 0x01;\r
-fp_ARB_fog_exp\r
-    .if (ARB_fog_exp2 == 0x00) .true .and .if (ARB_fog_linear == 0x00) "ARB_fog_exp";\r
-fp_ARB_fog_exp2\r
-    .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_linear == 0x00) "ARB_fog_exp2";\r
-fp_ARB_fog_linear\r
-    .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_exp2 == 0x00) "ARB_fog_linear";\r
-\r
-/*\r
-    <statementSequence>    ::= <statementSequence> <statement>\r
-                             | ""\r
-*/\r
-fp_statementSequence\r
-    .loop fp_statement;\r
-vp_statementSequence\r
-    .loop vp_statement;\r
-\r
-/*\r
-    <statement>            ::= <instruction> ";"\r
-                             | <namingStatement> ";"\r
-\r
-NOTE: ".emit $" in the definitions below means that we output instruction position (offset of\r
-      the first character of instruction) for program debugging purposes.\r
-*/\r
-fp_statement\r
-    fp_statement_1 .or fp_statement_2;\r
-vp_statement\r
-    vp_statement_1 .or vp_statement_2;\r
-fp_statement_1\r
-    fp_instruction .emit INSTRUCTION .emit $ .and semicolon;\r
-fp_statement_2\r
-    fp_namingStatement .emit DECLARATION .and semicolon;\r
-vp_statement_1\r
-    vp_instruction .emit INSTRUCTION .emit $ .and semicolon;\r
-vp_statement_2\r
-    vp_namingStatement .emit DECLARATION .and semicolon;\r
-\r
-/*\r
-fragment program\r
-    <instruction>          ::= <ALUInstruction>\r
-                             | <TexInstruction>\r
-\r
-vertex program\r
-    <instruction>          ::= <ARL_instruction>\r
-                             | <VECTORop_instruction>\r
-                             | <SCALARop_instruction>\r
-                             | <BINSCop_instruction>\r
-                             | <BINop_instruction>\r
-                             | <TRIop_instruction>\r
-                             | <SWZ_instruction>\r
-*/\r
-fp_instruction\r
-    ALUInstruction .emit OP_ALU_INST .or\r
-    TexInstruction .emit OP_TEX_INST;\r
-vp_instruction\r
-    ARL_instruction .emit OP_ALU_ARL .or\r
-    vp_VECTORop_instruction .emit OP_ALU_VECTOR .or\r
-    vp_SCALARop_instruction .emit OP_ALU_SCALAR .or\r
-    vp_BINSCop_instruction .emit OP_ALU_BINSC .or\r
-    vp_BINop_instruction .emit OP_ALU_BIN .or\r
-    vp_TRIop_instruction .emit OP_ALU_TRI .or\r
-    vp_SWZ_instruction .emit OP_ALU_SWZ;\r
-\r
-/*\r
-fragment program\r
-    <ALUInstruction>       ::= <VECTORop_instruction>\r
-                             | <SCALARop_instruction>\r
-                             | <BINSCop_instruction>\r
-                             | <BINop_instruction>\r
-                             | <TRIop_instruction>\r
-                             | <SWZ_instruction>\r
-*/\r
-ALUInstruction\r
-    fp_VECTORop_instruction .emit OP_ALU_VECTOR .or\r
-    fp_SCALARop_instruction .emit OP_ALU_SCALAR .or\r
-    fp_BINSCop_instruction .emit OP_ALU_BINSC .or\r
-    fp_BINop_instruction .emit OP_ALU_BIN .or\r
-    fp_TRIop_instruction .emit OP_ALU_TRI .or\r
-    fp_SWZ_instruction .emit OP_ALU_SWZ;\r
-\r
-/*\r
-fragment program\r
-    <TexInstruction>       ::= <SAMPLE_instruction>\r
-                             | <KIL_instruction>\r
-*/\r
-TexInstruction\r
-    SAMPLE_instruction .emit OP_TEX_SAMPLE .or\r
-    KIL_instruction .emit OP_TEX_KIL;\r
-\r
-/*\r
-vertex program\r
-    <ARL_instruction>      ::= "ARL" <maskedAddrReg> "," <scalarSrcReg>\r
-*/\r
-ARL_instruction\r
-    "ARL" .emit OP_ARL .and space_dst .and maskedAddrReg .and comma .and vp_scalarSrcReg;\r
-\r
-/*\r
-fragment program\r
-    <VECTORop_instruction> ::= <VECTORop> <maskedDstReg> "," \r
-                               <vectorSrcReg>\r
-\r
-vertex program\r
-    <VECTORop_instruction> ::= <VECTORop> <maskedDstReg> "," <swizzleSrcReg>\r
-*/\r
-fp_VECTORop_instruction\r
-    fp_VECTORop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg;\r
-vp_VECTORop_instruction\r
-    vp_VECTORop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg;\r
-\r
-/*\r
-fragment program\r
-    <VECTORop>             ::= "ABS" | "ABS_SAT"\r
-                             | "FLR" | "FLR_SAT"\r
-                             | "FRC" | "FRC_SAT"\r
-                             | "LIT" | "LIT_SAT"\r
-                             | "MOV" | "MOV_SAT"\r
-\r
-vertex program\r
-    <VECTORop>             ::= "ABS"\r
-                             | "FLR"\r
-                             | "FRC"\r
-                             | "LIT"\r
-                             | "MOV"\r
-*/\r
-fp_VECTORop\r
-    "ABS" .emit OP_ABS .or "ABS_SAT" .emit OP_ABS_SAT .or\r
-    "FLR" .emit OP_FLR .or "FLR_SAT" .emit OP_FLR_SAT .or\r
-    "FRC" .emit OP_FRC .or "FRC_SAT" .emit OP_FRC_SAT .or\r
-    "LIT" .emit OP_LIT .or "LIT_SAT" .emit OP_LIT_SAT .or\r
-    "MOV" .emit OP_MOV .or "MOV_SAT" .emit OP_MOV_SAT;\r
-vp_VECTORop\r
-    "ABS" .emit OP_ABS .or\r
-    "FLR" .emit OP_FLR .or\r
-    "FRC" .emit OP_FRC .or\r
-    "LIT" .emit OP_LIT .or\r
-    "MOV" .emit OP_MOV;\r
-\r
-/*\r
-    <SCALARop_instruction> ::= <SCALARop> <maskedDstReg> "," <scalarSrcReg>\r
-*/\r
-fp_SCALARop_instruction\r
-    fp_SCALARop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg;\r
-vp_SCALARop_instruction\r
-    vp_SCALARop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg;\r
-\r
-/*\r
-fragment program\r
-    <SCALARop>             ::= "COS" | "COS_SAT"\r
-                             | "EX2" | "EX2_SAT"\r
-                             | "LG2" | "LG2_SAT"\r
-                             | "RCP" | "RCP_SAT"\r
-                             | "RSQ" | "RSQ_SAT"\r
-                             | "SIN" | "SIN_SAT"\r
-                             | "SCS" | "SCS_SAT"\r
-\r
-vertex program\r
-    <SCALARop>             ::= "EX2"\r
-                             | "EXP"\r
-                             | "LG2"\r
-                             | "LOG"\r
-                             | "RCP"\r
-                             | "RSQ"\r
-*/\r
-fp_SCALARop\r
-    "COS" .emit OP_COS .or "COS_SAT" .emit OP_COS_SAT .or\r
-    "EX2" .emit OP_EX2 .or "EX2_SAT" .emit OP_EX2_SAT .or\r
-    "LG2" .emit OP_LG2 .or "LG2_SAT" .emit OP_LG2_SAT .or\r
-    "RCP" .emit OP_RCP .or "RCP_SAT" .emit OP_RCP_SAT .or\r
-    "RSQ" .emit OP_RSQ .or "RSQ_SAT" .emit OP_RSQ_SAT .or\r
-    "SIN" .emit OP_SIN .or "SIN_SAT" .emit OP_SIN_SAT .or\r
-    "SCS" .emit OP_SCS .or "SCS_SAT" .emit OP_SCS_SAT;\r
-vp_SCALARop\r
-    "EX2" .emit OP_EX2 .or\r
-    "EXP" .emit OP_EXP .or\r
-    "LG2" .emit OP_LG2 .or\r
-    "LOG" .emit OP_LOG .or\r
-    "RCP" .emit OP_RCP .or\r
-    "RSQ" .emit OP_RSQ;\r
-\r
-/*\r
-    <BINSCop_instruction>  ::= <BINSCop> <maskedDstReg> "," <scalarSrcReg> ","\r
-                               <scalarSrcReg>\r
-*/\r
-fp_BINSCop_instruction\r
-    fp_BINSCop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg .and comma .and\r
-    fp_scalarSrcReg;\r
-vp_BINSCop_instruction\r
-    vp_BINSCop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg .and comma .and\r
-    vp_scalarSrcReg;\r
-\r
-/*\r
-fragment program\r
-    <BINSCop>              ::= "POW" | "POW_SAT"\r
-\r
-vertex program\r
-    <BINSCop>              ::= "POW"\r
-*/\r
-fp_BINSCop\r
-    "POW" .emit OP_POW .or "POW_SAT" .emit OP_POW_SAT;\r
-vp_BINSCop\r
-    "POW" .emit OP_POW;\r
-\r
-/*\r
-fragment program\r
-    <BINop_instruction>    ::= <BINop> <maskedDstReg> ","\r
-                               <vectorSrcReg> "," <vectorSrcReg>\r
-\r
-vertex program\r
-    <BINop_instruction>    ::= <BINop> <maskedDstReg> ","\r
-                               <swizzleSrcReg> "," <swizzleSrcReg>\r
-*/\r
-fp_BINop_instruction\r
-    fp_BINop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\r
-    vectorSrcReg;\r
-vp_BINop_instruction\r
-    vp_BINop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and\r
-    swizzleSrcReg;\r
-\r
-/*\r
-fragment program\r
-    <BINop>                ::= "ADD" | "ADD_SAT"\r
-                             | "DP3" | "DP3_SAT"\r
-                             | "DP4" | "DP4_SAT"\r
-                             | "DPH" | "DPH_SAT"\r
-                             | "DST" | "DST_SAT"\r
-                             | "MAX" | "MAX_SAT"\r
-                             | "MIN" | "MIN_SAT"\r
-                             | "MUL" | "MUL_SAT"\r
-                             | "SGE" | "SGE_SAT"\r
-                             | "SLT" | "SLT_SAT"\r
-                             | "SUB" | "SUB_SAT"\r
-                             | "XPD" | "XPD_SAT"\r
-\r
-vertex program\r
-    <BINop>                ::= "ADD"\r
-                             | "DP3"\r
-                             | "DP4"\r
-                             | "DPH"\r
-                             | "DST"\r
-                             | "MAX"\r
-                             | "MIN"\r
-                             | "MUL"\r
-                             | "SGE"\r
-                             | "SLT"\r
-                             | "SUB"\r
-                             | "XPD"\r
-*/\r
-fp_BINop\r
-    "ADD" .emit OP_ADD .or "ADD_SAT" .emit OP_ADD_SAT .or\r
-    "DP3" .emit OP_DP3 .or "DP3_SAT" .emit OP_DP3_SAT .or\r
-    "DP4" .emit OP_DP4 .or "DP4_SAT" .emit OP_DP4_SAT .or\r
-    "DPH" .emit OP_DPH .or "DPH_SAT" .emit OP_DPH_SAT .or\r
-    "DST" .emit OP_DST .or "DST_SAT" .emit OP_DST_SAT .or\r
-    "MAX" .emit OP_MAX .or "MAX_SAT" .emit OP_MAX_SAT .or\r
-    "MIN" .emit OP_MIN .or "MIN_SAT" .emit OP_MIN_SAT .or\r
-    "MUL" .emit OP_MUL .or "MUL_SAT" .emit OP_MUL_SAT .or\r
-    "SGE" .emit OP_SGE .or "SGE_SAT" .emit OP_SGE_SAT .or\r
-    "SLT" .emit OP_SLT .or "SLT_SAT" .emit OP_SLT_SAT .or\r
-    "SUB" .emit OP_SUB .or "SUB_SAT" .emit OP_SUB_SAT .or\r
-    "XPD" .emit OP_XPD .or "XPD_SAT" .emit OP_XPD_SAT;\r
-vp_BINop\r
-    "ADD" .emit OP_ADD .or\r
-    "DP3" .emit OP_DP3 .or\r
-    "DP4" .emit OP_DP4 .or\r
-    "DPH" .emit OP_DPH .or\r
-    "DST" .emit OP_DST .or\r
-    "MAX" .emit OP_MAX .or\r
-    "MIN" .emit OP_MIN .or\r
-    "MUL" .emit OP_MUL .or\r
-    "SGE" .emit OP_SGE .or\r
-    "SLT" .emit OP_SLT .or\r
-    "SUB" .emit OP_SUB .or\r
-    "XPD" .emit OP_XPD;\r
-\r
-/*\r
-fragment program\r
-    <TRIop_instruction>    ::= <TRIop> <maskedDstReg> ","\r
-                               <vectorSrcReg> "," <vectorSrcReg> ","\r
-                               <vectorSrcReg>\r
-\r
-vertex program\r
-    <TRIop_instruction>    ::= <TRIop> <maskedDstReg> ","\r
-                               <swizzleSrcReg> "," <swizzleSrcReg> ","\r
-                               <swizzleSrcReg>\r
-*/\r
-fp_TRIop_instruction\r
-    fp_TRIop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\r
-    vectorSrcReg .and comma .and vectorSrcReg;\r
-vp_TRIop_instruction\r
-    vp_TRIop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and\r
-    swizzleSrcReg .and comma .and swizzleSrcReg;\r
-\r
-/*\r
-fragment program\r
-    <TRIop>                ::= "CMP" | "CMP_SAT"\r
-                             | "LRP" | "LRP_SAT"\r
-                             | "MAD" | "MAD_SAT"\r
-\r
-vertex program\r
-    <TRIop>                ::= "MAD"\r
-*/\r
-fp_TRIop\r
-    "CMP" .emit OP_CMP .or "CMP_SAT" .emit OP_CMP_SAT .or\r
-    "LRP" .emit OP_LRP .or "LRP_SAT" .emit OP_LRP_SAT .or\r
-    "MAD" .emit OP_MAD .or "MAD_SAT" .emit OP_MAD_SAT;\r
-vp_TRIop\r
-    "MAD" .emit OP_MAD;\r
-\r
-/*\r
-fragment program\r
-    <SWZ_instruction>      ::= <SWZop> <maskedDstReg> "," \r
-                               <srcReg> "," <extendedSwizzle>\r
-\r
-vertex program\r
-    <SWZ_instruction>      ::= "SWZ" <maskedDstReg> "," <srcReg> "," \r
-                               <extendedSwizzle>\r
-*/\r
-fp_SWZ_instruction\r
-    SWZop .and space_dst .and fp_maskedDstReg .and comma .and fp_srcReg .and comma .and\r
-    fp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;\r
-vp_SWZ_instruction\r
-    "SWZ" .emit OP_SWZ .and space_dst .and vp_maskedDstReg .and comma .and vp_srcReg .and comma .and\r
-    vp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;\r
-\r
-/*\r
-fragment program\r
-    <SWZop>                ::= "SWZ" | "SWZ_SAT"\r
-*/\r
-SWZop\r
-    "SWZ" .emit OP_SWZ .or "SWZ_SAT" .emit OP_SWZ_SAT;\r
-\r
-/*\r
-fragment program\r
-    <SAMPLE_instruction>   ::= <SAMPLEop> <maskedDstReg> ","\r
-                               <vectorSrcReg> "," <texImageUnit> "," \r
-                               <texTarget>\r
-*/\r
-SAMPLE_instruction\r
-    SAMPLEop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\r
-    texImageUnit .and comma .and texTarget .error TEX_TARGET_EXPECTED;\r
-\r
-/*\r
-fragment program\r
-    <SAMPLEop>             ::= "TEX" | "TEX_SAT"\r
-                             | "TXP" | "TXP_SAT"\r
-                             | "TXB" | "TXB_SAT"\r
-*/\r
-SAMPLEop\r
-    "TEX" .emit OP_TEX .or "TEX_SAT" .emit OP_TEX_SAT .or\r
-    "TXB" .emit OP_TXB .or "TXB_SAT" .emit OP_TXB_SAT .or\r
-    "TXP" .emit OP_TXP .or "TXP_SAT" .emit OP_TXP_SAT;\r
-\r
-/*\r
-fragment program\r
-    <KIL_instruction>      ::= "KIL" <vectorSrcReg>\r
-*/\r
-KIL_instruction\r
-    "KIL" .emit OP_KIL .and space_src .and vectorSrcReg;\r
-\r
-/*\r
-fragment program\r
-    <texImageUnit>         ::= "texture" <optTexImageUnitNum>\r
-*/\r
-texImageUnit\r
-    "texture" .error TEXTURE_EXPECTED .and optTexImageUnitNum;\r
-\r
-/*\r
-fragment program\r
-    <texTarget>            ::= "1D"\r
-                             | "2D"\r
-                             | "3D"\r
-                             | "CUBE"\r
-                             | "RECT"\r
-                             | <shadowTarget> (if option ARB_fragment_program_shadow present)\r
-*/\r
-texTarget\r
-    "1D" .emit TEXTARGET_1D .or\r
-    "2D" .emit TEXTARGET_2D .or\r
-    "3D" .emit TEXTARGET_3D .or\r
-    .if (texture_rectangle != 0x00) "RECT" .emit TEXTARGET_RECT .or\r
-    "CUBE" .emit TEXTARGET_CUBE .or\r
-    .if (ARB_fragment_program_shadow != 0x00) shadowTarget;\r
-\r
-/*\r
-GL_ARB_fragment_program_shadow\r
-    <shadowTarget>         ::= "SHADOW1D"\r
-                             | "SHADOW2D"\r
-                             | "SHADOWRECT"\r
-*/\r
-shadowTarget\r
-    "SHADOW1D" .emit TEXTARGET_SHADOW1D .or\r
-    "SHADOW2D" .emit TEXTARGET_SHADOW2D .or\r
-    .if (texture_rectangle != 0x00) "SHADOWRECT" .emit TEXTARGET_SHADOWRECT;\r
-\r
-/*\r
-fragment program\r
-    <optTexImageUnitNum>   ::= ""\r
-                             | "[" <texImageUnitNum> "]"\r
-*/\r
-optTexImageUnitNum\r
-    optTexImageUnitNum_1 .or .true .emit 0x00;\r
-optTexImageUnitNum_1\r
-    lbracket_ne .and texImageUnitNum .and rbracket;\r
-\r
-/*\r
-fragment program\r
-    <texImageUnitNum>      ::= <integer> from 0 to \r
-                               MAX_TEXTURE_IMAGE_UNITS_ARB-1\r
-*/\r
-texImageUnitNum\r
-    integer;\r
-\r
-/*\r
-    <scalarSrcReg>         ::= <optionalSign> <srcReg> <scalarSuffix>\r
-*/\r
-fp_scalarSrcReg\r
-    optionalSign .and fp_srcReg .and fp_scalarSuffix;\r
-vp_scalarSrcReg\r
-    optionalSign .and vp_srcReg .and vp_scalarSuffix;\r
-\r
-/*\r
-vertex program\r
-    <swizzleSrcReg>        ::= <optionalSign> <srcReg> <swizzleSuffix>\r
-*/\r
-swizzleSrcReg\r
-    optionalSign .and vp_srcReg .and swizzleSuffix;\r
-\r
-/*\r
-fragment program\r
-    <vectorSrcReg>         ::= <optionalSign> <srcReg> <optionalSuffix> \r
-*/\r
-vectorSrcReg\r
-    optionalSign .and fp_srcReg .and optionalSuffix;\r
-\r
-/*\r
-    <maskedDstReg>         ::= <dstReg> <optionalMask>\r
-*/\r
-fp_maskedDstReg\r
-    fp_dstReg .and fp_optionalMask;\r
-vp_maskedDstReg\r
-    vp_dstReg .and vp_optionalMask;\r
-\r
-/*\r
-vertex program\r
-    <maskedAddrReg>        ::= <addrReg> <addrWriteMask>\r
-*/\r
-maskedAddrReg\r
-    addrReg .error ADDRESS_REGISTER_EXPECTED .and addrWriteMask;\r
-\r
-/*\r
-fragment program\r
-    <extendedSwizzle>      ::= <xyzwExtendedSwizzle>\r
-                             | <rgbaExtendedSwizzle>\r
-\r
-vertex program\r
-    <extendedSwizzle>      ::= <extSwizComp> "," <extSwizComp> "," \r
-                                 <extSwizComp> "," <extSwizComp>\r
-\r
-NOTE: do NOT change the order of <rgbaExtendedSwizzle> and <xyzwExtendedSwizzle> rulez\r
-*/\r
-fp_extendedSwizzle\r
-    rgbaExtendedSwizzle .or xyzwExtendedSwizzle;\r
-vp_extendedSwizzle\r
-    extSwizComp .and comma .and\r
-    extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\r
-    extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\r
-    extSwizComp .error EXT_SWIZ_COMP_EXPECTED;\r
-\r
-/*\r
-fragment program\r
-    <xyzwExtendedSwizzle>  ::= <xyzwExtSwizComp> "," <xyzwExtSwizComp> "," \r
-                               <xyzwExtSwizComp> "," <xyzwExtSwizComp>\r
-*/\r
-xyzwExtendedSwizzle\r
-    xyzwExtSwizComp .and comma .and\r
-    xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\r
-    xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\r
-    xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\r
-\r
-/*\r
-fragment program\r
-    <rgbaExtendedSwizzle>  ::= <rgbaExtSwizComp> "," <rgbaExtSwizComp> "," \r
-                               <rgbaExtSwizComp> "," <rgbaExtSwizComp>\r
-*/\r
-rgbaExtendedSwizzle\r
-    rgbaExtendedSwizzle_1 .or rgbaExtendedSwizzle_2 .or rgbaExtendedSwizzle_3 .or\r
-    rgbaExtendedSwizzle_4;\r
-rgbaExtendedSwizzle_1\r
-    rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and\r
-    rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp;\r
-rgbaExtendedSwizzle_2\r
-    rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and\r
-    rgbaExtSwizComp_alpha .and comma .and rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\r
-rgbaExtendedSwizzle_3\r
-    rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_alpha .and comma .and\r
-    rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\r
-    rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\r
-rgbaExtendedSwizzle_4\r
-    rgbaExtSwizComp_alpha .and comma .and \r
-    rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\r
-    rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\r
-    rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\r
-\r
-/*\r
-fragment program\r
-    <xyzwExtSwizComp>      ::= <optionalSign> <xyzwExtSwizSel>\r
-*/\r
-xyzwExtSwizComp\r
-    optionalSign .and xyzwExtSwizSel;\r
-\r
-/*\r
-fragment program\r
-    <rgbaExtSwizComp>      ::= <optionalSign> <rgbaExtSwizSel>\r
-*/\r
-rgbaExtSwizComp\r
-    optionalSign .and rgbaExtSwizSel;\r
-rgbaExtSwizComp_digit\r
-    optionalSign .and rgbaExtSwizSel_digit;\r
-rgbaExtSwizComp_alpha\r
-    optionalSign .and rgbaExtSwizSel_alpha;\r
-\r
-/*\r
-vertex program\r
-    <extSwizComp>          ::= <optionalSign> <extSwizSel>\r
-*/\r
-extSwizComp\r
-    optionalSign .and extSwizSel;\r
-\r
-/*\r
-fragment program\r
-    <xyzwExtSwizSel>       ::= "0" \r
-                             | "1" \r
-                             | <xyzwComponent>\r
-*/\r
-xyzwExtSwizSel\r
-    "0" .emit COMPONENT_0 .or "1" .emit COMPONENT_1 .or xyzwComponent_single;\r
-\r
-/*\r
-fragment program\r
-    <rgbaExtSwizSel>       ::= "0" \r
-                             | "1" \r
-                             | <rgbaComponent>\r
-*/\r
-rgbaExtSwizSel\r
-    rgbaExtSwizSel_digit .or rgbaExtSwizSel_alpha;\r
-rgbaExtSwizSel_digit\r
-    "0" .emit COMPONENT_0 .or "1" .emit COMPONENT_1;\r
-rgbaExtSwizSel_alpha\r
-    rgbaComponent_single;\r
-\r
-/*\r
-vertex program\r
-    <extSwizSel>           ::= "0" \r
-                             | "1" \r
-                             | <component>\r
-*/\r
-extSwizSel\r
-    "0" .emit COMPONENT_0 .or "1" .emit COMPONENT_1 .or vp_component_single;\r
-\r
-/*\r
-fragment program\r
-    <srcReg>               ::= <fragmentAttribReg>\r
-                             | <temporaryReg>\r
-                             | <progParamReg>\r
-\r
-vertex program\r
-    <srcReg>               ::= <vertexAttribReg>\r
-                             | <temporaryReg>\r
-                             | <progParamReg>\r
-*/\r
-fp_srcReg\r
-    fp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;\r
-vp_srcReg\r
-    vp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;\r
-fp_srcReg_1\r
-    fragmentAttribReg .emit REGISTER_ATTRIB .or\r
-    fp_progParamReg .emit REGISTER_PARAM .or\r
-    fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\r
-vp_srcReg_1\r
-    vertexAttribReg .emit REGISTER_ATTRIB .or\r
-    vp_progParamReg .emit REGISTER_PARAM .or\r
-    vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\r
-\r
-/*\r
-fragment program\r
-    <dstReg>               ::= <temporaryReg>\r
-                             | <fragmentResultReg>\r
-\r
-vertex program\r
-    <dstReg>               ::= <temporaryReg>\r
-                             | <vertexResultReg>\r
-*/\r
-fp_dstReg\r
-    fp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;\r
-vp_dstReg\r
-    vp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;\r
-fp_dstReg_1\r
-    fragmentResultReg .emit REGISTER_RESULT .or\r
-    fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\r
-vp_dstReg_1\r
-    vertexResultReg .emit REGISTER_RESULT .or\r
-    vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\r
-\r
-/*\r
-fragment program\r
-    <fragmentAttribReg>    ::= <establishedName>\r
-                             | <fragAttribBinding>\r
-\r
-NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <srcReg>\r
-*/\r
-fragmentAttribReg\r
-    /*fp_establishedName .or */fragAttribBinding;\r
-\r
-/*\r
-vertex program\r
-    <vertexAttribReg>      ::= <establishedName>\r
-                             | <vtxAttribBinding>\r
-\r
-NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <srcReg>\r
-*/\r
-vertexAttribReg\r
-    vtxAttribBinding;\r
-\r
-/*\r
-    <temporaryReg>         ::= <establishedName>\r
-*/\r
-fp_temporaryReg\r
-    fp_establishedName_no_error_on_identifier;\r
-vp_temporaryReg\r
-    vp_establishedName_no_error_on_identifier;\r
-\r
-/*\r
-fragment program\r
-    <progParamReg>         ::= <progParamSingle>\r
-                             | <progParamArray> "[" <progParamArrayAbs> "]"\r
-                             | <paramSingleItemUse>\r
-\r
-vertex program\r
-    <progParamReg>         ::= <progParamSingle>\r
-                             | <progParamArray> "[" <progParamArrayMem> "]"\r
-                             | <paramSingleItemUse>\r
-*/\r
-fp_progParamReg\r
-    fp_paramSingleItemUse .or fp_progParamReg_1 .or fp_progParamSingle;\r
-vp_progParamReg\r
-    vp_paramSingleItemUse .or vp_progParamReg_1 .or vp_progParamSingle;\r
-fp_progParamReg_1\r
-    fp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayAbs .and\r
-    rbracket;\r
-vp_progParamReg_1\r
-    vp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayMem .and\r
-    rbracket;\r
-\r
-/*\r
-    <progParamSingle>      ::= <establishedName>\r
-\r
-NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <srcReg>\r
-*/\r
-fp_progParamSingle\r
-    .false;\r
-vp_progParamSingle\r
-    .false;\r
-\r
-/*\r
-    <progParamArray>       ::= <establishedName>\r
-*/\r
-fp_progParamArray\r
-    fp_establishedName_no_error_on_identifier;\r
-vp_progParamArray\r
-    vp_establishedName_no_error_on_identifier;\r
-\r
-/*\r
-vertex program\r
-    <progParamArrayMem>    ::= <progParamArrayAbs>\r
-                             | <progParamArrayRel>\r
-*/\r
-progParamArrayMem\r
-    progParamArrayAbs .or progParamArrayRel;\r
-\r
-/*\r
-    <progParamArrayAbs>    ::= <integer>\r
-*/\r
-progParamArrayAbs\r
-    integer_ne .emit ARRAY_INDEX_ABSOLUTE;\r
-\r
-/*\r
-vertex program\r
-    <progParamArrayRel>    ::= <addrReg> <addrComponent> <addrRegRelOffset>\r
-*/\r
-progParamArrayRel\r
-    addrReg .error ADDRESS_REGISTER_OR_INTEGER_EXPECTED .emit ARRAY_INDEX_RELATIVE .and\r
-    addrComponent .and addrRegRelOffset;\r
-\r
-/*\r
-vertex program\r
-    <addrRegRelOffset>     ::= ""\r
-                             | "+" <addrRegPosOffset>\r
-                             | "-" <addrRegNegOffset>\r
-*/\r
-addrRegRelOffset\r
-    addrRegRelOffset_1 .or addrRegRelOffset_2 .or .true .emit 0x00;\r
-addrRegRelOffset_1\r
-    plus_ne .and addrRegPosOffset;\r
-addrRegRelOffset_2\r
-    minus_ne .and addrRegNegOffset;\r
-\r
-/*\r
-vertex program\r
-    <addrRegPosOffset>     ::= <integer> from 0 to 63\r
-*/\r
-addrRegPosOffset\r
-    integer_0_63;\r
-\r
-/*\r
-vertex program\r
-    <addrRegNegOffset>     ::= <integer> from 0 to 64\r
-*/\r
-addrRegNegOffset\r
-    integer_0_64;\r
-\r
-/*\r
-fragment program\r
-    <fragmentResultReg>    ::= <establishedName>\r
-                             | <resultBinding>\r
-\r
-NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <dstReg>\r
-*/\r
-fragmentResultReg\r
-    fp_resultBinding;\r
-\r
-/*\r
-vertex program\r
-    <vertexResultReg>      ::= <establishedName>\r
-                             | <resultBinding>\r
-\r
-NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <dstReg>\r
-*/\r
-vertexResultReg\r
-    vp_resultBinding;\r
-\r
-/*\r
-vertex program\r
-    <addrReg>              ::= <establishedName>\r
-*/\r
-addrReg\r
-    vp_establishedName_no_error_on_identifier;\r
-\r
-/*\r
-vertex program\r
-    <addrComponent>        ::= "." "x"\r
-*/\r
-addrComponent\r
-    dot .and "x" .error INVALID_ADDRESS_COMPONENT .emit COMPONENT_X .emit COMPONENT_X\r
-    .emit COMPONENT_X .emit COMPONENT_X;\r
-\r
-/*\r
-vertex program\r
-    <addrWriteMask>        ::= "." "x"\r
-*/\r
-addrWriteMask\r
-    dot .and "x" .error INVALID_ADDRESS_WRITEMASK .emit 0x08;\r
-\r
-/*\r
-    <scalarSuffix>         ::= "." <component>\r
-*/\r
-fp_scalarSuffix\r
-    dot .and fp_component_single .error INVALID_COMPONENT;\r
-vp_scalarSuffix\r
-    dot .and vp_component_single .error INVALID_COMPONENT;\r
-\r
-/*\r
-vertex program\r
-    <swizzleSuffix>        ::= ""\r
-                             | "." <component>\r
-                             | "." <component> <component>\r
-                                   <component> <component>\r
-*/\r
-swizzleSuffix\r
-    swizzleSuffix_1 .or\r
-    .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;\r
-swizzleSuffix_1\r
-    dot_ne .and swizzleSuffix_2 .error INVALID_SUFFIX;\r
-swizzleSuffix_2\r
-    swizzleSuffix_3 .or swizzleSuffix_4;\r
-swizzleSuffix_3\r
-    vp_component_multi .and vp_component_multi .and vp_component_multi .error INVALID_COMPONENT .and\r
-    vp_component_multi .error INVALID_COMPONENT;\r
-swizzleSuffix_4\r
-    "x" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\r
-    "y" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\r
-    "z" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\r
-    "w" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;\r
-\r
-/*\r
-fragment program\r
-    <optionalSuffix>       ::= "" \r
-                             | "." <component> \r
-                             | "." <xyzwComponent> <xyzwComponent>\r
-                                   <xyzwComponent> <xyzwComponent>\r
-                             | "." <rgbaComponent> <rgbaComponent>\r
-                                   <rgbaComponent> <rgbaComponent>\r
-*/\r
-optionalSuffix\r
-    optionalSuffix_1 .or\r
-    .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;\r
-optionalSuffix_1\r
-    dot_ne .and optionalSuffix_2 .error INVALID_SUFFIX;\r
-optionalSuffix_2\r
-    optionalSuffix_3 .or optionalSuffix_4 .or optionalSuffix_5;\r
-optionalSuffix_3\r
-    xyzwComponent_multi .and xyzwComponent_multi .and\r
-    xyzwComponent_multi .error INVALID_COMPONENT .and xyzwComponent_multi .error INVALID_COMPONENT;\r
-optionalSuffix_4\r
-    rgbaComponent_multi .and rgbaComponent_multi .and\r
-    rgbaComponent_multi .error INVALID_COMPONENT .and rgbaComponent_multi .error INVALID_COMPONENT;\r
-optionalSuffix_5\r
-    "x" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\r
-    "y" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\r
-    "z" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\r
-    "w" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .or\r
-    "r" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\r
-    "g" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\r
-    "b" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\r
-    "a" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;\r
-\r
-/*\r
-fragment program\r
-    <component>            ::= <xyzwComponent>\r
-                             | <rgbaComponent>\r
-\r
-vertex program\r
-    <component>            ::= "x"\r
-                             | "y"\r
-                             | "z"\r
-                             | "w"\r
-*/\r
-fp_component_single\r
-    xyzwComponent_single .or rgbaComponent_single;\r
-vp_component_multi\r
-    'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or\r
-    'w' .emit COMPONENT_W;\r
-vp_component_single\r
-    "x" .emit COMPONENT_X .or "y" .emit COMPONENT_Y .or "z" .emit COMPONENT_Z .or\r
-    "w" .emit COMPONENT_W;\r
-\r
-/*\r
-fragment program\r
-    <xyzwComponent>        ::= "x" | "y" | "z" | "w"\r
-*/\r
-xyzwComponent_multi\r
-    'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or\r
-    'w' .emit COMPONENT_W;\r
-xyzwComponent_single\r
-    "x" .emit COMPONENT_X .or "y" .emit COMPONENT_Y .or "z" .emit COMPONENT_Z .or\r
-    "w" .emit COMPONENT_W;\r
-\r
-/*\r
-fragment program\r
-    <rgbaComponent>        ::= "r" | "g" | "b" | "a"\r
-*/\r
-rgbaComponent_multi\r
-    'r' .emit COMPONENT_X .or 'g' .emit COMPONENT_Y .or 'b' .emit COMPONENT_Z .or\r
-    'a' .emit COMPONENT_W;\r
-rgbaComponent_single\r
-    "r" .emit COMPONENT_X .or "g" .emit COMPONENT_Y .or "b" .emit COMPONENT_Z .or\r
-    "a" .emit COMPONENT_W;\r
-\r
-/*\r
-fragment program\r
-    <optionalMask>         ::= ""\r
-                             | <xyzwMask>\r
-                             | <rgbaMask>\r
-\r
-vertex program\r
-    <optionalMask>         ::= ""\r
-                             | "." "x"\r
-                             | "." "y"\r
-                             | "." "xy"\r
-                             | "." "z"\r
-                             | "." "xz"\r
-                             | "." "yz"\r
-                             | "." "xyz"\r
-                             | "." "w"\r
-                             | "." "xw"\r
-                             | "." "yw"\r
-                             | "." "xyw"\r
-                             | "." "zw"\r
-                             | "." "xzw"\r
-                             | "." "yzw"\r
-                             | "." "xyzw"\r
-\r
-NOTE: do NOT change the order of <rgbaMask> and <xyzwMask> rulez\r
-*/\r
-fp_optionalMask\r
-    rgbaMask .or xyzwMask .or .true .emit 0x0F;\r
-vp_optionalMask\r
-    xyzwMask .or .true .emit 0x0F;\r
-\r
-/*\r
-fragment program\r
-    <xyzwMask>             ::= "." "x"\r
-                             | "." "y"\r
-                             | "." "xy"\r
-                             | "." "z"\r
-                             | "." "xz"\r
-                             | "." "yz"\r
-                             | "." "xyz"\r
-                             | "." "w"\r
-                             | "." "xw"\r
-                             | "." "yw"\r
-                             | "." "xyw"\r
-                             | "." "zw"\r
-                             | "." "xzw"\r
-                             | "." "yzw"\r
-                             | "." "xyzw"\r
-\r
-NOTE: <xyzwMask> is also referenced by the vertex program symbol <optionalMask>.\r
-*/\r
-xyzwMask\r
-    dot_ne .and xyzwMask_1 .error INVALID_WRITEMASK;\r
-xyzwMask_1\r
-    "xyzw" .emit 0x0F .or "xyz" .emit 0x0E .or "xyw" .emit 0x0D .or "xy" .emit 0x0C .or\r
-    "xzw" .emit 0x0B .or "xz" .emit 0x0A .or "xw" .emit 0x09 .or "x" .emit 0x08 .or\r
-    "yzw" .emit 0x07 .or "yz" .emit 0x06 .or "yw" .emit 0x05 .or "y" .emit 0x04 .or\r
-    "zw" .emit 0x03 .or "z" .emit 0x02 .or "w" .emit 0x01;\r
-\r
-/*\r
-fragment program\r
-    <rgbaMask>             ::= "." "r"\r
-                             | "." "g"\r
-                             | "." "rg"\r
-                             | "." "b"\r
-                             | "." "rb"\r
-                             | "." "gb"\r
-                             | "." "rgb"\r
-                             | "." "a"\r
-                             | "." "ra"\r
-                             | "." "ga"\r
-                             | "." "rga"\r
-                             | "." "ba"\r
-                             | "." "rba"\r
-                             | "." "gba"\r
-                             | "." "rgba"\r
-*/\r
-rgbaMask\r
-    dot_ne .and rgbaMask_1;\r
-rgbaMask_1\r
-    "rgba" .emit 0x0F .or "rgb" .emit 0x0E .or "rga" .emit 0x0D .or "rg" .emit 0x0C .or\r
-    "rba" .emit 0x0B .or "rb" .emit 0x0A .or "ra" .emit 0x09 .or "r" .emit 0x08 .or\r
-    "gba" .emit 0x07 .or "gb" .emit 0x06 .or "ga" .emit 0x05 .or "g" .emit 0x04 .or\r
-    "ba" .emit 0x03 .or "b" .emit 0x02 .or "a" .emit 0x01;\r
-\r
-/*\r
-fragment program\r
-    <namingStatement>      ::= <ATTRIB_statement>\r
-                             | <PARAM_statement>\r
-                             | <TEMP_statement>\r
-                             | <OUTPUT_statement>\r
-                             | <ALIAS_statement>\r
-\r
-vertex program\r
-    <namingStatement>      ::= <ATTRIB_statement>\r
-                             | <PARAM_statement>\r
-                             | <TEMP_statement>\r
-                             | <ADDRESS_statement>\r
-                             | <OUTPUT_statement>\r
-                             | <ALIAS_statement>\r
-*/\r
-fp_namingStatement\r
-    fp_ATTRIB_statement .emit ATTRIB .or\r
-    fp_PARAM_statement .emit PARAM .or\r
-    fp_TEMP_statement .emit TEMP .or\r
-    fp_OUTPUT_statement .emit OUTPUT .or\r
-    fp_ALIAS_statement .emit ALIAS;\r
-vp_namingStatement\r
-    vp_ATTRIB_statement .emit ATTRIB .or\r
-    vp_PARAM_statement .emit PARAM .or\r
-    vp_TEMP_statement .emit TEMP .or\r
-    ADDRESS_statement .emit ADDRESS .or\r
-    vp_OUTPUT_statement .emit OUTPUT .or\r
-    vp_ALIAS_statement .emit ALIAS;\r
-\r
-/*\r
-fragment program\r
-    <ATTRIB_statement>     ::= "ATTRIB" <establishName> "="\r
-                                 <fragAttribBinding>\r
-\r
-vertex program\r
-    <ATTRIB_statement>     ::= "ATTRIB" <establishName> "="\r
-                                 <vtxAttribBinding>\r
-*/\r
-fp_ATTRIB_statement\r
-    "ATTRIB" .and space .and fp_establishName .and equal .and\r
-    fragAttribBinding .error FRAGMENT_EXPECTED;\r
-vp_ATTRIB_statement\r
-    "ATTRIB" .and space .and vp_establishName .and equal .and\r
-    vtxAttribBinding .error VERTEX_EXPECTED;\r
-\r
-/*\r
-fragment program\r
-    <fragAttribBinding>    ::= "fragment" "." <fragAttribItem>\r
-*/\r
-fragAttribBinding\r
-    "fragment" .and dot .and fragAttribItem .error INVALID_FRAGMENT_PROPERTY;\r
-\r
-/*\r
-vertex program\r
-    <vtxAttribBinding>     ::= "vertex" "." <vtxAttribItem>\r
-*/\r
-vtxAttribBinding\r
-    "vertex" .and dot .and vtxAttribItem .error INVALID_VERTEX_PROPERTY;\r
-\r
-/*\r
-fragment program\r
-    <fragAttribItem>       ::= "color" <optColorType>\r
-                             | "texcoord" <optTexCoordNum>\r
-                             | "fogcoord"\r
-                             | "position"\r
-*/\r
-fragAttribItem\r
-    fragAttribItem_1 .emit FRAGMENT_ATTRIB_COLOR .or\r
-    fragAttribItem_2 .emit FRAGMENT_ATTRIB_TEXCOORD .or\r
-    .if (fog_coord != 0x00) "fogcoord" .emit FRAGMENT_ATTRIB_FOGCOORD .or\r
-    "position" .emit FRAGMENT_ATTRIB_POSITION;\r
-fragAttribItem_1\r
-    "color" .and optColorType;\r
-fragAttribItem_2\r
-    "texcoord" .and optTexCoordNum;\r
-\r
-/*\r
-vertex program\r
-    <vtxAttribItem>        ::= "position"\r
-                             | "weight" <vtxOptWeightNum>\r
-                             | "normal"\r
-                             | "color" <optColorType>\r
-                             | "fogcoord"\r
-                             | "texcoord" <optTexCoordNum>\r
-                             | "matrixindex" "[" <vtxWeightNum> "]"\r
-                             | "attrib" "[" <vtxAttribNum> "]"\r
-*/\r
-vtxAttribItem\r
-    "position" .emit VERTEX_ATTRIB_POSITION .or\r
-    .if (vertex_blend != 0x00) vtxAttribItem_1 .emit VERTEX_ATTRIB_WEIGHT .or\r
-    "normal" .emit VERTEX_ATTRIB_NORMAL .or\r
-    vtxAttribItem_2 .emit VERTEX_ATTRIB_COLOR .or\r
-    "fogcoord" .emit VERTEX_ATTRIB_FOGCOORD .or\r
-    vtxAttribItem_3 .emit VERTEX_ATTRIB_TEXCOORD .or\r
-    .if (matrix_palette != 0x00) vtxAttribItem_4 .emit VERTEX_ATTRIB_MATRIXINDEX .or\r
-    vtxAttribItem_5 .emit VERTEX_ATTRIB_GENERIC;\r
-vtxAttribItem_1\r
-    "weight" .and vtxOptWeightNum;\r
-vtxAttribItem_2\r
-    "color" .and optColorType;\r
-vtxAttribItem_3\r
-    "texcoord" .and optTexCoordNum;\r
-vtxAttribItem_4\r
-    "matrixindex" .and lbracket .and vtxWeightNum .and rbracket;\r
-vtxAttribItem_5\r
-    "attrib" .and lbracket .and vtxAttribNum .and rbracket;\r
-\r
-/*\r
-vertex program\r
-    <vtxAttribNum>         ::= <integer> from 0 to MAX_VERTEX_ATTRIBS_ARB-1\r
-*/\r
-vtxAttribNum\r
-    integer;\r
-\r
-/*\r
-vertex program\r
-    <vtxOptWeightNum>      ::= ""\r
-                             | "[" <vtxWeightNum> "]"\r
-*/\r
-vtxOptWeightNum\r
-    vtxOptWeightNum_1 .or .true .emit 0x00;\r
-vtxOptWeightNum_1\r
-    lbracket_ne .and vtxWeightNum .and rbracket;\r
-\r
-/*\r
-vertex program\r
-    <vtxWeightNum>         ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1,\r
-                                 must be divisible by four\r
-*/\r
-vtxWeightNum\r
-    integer;\r
-\r
-/*\r
-    <PARAM_statement>      ::= <PARAM_singleStmt>\r
-                             | <PARAM_multipleStmt>\r
-*/\r
-fp_PARAM_statement\r
-    fp_PARAM_multipleStmt .or fp_PARAM_singleStmt;\r
-vp_PARAM_statement\r
-    vp_PARAM_multipleStmt .or vp_PARAM_singleStmt;\r
-\r
-/*\r
-    <PARAM_singleStmt>     ::= "PARAM" <establishName> <paramSingleInit>\r
-*/\r
-fp_PARAM_singleStmt\r
-    "PARAM" .and space .and fp_establishName .and .true .emit 0x00 .and fp_paramSingleInit .and\r
-    .true .emit PARAM_NULL;\r
-vp_PARAM_singleStmt\r
-    "PARAM" .and space .and vp_establishName .and .true .emit 0x00 .and vp_paramSingleInit .and\r
-    .true .emit PARAM_NULL;\r
-\r
-/*\r
-    <PARAM_multipleStmt>   ::= "PARAM" <establishName> "[" <optArraySize> "]"\r
-                                   <paramMultipleInit>\r
-*/\r
-fp_PARAM_multipleStmt\r
-    "PARAM" .and space .and fp_establishName .and lbracket_ne .and optArraySize .and rbracket .and\r
-    fp_paramMultipleInit .and .true .emit PARAM_NULL;\r
-vp_PARAM_multipleStmt\r
-    "PARAM" .and space .and vp_establishName .and lbracket_ne .and optArraySize .and rbracket .and\r
-    vp_paramMultipleInit .and .true .emit PARAM_NULL;\r
-\r
-/*\r
-    <optArraySize>         ::= ""\r
-                             | <integer> from 1 to MAX_PROGRAM_PARAMETERS_ARB\r
-                                 (maximum number of allowed program \r
-                                  parameter bindings)\r
-*/\r
-optArraySize\r
-    optional_integer;\r
-\r
-/*\r
-    <paramSingleInit>      ::= "=" <paramSingleItemDecl>\r
-*/\r
-fp_paramSingleInit\r
-    equal .and fp_paramSingleItemDecl;\r
-vp_paramSingleInit\r
-    equal .and vp_paramSingleItemDecl;\r
-\r
-/*\r
-    <paramMultipleInit>    ::= "=" "{" <paramMultInitList> "}"\r
-*/\r
-fp_paramMultipleInit\r
-    equal .and lbrace .and fp_paramMultInitList .and rbrace;\r
-vp_paramMultipleInit\r
-    equal .and lbrace .and vp_paramMultInitList .and rbrace;\r
-\r
-/*\r
-    <paramMultInitList>    ::= <paramMultipleItem>\r
-                             | <paramMultipleItem> "," <paramMultiInitList>\r
-*/\r
-fp_paramMultInitList\r
-    fp_paramMultInitList_1 .or fp_paramMultipleItem;\r
-vp_paramMultInitList\r
-    vp_paramMultInitList_1 .or vp_paramMultipleItem;\r
-fp_paramMultInitList_1\r
-    fp_paramMultipleItem .and comma_ne .and fp_paramMultInitList;\r
-vp_paramMultInitList_1\r
-    vp_paramMultipleItem .and comma_ne .and vp_paramMultInitList;\r
-\r
-/*\r
-    <paramSingleItemDecl>  ::= <stateSingleItem>\r
-                             | <programSingleItem>\r
-                             | <paramConstDecl>\r
-*/\r
-fp_paramSingleItemDecl\r
-    fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\r
-    programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\r
-    paramConstDecl .emit PARAM_CONSTANT;\r
-vp_paramSingleItemDecl\r
-    vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\r
-    programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\r
-    paramConstDecl .emit PARAM_CONSTANT;\r
-\r
-/*\r
-    <paramSingleItemUse>   ::= <stateSingleItem>\r
-                             | <programSingleItem>\r
-                             | <paramConstUse>\r
-*/\r
-fp_paramSingleItemUse\r
-    fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\r
-    programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\r
-    paramConstUse .emit PARAM_CONSTANT;\r
-vp_paramSingleItemUse\r
-    vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\r
-    programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\r
-    paramConstUse .emit PARAM_CONSTANT;\r
-\r
-/*\r
-    <paramMultipleItem>    ::= <stateMultipleItem>\r
-                             | <programMultipleItem>\r
-                             | <paramConstDecl>\r
-*/\r
-fp_paramMultipleItem\r
-    fp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or\r
-    programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or\r
-    paramConstDecl .emit PARAM_CONSTANT;\r
-vp_paramMultipleItem\r
-    vp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or\r
-    programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or\r
-    paramConstDecl .emit PARAM_CONSTANT;\r
-\r
-/*\r
-    <stateMultipleItem>    ::= <stateSingleItem>\r
-                             | "state" "." <stateMatrixRows>\r
-*/\r
-fp_stateMultipleItem\r
-    stateMultipleItem_1 .or fp_stateSingleItem;\r
-vp_stateMultipleItem\r
-    stateMultipleItem_1 .or vp_stateSingleItem;\r
-stateMultipleItem_1\r
-    "state" .and dot .and stateMatrixRows .emit STATE_MATRIX_ROWS;\r
-\r
-/*\r
-fragment program\r
-    <stateSingleItem>      ::= "state" "." <stateMaterialItem>\r
-                             | "state" "." <stateLightItem>\r
-                             | "state" "." <stateLightModelItem>\r
-                             | "state" "." <stateLightProdItem>\r
-                             | "state" "." <stateTexEnvItem>\r
-                             | "state" "." <stateFogItem>\r
-                             | "state" "." <stateDepthItem>\r
-                             | "state" "." <stateMatrixRow>\r
-\r
-vertex program\r
-    <stateSingleItem>      ::= "state" "." <stateMaterialItem>\r
-                             | "state" "." <stateLightItem>\r
-                             | "state" "." <stateLightModelItem>\r
-                             | "state" "." <stateLightProdItem>\r
-                             | "state" "." <stateTexGenItem>\r
-                             | "state" "." <stateFogItem>\r
-                             | "state" "." <stateClipPlaneItem>\r
-                             | "state" "." <statePointItem>\r
-                             | "state" "." <stateMatrixRow>\r
-*/\r
-fp_stateSingleItem\r
-    "state" .and dot .and fp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;\r
-vp_stateSingleItem\r
-    "state" .and dot .and vp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;\r
-fp_stateSingleItem_1\r
-    stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or\r
-    stateSingleItem_5 .or stateSingleItem_7 .or stateSingleItem_8 .or stateSingleItem_11;\r
-vp_stateSingleItem_1\r
-    stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or\r
-    stateSingleItem_6 .or stateSingleItem_7 .or stateSingleItem_9 .or stateSingleItem_10 .or\r
-    stateSingleItem_11;\r
-stateSingleItem_1\r
-    stateMaterialItem .emit STATE_MATERIAL;\r
-stateSingleItem_2\r
-    stateLightItem .emit STATE_LIGHT;\r
-stateSingleItem_3\r
-    stateLightModelItem .emit STATE_LIGHT_MODEL;\r
-stateSingleItem_4\r
-    stateLightProdItem .emit STATE_LIGHT_PROD;\r
-stateSingleItem_5\r
-    stateTexEnvItem .emit STATE_TEX_ENV;\r
-stateSingleItem_6\r
-    stateTexGenItem .emit STATE_TEX_GEN;\r
-stateSingleItem_7\r
-    stateFogItem .emit STATE_FOG;\r
-stateSingleItem_8\r
-    stateDepthItem .emit STATE_DEPTH;\r
-stateSingleItem_9\r
-    stateClipPlaneItem .emit STATE_CLIP_PLANE;\r
-stateSingleItem_10\r
-    statePointItem .emit STATE_POINT;\r
-stateSingleItem_11\r
-    stateMatrixRow .emit STATE_MATRIX_ROWS;\r
-\r
-/*\r
-    <stateMaterialItem>    ::= "material" <optFaceType> "." <stateMatProperty>\r
-*/\r
-stateMaterialItem\r
-    "material" .and optFaceType .and dot .and stateMatProperty .error INVALID_MATERIAL_PROPERTY;\r
-\r
-/*\r
-    <stateMatProperty>     ::= "ambient"\r
-                             | "diffuse"\r
-                             | "specular"\r
-                             | "emission"\r
-                             | "shininess"\r
-*/\r
-stateMatProperty\r
-    "ambient" .emit MATERIAL_AMBIENT .or\r
-    "diffuse" .emit MATERIAL_DIFFUSE .or\r
-    "specular" .emit MATERIAL_SPECULAR .or\r
-    "emission" .emit MATERIAL_EMISSION .or\r
-    "shininess" .emit MATERIAL_SHININESS;\r
-\r
-/*\r
-    <stateLightItem>       ::= "light" "[" <stateLightNumber> "]" "." \r
-                                 <stateLightProperty>\r
-*/\r
-stateLightItem\r
-    "light" .and lbracket .and stateLightNumber .and rbracket .and dot .and\r
-    stateLightProperty .error INVALID_LIGHT_PROPERTY;\r
-\r
-/*\r
-    <stateLightProperty>   ::= "ambient"\r
-                             | "diffuse" \r
-                             | "specular"\r
-                             | "position"\r
-                             | "attenuation"\r
-                             | "spot" "." <stateSpotProperty>\r
-                             | "half"\r
-*/\r
-stateLightProperty\r
-    "ambient" .emit LIGHT_AMBIENT .or\r
-    "diffuse" .emit LIGHT_DIFFUSE .or\r
-    "specular" .emit LIGHT_SPECULAR .or\r
-    "position" .emit LIGHT_POSITION .or\r
-    "attenuation" .emit LIGHT_ATTENUATION .or\r
-    stateLightProperty_1 .emit LIGHT_SPOT_DIRECTION .or\r
-    "half" .emit LIGHT_HALF;\r
-stateLightProperty_1\r
-    "spot" .and dot .and stateSpotProperty .error INVALID_SPOT_PROPERTY;\r
-\r
-/*\r
-    <stateSpotProperty>    ::= "direction" \r
-*/\r
-stateSpotProperty\r
-    "direction";\r
-\r
-/*\r
-    <stateLightModelItem>  ::= "lightmodel" <stateLModProperty>\r
-*/\r
-stateLightModelItem\r
-    "lightmodel" .and stateLModProperty .error INVALID_LIGHTMODEL_PROPERTY;\r
-\r
-/*\r
-    <stateLModProperty>    ::= "." "ambient"\r
-                             | <optFaceType> "." "scenecolor"\r
-*/\r
-stateLModProperty\r
-    stateLModProperty_1 .or stateLModProperty_2;\r
-stateLModProperty_1\r
-    dot .and "ambient" .emit LIGHT_MODEL_AMBIENT;\r
-stateLModProperty_2\r
-    stateLModProperty_3 .emit LIGHT_MODEL_SCENECOLOR;\r
-stateLModProperty_3\r
-    optFaceType .and dot .and "scenecolor";\r
-\r
-/*\r
-    <stateLightProdItem>   ::= "lightprod" "[" <stateLightNumber> "]"\r
-                                 <optFaceType> "." <stateLProdProperty>\r
-*/\r
-stateLightProdItem\r
-    "lightprod" .and lbracket .and stateLightNumber .and rbracket .and optFaceType .and dot .and\r
-    stateLProdProperty .error INVALID_LIGHTPROD_PROPERTY;\r
-\r
-/*\r
-    <stateLProdProperty>   ::= "ambient"\r
-                             | "diffuse"\r
-                             | "specular"\r
-*/\r
-stateLProdProperty\r
-    "ambient" .emit LIGHT_PROD_AMBIENT .or\r
-    "diffuse" .emit LIGHT_PROD_DIFFUSE .or\r
-    "specular" .emit LIGHT_PROD_SPECULAR;\r
-\r
-/*\r
-    <stateLightNumber>     ::= <integer> from 0 to MAX_LIGHTS-1\r
-*/\r
-stateLightNumber\r
-    integer;\r
-\r
-/*\r
-fragment program\r
-    <stateTexEnvItem>      ::= "texenv" <optLegacyTexUnitNum> "." \r
-                                 <stateTexEnvProperty>\r
-*/\r
-stateTexEnvItem\r
-    "texenv" .and optLegacyTexUnitNum .and dot .and\r
-    stateTexEnvProperty .error INVALID_TEXENV_PROPERTY;\r
-\r
-/*\r
-fragment program\r
-    <stateTexEnvProperty>  ::= "color"\r
-*/\r
-stateTexEnvProperty\r
-    "color" .emit TEX_ENV_COLOR;\r
-\r
-/*\r
-fragment program\r
-    <optLegacyTexUnitNum>  ::= ""\r
-                             | "[" <legacyTexUnitNum> "]"\r
-\r
-NOTE: <optLegaceTexUnitNum> is not optional.\r
-*/\r
-optLegacyTexUnitNum\r
-    lbracket_ne .and legacyTexUnitNum .and rbracket;\r
-\r
-/*\r
-fragment program\r
-    <legacyTexUnitNum>     ::= <integer> from 0 to MAX_TEXTURE_UNITS-1\r
-*/\r
-legacyTexUnitNum\r
-    integer;\r
-\r
-/*\r
-vertex program\r
-    <stateTexGenItem>      ::= "texgen" <optTexCoordNum> "."\r
-                                 <stateTexGenType> "." <stateTexGenCoord>\r
-*/\r
-stateTexGenItem\r
-    "texgen" .and optTexCoordNum .and dot .and stateTexGenType .error INVALID_TEXGEN_PROPERTY .and\r
-    dot .and stateTexGenCoord .error INVALID_TEXGEN_COORD;\r
-\r
-/*\r
-vertex program\r
-    <stateTexGenType>      ::= "eye"\r
-                             | "object"\r
-*/\r
-stateTexGenType\r
-    "eye" .emit TEX_GEN_EYE .or\r
-    "object" .emit TEX_GEN_OBJECT;\r
-\r
-/*\r
-vertex program\r
-    <stateTexGenCoord>     ::= "s"\r
-                             | "t"\r
-                             | "r"\r
-                             | "q"\r
-*/\r
-stateTexGenCoord\r
-    "s" .emit COMPONENT_X .or\r
-    "t" .emit COMPONENT_Y .or\r
-    "r" .emit COMPONENT_Z .or\r
-    "q" .emit COMPONENT_W;\r
-\r
-/*\r
-    <stateFogItem>         ::= "fog" "." <stateFogProperty>\r
-*/\r
-stateFogItem\r
-    "fog" .and dot .and stateFogProperty .error INVALID_FOG_PROPERTY;\r
-\r
-/*\r
-    <stateFogProperty>     ::= "color"\r
-                             | "params"\r
-*/\r
-stateFogProperty\r
-    "color" .emit FOG_COLOR .or\r
-    "params" .emit FOG_PARAMS;\r
-\r
-/*\r
-fragment program\r
-    <stateDepthItem>       ::= "depth" "." <stateDepthProperty>\r
-*/\r
-stateDepthItem\r
-    "depth" .and dot .and stateDepthProperty .error INVALID_DEPTH_PROPERTY;\r
-\r
-/*\r
-fragment program\r
-    <stateDepthProperty>   ::= "range"\r
-*/\r
-stateDepthProperty\r
-    "range" .emit DEPTH_RANGE;\r
-\r
-/*\r
-vertex program\r
-    <stateClipPlaneItem>   ::= "clip" "[" <stateClipPlaneNum> "]" "." "plane"\r
-*/\r
-stateClipPlaneItem\r
-    "clip" .and lbracket .and stateClipPlaneNum .and rbracket .and dot .and\r
-    "plane" .error INVALID_CLIPPLANE_PROPERTY;\r
-\r
-/*\r
-vertex program\r
-    <stateClipPlaneNum>    ::= <integer> from 0 to MAX_CLIP_PLANES-1\r
-*/\r
-stateClipPlaneNum\r
-    integer;\r
-\r
-/*\r
-vertex program\r
-    <statePointItem>       ::= "point" . <statePointProperty>\r
-*/\r
-statePointItem\r
-    "point" .and dot .and statePointProperty .error INVALID_POINT_PROPERTY;\r
-\r
-/*\r
-vertex program\r
-    <statePointProperty>   ::= "size"\r
-                             | "attenuation"\r
-*/\r
-statePointProperty\r
-    "size" .emit POINT_SIZE .or\r
-    .if (point_parameters != 0x00) "attenuation" .emit POINT_ATTENUATION;\r
-\r
-/*\r
-    <stateMatrixRow>       ::= <stateMatrixItem> "." "row" "[" \r
-                                  <stateMatrixRowNum> "]"\r
-*/\r
-stateMatrixRow\r
-    stateMatrixItem .and dot .and "row" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and\r
-    lbracket .and stateMatrixRowNum .and rbracket .emit 0x0;\r
-\r
-/*\r
-    <stateMatrixRows>      ::= <stateMatrixItem> <optMatrixRows>\r
-*/\r
-stateMatrixRows\r
-    stateMatrixItem .and optMatrixRows;\r
-\r
-/*\r
-    <optMatrixRows>        ::= ""\r
-                             | "." "row" "[" <stateMatrixRowNum> ".." \r
-                                  <stateMatrixRowNum> "]"\r
-*/\r
-optMatrixRows\r
-    optMatrixRows_1 .or .true .emit 0x0 .emit '3' .emit 0x0 .emit $;\r
-optMatrixRows_1\r
-    dot_ne .and "row" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and lbracket .and\r
-    stateMatrixRowNum .and dotdot .and stateMatrixRowNum .and rbracket;\r
-\r
-/*\r
-    <stateMatrixItem>      ::= "matrix" . <stateMatrixName> \r
-                               <stateOptMatModifier>\r
-*/\r
-stateMatrixItem\r
-    "matrix" .and dot .and stateMatrixName .error INVALID_MATRIX_NAME .and stateOptMatModifier;\r
-\r
-/*\r
-    <stateOptMatModifier>  ::= ""\r
-                             | "." <stateMatModifier>\r
-*/\r
-stateOptMatModifier\r
-    stateOptMatModifier_1 .or .true .emit MATRIX_MODIFIER_IDENTITY;\r
-stateOptMatModifier_1\r
-    dot_ne .and stateMatModifier;\r
-\r
-/*\r
-    <stateMatModifier>     ::= "inverse" \r
-                             | "transpose" \r
-                             | "invtrans"\r
-*/\r
-stateMatModifier\r
-    "inverse" .emit MATRIX_MODIFIER_INVERSE .or\r
-    "transpose" .emit MATRIX_MODIFIER_TRANSPOSE .or\r
-    "invtrans" .emit MATRIX_MODIFIER_INVTRANS;\r
-\r
-/*\r
-    <stateMatrixRowNum>    ::= <integer> from 0 to 3\r
-*/\r
-stateMatrixRowNum\r
-    integer_0_3;\r
-\r
-/*\r
-    <stateMatrixName>      ::= "modelview" <stateOptModMatNum>\r
-                             | "projection"\r
-                             | "mvp"\r
-                             | "texture" <optTexCoordNum>\r
-                             | "palette" "[" <statePaletteMatNum> "]"\r
-                             | "program" "[" <stateProgramMatNum> "]"\r
-*/\r
-stateMatrixName\r
-    stateMatrixName_1_1 .emit MATRIX_MODELVIEW .or\r
-    "projection" .emit MATRIX_PROJECTION .or\r
-    "mvp" .emit MATRIX_MVP .or\r
-    stateMatrixName_1_2 .emit MATRIX_TEXTURE .or\r
-    .if (matrix_palette != 0x00) stateMatrixName_1_3 .emit MATRIX_PALETTE .or\r
-    stateMatrixName_1_4 .emit MATRIX_PROGRAM;\r
-stateMatrixName_1_1\r
-    "modelview" .and stateOptModMatNum;\r
-stateMatrixName_1_2\r
-    "texture" .and optTexCoordNum;\r
-stateMatrixName_1_3\r
-    "palette" .and lbracket .and statePaletteMatNum .and rbracket;\r
-stateMatrixName_1_4\r
-    "program" .and lbracket .and stateProgramMatNum .and rbracket;\r
-\r
-/*\r
-    <stateOptModMatNum>    ::= ""\r
-                             | "[" <stateModMatNum> "]"\r
-*/\r
-stateOptModMatNum\r
-    .if (vertex_blend != 0x00) stateOptModMatNum_1 .or\r
-    .true .emit 0x00;\r
-stateOptModMatNum_1\r
-    lbracket_ne .and stateModMatNum .and rbracket;\r
-\r
-/*\r
-    <stateModMatNum>       ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1\r
-*/\r
-stateModMatNum\r
-    integer;\r
-\r
-/*\r
-    <optTexCoordNum>       ::= ""\r
-                             | "[" <texCoordNum> "]"\r
-*/\r
-optTexCoordNum\r
-    optTexCoordNum_1 .or .true .emit 0x00;\r
-optTexCoordNum_1\r
-    lbracket_ne .and texCoordNum .and rbracket;\r
-\r
-/*\r
-    <texCoordNum>          ::= <integer> from 0 to MAX_TEXTURE_COORDS_ARB-1\r
-*/\r
-texCoordNum\r
-    integer;\r
-\r
-/*\r
-    <statePaletteMatNum>   ::= <integer> from 0 to MAX_PALETTE_MATRICES_ARB-1\r
-*/\r
-statePaletteMatNum\r
-    integer;\r
-\r
-/*\r
-    <stateProgramMatNum>   ::= <integer> from 0 to MAX_PROGRAM_MATRICES_ARB-1\r
-*/\r
-stateProgramMatNum\r
-    integer;\r
-\r
-/*\r
-    <programSingleItem>    ::= <progEnvParam>\r
-                             | <progLocalParam>\r
-\r
-NOTE: <programSingleItem> has been modified for correct error handling. If program property\r
-      is neither "env" nor "local" INVALID_PROGRAM_PROPERTY is generated.\r
-*/\r
-programSingleItem\r
-    "program" .and dot .and programSingleItem_1 .error INVALID_PROGRAM_PROPERTY;\r
-programSingleItem_1\r
-    progEnvParam .or progLocalParam;\r
-\r
-/*\r
-    <programMultipleItem>  ::= <progEnvParams>\r
-                             | <progLocalParams>\r
-\r
-NOTE: <programMultipleItem> has been modified for correct error handling. If program property\r
-      is neither "env" nor "local" INVALID_PROGRAM_PROPERTY is generated.\r
-*/\r
-programMultipleItem\r
-    "program" .and dot .and programMultipleItem_1 .error INVALID_PROGRAM_PROPERTY;\r
-programMultipleItem_1\r
-    progEnvParams .or progLocalParams;\r
-\r
-/*\r
-    <progEnvParams>        ::= "program" "." "env" \r
-                                 "[" <progEnvParamNums> "]"\r
-\r
-NOTE: "program" "." has been moved to <programMultipleItem>.\r
-*/\r
-progEnvParams\r
-    "env" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNums .and rbracket;\r
-\r
-/*\r
-    <progEnvParamNums>     ::= <progEnvParamNum>\r
-                             | <progEnvParamNum> ".." <progEnvParamNum>\r
-*/\r
-progEnvParamNums\r
-    progEnvParamNums_1 .or progEnvParamNums_2;\r
-progEnvParamNums_1\r
-    progEnvParamNum .and dotdot_ne .and progEnvParamNum;\r
-progEnvParamNums_2\r
-    progEnvParamNum .and .true .emit 0x00;\r
-\r
-/*\r
-    <progEnvParam>         ::= "program" "." "env" \r
-                                 "[" <progEnvParamNum> "]"\r
-\r
-NOTE: "program" "." has been moved to <programSingleItem>.\r
-*/\r
-progEnvParam\r
-    "env" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket .emit 0x00;\r
-\r
-/*\r
-    <progLocalParams>      ::= "program" "." "local" \r
-                                 "[" <progLocalParamNums> "]"\r
-\r
-NOTE: "program" "." has been moved to <programMultipleItem>.\r
-*/\r
-progLocalParams\r
-    "local" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNums .and rbracket;\r
-\r
-/*\r
-    <progLocalParamNums>   ::= <progLocalParamNum>\r
-                             | <progLocalParamNum> ".." <progLocalParamNum>\r
-*/\r
-progLocalParamNums\r
-    progLocalParamNums_1 .or progLocalParamNums_2;\r
-progLocalParamNums_1\r
-    progLocalParamNum .and dotdot_ne .and progLocalParamNum;\r
-progLocalParamNums_2\r
-    progLocalParamNum .and .true .emit 0x00;\r
-\r
-/*\r
-    <progLocalParam>       ::= "program" "." "local" \r
-                                 "[" <progLocalParamNum> "]"\r
-\r
-NOTE: "program" "." has been moved to <programSingleItem>.\r
-*/\r
-progLocalParam\r
-    "local" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket .emit 0x00;\r
-\r
-/*\r
-    <progEnvParamNum>      ::= <integer> from 0 to\r
-                               MAX_PROGRAM_ENV_PARAMETERS_ARB - 1\r
-*/\r
-progEnvParamNum\r
-    integer;\r
-\r
-/*\r
-    <progLocalParamNum>    ::= <integer> from 0 to\r
-                               MAX_PROGRAM_LOCAL_PARAMETERS_ARB - 1\r
-*/\r
-progLocalParamNum\r
-    integer;\r
-\r
-/*\r
-    <paramConstDecl>       ::= <paramConstScalarDecl>\r
-                             | <paramConstVector>\r
-*/\r
-paramConstDecl\r
-    paramConstScalarDecl .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;\r
-\r
-/*\r
-    <paramConstUse>        ::= <paramConstScalarUse>\r
-                             | <paramConstVector>\r
-*/\r
-paramConstUse\r
-    paramConstScalarUse .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;\r
-\r
-/*\r
-    <paramConstScalarDecl> ::= <signedFloatConstant>\r
-*/\r
-paramConstScalarDecl\r
-    signedFloatConstant;\r
-\r
-/*\r
-    <paramConstScalarUse>  ::= <floatConstant>\r
-*/\r
-paramConstScalarUse\r
-    floatConstant;\r
-\r
-/*\r
-    <paramConstVector>     ::= "{" <signedFloatConstant> "}"\r
-                             | "{" <signedFloatConstant> "," \r
-                                   <signedFloatConstant> "}"\r
-                             | "{" <signedFloatConstant> "," \r
-                                   <signedFloatConstant> ","\r
-                                   <signedFloatConstant> "}"\r
-                             | "{" <signedFloatConstant> "," \r
-                                   <signedFloatConstant> ","\r
-                                   <signedFloatConstant> "," \r
-                                   <signedFloatConstant> "}"\r
-*/\r
-paramConstVector\r
-    paramConstVector_4 .emit 0x04 .or paramConstVector_3 .emit 0x03 .or\r
-    paramConstVector_2 .emit 0x02 .or paramConstVector_1 .emit 0x01;\r
-paramConstVector_1\r
-    lbrace_ne .and signedFloatConstant .and rbrace;\r
-paramConstVector_2\r
-    lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;\r
-paramConstVector_3\r
-    lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and\r
-    signedFloatConstant .and rbrace;\r
-paramConstVector_4\r
-    lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and\r
-    signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;\r
-\r
-/*\r
-    <signedFloatConstant>  ::= <optionalSign> <floatConstant>\r
-*/\r
-signedFloatConstant\r
-    optionalSign .and floatConstant;\r
-\r
-/*\r
-    <floatConstant>        ::= see text\r
-    The <floatConstant> rule matches a floating-point constant consisting\r
-    of an integer part, a decimal point, a fraction part, an "e" or\r
-    "E", and an optionally signed integer exponent.  The integer and\r
-    fraction parts both consist of a sequence of one or more digits ("0"\r
-    through "9").  Either the integer part or the fraction parts (not\r
-    both) may be missing; either the decimal point or the "e" (or "E")\r
-    and the exponent (not both) may be missing.\r
-*/\r
-floatConstant\r
-    float;\r
-\r
-/*\r
-    <optionalSign>         ::= ""\r
-                             | "-"\r
-                             | "+"\r
-*/\r
-optionalSign\r
-    optional_sign_ne;\r
-\r
-/*\r
-    <TEMP_statement>       ::= "TEMP" <varNameList>\r
-*/\r
-fp_TEMP_statement\r
-    "TEMP" .and space .and fp_varNameList .and .true .emit 0x00;\r
-vp_TEMP_statement\r
-    "TEMP" .and space .and vp_varNameList .and .true .emit 0x00;\r
-\r
-/*\r
-vertex program\r
-    <ADDRESS_statement>    ::= "ADDRESS" <varNameList>\r
-*/\r
-ADDRESS_statement\r
-    "ADDRESS" .and space .and vp_varNameList .and .true .emit 0x00;\r
-\r
-/*\r
-    <varNameList>          ::= <establishName>\r
-                             | <establishName> "," <varNameList>\r
-*/\r
-fp_varNameList\r
-    fp_varNameList_1 .or fp_establishName;\r
-vp_varNameList\r
-    vp_varNameList_1 .or vp_establishName;\r
-fp_varNameList_1\r
-    fp_establishName .and comma_ne .and fp_varNameList;\r
-vp_varNameList_1\r
-    vp_establishName .and comma_ne .and vp_varNameList;\r
-\r
-/*\r
-    <OUTPUT_statement>     ::= "OUTPUT" <establishName> "="\r
-                                 <resultBinding>\r
-*/\r
-fp_OUTPUT_statement\r
-    "OUTPUT" .and space .and fp_establishName .and equal .and\r
-    fp_resultBinding .error RESULT_EXPECTED;\r
-vp_OUTPUT_statement\r
-    "OUTPUT" .and space .and vp_establishName .and equal .and\r
-    vp_resultBinding .error RESULT_EXPECTED;\r
-\r
-/*\r
-fragment program\r
-    <resultBinding>        ::= "result" "." "color"\r
-                             | "result" "." "depth"\r
-\r
-vertex program\r
-    <resultBinding>        ::= "result" "." "position"\r
-                             | "result" "." <resultColBinding>\r
-                             | "result" "." "fogcoord"\r
-                             | "result" "." "pointsize"\r
-                             | "result" "." "texcoord" <optTexCoordNum>\r
-*/\r
-fp_resultBinding\r
-    "result" .and dot .and fp_resultBinding_1 .error INVALID_RESULT_PROPERTY;\r
-vp_resultBinding\r
-    "result" .and dot .and vp_resultBinding_1 .error INVALID_RESULT_PROPERTY;\r
-fp_resultBinding_1\r
-    "color" .emit FRAGMENT_RESULT_COLOR .or\r
-    "depth" .emit FRAGMENT_RESULT_DEPTH;\r
-vp_resultBinding_1\r
-    .if (ARB_position_invariant == 0x00) "position" .emit VERTEX_RESULT_POSITION .or\r
-    resultColBinding .emit VERTEX_RESULT_COLOR .or\r
-    "fogcoord" .emit VERTEX_RESULT_FOGCOORD .or\r
-    "pointsize" .emit VERTEX_RESULT_POINTSIZE .or\r
-    vp_resultBinding_2 .emit VERTEX_RESULT_TEXCOORD;\r
-vp_resultBinding_2\r
-    "texcoord" .and optTexCoordNum;\r
-\r
-/*\r
-vertex program\r
-    <resultColBinding>     ::= "color" <optFaceType> <optColorType>\r
-*/\r
-resultColBinding\r
-    "color" .and optFaceType .and optColorType;\r
-\r
-/*\r
-    <optFaceType>          ::= ""\r
-                             | "." "front"\r
-                             | "." "back"\r
-*/\r
-optFaceType\r
-    FaceType .or .true .emit FACE_FRONT;\r
-FaceType\r
-    dot_ne .and FaceProperty;\r
-FaceProperty\r
-    "front" .emit FACE_FRONT .or "back" .emit FACE_BACK;\r
-\r
-/*\r
-    <optColorType>         ::= ""\r
-                             | "." "primary"\r
-                             | "." "secondary"\r
-*/\r
-optColorType\r
-    ColorType .or .true .emit COLOR_PRIMARY;\r
-ColorType\r
-    dot_ne .and ColorProperty;\r
-ColorProperty\r
-    "primary" .emit COLOR_PRIMARY .or\r
-    .if (secondary_color != 0x00) "secondary" .emit COLOR_SECONDARY;\r
-\r
-/*\r
-    <ALIAS_statement>      ::= "ALIAS" <establishName> "="\r
-                                 <establishedName>\r
-*/\r
-fp_ALIAS_statement\r
-    "ALIAS" .and fp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and fp_establishedName;\r
-vp_ALIAS_statement\r
-    "ALIAS" .and vp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and vp_establishedName;\r
-fp_ALIAS_statement_1\r
-    space .and fp_establishName;\r
-vp_ALIAS_statement_1\r
-    space .and vp_establishName;\r
-\r
-/*\r
-    <establishName>        ::= <identifier>\r
-*/\r
-fp_establishName\r
-    fp_identifier;\r
-vp_establishName\r
-    vp_identifier;\r
-\r
-/*\r
-    <establishedName>      ::= <identifier>\r
-*/\r
-fp_establishedName\r
-    fp_identifier;\r
-vp_establishedName\r
-    vp_identifier;\r
-fp_establishedName_no_error_on_identifier\r
-    fp_identifier_ne;\r
-vp_establishedName_no_error_on_identifier\r
-    vp_identifier_ne;\r
-\r
-/*\r
-fragment program\r
-    <identifier>           ::= see text\r
-    The <identifier> rule matches a sequence of one or more letters ("A"\r
-    through "Z", "a" through "z"), digits ("0" through "9), underscores \r
-    ("_"), or dollar signs ("$"); the first character must not be a \r
-    number.  Upper and lower case letters are considered different \r
-    (names are case-sensitive).  The following strings are reserved \r
-    keywords and may not be used as identifiers:\r
-\r
-        ABS, ABS_SAT, ADD, ADD_SAT, ALIAS, ATTRIB, CMP, CMP_SAT, COS,\r
-        COS_SAT, DP3, DP3_SAT, DP4, DP4_SAT, DPH, DPH_SAT, DST, DST_SAT, \r
-        END, EX2, EX2_SAT, FLR, FLR_SAT, FRC, FRC_SAT, KIL, LG2, \r
-        LG2_SAT, LIT, LIT_SAT, LRP, LRP_SAT, MAD, MAD_SAT, MAX, MAX_SAT, \r
-        MIN, MIN_SAT, MOV, MOV_SAT, MUL, MUL_SAT, OPTION, OUTPUT, PARAM, \r
-        POW, POW_SAT, RCP, RCP_SAT, RSQ, RSQ_SAT, SIN, SIN_SAT, SCS, \r
-        SCS_SAT, SGE, SGE_SAT, SLT, SLT_SAT, SUB, SUB_SAT, SWZ, SWZ_SAT, \r
-        TEMP, TEX, TEX_SAT, TXB, TXB_SAT, TXP, TXP_SAT, XPD, XPD_SAT, \r
-        fragment, program, result, state, and texture.\r
-\r
-vertex program\r
-    <identifier>           ::= see text\r
-    The <identifier> rule matches a sequence of one or more letters ("A"\r
-    through "Z", "a" through "z"), digits ("0" through "9), underscores ("_"),\r
-    or dollar signs ("$"); the first character must not be a number.  Upper\r
-    and lower case letters are considered different (names are\r
-    case-sensitive).  The following strings are reserved keywords and may not\r
-    be used as identifiers:\r
-\r
-        ABS, ADD, ADDRESS, ALIAS, ARL, ATTRIB, DP3, DP4, DPH, DST, END, EX2,\r
-        EXP, FLR, FRC, LG2, LIT, LOG, MAD, MAX, MIN, MOV, MUL, OPTION, OUTPUT,\r
-        PARAM, POW, RCP, RSQ, SGE, SLT, SUB, SWZ, TEMP, XPD, program, result,\r
-        state, and vertex.\r
-*/\r
-fp_identifier\r
-    fp_identifier_ne .error IDENTIFIER_EXPECTED;\r
-vp_identifier\r
-    vp_identifier_ne .error IDENTIFIER_EXPECTED;\r
-fp_identifier_ne\r
-    fp_not_reserved_identifier .and identifier_ne;\r
-vp_identifier_ne\r
-    vp_not_reserved_identifier .and identifier_ne;\r
-\r
-fp_not_reserved_identifier\r
-    fp_not_reserved_identifier_1 .or .true;\r
-fp_not_reserved_identifier_1\r
-    fp_reserved_identifier .and .false .error RESERVED_KEYWORD;\r
-vp_not_reserved_identifier\r
-    vp_not_reserved_identifier_1 .or .true;\r
-vp_not_reserved_identifier_1\r
-    vp_reserved_identifier .and .false .error RESERVED_KEYWORD;\r
-\r
-fp_reserved_identifier\r
-    "ABS" .or "ABS_SAT" .or "ADD" .or "ADD_SAT" .or "ALIAS" .or "ATTRIB" .or "CMP" .or "CMP_SAT" .or\r
-    "COS" .or "COS_SAT" .or "DP3" .or "DP3_SAT" .or "DP4" .or "DP4_SAT" .or "DPH" .or "DPH_SAT" .or\r
-    "DST" .or "DST_SAT" .or "END" .or "EX2" .or "EX2_SAT" .or "FLR" .or "FLR_SAT" .or "FRC" .or\r
-    "FRC_SAT" .or "KIL" .or "LG2" .or "LG2_SAT" .or "LIT" .or "LIT_SAT" .or "LRP" .or "LRP_SAT" .or\r
-    "MAD" .or "MAD_SAT" .or "MAX" .or "MAX_SAT" .or "MIN" .or "MIN_SAT" .or "MOV" .or "MOV_SAT" .or\r
-    "MUL" .or "MUL_SAT" .or "OPTION" .or "OUTPUT" .or "PARAM" .or "POW" .or "POW_SAT" .or "RCP" .or\r
-    "RCP_SAT" .or "RSQ" .or "RSQ_SAT" .or "SIN" .or "SIN_SAT" .or "SCS" .or "SCS_SAT" .or "SGE" .or\r
-    "SGE_SAT" .or "SLT" .or "SLT_SAT" .or "SUB" .or "SUB_SAT" .or "SWZ" .or "SWZ_SAT" .or "TEMP" .or\r
-    "TEX" .or "TEX_SAT" .or "TXB" .or "TXB_SAT" .or "TXP" .or "TXP_SAT" .or "XPD" .or "XPD_SAT" .or\r
-    "fragment" .or "program" .or "result" .or "state" .or "texture";\r
-vp_reserved_identifier\r
-    "ABS" .or "ADD" .or "ADDRESS" .or "ALIAS" .or "ARL" .or "ATTRIB" .or "DP3" .or "DP4" .or\r
-    "DPH" .or "DST" .or "END" .or "EX2" .or "EXP" .or "FLR" .or "FRC" .or "LG2" .or "LIT" .or\r
-    "LOG" .or "MAD" .or "MAX" .or "MIN" .or "MOV" .or "MUL" .or "OPTION" .or "OUTPUT" .or\r
-    "PARAM" .or "POW" .or "RCP" .or "RSQ" .or "SGE" .or "SLT" .or "SUB" .or "SWZ" .or "TEMP" .or\r
-    "XPD" .or "program" .or "result" .or "state" .or "vertex";\r
-\r
-/*\r
-    The <integer> rule matches an integer constant.  The integer consists\r
-    of a sequence of one or more digits ("0" through "9").\r
-*/\r
-integer\r
-    integer_ne .error INTEGER_EXPECTED;\r
-\r
-zero\r
-    '0';\r
-\r
-leading_zeroes\r
-    .loop zero;\r
-\r
-no_digit\r
-    no_digit_1 .or .true;\r
-no_digit_1\r
-    digit10 .and .false .error INTEGER_OUT_OF_RANGE;\r
-\r
-all_zeroes\r
-    all_zeroes_1 .or no_digit_1;\r
-all_zeroes_1\r
-    '0' .and .loop zero .and no_digit;\r
-\r
-integer_0_3\r
-    integer_0_3_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\r
-integer_0_3_1\r
-    integer_0_3_2 .or all_zeroes .emit '0';\r
-integer_0_3_2       /* [1, 3] */\r
-    leading_zeroes .and '1'-'3' .emit * .and no_digit;\r
-\r
-integer_0_63\r
-    integer_0_63_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\r
-integer_0_63_1\r
-    integer_0_63_2 .or integer_0_63_3 .or integer_0_63_4 .or integer_0_63_5 .or\r
-    all_zeroes .emit '0';\r
-integer_0_63_2      /* [7, 9] */\r
-    leading_zeroes .and '7'-'9' .emit * .and no_digit;\r
-integer_0_63_3      /* [10, 59] */\r
-    leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;\r
-integer_0_63_4      /* [60, 63] */\r
-    leading_zeroes .and '6' .emit * .and '0'-'3' .emit * .and no_digit;\r
-integer_0_63_5      /* [1, 6] */\r
-    leading_zeroes .and '1'-'6' .emit * .and no_digit;\r
-\r
-integer_0_64\r
-    integer_0_64_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\r
-integer_0_64_1\r
-    integer_0_64_2 .or integer_0_64_3 .or integer_0_64_4 .or integer_0_64_5 .or\r
-    all_zeroes .emit '0';\r
-integer_0_64_2      /* [7, 9] */\r
-    leading_zeroes .and '7'-'9' .emit * .and no_digit;\r
-integer_0_64_3      /* [10, 59] */\r
-    leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;\r
-integer_0_64_4      /* [60, 64] */\r
-    leading_zeroes .and '6' .emit * .and '0'-'4' .emit * .and no_digit;\r
-integer_0_64_5      /* [1, 6] */\r
-    leading_zeroes .and '1'-'6' .emit * .and no_digit;\r
-\r
-optional_space\r
-    space .or .true;\r
-\r
-space_dst\r
-    space .error OPERATION_NEEDS_DESTINATION_VARIABLE;\r
-\r
-space_src\r
-    space .error OPERATION_NEEDS_SOURCE_VARIABLE;\r
-\r
-space\r
-    single_space .and .loop single_space;\r
-\r
-single_space\r
-    white_char .or comment_block;\r
-\r
-white_char\r
-    ' ' .or '\t' .or '\n' .or '\r';\r
-\r
-comment_block\r
-    '#' .and .loop comment_char .and new_line;\r
-\r
-/* All ASCII characters except '\r', '\n' and '\0' */\r
-comment_char\r
-    '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C';\r
-\r
-new_line\r
-    '\n' .or crlf .or '\0';\r
-\r
-crlf\r
-    '\r' .and '\n';\r
-\r
-semicolon\r
-    optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;\r
-\r
-comma\r
-    optional_space .and ',' .error MISSING_COMMA .and optional_space;\r
-\r
-comma_ne\r
-    optional_space .and ',' .and optional_space;\r
-\r
-lbracket\r
-    optional_space .and '[' .error MISSING_LBRACKET .and optional_space;\r
-\r
-lbracket_ne\r
-    optional_space .and '[' .and optional_space;\r
-\r
-rbracket\r
-    optional_space .and ']' .error MISSING_RBRACKET .and optional_space;\r
-\r
-dot\r
-    optional_space .and '.' .error MISSING_DOT .and optional_space;\r
-\r
-dot_ne\r
-    optional_space .and '.' .and optional_space;\r
-\r
-equal\r
-    optional_space .and '=' .error MISSING_EQUAL .and optional_space;\r
-\r
-lbrace\r
-    optional_space .and '{' .error MISSING_LBRACE .and optional_space;\r
-\r
-lbrace_ne\r
-    optional_space .and '{' .and optional_space;\r
-\r
-rbrace\r
-    optional_space .and '}' .error MISSING_RBRACE .and optional_space;\r
-\r
-dotdot\r
-    optional_space .and '.' .and '.' .error MISSING_DOTDOT .and optional_space;\r
-\r
-dotdot_ne\r
-    optional_space .and '.' .and '.' .and optional_space;\r
-\r
-/*\r
-    The definition below accepts the following floating point number formats:\r
-    .99 .99e99 99. 99.99 99.99e99 99.e99 99e99\r
-    Also 99 format was considered and accepted because of a large number of existing program\r
-    strings with such a format.\r
-*/\r
-float\r
-    float_1 .or float_2 .or float_legacy;\r
-float_1\r
-    '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent;\r
-float_2\r
-    integer_ne .and float_3;\r
-float_3\r
-    float_4 .or float_5;\r
-float_4\r
-    '.' .and optional_integer .and optional_exponent;\r
-float_5\r
-    exponent .emit 0x00;\r
-float_legacy\r
-    integer_ne .and .true .emit 0x00 .emit 0x00;\r
-\r
-/*\r
-    Below is a correct version of <float> definiton.\r
-*/\r
-/*\r
-float\r
-    float_1 .or float_2;\r
-float_1\r
-    '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent;\r
-float_2\r
-    integer_ne .and float_3 .error MISSING_DOT_OR_EXPONENT;\r
-float_3\r
-    float_4 .or float_5;\r
-float_4\r
-    '.' .and optional_integer .and optional_exponent;\r
-float_5\r
-    exponent .emit 0x00;\r
-*/\r
-\r
-integer_ne\r
-    integer_ne_1 .and .true .emit 0x00 .emit $;\r
-integer_ne_1\r
-    digit10 .emit * .and .loop digit10 .emit *;\r
-\r
-optional_integer\r
-    integer_ne .or .true .emit 0x00;\r
-\r
-/*\r
-NOTE: If exponent part is omited we treat it as if it was "E+1".\r
-*/\r
-optional_exponent\r
-    exponent .or .true .emit 0x00;\r
-\r
-exponent\r
-    exponent_1 .and optional_sign_ne .and integer_ne .error EXPONENT_VALUE_EXPECTED;\r
-exponent_1\r
-    'e' .or 'E';\r
-\r
-optional_sign_ne\r
-    minus_ne .or plus_ne .or .true;\r
-\r
-plus_ne\r
-    optional_space .and '+' .and optional_space;\r
-\r
-minus_ne\r
-    optional_space .and '-' .emit '-' .and optional_space;\r
-\r
-identifier_ne\r
-    first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit 0x00 .emit $;\r
-\r
-follow_idchar\r
-    first_idchar .or digit10;\r
-\r
-first_idchar\r
-    'a'-'z' .or 'A'-'Z' .or '_' .or '$';\r
-\r
-digit10\r
-    '0'-'9';\r
-\r
-/*\r
-    string filtering - if a string is encountered in grammar ("blabla"), the symbol below is\r
-    executed to create the string. The symbol must not throw any errors and emit bytes - it should\r
-    stop if it encounters invalid character. After this the resulting string (from starting\r
-    position up to the invalid character (but without it) is compared with the grammar string.\r
-*/\r
-.string __string_filter;\r
-\r
-__string_filter\r
-    .loop __identifier_char;\r
-\r
-__identifier_char\r
-    'a'-'z' .or 'A'-'Z' .or '_' .or '$' .or '0'-'9';\r
-\r
-/*\r
-    error token filtering\r
-*/\r
-e_signature\r
-    e_signature_char .and .loop e_signature_char;\r
-e_signature_char\r
-    '!' .or '.' .or 'A'-'Z' .or 'a'-'z' .or '0'-'9';\r
-\r
-e_statement\r
-    .loop e_statement_not_term;\r
-/* All ASCII characters to one of '\r', '\n', '\0' and ';' */\r
-e_statement_not_term\r
-    '\x3C'-'\xFF' .or '\x0E'-'\x3A' .or '\x01'-'\x09' .or '\x0B'-'\x0C';\r
-\r
-e_identifier\r
-    e_identifier_first .and .loop e_identifier_next;\r
-e_identifier_first\r
-    'a'-'z' .or 'A'-'Z' .or '_' .or '$';\r
-e_identifier_next\r
-    e_identifier_first .or '0'-'9';\r
-\r
-e_token\r
-    e_identifier .or e_token_number .or '[' .or ']' .or '.' .or '{' .or '}' .or '=' .or '+' .or\r
-    '-' .or ',' .or ';';\r
-e_token_number\r
-    e_token_digit .and .loop e_token_digit;\r
-e_token_digit\r
-    '0'-'9';\r
-\r
-e_charordigit\r
-    'A'-'Z' .or 'a'-'z' .or '0'-'9';\r
-\r
+.syntax program;
+
+/*
+   This value must be incremented every time emit code values or structure of the production
+   array changes. This value is placed at the beginning of the production array. The loader
+   compares the value with its REVISION value. If they do not match, the loader is not up
+   to date.
+*/
+.emtcode REVISION                                   0x07
+
+/* program type */
+.emtcode FRAGMENT_PROGRAM                           0x01
+.emtcode VERTEX_PROGRAM                             0x02
+
+/* program section */
+.emtcode OPTION                                     0x01
+.emtcode INSTRUCTION                                0x02
+.emtcode DECLARATION                                0x03
+.emtcode END                                        0x04
+
+/* GL_ARB_fragment_program option flags */
+.emtcode ARB_PRECISION_HINT_FASTEST                 0x01
+.emtcode ARB_PRECISION_HINT_NICEST                  0x02
+.emtcode ARB_FOG_EXP                                0x04
+.emtcode ARB_FOG_EXP2                               0x08
+.emtcode ARB_FOG_LINEAR                             0x10
+
+/* GL_ARB_vertex_program option flags */
+.emtcode ARB_POSITION_INVARIANT                     0x20
+
+/* GL_ARB_fragment_program_shadow option flags */
+.emtcode ARB_FRAGMENT_PROGRAM_SHADOW                0x40
+
+/* GL_ARB_fragment_program instruction class */
+.emtcode OP_ALU_INST                                0x00
+.emtcode OP_TEX_INST                                0x01
+
+/* GL_ARB_vertex_program instruction class */
+/*       OP_ALU_INST */
+
+/* GL_ARB_fragment_program instruction type */
+.emtcode OP_ALU_VECTOR                               0x00
+.emtcode OP_ALU_SCALAR                               0x01
+.emtcode OP_ALU_BINSC                                0x02
+.emtcode OP_ALU_BIN                                  0x03
+.emtcode OP_ALU_TRI                                  0x04
+.emtcode OP_ALU_SWZ                                  0x05
+.emtcode OP_TEX_SAMPLE                               0x06
+.emtcode OP_TEX_KIL                                  0x07
+
+/* GL_ARB_vertex_program instruction type */
+.emtcode OP_ALU_ARL                                  0x08
+/*       OP_ALU_VECTOR */
+/*       OP_ALU_SCALAR */
+/*       OP_ALU_BINSC */
+/*       OP_ALU_BIN */
+/*       OP_ALU_TRI */
+/*       OP_ALU_SWZ */
+
+/* GL_ARB_fragment_program instruction code */
+.emtcode OP_ABS                                     0x00
+.emtcode OP_ABS_SAT                                 0x1B
+.emtcode OP_FLR                                     0x09
+.emtcode OP_FLR_SAT                                 0x26
+.emtcode OP_FRC                                     0x0A
+.emtcode OP_FRC_SAT                                 0x27
+.emtcode OP_LIT                                     0x0C
+.emtcode OP_LIT_SAT                                 0x2A
+.emtcode OP_MOV                                     0x11
+.emtcode OP_MOV_SAT                                 0x30
+.emtcode OP_COS                                     0x1F
+.emtcode OP_COS_SAT                                 0x20
+.emtcode OP_EX2                                     0x07
+.emtcode OP_EX2_SAT                                 0x25
+.emtcode OP_LG2                                     0x0B
+.emtcode OP_LG2_SAT                                 0x29
+.emtcode OP_RCP                                     0x14
+.emtcode OP_RCP_SAT                                 0x33
+.emtcode OP_RSQ                                     0x15
+.emtcode OP_RSQ_SAT                                 0x34
+.emtcode OP_SIN                                     0x38
+.emtcode OP_SIN_SAT                                 0x39
+.emtcode OP_SCS                                     0x35
+.emtcode OP_SCS_SAT                                 0x36
+.emtcode OP_POW                                     0x13
+.emtcode OP_POW_SAT                                 0x32
+.emtcode OP_ADD                                     0x01
+.emtcode OP_ADD_SAT                                 0x1C
+.emtcode OP_DP3                                     0x03
+.emtcode OP_DP3_SAT                                 0x21
+.emtcode OP_DP4                                     0x04
+.emtcode OP_DP4_SAT                                 0x22
+.emtcode OP_DPH                                     0x05
+.emtcode OP_DPH_SAT                                 0x23
+.emtcode OP_DST                                     0x06
+.emtcode OP_DST_SAT                                 0x24
+.emtcode OP_MAX                                     0x0F
+.emtcode OP_MAX_SAT                                 0x2E
+.emtcode OP_MIN                                     0x10
+.emtcode OP_MIN_SAT                                 0x2F
+.emtcode OP_MUL                                     0x12
+.emtcode OP_MUL_SAT                                 0x31
+.emtcode OP_SGE                                     0x16
+.emtcode OP_SGE_SAT                                 0x37
+.emtcode OP_SLT                                     0x17
+.emtcode OP_SLT_SAT                                 0x3A
+.emtcode OP_SUB                                     0x18
+.emtcode OP_SUB_SAT                                 0x3B
+.emtcode OP_XPD                                     0x1A
+.emtcode OP_XPD_SAT                                 0x43
+.emtcode OP_CMP                                     0x1D
+.emtcode OP_CMP_SAT                                 0x1E
+.emtcode OP_LRP                                     0x2B
+.emtcode OP_LRP_SAT                                 0x2C
+.emtcode OP_MAD                                     0x0E
+.emtcode OP_MAD_SAT                                 0x2D
+.emtcode OP_SWZ                                     0x19
+.emtcode OP_SWZ_SAT                                 0x3C
+.emtcode OP_TEX                                     0x3D
+.emtcode OP_TEX_SAT                                 0x3E
+.emtcode OP_TXB                                     0x3F
+.emtcode OP_TXB_SAT                                 0x40
+.emtcode OP_TXP                                     0x41
+.emtcode OP_TXP_SAT                                 0x42
+.emtcode OP_KIL                                     0x28
+
+/* GL_ARB_vertex_program instruction code */
+.emtcode OP_ARL                                     0x02
+/*       OP_ABS */
+/*       OP_FLR */
+/*       OP_FRC */
+/*       OP_LIT */
+/*       OP_MOV */
+/*       OP_EX2 */
+.emtcode OP_EXP                                     0x08
+/*       OP_LG2 */
+.emtcode OP_LOG                                     0x0D
+/*       OP_RCP */
+/*       OP_RSQ */
+/*       OP_POW */
+/*       OP_ADD */
+/*       OP_DP3 */
+/*       OP_DP4 */
+/*       OP_DPH */
+/*       OP_DST */
+/*       OP_MAX */
+/*       OP_MIN */
+/*       OP_MUL */
+/*       OP_SGE */
+/*       OP_SLT */
+/*       OP_SUB */
+/*       OP_XPD */
+/*       OP_MAD */
+/*       OP_SWZ */
+
+/* fragment attribute binding */
+.emtcode FRAGMENT_ATTRIB_COLOR                      0x01
+.emtcode FRAGMENT_ATTRIB_TEXCOORD                   0x02
+.emtcode FRAGMENT_ATTRIB_FOGCOORD                   0x03
+.emtcode FRAGMENT_ATTRIB_POSITION                   0x04
+
+/* vertex attribute binding */
+.emtcode VERTEX_ATTRIB_POSITION                     0x01
+.emtcode VERTEX_ATTRIB_WEIGHT                       0x02
+.emtcode VERTEX_ATTRIB_NORMAL                       0x03
+.emtcode VERTEX_ATTRIB_COLOR                        0x04
+.emtcode VERTEX_ATTRIB_FOGCOORD                     0x05
+.emtcode VERTEX_ATTRIB_TEXCOORD                     0x06
+.emtcode VERTEX_ATTRIB_MATRIXINDEX                  0x07
+.emtcode VERTEX_ATTRIB_GENERIC                      0x08
+
+/* fragment result binding */
+.emtcode FRAGMENT_RESULT_COLOR                      0x01
+.emtcode FRAGMENT_RESULT_DEPTH                      0x02
+
+/* vertex result binding */
+.emtcode VERTEX_RESULT_POSITION                     0x01
+.emtcode VERTEX_RESULT_COLOR                        0x02
+.emtcode VERTEX_RESULT_FOGCOORD                     0x03
+.emtcode VERTEX_RESULT_POINTSIZE                    0x04
+.emtcode VERTEX_RESULT_TEXCOORD                     0x05
+
+/* texture target */
+.emtcode TEXTARGET_1D                               0x01
+.emtcode TEXTARGET_2D                               0x02
+.emtcode TEXTARGET_3D                               0x03
+.emtcode TEXTARGET_RECT                             0x04
+.emtcode TEXTARGET_CUBE                             0x05
+/* GL_ARB_fragment_program_shadow */
+.emtcode TEXTARGET_SHADOW1D                         0x06
+.emtcode TEXTARGET_SHADOW2D                         0x07
+.emtcode TEXTARGET_SHADOWRECT                       0x08
+
+/* face type */
+.emtcode FACE_FRONT                                 0x00
+.emtcode FACE_BACK                                  0x01
+
+/* color type */
+.emtcode COLOR_PRIMARY                              0x00
+.emtcode COLOR_SECONDARY                            0x01
+
+/* component */
+.emtcode COMPONENT_X                                0x00
+.emtcode COMPONENT_Y                                0x01
+.emtcode COMPONENT_Z                                0x02
+.emtcode COMPONENT_W                                0x03
+.emtcode COMPONENT_0                                0x04
+.emtcode COMPONENT_1                                0x05
+
+/* array index type */
+.emtcode ARRAY_INDEX_ABSOLUTE                       0x00
+.emtcode ARRAY_INDEX_RELATIVE                       0x01
+
+/* matrix name */
+.emtcode MATRIX_MODELVIEW                           0x01
+.emtcode MATRIX_PROJECTION                          0x02
+.emtcode MATRIX_MVP                                 0x03
+.emtcode MATRIX_TEXTURE                             0x04
+.emtcode MATRIX_PALETTE                             0x05
+.emtcode MATRIX_PROGRAM                             0x06
+
+/* matrix modifier */
+.emtcode MATRIX_MODIFIER_IDENTITY                   0x00
+.emtcode MATRIX_MODIFIER_INVERSE                    0x01
+.emtcode MATRIX_MODIFIER_TRANSPOSE                  0x02
+.emtcode MATRIX_MODIFIER_INVTRANS                   0x03
+
+/* constant type */
+.emtcode CONSTANT_SCALAR                            0x01
+.emtcode CONSTANT_VECTOR                            0x02
+
+/* program param type */
+.emtcode PROGRAM_PARAM_ENV                          0x01
+.emtcode PROGRAM_PARAM_LOCAL                        0x02
+
+/* register type */
+.emtcode REGISTER_ATTRIB                            0x01
+.emtcode REGISTER_PARAM                             0x02
+.emtcode REGISTER_RESULT                            0x03
+.emtcode REGISTER_ESTABLISHED_NAME                  0x04
+
+/* param binding */
+.emtcode PARAM_NULL                                 0x00
+.emtcode PARAM_ARRAY_ELEMENT                        0x01
+.emtcode PARAM_STATE_ELEMENT                        0x02
+.emtcode PARAM_PROGRAM_ELEMENT                      0x03
+.emtcode PARAM_PROGRAM_ELEMENTS                     0x04
+.emtcode PARAM_CONSTANT                             0x05
+
+/* param state property */
+.emtcode STATE_MATERIAL                             0x01
+.emtcode STATE_LIGHT                                0x02
+.emtcode STATE_LIGHT_MODEL                          0x03
+.emtcode STATE_LIGHT_PROD                           0x04
+.emtcode STATE_FOG                                  0x05
+.emtcode STATE_MATRIX_ROWS                          0x06
+/* GL_ARB_fragment_program */
+.emtcode STATE_TEX_ENV                              0x07
+.emtcode STATE_DEPTH                                0x08
+/* GL_ARB_vertex_program */
+.emtcode STATE_TEX_GEN                              0x09
+.emtcode STATE_CLIP_PLANE                           0x0A
+.emtcode STATE_POINT                                0x0B
+
+/* state material property */
+.emtcode MATERIAL_AMBIENT                           0x01
+.emtcode MATERIAL_DIFFUSE                           0x02
+.emtcode MATERIAL_SPECULAR                          0x03
+.emtcode MATERIAL_EMISSION                          0x04
+.emtcode MATERIAL_SHININESS                         0x05
+
+/* state light property */
+.emtcode LIGHT_AMBIENT                              0x01
+.emtcode LIGHT_DIFFUSE                              0x02
+.emtcode LIGHT_SPECULAR                             0x03
+.emtcode LIGHT_POSITION                             0x04
+.emtcode LIGHT_ATTENUATION                          0x05
+.emtcode LIGHT_HALF                                 0x06
+.emtcode LIGHT_SPOT_DIRECTION                       0x07
+
+/* state light model property */
+.emtcode LIGHT_MODEL_AMBIENT                        0x01
+.emtcode LIGHT_MODEL_SCENECOLOR                     0x02
+
+/* state light product property */
+.emtcode LIGHT_PROD_AMBIENT                         0x01
+.emtcode LIGHT_PROD_DIFFUSE                         0x02
+.emtcode LIGHT_PROD_SPECULAR                        0x03
+
+/* state texture environment property */
+.emtcode TEX_ENV_COLOR                              0x01
+
+/* state texture generation coord property */
+.emtcode TEX_GEN_EYE                                0x01
+.emtcode TEX_GEN_OBJECT                             0x02
+
+/* state fog property */
+.emtcode FOG_COLOR                                  0x01
+.emtcode FOG_PARAMS                                 0x02
+
+/* state depth property */
+.emtcode DEPTH_RANGE                                0x01
+
+/* state point parameters property */
+.emtcode POINT_SIZE                                 0x01
+.emtcode POINT_ATTENUATION                          0x02
+
+/* declaration */
+.emtcode ATTRIB                                     0x01
+.emtcode PARAM                                      0x02
+.emtcode TEMP                                       0x03
+.emtcode OUTPUT                                     0x04
+.emtcode ALIAS                                      0x05
+/* GL_ARB_vertex_program */
+.emtcode ADDRESS                                    0x06
+
+/* error messages */
+.errtext UNKNOWN_PROGRAM_SIGNATURE                  "1001: '$e_signature$': unknown program signature"
+.errtext MISSING_END_OR_INVALID_STATEMENT           "1002: '$e_statement$': invalid statement"
+.errtext CODE_AFTER_END                             "1003: '$e_statement$': code after 'END' keyword"
+.errtext INVALID_PROGRAM_OPTION                     "1004: '$e_identifier$': invalid program option"
+.errtext EXT_SWIZ_COMP_EXPECTED                     "1005: extended swizzle component expected but '$e_token$' found"
+.errtext TEX_TARGET_EXPECTED                        "1006: texture target expected but '$e_token$' found"
+.errtext TEXTURE_EXPECTED                           "1007: 'texture' expected but '$e_identifier$' found"
+.errtext SOURCE_REGISTER_EXPECTED                   "1008: source register expected but '$e_token$' found"
+.errtext DESTINATION_REGISTER_EXPECTED              "1009: destination register expected but '$e_token$' found"
+.errtext INVALID_ADDRESS_COMPONENT                  "1010: '$e_identifier$': invalid address component"
+.errtext INVALID_ADDRESS_WRITEMASK                  "1011: '$e_identifier$': invalid address writemask"
+.errtext INVALID_COMPONENT                          "1012: '$e_charordigit$': invalid component"
+.errtext INVALID_SUFFIX                             "1013: '$e_identifier$': invalid suffix"
+.errtext INVALID_WRITEMASK                          "1014: '$e_identifier$': invalid writemask"
+.errtext FRAGMENT_EXPECTED                          "1015: 'fragment' expected but '$e_identifier$' found"
+.errtext VERTEX_EXPECTED                            "1016: 'vertex' expected but '$e_identifier$' found"
+.errtext INVALID_FRAGMENT_PROPERTY                  "1017: '$e_identifier$': invalid fragment property"
+.errtext INVALID_VERTEX_PROPERTY                    "1018: '$e_identifier$': invalid vertex property"
+.errtext INVALID_STATE_PROPERTY                     "1019: '$e_identifier$': invalid state property"
+.errtext INVALID_MATERIAL_PROPERTY                  "1020: '$e_identifier$': invalid material property"
+.errtext INVALID_LIGHT_PROPERTY                     "1021: '$e_identifier$': invalid light property"
+.errtext INVALID_SPOT_PROPERTY                      "1022: '$e_identifier$': invalid spot property"
+.errtext INVALID_LIGHTMODEL_PROPERTY                "1023: '$e_identifier$': invalid light model property"
+.errtext INVALID_LIGHTPROD_PROPERTY                 "1024: '$e_identifier$': invalid light product property"
+.errtext INVALID_TEXENV_PROPERTY                    "1025: '$e_identifier$': invalid texture environment property"
+.errtext INVALID_TEXGEN_PROPERTY                    "1026: '$e_identifier$': invalid texture generating property"
+.errtext INVALID_TEXGEN_COORD                       "1027: '$e_identifier$': invalid texture generating coord"
+.errtext INVALID_FOG_PROPERTY                       "1028: '$e_identifier$': invalid fog property"
+.errtext INVALID_DEPTH_PROPERTY                     "1029: '$e_identifier$': invalid depth property"
+.errtext INVALID_CLIPPLANE_PROPERTY                 "1030: '$e_identifier$': invalid clip plane property"
+.errtext INVALID_POINT_PROPERTY                     "1031: '$e_identifier$': invalid point property"
+.errtext MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED   "1032: matrix row selector or modifier expected but '$e_token$' found"
+.errtext INVALID_MATRIX_NAME                        "1033: '$e_identifier$': invalid matrix name"
+.errtext INVALID_PROGRAM_PROPERTY                   "1034: '$e_identifier$': invalid program property"
+.errtext RESULT_EXPECTED                            "1035: 'result' expected but '$e_token$' found"
+.errtext INVALID_RESULT_PROPERTY                    "1036: '$e_identifier$': invalid result property"
+.errtext INVALID_FACE_PROPERTY                      "1037: '$e_identifier$': invalid face property"
+.errtext INVALID_COLOR_PROPERTY                     "1038: '$e_identifier$': invalid color property"
+.errtext IDENTIFIER_EXPECTED                        "1039: identifier expected but '$e_token$' found"
+.errtext RESERVED_KEYWORD                           "1040: use of reserved keyword as an identifier"
+.errtext INTEGER_EXPECTED                           "1041: integer value expected but '$e_token$' found"
+.errtext MISSING_SEMICOLON                          "1042: ';' expected but '$e_token$' found"
+.errtext MISSING_COMMA                              "1043: ',' expected but '$e_token$' found"
+.errtext MISSING_LBRACKET                           "1044: '[' expected but '$e_token$' found"
+.errtext MISSING_RBRACKET                           "1045: ']' expected but '$e_token$' found"
+.errtext MISSING_DOT                                "1046: '.' expected but '$e_token$' found"
+.errtext MISSING_EQUAL                              "1047: '=' expected but '$e_token$' found"
+.errtext MISSING_LBRACE                             "1048: '{' expected but '$e_token$' found"
+.errtext MISSING_RBRACE                             "1049: '}' expected but '$e_token$' found"
+.errtext MISSING_DOTDOT                             "1050: '..' expected but '$e_token$' found"
+.errtext MISSING_FRACTION_OR_EXPONENT               "1051: missing fraction part or exponent"
+.errtext MISSING_DOT_OR_EXPONENT                    "1052: missing '.' or exponent"
+.errtext EXPONENT_VALUE_EXPECTED                    "1053: exponent value expected"
+.errtext INTEGER_OUT_OF_RANGE                       "1054: integer value out of range"
+.errtext OPERATION_NEEDS_DESTINATION_VARIABLE       "1055: operation needs destination variable"
+.errtext OPERATION_NEEDS_SOURCE_VARIABLE            "1056: operation needs source variable"
+.errtext ADDRESS_REGISTER_EXPECTED                  "1057: address register expected but '$e_token$' found"
+.errtext ADDRESS_REGISTER_OR_INTEGER_EXPECTED       "1058: address register or integer literal expected but '$e_token$' found"
+
+/* extension presence condition registers */
+
+/* GL_ARB_vertex_blend */
+/* GL_EXT_vertex_weighting */
+.regbyte vertex_blend                               0x00
+
+/* GL_ARB_matrix_palette */
+.regbyte matrix_palette                             0x00
+
+/* GL_ARB_point_parameters */
+/* GL_EXT_point_parameters */
+.regbyte point_parameters                           0x00
+
+/* GL_EXT_secondary_color */
+.regbyte secondary_color                            0x00
+
+/* GL_EXT_fog_coord */
+.regbyte fog_coord                                  0x00
+
+/* GL_EXT_texture_rectangle */
+/* GL_NV_texture_rectangle */
+.regbyte texture_rectangle                          0x00
+
+/* GL_ARB_fragment_program_shadow */
+.regbyte fragment_program_shadow                    0x00
+
+/* option presence condition registers */
+/* they are all initially set to zero - when a particular OPTION is encountered, the appropriate */
+/* register is set to 1 to indicate that the OPTION was specified. */
+
+/* GL_ARB_fragment_program */
+.regbyte ARB_precision_hint_fastest                 0x00
+.regbyte ARB_precision_hint_nicest                  0x00
+.regbyte ARB_fog_exp                                0x00
+.regbyte ARB_fog_exp2                               0x00
+.regbyte ARB_fog_linear                             0x00
+
+/* GL_ARB_vertex_program */
+.regbyte ARB_position_invariant                     0x00
+
+/* GL_ARB_fragment_program_shadow */
+.regbyte ARB_fragment_program_shadow                0x00
+
+/* program target condition register */
+/* this syntax script deals with two program targets - VERTEX_PROGRAM and FRAGMENT_PROGRAM. */
+/* to distinguish between them we need a register that will store for us the current target. */
+/* the client will typically set the register to apropriate value before parsing a particular */
+/* program. the mapping between program targets and their values is listed below. */
+/* */
+/* program target               register value    */
+/* ---------------------------------------------- */
+/* FRAGMENT_PROGRAM             0x10              */
+/* VERTEX_PROGRAM               0x20              */
+/* */
+/* the initial value of the register is 0 to catch potential errors with not setting the register */
+/* with the proper value. */
+.regbyte program_target                             0x00
+
+/*
+    <program>              ::= <optionSequence> <statementSequence> "END"
+*/
+program
+    programs .error UNKNOWN_PROGRAM_SIGNATURE .emit REVISION;
+programs
+    .if (program_target == 0x10) frag_program_1_0 .emit FRAGMENT_PROGRAM .emit 0x01 .emit 0x00 .or
+    .if (program_target == 0x20) vert_program_1_0 .emit VERTEX_PROGRAM .emit 0x01 .emit 0x00;
+frag_program_1_0
+    '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'f' .and 'p' .and '1' .and '.' .and '0' .and
+    optional_space .and fp_optionSequence .and fp_statementSequence .and
+    "END" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and
+    '\0' .error CODE_AFTER_END;
+vert_program_1_0
+    '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'v' .and 'p' .and '1' .and '.' .and '0' .and
+    optional_space .and vp_optionSequence .and vp_statementSequence .and
+    "END" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and
+    '\0' .error CODE_AFTER_END;
+
+/*
+    <optionSequence>       ::= <optionSequence> <option>
+                             | ""
+*/
+fp_optionSequence
+    .loop fp_option;
+vp_optionSequence
+    .loop vp_option;
+
+/*
+    <option>               ::= "OPTION" <identifier> ";"
+
+NOTE: options ARB_precision_hint_nicest and ARB_precision_hint_fastest are exclusive. When one of
+      these options is encountered, the other one is automatically disabled.
+      the same applies to options ARB_fog_exp, ARB_fog_exp2 and ARB_fog_linear.
+*/
+fp_option
+    "OPTION" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and
+    fp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;
+vp_option
+    "OPTION" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and
+    vp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;
+fp_optionString
+    .if (ARB_precision_hint_nicest == 0x00) "ARB_precision_hint_fastest"
+        .emit ARB_PRECISION_HINT_FASTEST .load ARB_precision_hint_fastest 0x01 .or
+    .if (ARB_precision_hint_fastest == 0x00) "ARB_precision_hint_nicest"
+        .emit ARB_PRECISION_HINT_NICEST .load ARB_precision_hint_nicest 0x01 .or
+    fp_ARB_fog_exp .emit ARB_FOG_EXP .load ARB_fog_exp 0x01 .or
+    fp_ARB_fog_exp2 .emit ARB_FOG_EXP2 .load ARB_fog_exp2 0x01 .or
+    fp_ARB_fog_linear .emit ARB_FOG_LINEAR .load ARB_fog_linear 0x01 .or
+    .if (fragment_program_shadow != 0x00) "ARB_fragment_program_shadow"
+        .emit ARB_FRAGMENT_PROGRAM_SHADOW .load ARB_fragment_program_shadow 0x01;
+vp_optionString
+    "ARB_position_invariant" .emit ARB_POSITION_INVARIANT .load ARB_position_invariant 0x01;
+fp_ARB_fog_exp
+    .if (ARB_fog_exp2 == 0x00) .true .and .if (ARB_fog_linear == 0x00) "ARB_fog_exp";
+fp_ARB_fog_exp2
+    .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_linear == 0x00) "ARB_fog_exp2";
+fp_ARB_fog_linear
+    .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_exp2 == 0x00) "ARB_fog_linear";
+
+/*
+    <statementSequence>    ::= <statementSequence> <statement>
+                             | ""
+*/
+fp_statementSequence
+    .loop fp_statement;
+vp_statementSequence
+    .loop vp_statement;
+
+/*
+    <statement>            ::= <instruction> ";"
+                             | <namingStatement> ";"
+
+NOTE: ".emit $" in the definitions below means that we output instruction position (offset of
+      the first character of instruction) for program debugging purposes.
+*/
+fp_statement
+    fp_statement_1 .or fp_statement_2;
+vp_statement
+    vp_statement_1 .or vp_statement_2;
+fp_statement_1
+    fp_instruction .emit INSTRUCTION .emit $ .and semicolon;
+fp_statement_2
+    fp_namingStatement .emit DECLARATION .and semicolon;
+vp_statement_1
+    vp_instruction .emit INSTRUCTION .emit $ .and semicolon;
+vp_statement_2
+    vp_namingStatement .emit DECLARATION .and semicolon;
+
+/*
+fragment program
+    <instruction>          ::= <ALUInstruction>
+                             | <TexInstruction>
+
+vertex program
+    <instruction>          ::= <ARL_instruction>
+                             | <VECTORop_instruction>
+                             | <SCALARop_instruction>
+                             | <BINSCop_instruction>
+                             | <BINop_instruction>
+                             | <TRIop_instruction>
+                             | <SWZ_instruction>
+*/
+fp_instruction
+    ALUInstruction .emit OP_ALU_INST .or
+    TexInstruction .emit OP_TEX_INST;
+vp_instruction
+    ARL_instruction .emit OP_ALU_ARL .or
+    vp_VECTORop_instruction .emit OP_ALU_VECTOR .or
+    vp_SCALARop_instruction .emit OP_ALU_SCALAR .or
+    vp_BINSCop_instruction .emit OP_ALU_BINSC .or
+    vp_BINop_instruction .emit OP_ALU_BIN .or
+    vp_TRIop_instruction .emit OP_ALU_TRI .or
+    vp_SWZ_instruction .emit OP_ALU_SWZ;
+
+/*
+fragment program
+    <ALUInstruction>       ::= <VECTORop_instruction>
+                             | <SCALARop_instruction>
+                             | <BINSCop_instruction>
+                             | <BINop_instruction>
+                             | <TRIop_instruction>
+                             | <SWZ_instruction>
+*/
+ALUInstruction
+    fp_VECTORop_instruction .emit OP_ALU_VECTOR .or
+    fp_SCALARop_instruction .emit OP_ALU_SCALAR .or
+    fp_BINSCop_instruction .emit OP_ALU_BINSC .or
+    fp_BINop_instruction .emit OP_ALU_BIN .or
+    fp_TRIop_instruction .emit OP_ALU_TRI .or
+    fp_SWZ_instruction .emit OP_ALU_SWZ;
+
+/*
+fragment program
+    <TexInstruction>       ::= <SAMPLE_instruction>
+                             | <KIL_instruction>
+*/
+TexInstruction
+    SAMPLE_instruction .emit OP_TEX_SAMPLE .or
+    KIL_instruction .emit OP_TEX_KIL;
+
+/*
+vertex program
+    <ARL_instruction>      ::= "ARL" <maskedAddrReg> "," <scalarSrcReg>
+*/
+ARL_instruction
+    "ARL" .emit OP_ARL .and space_dst .and maskedAddrReg .and comma .and vp_scalarSrcReg;
+
+/*
+fragment program
+    <VECTORop_instruction> ::= <VECTORop> <maskedDstReg> "," 
+                               <vectorSrcReg>
+
+vertex program
+    <VECTORop_instruction> ::= <VECTORop> <maskedDstReg> "," <swizzleSrcReg>
+*/
+fp_VECTORop_instruction
+    fp_VECTORop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg;
+vp_VECTORop_instruction
+    vp_VECTORop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg;
+
+/*
+fragment program
+    <VECTORop>             ::= "ABS" | "ABS_SAT"
+                             | "FLR" | "FLR_SAT"
+                             | "FRC" | "FRC_SAT"
+                             | "LIT" | "LIT_SAT"
+                             | "MOV" | "MOV_SAT"
+
+vertex program
+    <VECTORop>             ::= "ABS"
+                             | "FLR"
+                             | "FRC"
+                             | "LIT"
+                             | "MOV"
+*/
+fp_VECTORop
+    "ABS" .emit OP_ABS .or "ABS_SAT" .emit OP_ABS_SAT .or
+    "FLR" .emit OP_FLR .or "FLR_SAT" .emit OP_FLR_SAT .or
+    "FRC" .emit OP_FRC .or "FRC_SAT" .emit OP_FRC_SAT .or
+    "LIT" .emit OP_LIT .or "LIT_SAT" .emit OP_LIT_SAT .or
+    "MOV" .emit OP_MOV .or "MOV_SAT" .emit OP_MOV_SAT;
+vp_VECTORop
+    "ABS" .emit OP_ABS .or
+    "FLR" .emit OP_FLR .or
+    "FRC" .emit OP_FRC .or
+    "LIT" .emit OP_LIT .or
+    "MOV" .emit OP_MOV;
+
+/*
+    <SCALARop_instruction> ::= <SCALARop> <maskedDstReg> "," <scalarSrcReg>
+*/
+fp_SCALARop_instruction
+    fp_SCALARop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg;
+vp_SCALARop_instruction
+    vp_SCALARop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg;
+
+/*
+fragment program
+    <SCALARop>             ::= "COS" | "COS_SAT"
+                             | "EX2" | "EX2_SAT"
+                             | "LG2" | "LG2_SAT"
+                             | "RCP" | "RCP_SAT"
+                             | "RSQ" | "RSQ_SAT"
+                             | "SIN" | "SIN_SAT"
+                             | "SCS" | "SCS_SAT"
+
+vertex program
+    <SCALARop>             ::= "EX2"
+                             | "EXP"
+                             | "LG2"
+                             | "LOG"
+                             | "RCP"
+                             | "RSQ"
+*/
+fp_SCALARop
+    "COS" .emit OP_COS .or "COS_SAT" .emit OP_COS_SAT .or
+    "EX2" .emit OP_EX2 .or "EX2_SAT" .emit OP_EX2_SAT .or
+    "LG2" .emit OP_LG2 .or "LG2_SAT" .emit OP_LG2_SAT .or
+    "RCP" .emit OP_RCP .or "RCP_SAT" .emit OP_RCP_SAT .or
+    "RSQ" .emit OP_RSQ .or "RSQ_SAT" .emit OP_RSQ_SAT .or
+    "SIN" .emit OP_SIN .or "SIN_SAT" .emit OP_SIN_SAT .or
+    "SCS" .emit OP_SCS .or "SCS_SAT" .emit OP_SCS_SAT;
+vp_SCALARop
+    "EX2" .emit OP_EX2 .or
+    "EXP" .emit OP_EXP .or
+    "LG2" .emit OP_LG2 .or
+    "LOG" .emit OP_LOG .or
+    "RCP" .emit OP_RCP .or
+    "RSQ" .emit OP_RSQ;
+
+/*
+    <BINSCop_instruction>  ::= <BINSCop> <maskedDstReg> "," <scalarSrcReg> ","
+                               <scalarSrcReg>
+*/
+fp_BINSCop_instruction
+    fp_BINSCop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg .and comma .and
+    fp_scalarSrcReg;
+vp_BINSCop_instruction
+    vp_BINSCop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg .and comma .and
+    vp_scalarSrcReg;
+
+/*
+fragment program
+    <BINSCop>              ::= "POW" | "POW_SAT"
+
+vertex program
+    <BINSCop>              ::= "POW"
+*/
+fp_BINSCop
+    "POW" .emit OP_POW .or "POW_SAT" .emit OP_POW_SAT;
+vp_BINSCop
+    "POW" .emit OP_POW;
+
+/*
+fragment program
+    <BINop_instruction>    ::= <BINop> <maskedDstReg> ","
+                               <vectorSrcReg> "," <vectorSrcReg>
+
+vertex program
+    <BINop_instruction>    ::= <BINop> <maskedDstReg> ","
+                               <swizzleSrcReg> "," <swizzleSrcReg>
+*/
+fp_BINop_instruction
+    fp_BINop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and
+    vectorSrcReg;
+vp_BINop_instruction
+    vp_BINop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and
+    swizzleSrcReg;
+
+/*
+fragment program
+    <BINop>                ::= "ADD" | "ADD_SAT"
+                             | "DP3" | "DP3_SAT"
+                             | "DP4" | "DP4_SAT"
+                             | "DPH" | "DPH_SAT"
+                             | "DST" | "DST_SAT"
+                             | "MAX" | "MAX_SAT"
+                             | "MIN" | "MIN_SAT"
+                             | "MUL" | "MUL_SAT"
+                             | "SGE" | "SGE_SAT"
+                             | "SLT" | "SLT_SAT"
+                             | "SUB" | "SUB_SAT"
+                             | "XPD" | "XPD_SAT"
+
+vertex program
+    <BINop>                ::= "ADD"
+                             | "DP3"
+                             | "DP4"
+                             | "DPH"
+                             | "DST"
+                             | "MAX"
+                             | "MIN"
+                             | "MUL"
+                             | "SGE"
+                             | "SLT"
+                             | "SUB"
+                             | "XPD"
+*/
+fp_BINop
+    "ADD" .emit OP_ADD .or "ADD_SAT" .emit OP_ADD_SAT .or
+    "DP3" .emit OP_DP3 .or "DP3_SAT" .emit OP_DP3_SAT .or
+    "DP4" .emit OP_DP4 .or "DP4_SAT" .emit OP_DP4_SAT .or
+    "DPH" .emit OP_DPH .or "DPH_SAT" .emit OP_DPH_SAT .or
+    "DST" .emit OP_DST .or "DST_SAT" .emit OP_DST_SAT .or
+    "MAX" .emit OP_MAX .or "MAX_SAT" .emit OP_MAX_SAT .or
+    "MIN" .emit OP_MIN .or "MIN_SAT" .emit OP_MIN_SAT .or
+    "MUL" .emit OP_MUL .or "MUL_SAT" .emit OP_MUL_SAT .or
+    "SGE" .emit OP_SGE .or "SGE_SAT" .emit OP_SGE_SAT .or
+    "SLT" .emit OP_SLT .or "SLT_SAT" .emit OP_SLT_SAT .or
+    "SUB" .emit OP_SUB .or "SUB_SAT" .emit OP_SUB_SAT .or
+    "XPD" .emit OP_XPD .or "XPD_SAT" .emit OP_XPD_SAT;
+vp_BINop
+    "ADD" .emit OP_ADD .or
+    "DP3" .emit OP_DP3 .or
+    "DP4" .emit OP_DP4 .or
+    "DPH" .emit OP_DPH .or
+    "DST" .emit OP_DST .or
+    "MAX" .emit OP_MAX .or
+    "MIN" .emit OP_MIN .or
+    "MUL" .emit OP_MUL .or
+    "SGE" .emit OP_SGE .or
+    "SLT" .emit OP_SLT .or
+    "SUB" .emit OP_SUB .or
+    "XPD" .emit OP_XPD;
+
+/*
+fragment program
+    <TRIop_instruction>    ::= <TRIop> <maskedDstReg> ","
+                               <vectorSrcReg> "," <vectorSrcReg> ","
+                               <vectorSrcReg>
+
+vertex program
+    <TRIop_instruction>    ::= <TRIop> <maskedDstReg> ","
+                               <swizzleSrcReg> "," <swizzleSrcReg> ","
+                               <swizzleSrcReg>
+*/
+fp_TRIop_instruction
+    fp_TRIop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and
+    vectorSrcReg .and comma .and vectorSrcReg;
+vp_TRIop_instruction
+    vp_TRIop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and
+    swizzleSrcReg .and comma .and swizzleSrcReg;
+
+/*
+fragment program
+    <TRIop>                ::= "CMP" | "CMP_SAT"
+                             | "LRP" | "LRP_SAT"
+                             | "MAD" | "MAD_SAT"
+
+vertex program
+    <TRIop>                ::= "MAD"
+*/
+fp_TRIop
+    "CMP" .emit OP_CMP .or "CMP_SAT" .emit OP_CMP_SAT .or
+    "LRP" .emit OP_LRP .or "LRP_SAT" .emit OP_LRP_SAT .or
+    "MAD" .emit OP_MAD .or "MAD_SAT" .emit OP_MAD_SAT;
+vp_TRIop
+    "MAD" .emit OP_MAD;
+
+/*
+fragment program
+    <SWZ_instruction>      ::= <SWZop> <maskedDstReg> "," 
+                               <srcReg> "," <extendedSwizzle>
+
+vertex program
+    <SWZ_instruction>      ::= "SWZ" <maskedDstReg> "," <srcReg> "," 
+                               <extendedSwizzle>
+*/
+fp_SWZ_instruction
+    SWZop .and space_dst .and fp_maskedDstReg .and comma .and fp_srcReg .and comma .and
+    fp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;
+vp_SWZ_instruction
+    "SWZ" .emit OP_SWZ .and space_dst .and vp_maskedDstReg .and comma .and vp_srcReg .and comma .and
+    vp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;
+
+/*
+fragment program
+    <SWZop>                ::= "SWZ" | "SWZ_SAT"
+*/
+SWZop
+    "SWZ" .emit OP_SWZ .or "SWZ_SAT" .emit OP_SWZ_SAT;
+
+/*
+fragment program
+    <SAMPLE_instruction>   ::= <SAMPLEop> <maskedDstReg> ","
+                               <vectorSrcReg> "," <texImageUnit> "," 
+                               <texTarget>
+*/
+SAMPLE_instruction
+    SAMPLEop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and
+    texImageUnit .and comma .and texTarget .error TEX_TARGET_EXPECTED;
+
+/*
+fragment program
+    <SAMPLEop>             ::= "TEX" | "TEX_SAT"
+                             | "TXP" | "TXP_SAT"
+                             | "TXB" | "TXB_SAT"
+*/
+SAMPLEop
+    "TEX" .emit OP_TEX .or "TEX_SAT" .emit OP_TEX_SAT .or
+    "TXB" .emit OP_TXB .or "TXB_SAT" .emit OP_TXB_SAT .or
+    "TXP" .emit OP_TXP .or "TXP_SAT" .emit OP_TXP_SAT;
+
+/*
+fragment program
+    <KIL_instruction>      ::= "KIL" <vectorSrcReg>
+*/
+KIL_instruction
+    "KIL" .emit OP_KIL .and space_src .and vectorSrcReg;
+
+/*
+fragment program
+    <texImageUnit>         ::= "texture" <optTexImageUnitNum>
+*/
+texImageUnit
+    "texture" .error TEXTURE_EXPECTED .and optTexImageUnitNum;
+
+/*
+fragment program
+    <texTarget>            ::= "1D"
+                             | "2D"
+                             | "3D"
+                             | "CUBE"
+                             | "RECT"
+                             | <shadowTarget> (if option ARB_fragment_program_shadow present)
+*/
+texTarget
+    "1D" .emit TEXTARGET_1D .or
+    "2D" .emit TEXTARGET_2D .or
+    "3D" .emit TEXTARGET_3D .or
+    .if (texture_rectangle != 0x00) "RECT" .emit TEXTARGET_RECT .or
+    "CUBE" .emit TEXTARGET_CUBE .or
+    .if (ARB_fragment_program_shadow != 0x00) shadowTarget;
+
+/*
+GL_ARB_fragment_program_shadow
+    <shadowTarget>         ::= "SHADOW1D"
+                             | "SHADOW2D"
+                             | "SHADOWRECT"
+*/
+shadowTarget
+    "SHADOW1D" .emit TEXTARGET_SHADOW1D .or
+    "SHADOW2D" .emit TEXTARGET_SHADOW2D .or
+    .if (texture_rectangle != 0x00) "SHADOWRECT" .emit TEXTARGET_SHADOWRECT;
+
+/*
+fragment program
+    <optTexImageUnitNum>   ::= ""
+                             | "[" <texImageUnitNum> "]"
+*/
+optTexImageUnitNum
+    optTexImageUnitNum_1 .or .true .emit 0x00;
+optTexImageUnitNum_1
+    lbracket_ne .and texImageUnitNum .and rbracket;
+
+/*
+fragment program
+    <texImageUnitNum>      ::= <integer> from 0 to 
+                               MAX_TEXTURE_IMAGE_UNITS_ARB-1
+*/
+texImageUnitNum
+    integer;
+
+/*
+    <scalarSrcReg>         ::= <optionalSign> <srcReg> <scalarSuffix>
+*/
+fp_scalarSrcReg
+    optionalSign .and fp_srcReg .and fp_scalarSuffix;
+vp_scalarSrcReg
+    optionalSign .and vp_srcReg .and vp_scalarSuffix;
+
+/*
+vertex program
+    <swizzleSrcReg>        ::= <optionalSign> <srcReg> <swizzleSuffix>
+*/
+swizzleSrcReg
+    optionalSign .and vp_srcReg .and swizzleSuffix;
+
+/*
+fragment program
+    <vectorSrcReg>         ::= <optionalSign> <srcReg> <optionalSuffix> 
+*/
+vectorSrcReg
+    optionalSign .and fp_srcReg .and optionalSuffix;
+
+/*
+    <maskedDstReg>         ::= <dstReg> <optionalMask>
+*/
+fp_maskedDstReg
+    fp_dstReg .and fp_optionalMask;
+vp_maskedDstReg
+    vp_dstReg .and vp_optionalMask;
+
+/*
+vertex program
+    <maskedAddrReg>        ::= <addrReg> <addrWriteMask>
+*/
+maskedAddrReg
+    addrReg .error ADDRESS_REGISTER_EXPECTED .and addrWriteMask;
+
+/*
+fragment program
+    <extendedSwizzle>      ::= <xyzwExtendedSwizzle>
+                             | <rgbaExtendedSwizzle>
+
+vertex program
+    <extendedSwizzle>      ::= <extSwizComp> "," <extSwizComp> "," 
+                                 <extSwizComp> "," <extSwizComp>
+
+NOTE: do NOT change the order of <rgbaExtendedSwizzle> and <xyzwExtendedSwizzle> rulez
+*/
+fp_extendedSwizzle
+    rgbaExtendedSwizzle .or xyzwExtendedSwizzle;
+vp_extendedSwizzle
+    extSwizComp .and comma .and
+    extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
+    extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
+    extSwizComp .error EXT_SWIZ_COMP_EXPECTED;
+
+/*
+fragment program
+    <xyzwExtendedSwizzle>  ::= <xyzwExtSwizComp> "," <xyzwExtSwizComp> "," 
+                               <xyzwExtSwizComp> "," <xyzwExtSwizComp>
+*/
+xyzwExtendedSwizzle
+    xyzwExtSwizComp .and comma .and
+    xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
+    xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
+    xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;
+
+/*
+fragment program
+    <rgbaExtendedSwizzle>  ::= <rgbaExtSwizComp> "," <rgbaExtSwizComp> "," 
+                               <rgbaExtSwizComp> "," <rgbaExtSwizComp>
+*/
+rgbaExtendedSwizzle
+    rgbaExtendedSwizzle_1 .or rgbaExtendedSwizzle_2 .or rgbaExtendedSwizzle_3 .or
+    rgbaExtendedSwizzle_4;
+rgbaExtendedSwizzle_1
+    rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and
+    rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp;
+rgbaExtendedSwizzle_2
+    rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and
+    rgbaExtSwizComp_alpha .and comma .and rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;
+rgbaExtendedSwizzle_3
+    rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_alpha .and comma .and
+    rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
+    rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;
+rgbaExtendedSwizzle_4
+    rgbaExtSwizComp_alpha .and comma .and 
+    rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
+    rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
+    rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;
+
+/*
+fragment program
+    <xyzwExtSwizComp>      ::= <optionalSign> <xyzwExtSwizSel>
+*/
+xyzwExtSwizComp
+    optionalSign .and xyzwExtSwizSel;
+
+/*
+fragment program
+    <rgbaExtSwizComp>      ::= <optionalSign> <rgbaExtSwizSel>
+*/
+rgbaExtSwizComp
+    optionalSign .and rgbaExtSwizSel;
+rgbaExtSwizComp_digit
+    optionalSign .and rgbaExtSwizSel_digit;
+rgbaExtSwizComp_alpha
+    optionalSign .and rgbaExtSwizSel_alpha;
+
+/*
+vertex program
+    <extSwizComp>          ::= <optionalSign> <extSwizSel>
+*/
+extSwizComp
+    optionalSign .and extSwizSel;
+
+/*
+fragment program
+    <xyzwExtSwizSel>       ::= "0" 
+                             | "1" 
+                             | <xyzwComponent>
+*/
+xyzwExtSwizSel
+    "0" .emit COMPONENT_0 .or "1" .emit COMPONENT_1 .or xyzwComponent_single;
+
+/*
+fragment program
+    <rgbaExtSwizSel>       ::= "0" 
+                             | "1" 
+                             | <rgbaComponent>
+*/
+rgbaExtSwizSel
+    rgbaExtSwizSel_digit .or rgbaExtSwizSel_alpha;
+rgbaExtSwizSel_digit
+    "0" .emit COMPONENT_0 .or "1" .emit COMPONENT_1;
+rgbaExtSwizSel_alpha
+    rgbaComponent_single;
+
+/*
+vertex program
+    <extSwizSel>           ::= "0" 
+                             | "1" 
+                             | <component>
+*/
+extSwizSel
+    "0" .emit COMPONENT_0 .or "1" .emit COMPONENT_1 .or vp_component_single;
+
+/*
+fragment program
+    <srcReg>               ::= <fragmentAttribReg>
+                             | <temporaryReg>
+                             | <progParamReg>
+
+vertex program
+    <srcReg>               ::= <vertexAttribReg>
+                             | <temporaryReg>
+                             | <progParamReg>
+*/
+fp_srcReg
+    fp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;
+vp_srcReg
+    vp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;
+fp_srcReg_1
+    fragmentAttribReg .emit REGISTER_ATTRIB .or
+    fp_progParamReg .emit REGISTER_PARAM .or
+    fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;
+vp_srcReg_1
+    vertexAttribReg .emit REGISTER_ATTRIB .or
+    vp_progParamReg .emit REGISTER_PARAM .or
+    vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;
+
+/*
+fragment program
+    <dstReg>               ::= <temporaryReg>
+                             | <fragmentResultReg>
+
+vertex program
+    <dstReg>               ::= <temporaryReg>
+                             | <vertexResultReg>
+*/
+fp_dstReg
+    fp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;
+vp_dstReg
+    vp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;
+fp_dstReg_1
+    fragmentResultReg .emit REGISTER_RESULT .or
+    fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;
+vp_dstReg_1
+    vertexResultReg .emit REGISTER_RESULT .or
+    vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;
+
+/*
+fragment program
+    <fragmentAttribReg>    ::= <establishedName>
+                             | <fragAttribBinding>
+
+NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <srcReg>
+*/
+fragmentAttribReg
+    /*fp_establishedName .or */fragAttribBinding;
+
+/*
+vertex program
+    <vertexAttribReg>      ::= <establishedName>
+                             | <vtxAttribBinding>
+
+NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <srcReg>
+*/
+vertexAttribReg
+    vtxAttribBinding;
+
+/*
+    <temporaryReg>         ::= <establishedName>
+*/
+fp_temporaryReg
+    fp_establishedName_no_error_on_identifier;
+vp_temporaryReg
+    vp_establishedName_no_error_on_identifier;
+
+/*
+fragment program
+    <progParamReg>         ::= <progParamSingle>
+                             | <progParamArray> "[" <progParamArrayAbs> "]"
+                             | <paramSingleItemUse>
+
+vertex program
+    <progParamReg>         ::= <progParamSingle>
+                             | <progParamArray> "[" <progParamArrayMem> "]"
+                             | <paramSingleItemUse>
+*/
+fp_progParamReg
+    fp_paramSingleItemUse .or fp_progParamReg_1 .or fp_progParamSingle;
+vp_progParamReg
+    vp_paramSingleItemUse .or vp_progParamReg_1 .or vp_progParamSingle;
+fp_progParamReg_1
+    fp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayAbs .and
+    rbracket;
+vp_progParamReg_1
+    vp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayMem .and
+    rbracket;
+
+/*
+    <progParamSingle>      ::= <establishedName>
+
+NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <srcReg>
+*/
+fp_progParamSingle
+    .false;
+vp_progParamSingle
+    .false;
+
+/*
+    <progParamArray>       ::= <establishedName>
+*/
+fp_progParamArray
+    fp_establishedName_no_error_on_identifier;
+vp_progParamArray
+    vp_establishedName_no_error_on_identifier;
+
+/*
+vertex program
+    <progParamArrayMem>    ::= <progParamArrayAbs>
+                             | <progParamArrayRel>
+*/
+progParamArrayMem
+    progParamArrayAbs .or progParamArrayRel;
+
+/*
+    <progParamArrayAbs>    ::= <integer>
+*/
+progParamArrayAbs
+    integer_ne .emit ARRAY_INDEX_ABSOLUTE;
+
+/*
+vertex program
+    <progParamArrayRel>    ::= <addrReg> <addrComponent> <addrRegRelOffset>
+*/
+progParamArrayRel
+    addrReg .error ADDRESS_REGISTER_OR_INTEGER_EXPECTED .emit ARRAY_INDEX_RELATIVE .and
+    addrComponent .and addrRegRelOffset;
+
+/*
+vertex program
+    <addrRegRelOffset>     ::= ""
+                             | "+" <addrRegPosOffset>
+                             | "-" <addrRegNegOffset>
+*/
+addrRegRelOffset
+    addrRegRelOffset_1 .or addrRegRelOffset_2 .or .true .emit 0x00;
+addrRegRelOffset_1
+    plus_ne .and addrRegPosOffset;
+addrRegRelOffset_2
+    minus_ne .and addrRegNegOffset;
+
+/*
+vertex program
+    <addrRegPosOffset>     ::= <integer> from 0 to 63
+*/
+addrRegPosOffset
+    integer_0_63;
+
+/*
+vertex program
+    <addrRegNegOffset>     ::= <integer> from 0 to 64
+*/
+addrRegNegOffset
+    integer_0_64;
+
+/*
+fragment program
+    <fragmentResultReg>    ::= <establishedName>
+                             | <resultBinding>
+
+NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <dstReg>
+*/
+fragmentResultReg
+    fp_resultBinding;
+
+/*
+vertex program
+    <vertexResultReg>      ::= <establishedName>
+                             | <resultBinding>
+
+NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <dstReg>
+*/
+vertexResultReg
+    vp_resultBinding;
+
+/*
+vertex program
+    <addrReg>              ::= <establishedName>
+*/
+addrReg
+    vp_establishedName_no_error_on_identifier;
+
+/*
+vertex program
+    <addrComponent>        ::= "." "x"
+*/
+addrComponent
+    dot .and "x" .error INVALID_ADDRESS_COMPONENT .emit COMPONENT_X .emit COMPONENT_X
+    .emit COMPONENT_X .emit COMPONENT_X;
+
+/*
+vertex program
+    <addrWriteMask>        ::= "." "x"
+*/
+addrWriteMask
+    dot .and "x" .error INVALID_ADDRESS_WRITEMASK .emit 0x08;
+
+/*
+    <scalarSuffix>         ::= "." <component>
+*/
+fp_scalarSuffix
+    dot .and fp_component_single .error INVALID_COMPONENT;
+vp_scalarSuffix
+    dot .and vp_component_single .error INVALID_COMPONENT;
+
+/*
+vertex program
+    <swizzleSuffix>        ::= ""
+                             | "." <component>
+                             | "." <component> <component>
+                                   <component> <component>
+*/
+swizzleSuffix
+    swizzleSuffix_1 .or
+    .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;
+swizzleSuffix_1
+    dot_ne .and swizzleSuffix_2 .error INVALID_SUFFIX;
+swizzleSuffix_2
+    swizzleSuffix_3 .or swizzleSuffix_4;
+swizzleSuffix_3
+    vp_component_multi .and vp_component_multi .and vp_component_multi .error INVALID_COMPONENT .and
+    vp_component_multi .error INVALID_COMPONENT;
+swizzleSuffix_4
+    "x" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or
+    "y" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or
+    "z" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or
+    "w" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;
+
+/*
+fragment program
+    <optionalSuffix>       ::= "" 
+                             | "." <component> 
+                             | "." <xyzwComponent> <xyzwComponent>
+                                   <xyzwComponent> <xyzwComponent>
+                             | "." <rgbaComponent> <rgbaComponent>
+                                   <rgbaComponent> <rgbaComponent>
+*/
+optionalSuffix
+    optionalSuffix_1 .or
+    .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;
+optionalSuffix_1
+    dot_ne .and optionalSuffix_2 .error INVALID_SUFFIX;
+optionalSuffix_2
+    optionalSuffix_3 .or optionalSuffix_4 .or optionalSuffix_5;
+optionalSuffix_3
+    xyzwComponent_multi .and xyzwComponent_multi .and
+    xyzwComponent_multi .error INVALID_COMPONENT .and xyzwComponent_multi .error INVALID_COMPONENT;
+optionalSuffix_4
+    rgbaComponent_multi .and rgbaComponent_multi .and
+    rgbaComponent_multi .error INVALID_COMPONENT .and rgbaComponent_multi .error INVALID_COMPONENT;
+optionalSuffix_5
+    "x" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or
+    "y" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or
+    "z" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or
+    "w" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .or
+    "r" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or
+    "g" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or
+    "b" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or
+    "a" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;
+
+/*
+fragment program
+    <component>            ::= <xyzwComponent>
+                             | <rgbaComponent>
+
+vertex program
+    <component>            ::= "x"
+                             | "y"
+                             | "z"
+                             | "w"
+*/
+fp_component_single
+    xyzwComponent_single .or rgbaComponent_single;
+vp_component_multi
+    'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or
+    'w' .emit COMPONENT_W;
+vp_component_single
+    "x" .emit COMPONENT_X .or "y" .emit COMPONENT_Y .or "z" .emit COMPONENT_Z .or
+    "w" .emit COMPONENT_W;
+
+/*
+fragment program
+    <xyzwComponent>        ::= "x" | "y" | "z" | "w"
+*/
+xyzwComponent_multi
+    'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or
+    'w' .emit COMPONENT_W;
+xyzwComponent_single
+    "x" .emit COMPONENT_X .or "y" .emit COMPONENT_Y .or "z" .emit COMPONENT_Z .or
+    "w" .emit COMPONENT_W;
+
+/*
+fragment program
+    <rgbaComponent>        ::= "r" | "g" | "b" | "a"
+*/
+rgbaComponent_multi
+    'r' .emit COMPONENT_X .or 'g' .emit COMPONENT_Y .or 'b' .emit COMPONENT_Z .or
+    'a' .emit COMPONENT_W;
+rgbaComponent_single
+    "r" .emit COMPONENT_X .or "g" .emit COMPONENT_Y .or "b" .emit COMPONENT_Z .or
+    "a" .emit COMPONENT_W;
+
+/*
+fragment program
+    <optionalMask>         ::= ""
+                             | <xyzwMask>
+                             | <rgbaMask>
+
+vertex program
+    <optionalMask>         ::= ""
+                             | "." "x"
+                             | "." "y"
+                             | "." "xy"
+                             | "." "z"
+                             | "." "xz"
+                             | "." "yz"
+                             | "." "xyz"
+                             | "." "w"
+                             | "." "xw"
+                             | "." "yw"
+                             | "." "xyw"
+                             | "." "zw"
+                             | "." "xzw"
+                             | "." "yzw"
+                             | "." "xyzw"
+
+NOTE: do NOT change the order of <rgbaMask> and <xyzwMask> rulez
+*/
+fp_optionalMask
+    rgbaMask .or xyzwMask .or .true .emit 0x0F;
+vp_optionalMask
+    xyzwMask .or .true .emit 0x0F;
+
+/*
+fragment program
+    <xyzwMask>             ::= "." "x"
+                             | "." "y"
+                             | "." "xy"
+                             | "." "z"
+                             | "." "xz"
+                             | "." "yz"
+                             | "." "xyz"
+                             | "." "w"
+                             | "." "xw"
+                             | "." "yw"
+                             | "." "xyw"
+                             | "." "zw"
+                             | "." "xzw"
+                             | "." "yzw"
+                             | "." "xyzw"
+
+NOTE: <xyzwMask> is also referenced by the vertex program symbol <optionalMask>.
+*/
+xyzwMask
+    dot_ne .and xyzwMask_1 .error INVALID_WRITEMASK;
+xyzwMask_1
+    "xyzw" .emit 0x0F .or "xyz" .emit 0x0E .or "xyw" .emit 0x0D .or "xy" .emit 0x0C .or
+    "xzw" .emit 0x0B .or "xz" .emit 0x0A .or "xw" .emit 0x09 .or "x" .emit 0x08 .or
+    "yzw" .emit 0x07 .or "yz" .emit 0x06 .or "yw" .emit 0x05 .or "y" .emit 0x04 .or
+    "zw" .emit 0x03 .or "z" .emit 0x02 .or "w" .emit 0x01;
+
+/*
+fragment program
+    <rgbaMask>             ::= "." "r"
+                             | "." "g"
+                             | "." "rg"
+                             | "." "b"
+                             | "." "rb"
+                             | "." "gb"
+                             | "." "rgb"
+                             | "." "a"
+                             | "." "ra"
+                             | "." "ga"
+                             | "." "rga"
+                             | "." "ba"
+                             | "." "rba"
+                             | "." "gba"
+                             | "." "rgba"
+*/
+rgbaMask
+    dot_ne .and rgbaMask_1;
+rgbaMask_1
+    "rgba" .emit 0x0F .or "rgb" .emit 0x0E .or "rga" .emit 0x0D .or "rg" .emit 0x0C .or
+    "rba" .emit 0x0B .or "rb" .emit 0x0A .or "ra" .emit 0x09 .or "r" .emit 0x08 .or
+    "gba" .emit 0x07 .or "gb" .emit 0x06 .or "ga" .emit 0x05 .or "g" .emit 0x04 .or
+    "ba" .emit 0x03 .or "b" .emit 0x02 .or "a" .emit 0x01;
+
+/*
+fragment program
+    <namingStatement>      ::= <ATTRIB_statement>
+                             | <PARAM_statement>
+                             | <TEMP_statement>
+                             | <OUTPUT_statement>
+                             | <ALIAS_statement>
+
+vertex program
+    <namingStatement>      ::= <ATTRIB_statement>
+                             | <PARAM_statement>
+                             | <TEMP_statement>
+                             | <ADDRESS_statement>
+                             | <OUTPUT_statement>
+                             | <ALIAS_statement>
+*/
+fp_namingStatement
+    fp_ATTRIB_statement .emit ATTRIB .or
+    fp_PARAM_statement .emit PARAM .or
+    fp_TEMP_statement .emit TEMP .or
+    fp_OUTPUT_statement .emit OUTPUT .or
+    fp_ALIAS_statement .emit ALIAS;
+vp_namingStatement
+    vp_ATTRIB_statement .emit ATTRIB .or
+    vp_PARAM_statement .emit PARAM .or
+    vp_TEMP_statement .emit TEMP .or
+    ADDRESS_statement .emit ADDRESS .or
+    vp_OUTPUT_statement .emit OUTPUT .or
+    vp_ALIAS_statement .emit ALIAS;
+
+/*
+fragment program
+    <ATTRIB_statement>     ::= "ATTRIB" <establishName> "="
+                                 <fragAttribBinding>
+
+vertex program
+    <ATTRIB_statement>     ::= "ATTRIB" <establishName> "="
+                                 <vtxAttribBinding>
+*/
+fp_ATTRIB_statement
+    "ATTRIB" .and space .and fp_establishName .and equal .and
+    fragAttribBinding .error FRAGMENT_EXPECTED;
+vp_ATTRIB_statement
+    "ATTRIB" .and space .and vp_establishName .and equal .and
+    vtxAttribBinding .error VERTEX_EXPECTED;
+
+/*
+fragment program
+    <fragAttribBinding>    ::= "fragment" "." <fragAttribItem>
+*/
+fragAttribBinding
+    "fragment" .and dot .and fragAttribItem .error INVALID_FRAGMENT_PROPERTY;
+
+/*
+vertex program
+    <vtxAttribBinding>     ::= "vertex" "." <vtxAttribItem>
+*/
+vtxAttribBinding
+    "vertex" .and dot .and vtxAttribItem .error INVALID_VERTEX_PROPERTY;
+
+/*
+fragment program
+    <fragAttribItem>       ::= "color" <optColorType>
+                             | "texcoord" <optTexCoordNum>
+                             | "fogcoord"
+                             | "position"
+*/
+fragAttribItem
+    fragAttribItem_1 .emit FRAGMENT_ATTRIB_COLOR .or
+    fragAttribItem_2 .emit FRAGMENT_ATTRIB_TEXCOORD .or
+    .if (fog_coord != 0x00) "fogcoord" .emit FRAGMENT_ATTRIB_FOGCOORD .or
+    "position" .emit FRAGMENT_ATTRIB_POSITION;
+fragAttribItem_1
+    "color" .and optColorType;
+fragAttribItem_2
+    "texcoord" .and optTexCoordNum;
+
+/*
+vertex program
+    <vtxAttribItem>        ::= "position"
+                             | "weight" <vtxOptWeightNum>
+                             | "normal"
+                             | "color" <optColorType>
+                             | "fogcoord"
+                             | "texcoord" <optTexCoordNum>
+                             | "matrixindex" "[" <vtxWeightNum> "]"
+                             | "attrib" "[" <vtxAttribNum> "]"
+*/
+vtxAttribItem
+    "position" .emit VERTEX_ATTRIB_POSITION .or
+    .if (vertex_blend != 0x00) vtxAttribItem_1 .emit VERTEX_ATTRIB_WEIGHT .or
+    "normal" .emit VERTEX_ATTRIB_NORMAL .or
+    vtxAttribItem_2 .emit VERTEX_ATTRIB_COLOR .or
+    "fogcoord" .emit VERTEX_ATTRIB_FOGCOORD .or
+    vtxAttribItem_3 .emit VERTEX_ATTRIB_TEXCOORD .or
+    .if (matrix_palette != 0x00) vtxAttribItem_4 .emit VERTEX_ATTRIB_MATRIXINDEX .or
+    vtxAttribItem_5 .emit VERTEX_ATTRIB_GENERIC;
+vtxAttribItem_1
+    "weight" .and vtxOptWeightNum;
+vtxAttribItem_2
+    "color" .and optColorType;
+vtxAttribItem_3
+    "texcoord" .and optTexCoordNum;
+vtxAttribItem_4
+    "matrixindex" .and lbracket .and vtxWeightNum .and rbracket;
+vtxAttribItem_5
+    "attrib" .and lbracket .and vtxAttribNum .and rbracket;
+
+/*
+vertex program
+    <vtxAttribNum>         ::= <integer> from 0 to MAX_VERTEX_ATTRIBS_ARB-1
+*/
+vtxAttribNum
+    integer;
+
+/*
+vertex program
+    <vtxOptWeightNum>      ::= ""
+                             | "[" <vtxWeightNum> "]"
+*/
+vtxOptWeightNum
+    vtxOptWeightNum_1 .or .true .emit 0x00;
+vtxOptWeightNum_1
+    lbracket_ne .and vtxWeightNum .and rbracket;
+
+/*
+vertex program
+    <vtxWeightNum>         ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1,
+                                 must be divisible by four
+*/
+vtxWeightNum
+    integer;
+
+/*
+    <PARAM_statement>      ::= <PARAM_singleStmt>
+                             | <PARAM_multipleStmt>
+*/
+fp_PARAM_statement
+    fp_PARAM_multipleStmt .or fp_PARAM_singleStmt;
+vp_PARAM_statement
+    vp_PARAM_multipleStmt .or vp_PARAM_singleStmt;
+
+/*
+    <PARAM_singleStmt>     ::= "PARAM" <establishName> <paramSingleInit>
+*/
+fp_PARAM_singleStmt
+    "PARAM" .and space .and fp_establishName .and .true .emit 0x00 .and fp_paramSingleInit .and
+    .true .emit PARAM_NULL;
+vp_PARAM_singleStmt
+    "PARAM" .and space .and vp_establishName .and .true .emit 0x00 .and vp_paramSingleInit .and
+    .true .emit PARAM_NULL;
+
+/*
+    <PARAM_multipleStmt>   ::= "PARAM" <establishName> "[" <optArraySize> "]"
+                                   <paramMultipleInit>
+*/
+fp_PARAM_multipleStmt
+    "PARAM" .and space .and fp_establishName .and lbracket_ne .and optArraySize .and rbracket .and
+    fp_paramMultipleInit .and .true .emit PARAM_NULL;
+vp_PARAM_multipleStmt
+    "PARAM" .and space .and vp_establishName .and lbracket_ne .and optArraySize .and rbracket .and
+    vp_paramMultipleInit .and .true .emit PARAM_NULL;
+
+/*
+    <optArraySize>         ::= ""
+                             | <integer> from 1 to MAX_PROGRAM_PARAMETERS_ARB
+                                 (maximum number of allowed program 
+                                  parameter bindings)
+*/
+optArraySize
+    optional_integer;
+
+/*
+    <paramSingleInit>      ::= "=" <paramSingleItemDecl>
+*/
+fp_paramSingleInit
+    equal .and fp_paramSingleItemDecl;
+vp_paramSingleInit
+    equal .and vp_paramSingleItemDecl;
+
+/*
+    <paramMultipleInit>    ::= "=" "{" <paramMultInitList> "}"
+*/
+fp_paramMultipleInit
+    equal .and lbrace .and fp_paramMultInitList .and rbrace;
+vp_paramMultipleInit
+    equal .and lbrace .and vp_paramMultInitList .and rbrace;
+
+/*
+    <paramMultInitList>    ::= <paramMultipleItem>
+                             | <paramMultipleItem> "," <paramMultiInitList>
+*/
+fp_paramMultInitList
+    fp_paramMultInitList_1 .or fp_paramMultipleItem;
+vp_paramMultInitList
+    vp_paramMultInitList_1 .or vp_paramMultipleItem;
+fp_paramMultInitList_1
+    fp_paramMultipleItem .and comma_ne .and fp_paramMultInitList;
+vp_paramMultInitList_1
+    vp_paramMultipleItem .and comma_ne .and vp_paramMultInitList;
+
+/*
+    <paramSingleItemDecl>  ::= <stateSingleItem>
+                             | <programSingleItem>
+                             | <paramConstDecl>
+*/
+fp_paramSingleItemDecl
+    fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or
+    programSingleItem .emit PARAM_PROGRAM_ELEMENT .or
+    paramConstDecl .emit PARAM_CONSTANT;
+vp_paramSingleItemDecl
+    vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or
+    programSingleItem .emit PARAM_PROGRAM_ELEMENT .or
+    paramConstDecl .emit PARAM_CONSTANT;
+
+/*
+    <paramSingleItemUse>   ::= <stateSingleItem>
+                             | <programSingleItem>
+                             | <paramConstUse>
+*/
+fp_paramSingleItemUse
+    fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or
+    programSingleItem .emit PARAM_PROGRAM_ELEMENT .or
+    paramConstUse .emit PARAM_CONSTANT;
+vp_paramSingleItemUse
+    vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or
+    programSingleItem .emit PARAM_PROGRAM_ELEMENT .or
+    paramConstUse .emit PARAM_CONSTANT;
+
+/*
+    <paramMultipleItem>    ::= <stateMultipleItem>
+                             | <programMultipleItem>
+                             | <paramConstDecl>
+*/
+fp_paramMultipleItem
+    fp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or
+    programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or
+    paramConstDecl .emit PARAM_CONSTANT;
+vp_paramMultipleItem
+    vp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or
+    programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or
+    paramConstDecl .emit PARAM_CONSTANT;
+
+/*
+    <stateMultipleItem>    ::= <stateSingleItem>
+                             | "state" "." <stateMatrixRows>
+*/
+fp_stateMultipleItem
+    stateMultipleItem_1 .or fp_stateSingleItem;
+vp_stateMultipleItem
+    stateMultipleItem_1 .or vp_stateSingleItem;
+stateMultipleItem_1
+    "state" .and dot .and stateMatrixRows .emit STATE_MATRIX_ROWS;
+
+/*
+fragment program
+    <stateSingleItem>      ::= "state" "." <stateMaterialItem>
+                             | "state" "." <stateLightItem>
+                             | "state" "." <stateLightModelItem>
+                             | "state" "." <stateLightProdItem>
+                             | "state" "." <stateTexEnvItem>
+                             | "state" "." <stateFogItem>
+                             | "state" "." <stateDepthItem>
+                             | "state" "." <stateMatrixRow>
+
+vertex program
+    <stateSingleItem>      ::= "state" "." <stateMaterialItem>
+                             | "state" "." <stateLightItem>
+                             | "state" "." <stateLightModelItem>
+                             | "state" "." <stateLightProdItem>
+                             | "state" "." <stateTexGenItem>
+                             | "state" "." <stateFogItem>
+                             | "state" "." <stateClipPlaneItem>
+                             | "state" "." <statePointItem>
+                             | "state" "." <stateMatrixRow>
+*/
+fp_stateSingleItem
+    "state" .and dot .and fp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;
+vp_stateSingleItem
+    "state" .and dot .and vp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;
+fp_stateSingleItem_1
+    stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or
+    stateSingleItem_5 .or stateSingleItem_7 .or stateSingleItem_8 .or stateSingleItem_11;
+vp_stateSingleItem_1
+    stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or
+    stateSingleItem_6 .or stateSingleItem_7 .or stateSingleItem_9 .or stateSingleItem_10 .or
+    stateSingleItem_11;
+stateSingleItem_1
+    stateMaterialItem .emit STATE_MATERIAL;
+stateSingleItem_2
+    stateLightItem .emit STATE_LIGHT;
+stateSingleItem_3
+    stateLightModelItem .emit STATE_LIGHT_MODEL;
+stateSingleItem_4
+    stateLightProdItem .emit STATE_LIGHT_PROD;
+stateSingleItem_5
+    stateTexEnvItem .emit STATE_TEX_ENV;
+stateSingleItem_6
+    stateTexGenItem .emit STATE_TEX_GEN;
+stateSingleItem_7
+    stateFogItem .emit STATE_FOG;
+stateSingleItem_8
+    stateDepthItem .emit STATE_DEPTH;
+stateSingleItem_9
+    stateClipPlaneItem .emit STATE_CLIP_PLANE;
+stateSingleItem_10
+    statePointItem .emit STATE_POINT;
+stateSingleItem_11
+    stateMatrixRow .emit STATE_MATRIX_ROWS;
+
+/*
+    <stateMaterialItem>    ::= "material" <optFaceType> "." <stateMatProperty>
+*/
+stateMaterialItem
+    "material" .and optFaceType .and dot .and stateMatProperty .error INVALID_MATERIAL_PROPERTY;
+
+/*
+    <stateMatProperty>     ::= "ambient"
+                             | "diffuse"
+                             | "specular"
+                             | "emission"
+                             | "shininess"
+*/
+stateMatProperty
+    "ambient" .emit MATERIAL_AMBIENT .or
+    "diffuse" .emit MATERIAL_DIFFUSE .or
+    "specular" .emit MATERIAL_SPECULAR .or
+    "emission" .emit MATERIAL_EMISSION .or
+    "shininess" .emit MATERIAL_SHININESS;
+
+/*
+    <stateLightItem>       ::= "light" "[" <stateLightNumber> "]" "." 
+                                 <stateLightProperty>
+*/
+stateLightItem
+    "light" .and lbracket .and stateLightNumber .and rbracket .and dot .and
+    stateLightProperty .error INVALID_LIGHT_PROPERTY;
+
+/*
+    <stateLightProperty>   ::= "ambient"
+                             | "diffuse" 
+                             | "specular"
+                             | "position"
+                             | "attenuation"
+                             | "spot" "." <stateSpotProperty>
+                             | "half"
+*/
+stateLightProperty
+    "ambient" .emit LIGHT_AMBIENT .or
+    "diffuse" .emit LIGHT_DIFFUSE .or
+    "specular" .emit LIGHT_SPECULAR .or
+    "position" .emit LIGHT_POSITION .or
+    "attenuation" .emit LIGHT_ATTENUATION .or
+    stateLightProperty_1 .emit LIGHT_SPOT_DIRECTION .or
+    "half" .emit LIGHT_HALF;
+stateLightProperty_1
+    "spot" .and dot .and stateSpotProperty .error INVALID_SPOT_PROPERTY;
+
+/*
+    <stateSpotProperty>    ::= "direction" 
+*/
+stateSpotProperty
+    "direction";
+
+/*
+    <stateLightModelItem>  ::= "lightmodel" <stateLModProperty>
+*/
+stateLightModelItem
+    "lightmodel" .and stateLModProperty .error INVALID_LIGHTMODEL_PROPERTY;
+
+/*
+    <stateLModProperty>    ::= "." "ambient"
+                             | <optFaceType> "." "scenecolor"
+*/
+stateLModProperty
+    stateLModProperty_1 .or stateLModProperty_2;
+stateLModProperty_1
+    dot .and "ambient" .emit LIGHT_MODEL_AMBIENT;
+stateLModProperty_2
+    stateLModProperty_3 .emit LIGHT_MODEL_SCENECOLOR;
+stateLModProperty_3
+    optFaceType .and dot .and "scenecolor";
+
+/*
+    <stateLightProdItem>   ::= "lightprod" "[" <stateLightNumber> "]"
+                                 <optFaceType> "." <stateLProdProperty>
+*/
+stateLightProdItem
+    "lightprod" .and lbracket .and stateLightNumber .and rbracket .and optFaceType .and dot .and
+    stateLProdProperty .error INVALID_LIGHTPROD_PROPERTY;
+
+/*
+    <stateLProdProperty>   ::= "ambient"
+                             | "diffuse"
+                             | "specular"
+*/
+stateLProdProperty
+    "ambient" .emit LIGHT_PROD_AMBIENT .or
+    "diffuse" .emit LIGHT_PROD_DIFFUSE .or
+    "specular" .emit LIGHT_PROD_SPECULAR;
+
+/*
+    <stateLightNumber>     ::= <integer> from 0 to MAX_LIGHTS-1
+*/
+stateLightNumber
+    integer;
+
+/*
+fragment program
+    <stateTexEnvItem>      ::= "texenv" <optLegacyTexUnitNum> "." 
+                                 <stateTexEnvProperty>
+*/
+stateTexEnvItem
+    "texenv" .and optLegacyTexUnitNum .and dot .and
+    stateTexEnvProperty .error INVALID_TEXENV_PROPERTY;
+
+/*
+fragment program
+    <stateTexEnvProperty>  ::= "color"
+*/
+stateTexEnvProperty
+    "color" .emit TEX_ENV_COLOR;
+
+/*
+fragment program
+    <optLegacyTexUnitNum>  ::= ""
+                             | "[" <legacyTexUnitNum> "]"
+
+NOTE: <optLegaceTexUnitNum> is not optional.
+*/
+optLegacyTexUnitNum
+    lbracket_ne .and legacyTexUnitNum .and rbracket;
+
+/*
+fragment program
+    <legacyTexUnitNum>     ::= <integer> from 0 to MAX_TEXTURE_UNITS-1
+*/
+legacyTexUnitNum
+    integer;
+
+/*
+vertex program
+    <stateTexGenItem>      ::= "texgen" <optTexCoordNum> "."
+                                 <stateTexGenType> "." <stateTexGenCoord>
+*/
+stateTexGenItem
+    "texgen" .and optTexCoordNum .and dot .and stateTexGenType .error INVALID_TEXGEN_PROPERTY .and
+    dot .and stateTexGenCoord .error INVALID_TEXGEN_COORD;
+
+/*
+vertex program
+    <stateTexGenType>      ::= "eye"
+                             | "object"
+*/
+stateTexGenType
+    "eye" .emit TEX_GEN_EYE .or
+    "object" .emit TEX_GEN_OBJECT;
+
+/*
+vertex program
+    <stateTexGenCoord>     ::= "s"
+                             | "t"
+                             | "r"
+                             | "q"
+*/
+stateTexGenCoord
+    "s" .emit COMPONENT_X .or
+    "t" .emit COMPONENT_Y .or
+    "r" .emit COMPONENT_Z .or
+    "q" .emit COMPONENT_W;
+
+/*
+    <stateFogItem>         ::= "fog" "." <stateFogProperty>
+*/
+stateFogItem
+    "fog" .and dot .and stateFogProperty .error INVALID_FOG_PROPERTY;
+
+/*
+    <stateFogProperty>     ::= "color"
+                             | "params"
+*/
+stateFogProperty
+    "color" .emit FOG_COLOR .or
+    "params" .emit FOG_PARAMS;
+
+/*
+fragment program
+    <stateDepthItem>       ::= "depth" "." <stateDepthProperty>
+*/
+stateDepthItem
+    "depth" .and dot .and stateDepthProperty .error INVALID_DEPTH_PROPERTY;
+
+/*
+fragment program
+    <stateDepthProperty>   ::= "range"
+*/
+stateDepthProperty
+    "range" .emit DEPTH_RANGE;
+
+/*
+vertex program
+    <stateClipPlaneItem>   ::= "clip" "[" <stateClipPlaneNum> "]" "." "plane"
+*/
+stateClipPlaneItem
+    "clip" .and lbracket .and stateClipPlaneNum .and rbracket .and dot .and
+    "plane" .error INVALID_CLIPPLANE_PROPERTY;
+
+/*
+vertex program
+    <stateClipPlaneNum>    ::= <integer> from 0 to MAX_CLIP_PLANES-1
+*/
+stateClipPlaneNum
+    integer;
+
+/*
+vertex program
+    <statePointItem>       ::= "point" . <statePointProperty>
+*/
+statePointItem
+    "point" .and dot .and statePointProperty .error INVALID_POINT_PROPERTY;
+
+/*
+vertex program
+    <statePointProperty>   ::= "size"
+                             | "attenuation"
+*/
+statePointProperty
+    "size" .emit POINT_SIZE .or
+    .if (point_parameters != 0x00) "attenuation" .emit POINT_ATTENUATION;
+
+/*
+    <stateMatrixRow>       ::= <stateMatrixItem> "." "row" "[" 
+                                  <stateMatrixRowNum> "]"
+*/
+stateMatrixRow
+    stateMatrixItem .and dot .and "row" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and
+    lbracket .and stateMatrixRowNum .and rbracket .emit 0x0;
+
+/*
+    <stateMatrixRows>      ::= <stateMatrixItem> <optMatrixRows>
+*/
+stateMatrixRows
+    stateMatrixItem .and optMatrixRows;
+
+/*
+    <optMatrixRows>        ::= ""
+                             | "." "row" "[" <stateMatrixRowNum> ".." 
+                                  <stateMatrixRowNum> "]"
+*/
+optMatrixRows
+    optMatrixRows_1 .or .true .emit 0x0 .emit '3' .emit 0x0 .emit $;
+optMatrixRows_1
+    dot_ne .and "row" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and lbracket .and
+    stateMatrixRowNum .and dotdot .and stateMatrixRowNum .and rbracket;
+
+/*
+    <stateMatrixItem>      ::= "matrix" . <stateMatrixName> 
+                               <stateOptMatModifier>
+*/
+stateMatrixItem
+    "matrix" .and dot .and stateMatrixName .error INVALID_MATRIX_NAME .and stateOptMatModifier;
+
+/*
+    <stateOptMatModifier>  ::= ""
+                             | "." <stateMatModifier>
+*/
+stateOptMatModifier
+    stateOptMatModifier_1 .or .true .emit MATRIX_MODIFIER_IDENTITY;
+stateOptMatModifier_1
+    dot_ne .and stateMatModifier;
+
+/*
+    <stateMatModifier>     ::= "inverse" 
+                             | "transpose" 
+                             | "invtrans"
+*/
+stateMatModifier
+    "inverse" .emit MATRIX_MODIFIER_INVERSE .or
+    "transpose" .emit MATRIX_MODIFIER_TRANSPOSE .or
+    "invtrans" .emit MATRIX_MODIFIER_INVTRANS;
+
+/*
+    <stateMatrixRowNum>    ::= <integer> from 0 to 3
+*/
+stateMatrixRowNum
+    integer_0_3;
+
+/*
+    <stateMatrixName>      ::= "modelview" <stateOptModMatNum>
+                             | "projection"
+                             | "mvp"
+                             | "texture" <optTexCoordNum>
+                             | "palette" "[" <statePaletteMatNum> "]"
+                             | "program" "[" <stateProgramMatNum> "]"
+*/
+stateMatrixName
+    stateMatrixName_1_1 .emit MATRIX_MODELVIEW .or
+    "projection" .emit MATRIX_PROJECTION .or
+    "mvp" .emit MATRIX_MVP .or
+    stateMatrixName_1_2 .emit MATRIX_TEXTURE .or
+    .if (matrix_palette != 0x00) stateMatrixName_1_3 .emit MATRIX_PALETTE .or
+    stateMatrixName_1_4 .emit MATRIX_PROGRAM;
+stateMatrixName_1_1
+    "modelview" .and stateOptModMatNum;
+stateMatrixName_1_2
+    "texture" .and optTexCoordNum;
+stateMatrixName_1_3
+    "palette" .and lbracket .and statePaletteMatNum .and rbracket;
+stateMatrixName_1_4
+    "program" .and lbracket .and stateProgramMatNum .and rbracket;
+
+/*
+    <stateOptModMatNum>    ::= ""
+                             | "[" <stateModMatNum> "]"
+*/
+stateOptModMatNum
+    .if (vertex_blend != 0x00) stateOptModMatNum_1 .or
+    .true .emit 0x00;
+stateOptModMatNum_1
+    lbracket_ne .and stateModMatNum .and rbracket;
+
+/*
+    <stateModMatNum>       ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1
+*/
+stateModMatNum
+    integer;
+
+/*
+    <optTexCoordNum>       ::= ""
+                             | "[" <texCoordNum> "]"
+*/
+optTexCoordNum
+    optTexCoordNum_1 .or .true .emit 0x00;
+optTexCoordNum_1
+    lbracket_ne .and texCoordNum .and rbracket;
+
+/*
+    <texCoordNum>          ::= <integer> from 0 to MAX_TEXTURE_COORDS_ARB-1
+*/
+texCoordNum
+    integer;
+
+/*
+    <statePaletteMatNum>   ::= <integer> from 0 to MAX_PALETTE_MATRICES_ARB-1
+*/
+statePaletteMatNum
+    integer;
+
+/*
+    <stateProgramMatNum>   ::= <integer> from 0 to MAX_PROGRAM_MATRICES_ARB-1
+*/
+stateProgramMatNum
+    integer;
+
+/*
+    <programSingleItem>    ::= <progEnvParam>
+                             | <progLocalParam>
+
+NOTE: <programSingleItem> has been modified for correct error handling. If program property
+      is neither "env" nor "local" INVALID_PROGRAM_PROPERTY is generated.
+*/
+programSingleItem
+    "program" .and dot .and programSingleItem_1 .error INVALID_PROGRAM_PROPERTY;
+programSingleItem_1
+    progEnvParam .or progLocalParam;
+
+/*
+    <programMultipleItem>  ::= <progEnvParams>
+                             | <progLocalParams>
+
+NOTE: <programMultipleItem> has been modified for correct error handling. If program property
+      is neither "env" nor "local" INVALID_PROGRAM_PROPERTY is generated.
+*/
+programMultipleItem
+    "program" .and dot .and programMultipleItem_1 .error INVALID_PROGRAM_PROPERTY;
+programMultipleItem_1
+    progEnvParams .or progLocalParams;
+
+/*
+    <progEnvParams>        ::= "program" "." "env" 
+                                 "[" <progEnvParamNums> "]"
+
+NOTE: "program" "." has been moved to <programMultipleItem>.
+*/
+progEnvParams
+    "env" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNums .and rbracket;
+
+/*
+    <progEnvParamNums>     ::= <progEnvParamNum>
+                             | <progEnvParamNum> ".." <progEnvParamNum>
+*/
+progEnvParamNums
+    progEnvParamNums_1 .or progEnvParamNums_2;
+progEnvParamNums_1
+    progEnvParamNum .and dotdot_ne .and progEnvParamNum;
+progEnvParamNums_2
+    progEnvParamNum .and .true .emit 0x00;
+
+/*
+    <progEnvParam>         ::= "program" "." "env" 
+                                 "[" <progEnvParamNum> "]"
+
+NOTE: "program" "." has been moved to <programSingleItem>.
+*/
+progEnvParam
+    "env" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket .emit 0x00;
+
+/*
+    <progLocalParams>      ::= "program" "." "local" 
+                                 "[" <progLocalParamNums> "]"
+
+NOTE: "program" "." has been moved to <programMultipleItem>.
+*/
+progLocalParams
+    "local" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNums .and rbracket;
+
+/*
+    <progLocalParamNums>   ::= <progLocalParamNum>
+                             | <progLocalParamNum> ".." <progLocalParamNum>
+*/
+progLocalParamNums
+    progLocalParamNums_1 .or progLocalParamNums_2;
+progLocalParamNums_1
+    progLocalParamNum .and dotdot_ne .and progLocalParamNum;
+progLocalParamNums_2
+    progLocalParamNum .and .true .emit 0x00;
+
+/*
+    <progLocalParam>       ::= "program" "." "local" 
+                                 "[" <progLocalParamNum> "]"
+
+NOTE: "program" "." has been moved to <programSingleItem>.
+*/
+progLocalParam
+    "local" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket .emit 0x00;
+
+/*
+    <progEnvParamNum>      ::= <integer> from 0 to
+                               MAX_PROGRAM_ENV_PARAMETERS_ARB - 1
+*/
+progEnvParamNum
+    integer;
+
+/*
+    <progLocalParamNum>    ::= <integer> from 0 to
+                               MAX_PROGRAM_LOCAL_PARAMETERS_ARB - 1
+*/
+progLocalParamNum
+    integer;
+
+/*
+    <paramConstDecl>       ::= <paramConstScalarDecl>
+                             | <paramConstVector>
+*/
+paramConstDecl
+    paramConstScalarDecl .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;
+
+/*
+    <paramConstUse>        ::= <paramConstScalarUse>
+                             | <paramConstVector>
+*/
+paramConstUse
+    paramConstScalarUse .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;
+
+/*
+    <paramConstScalarDecl> ::= <signedFloatConstant>
+*/
+paramConstScalarDecl
+    signedFloatConstant;
+
+/*
+    <paramConstScalarUse>  ::= <floatConstant>
+*/
+paramConstScalarUse
+    floatConstant;
+
+/*
+    <paramConstVector>     ::= "{" <signedFloatConstant> "}"
+                             | "{" <signedFloatConstant> "," 
+                                   <signedFloatConstant> "}"
+                             | "{" <signedFloatConstant> "," 
+                                   <signedFloatConstant> ","
+                                   <signedFloatConstant> "}"
+                             | "{" <signedFloatConstant> "," 
+                                   <signedFloatConstant> ","
+                                   <signedFloatConstant> "," 
+                                   <signedFloatConstant> "}"
+*/
+paramConstVector
+    paramConstVector_4 .emit 0x04 .or paramConstVector_3 .emit 0x03 .or
+    paramConstVector_2 .emit 0x02 .or paramConstVector_1 .emit 0x01;
+paramConstVector_1
+    lbrace_ne .and signedFloatConstant .and rbrace;
+paramConstVector_2
+    lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;
+paramConstVector_3
+    lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and
+    signedFloatConstant .and rbrace;
+paramConstVector_4
+    lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and
+    signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;
+
+/*
+    <signedFloatConstant>  ::= <optionalSign> <floatConstant>
+*/
+signedFloatConstant
+    optionalSign .and floatConstant;
+
+/*
+    <floatConstant>        ::= see text
+    The <floatConstant> rule matches a floating-point constant consisting
+    of an integer part, a decimal point, a fraction part, an "e" or
+    "E", and an optionally signed integer exponent.  The integer and
+    fraction parts both consist of a sequence of one or more digits ("0"
+    through "9").  Either the integer part or the fraction parts (not
+    both) may be missing; either the decimal point or the "e" (or "E")
+    and the exponent (not both) may be missing.
+*/
+floatConstant
+    float;
+
+/*
+    <optionalSign>         ::= ""
+                             | "-"
+                             | "+"
+*/
+optionalSign
+    optional_sign_ne;
+
+/*
+    <TEMP_statement>       ::= "TEMP" <varNameList>
+*/
+fp_TEMP_statement
+    "TEMP" .and space .and fp_varNameList .and .true .emit 0x00;
+vp_TEMP_statement
+    "TEMP" .and space .and vp_varNameList .and .true .emit 0x00;
+
+/*
+vertex program
+    <ADDRESS_statement>    ::= "ADDRESS" <varNameList>
+*/
+ADDRESS_statement
+    "ADDRESS" .and space .and vp_varNameList .and .true .emit 0x00;
+
+/*
+    <varNameList>          ::= <establishName>
+                             | <establishName> "," <varNameList>
+*/
+fp_varNameList
+    fp_varNameList_1 .or fp_establishName;
+vp_varNameList
+    vp_varNameList_1 .or vp_establishName;
+fp_varNameList_1
+    fp_establishName .and comma_ne .and fp_varNameList;
+vp_varNameList_1
+    vp_establishName .and comma_ne .and vp_varNameList;
+
+/*
+    <OUTPUT_statement>     ::= "OUTPUT" <establishName> "="
+                                 <resultBinding>
+*/
+fp_OUTPUT_statement
+    "OUTPUT" .and space .and fp_establishName .and equal .and
+    fp_resultBinding .error RESULT_EXPECTED;
+vp_OUTPUT_statement
+    "OUTPUT" .and space .and vp_establishName .and equal .and
+    vp_resultBinding .error RESULT_EXPECTED;
+
+/*
+fragment program
+    <resultBinding>        ::= "result" "." "color"
+                             | "result" "." "depth"
+
+vertex program
+    <resultBinding>        ::= "result" "." "position"
+                             | "result" "." <resultColBinding>
+                             | "result" "." "fogcoord"
+                             | "result" "." "pointsize"
+                             | "result" "." "texcoord" <optTexCoordNum>
+*/
+fp_resultBinding
+    "result" .and dot .and fp_resultBinding_1 .error INVALID_RESULT_PROPERTY;
+vp_resultBinding
+    "result" .and dot .and vp_resultBinding_1 .error INVALID_RESULT_PROPERTY;
+fp_resultBinding_1
+    "color" .emit FRAGMENT_RESULT_COLOR .or
+    "depth" .emit FRAGMENT_RESULT_DEPTH;
+vp_resultBinding_1
+    .if (ARB_position_invariant == 0x00) "position" .emit VERTEX_RESULT_POSITION .or
+    resultColBinding .emit VERTEX_RESULT_COLOR .or
+    "fogcoord" .emit VERTEX_RESULT_FOGCOORD .or
+    "pointsize" .emit VERTEX_RESULT_POINTSIZE .or
+    vp_resultBinding_2 .emit VERTEX_RESULT_TEXCOORD;
+vp_resultBinding_2
+    "texcoord" .and optTexCoordNum;
+
+/*
+vertex program
+    <resultColBinding>     ::= "color" <optFaceType> <optColorType>
+*/
+resultColBinding
+    "color" .and optFaceType .and optColorType;
+
+/*
+    <optFaceType>          ::= ""
+                             | "." "front"
+                             | "." "back"
+*/
+optFaceType
+    FaceType .or .true .emit FACE_FRONT;
+FaceType
+    dot_ne .and FaceProperty;
+FaceProperty
+    "front" .emit FACE_FRONT .or "back" .emit FACE_BACK;
+
+/*
+    <optColorType>         ::= ""
+                             | "." "primary"
+                             | "." "secondary"
+*/
+optColorType
+    ColorType .or .true .emit COLOR_PRIMARY;
+ColorType
+    dot_ne .and ColorProperty;
+ColorProperty
+    "primary" .emit COLOR_PRIMARY .or
+    .if (secondary_color != 0x00) "secondary" .emit COLOR_SECONDARY;
+
+/*
+    <ALIAS_statement>      ::= "ALIAS" <establishName> "="
+                                 <establishedName>
+*/
+fp_ALIAS_statement
+    "ALIAS" .and fp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and fp_establishedName;
+vp_ALIAS_statement
+    "ALIAS" .and vp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and vp_establishedName;
+fp_ALIAS_statement_1
+    space .and fp_establishName;
+vp_ALIAS_statement_1
+    space .and vp_establishName;
+
+/*
+    <establishName>        ::= <identifier>
+*/
+fp_establishName
+    fp_identifier;
+vp_establishName
+    vp_identifier;
+
+/*
+    <establishedName>      ::= <identifier>
+*/
+fp_establishedName
+    fp_identifier;
+vp_establishedName
+    vp_identifier;
+fp_establishedName_no_error_on_identifier
+    fp_identifier_ne;
+vp_establishedName_no_error_on_identifier
+    vp_identifier_ne;
+
+/*
+fragment program
+    <identifier>           ::= see text
+    The <identifier> rule matches a sequence of one or more letters ("A"
+    through "Z", "a" through "z"), digits ("0" through "9), underscores 
+    ("_"), or dollar signs ("$"); the first character must not be a 
+    number.  Upper and lower case letters are considered different 
+    (names are case-sensitive).  The following strings are reserved 
+    keywords and may not be used as identifiers:
+
+        ABS, ABS_SAT, ADD, ADD_SAT, ALIAS, ATTRIB, CMP, CMP_SAT, COS,
+        COS_SAT, DP3, DP3_SAT, DP4, DP4_SAT, DPH, DPH_SAT, DST, DST_SAT, 
+        END, EX2, EX2_SAT, FLR, FLR_SAT, FRC, FRC_SAT, KIL, LG2, 
+        LG2_SAT, LIT, LIT_SAT, LRP, LRP_SAT, MAD, MAD_SAT, MAX, MAX_SAT, 
+        MIN, MIN_SAT, MOV, MOV_SAT, MUL, MUL_SAT, OPTION, OUTPUT, PARAM, 
+        POW, POW_SAT, RCP, RCP_SAT, RSQ, RSQ_SAT, SIN, SIN_SAT, SCS, 
+        SCS_SAT, SGE, SGE_SAT, SLT, SLT_SAT, SUB, SUB_SAT, SWZ, SWZ_SAT, 
+        TEMP, TEX, TEX_SAT, TXB, TXB_SAT, TXP, TXP_SAT, XPD, XPD_SAT, 
+        fragment, program, result, state, and texture.
+
+vertex program
+    <identifier>           ::= see text
+    The <identifier> rule matches a sequence of one or more letters ("A"
+    through "Z", "a" through "z"), digits ("0" through "9), underscores ("_"),
+    or dollar signs ("$"); the first character must not be a number.  Upper
+    and lower case letters are considered different (names are
+    case-sensitive).  The following strings are reserved keywords and may not
+    be used as identifiers:
+
+        ABS, ADD, ADDRESS, ALIAS, ARL, ATTRIB, DP3, DP4, DPH, DST, END, EX2,
+        EXP, FLR, FRC, LG2, LIT, LOG, MAD, MAX, MIN, MOV, MUL, OPTION, OUTPUT,
+        PARAM, POW, RCP, RSQ, SGE, SLT, SUB, SWZ, TEMP, XPD, program, result,
+        state, and vertex.
+*/
+fp_identifier
+    fp_identifier_ne .error IDENTIFIER_EXPECTED;
+vp_identifier
+    vp_identifier_ne .error IDENTIFIER_EXPECTED;
+fp_identifier_ne
+    fp_not_reserved_identifier .and identifier_ne;
+vp_identifier_ne
+    vp_not_reserved_identifier .and identifier_ne;
+
+fp_not_reserved_identifier
+    fp_not_reserved_identifier_1 .or .true;
+fp_not_reserved_identifier_1
+    fp_reserved_identifier .and .false .error RESERVED_KEYWORD;
+vp_not_reserved_identifier
+    vp_not_reserved_identifier_1 .or .true;
+vp_not_reserved_identifier_1
+    vp_reserved_identifier .and .false .error RESERVED_KEYWORD;
+
+fp_reserved_identifier
+    "ABS" .or "ABS_SAT" .or "ADD" .or "ADD_SAT" .or "ALIAS" .or "ATTRIB" .or "CMP" .or "CMP_SAT" .or
+    "COS" .or "COS_SAT" .or "DP3" .or "DP3_SAT" .or "DP4" .or "DP4_SAT" .or "DPH" .or "DPH_SAT" .or
+    "DST" .or "DST_SAT" .or "END" .or "EX2" .or "EX2_SAT" .or "FLR" .or "FLR_SAT" .or "FRC" .or
+    "FRC_SAT" .or "KIL" .or "LG2" .or "LG2_SAT" .or "LIT" .or "LIT_SAT" .or "LRP" .or "LRP_SAT" .or
+    "MAD" .or "MAD_SAT" .or "MAX" .or "MAX_SAT" .or "MIN" .or "MIN_SAT" .or "MOV" .or "MOV_SAT" .or
+    "MUL" .or "MUL_SAT" .or "OPTION" .or "OUTPUT" .or "PARAM" .or "POW" .or "POW_SAT" .or "RCP" .or
+    "RCP_SAT" .or "RSQ" .or "RSQ_SAT" .or "SIN" .or "SIN_SAT" .or "SCS" .or "SCS_SAT" .or "SGE" .or
+    "SGE_SAT" .or "SLT" .or "SLT_SAT" .or "SUB" .or "SUB_SAT" .or "SWZ" .or "SWZ_SAT" .or "TEMP" .or
+    "TEX" .or "TEX_SAT" .or "TXB" .or "TXB_SAT" .or "TXP" .or "TXP_SAT" .or "XPD" .or "XPD_SAT" .or
+    "fragment" .or "program" .or "result" .or "state" .or "texture";
+vp_reserved_identifier
+    "ABS" .or "ADD" .or "ADDRESS" .or "ALIAS" .or "ARL" .or "ATTRIB" .or "DP3" .or "DP4" .or
+    "DPH" .or "DST" .or "END" .or "EX2" .or "EXP" .or "FLR" .or "FRC" .or "LG2" .or "LIT" .or
+    "LOG" .or "MAD" .or "MAX" .or "MIN" .or "MOV" .or "MUL" .or "OPTION" .or "OUTPUT" .or
+    "PARAM" .or "POW" .or "RCP" .or "RSQ" .or "SGE" .or "SLT" .or "SUB" .or "SWZ" .or "TEMP" .or
+    "XPD" .or "program" .or "result" .or "state" .or "vertex";
+
+/*
+    The <integer> rule matches an integer constant.  The integer consists
+    of a sequence of one or more digits ("0" through "9").
+*/
+integer
+    integer_ne .error INTEGER_EXPECTED;
+
+zero
+    '0';
+
+leading_zeroes
+    .loop zero;
+
+no_digit
+    no_digit_1 .or .true;
+no_digit_1
+    digit10 .and .false .error INTEGER_OUT_OF_RANGE;
+
+all_zeroes
+    all_zeroes_1 .or no_digit_1;
+all_zeroes_1
+    '0' .and .loop zero .and no_digit;
+
+integer_0_3
+    integer_0_3_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;
+integer_0_3_1
+    integer_0_3_2 .or all_zeroes .emit '0';
+integer_0_3_2       /* [1, 3] */
+    leading_zeroes .and '1'-'3' .emit * .and no_digit;
+
+integer_0_63
+    integer_0_63_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;
+integer_0_63_1
+    integer_0_63_2 .or integer_0_63_3 .or integer_0_63_4 .or integer_0_63_5 .or
+    all_zeroes .emit '0';
+integer_0_63_2      /* [7, 9] */
+    leading_zeroes .and '7'-'9' .emit * .and no_digit;
+integer_0_63_3      /* [10, 59] */
+    leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;
+integer_0_63_4      /* [60, 63] */
+    leading_zeroes .and '6' .emit * .and '0'-'3' .emit * .and no_digit;
+integer_0_63_5      /* [1, 6] */
+    leading_zeroes .and '1'-'6' .emit * .and no_digit;
+
+integer_0_64
+    integer_0_64_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;
+integer_0_64_1
+    integer_0_64_2 .or integer_0_64_3 .or integer_0_64_4 .or integer_0_64_5 .or
+    all_zeroes .emit '0';
+integer_0_64_2      /* [7, 9] */
+    leading_zeroes .and '7'-'9' .emit * .and no_digit;
+integer_0_64_3      /* [10, 59] */
+    leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;
+integer_0_64_4      /* [60, 64] */
+    leading_zeroes .and '6' .emit * .and '0'-'4' .emit * .and no_digit;
+integer_0_64_5      /* [1, 6] */
+    leading_zeroes .and '1'-'6' .emit * .and no_digit;
+
+optional_space
+    space .or .true;
+
+space_dst
+    space .error OPERATION_NEEDS_DESTINATION_VARIABLE;
+
+space_src
+    space .error OPERATION_NEEDS_SOURCE_VARIABLE;
+
+space
+    single_space .and .loop single_space;
+
+single_space
+    white_char .or comment_block;
+
+white_char
+    ' ' .or '\t' .or '\n' .or '\r';
+
+comment_block
+    '#' .and .loop comment_char .and new_line;
+
+/* All ASCII characters except '\r', '\n' and '\0' */
+comment_char
+    '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C';
+
+new_line
+    '\n' .or crlf .or '\0';
+
+crlf
+    '\r' .and '\n';
+
+semicolon
+    optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;
+
+comma
+    optional_space .and ',' .error MISSING_COMMA .and optional_space;
+
+comma_ne
+    optional_space .and ',' .and optional_space;
+
+lbracket
+    optional_space .and '[' .error MISSING_LBRACKET .and optional_space;
+
+lbracket_ne
+    optional_space .and '[' .and optional_space;
+
+rbracket
+    optional_space .and ']' .error MISSING_RBRACKET .and optional_space;
+
+dot
+    optional_space .and '.' .error MISSING_DOT .and optional_space;
+
+dot_ne
+    optional_space .and '.' .and optional_space;
+
+equal
+    optional_space .and '=' .error MISSING_EQUAL .and optional_space;
+
+lbrace
+    optional_space .and '{' .error MISSING_LBRACE .and optional_space;
+
+lbrace_ne
+    optional_space .and '{' .and optional_space;
+
+rbrace
+    optional_space .and '}' .error MISSING_RBRACE .and optional_space;
+
+dotdot
+    optional_space .and '.' .and '.' .error MISSING_DOTDOT .and optional_space;
+
+dotdot_ne
+    optional_space .and '.' .and '.' .and optional_space;
+
+/*
+    The definition below accepts the following floating point number formats:
+    .99 .99e99 99. 99.99 99.99e99 99.e99 99e99
+    Also 99 format was considered and accepted because of a large number of existing program
+    strings with such a format.
+*/
+float
+    float_1 .or float_2 .or float_legacy;
+float_1
+    '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent;
+float_2
+    integer_ne .and float_3;
+float_3
+    float_4 .or float_5;
+float_4
+    '.' .and optional_integer .and optional_exponent;
+float_5
+    exponent .emit 0x00;
+float_legacy
+    integer_ne .and .true .emit 0x00 .emit 0x00;
+
+/*
+    Below is a correct version of <float> definiton.
+*/
+/*
+float
+    float_1 .or float_2;
+float_1
+    '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent;
+float_2
+    integer_ne .and float_3 .error MISSING_DOT_OR_EXPONENT;
+float_3
+    float_4 .or float_5;
+float_4
+    '.' .and optional_integer .and optional_exponent;
+float_5
+    exponent .emit 0x00;
+*/
+
+integer_ne
+    integer_ne_1 .and .true .emit 0x00 .emit $;
+integer_ne_1
+    digit10 .emit * .and .loop digit10 .emit *;
+
+optional_integer
+    integer_ne .or .true .emit 0x00;
+
+/*
+NOTE: If exponent part is omited we treat it as if it was "E+1".
+*/
+optional_exponent
+    exponent .or .true .emit 0x00;
+
+exponent
+    exponent_1 .and optional_sign_ne .and integer_ne .error EXPONENT_VALUE_EXPECTED;
+exponent_1
+    'e' .or 'E';
+
+optional_sign_ne
+    minus_ne .or plus_ne .or .true;
+
+plus_ne
+    optional_space .and '+' .and optional_space;
+
+minus_ne
+    optional_space .and '-' .emit '-' .and optional_space;
+
+identifier_ne
+    first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit 0x00 .emit $;
+
+follow_idchar
+    first_idchar .or digit10;
+
+first_idchar
+    'a'-'z' .or 'A'-'Z' .or '_' .or '$';
+
+digit10
+    '0'-'9';
+
+/*
+    string filtering - if a string is encountered in grammar ("blabla"), the symbol below is
+    executed to create the string. The symbol must not throw any errors and emit bytes - it should
+    stop if it encounters invalid character. After this the resulting string (from starting
+    position up to the invalid character (but without it) is compared with the grammar string.
+*/
+.string __string_filter;
+
+__string_filter
+    .loop __identifier_char;
+
+__identifier_char
+    'a'-'z' .or 'A'-'Z' .or '_' .or '$' .or '0'-'9';
+
+/*
+    error token filtering
+*/
+e_signature
+    e_signature_char .and .loop e_signature_char;
+e_signature_char
+    '!' .or '.' .or 'A'-'Z' .or 'a'-'z' .or '0'-'9';
+
+e_statement
+    .loop e_statement_not_term;
+/* All ASCII characters to one of '\r', '\n', '\0' and ';' */
+e_statement_not_term
+    '\x3C'-'\xFF' .or '\x0E'-'\x3A' .or '\x01'-'\x09' .or '\x0B'-'\x0C';
+
+e_identifier
+    e_identifier_first .and .loop e_identifier_next;
+e_identifier_first
+    'a'-'z' .or 'A'-'Z' .or '_' .or '$';
+e_identifier_next
+    e_identifier_first .or '0'-'9';
+
+e_token
+    e_identifier .or e_token_number .or '[' .or ']' .or '.' .or '{' .or '}' .or '=' .or '+' .or
+    '-' .or ',' .or ';';
+e_token_number
+    e_token_digit .and .loop e_token_digit;
+e_token_digit
+    '0'-'9';
+
+e_charordigit
+    'A'-'Z' .or 'a'-'z' .or '0'-'9';
+
index fe89b5ff3b57e33922642b9c5d3f47a1f82c492d..71ccd204d127aa85d1ec816ab030834dca28a70b 100644 (file)
-".syntax program;\n"\r
-".emtcode REVISION 0x07\n"\r
-".emtcode FRAGMENT_PROGRAM 0x01\n"\r
-".emtcode VERTEX_PROGRAM 0x02\n"\r
-".emtcode OPTION 0x01\n"\r
-".emtcode INSTRUCTION 0x02\n"\r
-".emtcode DECLARATION 0x03\n"\r
-".emtcode END 0x04\n"\r
-".emtcode ARB_PRECISION_HINT_FASTEST 0x01\n"\r
-".emtcode ARB_PRECISION_HINT_NICEST 0x02\n"\r
-".emtcode ARB_FOG_EXP 0x04\n"\r
-".emtcode ARB_FOG_EXP2 0x08\n"\r
-".emtcode ARB_FOG_LINEAR 0x10\n"\r
-".emtcode ARB_POSITION_INVARIANT 0x20\n"\r
-".emtcode ARB_FRAGMENT_PROGRAM_SHADOW 0x40\n"\r
-".emtcode OP_ALU_INST 0x00\n"\r
-".emtcode OP_TEX_INST 0x01\n"\r
-".emtcode OP_ALU_VECTOR 0x00\n"\r
-".emtcode OP_ALU_SCALAR 0x01\n"\r
-".emtcode OP_ALU_BINSC 0x02\n"\r
-".emtcode OP_ALU_BIN 0x03\n"\r
-".emtcode OP_ALU_TRI 0x04\n"\r
-".emtcode OP_ALU_SWZ 0x05\n"\r
-".emtcode OP_TEX_SAMPLE 0x06\n"\r
-".emtcode OP_TEX_KIL 0x07\n"\r
-".emtcode OP_ALU_ARL 0x08\n"\r
-".emtcode OP_ABS 0x00\n"\r
-".emtcode OP_ABS_SAT 0x1B\n"\r
-".emtcode OP_FLR 0x09\n"\r
-".emtcode OP_FLR_SAT 0x26\n"\r
-".emtcode OP_FRC 0x0A\n"\r
-".emtcode OP_FRC_SAT 0x27\n"\r
-".emtcode OP_LIT 0x0C\n"\r
-".emtcode OP_LIT_SAT 0x2A\n"\r
-".emtcode OP_MOV 0x11\n"\r
-".emtcode OP_MOV_SAT 0x30\n"\r
-".emtcode OP_COS 0x1F\n"\r
-".emtcode OP_COS_SAT 0x20\n"\r
-".emtcode OP_EX2 0x07\n"\r
-".emtcode OP_EX2_SAT 0x25\n"\r
-".emtcode OP_LG2 0x0B\n"\r
-".emtcode OP_LG2_SAT 0x29\n"\r
-".emtcode OP_RCP 0x14\n"\r
-".emtcode OP_RCP_SAT 0x33\n"\r
-".emtcode OP_RSQ 0x15\n"\r
-".emtcode OP_RSQ_SAT 0x34\n"\r
-".emtcode OP_SIN 0x38\n"\r
-".emtcode OP_SIN_SAT 0x39\n"\r
-".emtcode OP_SCS 0x35\n"\r
-".emtcode OP_SCS_SAT 0x36\n"\r
-".emtcode OP_POW 0x13\n"\r
-".emtcode OP_POW_SAT 0x32\n"\r
-".emtcode OP_ADD 0x01\n"\r
-".emtcode OP_ADD_SAT 0x1C\n"\r
-".emtcode OP_DP3 0x03\n"\r
-".emtcode OP_DP3_SAT 0x21\n"\r
-".emtcode OP_DP4 0x04\n"\r
-".emtcode OP_DP4_SAT 0x22\n"\r
-".emtcode OP_DPH 0x05\n"\r
-".emtcode OP_DPH_SAT 0x23\n"\r
-".emtcode OP_DST 0x06\n"\r
-".emtcode OP_DST_SAT 0x24\n"\r
-".emtcode OP_MAX 0x0F\n"\r
-".emtcode OP_MAX_SAT 0x2E\n"\r
-".emtcode OP_MIN 0x10\n"\r
-".emtcode OP_MIN_SAT 0x2F\n"\r
-".emtcode OP_MUL 0x12\n"\r
-".emtcode OP_MUL_SAT 0x31\n"\r
-".emtcode OP_SGE 0x16\n"\r
-".emtcode OP_SGE_SAT 0x37\n"\r
-".emtcode OP_SLT 0x17\n"\r
-".emtcode OP_SLT_SAT 0x3A\n"\r
-".emtcode OP_SUB 0x18\n"\r
-".emtcode OP_SUB_SAT 0x3B\n"\r
-".emtcode OP_XPD 0x1A\n"\r
-".emtcode OP_XPD_SAT 0x43\n"\r
-".emtcode OP_CMP 0x1D\n"\r
-".emtcode OP_CMP_SAT 0x1E\n"\r
-".emtcode OP_LRP 0x2B\n"\r
-".emtcode OP_LRP_SAT 0x2C\n"\r
-".emtcode OP_MAD 0x0E\n"\r
-".emtcode OP_MAD_SAT 0x2D\n"\r
-".emtcode OP_SWZ 0x19\n"\r
-".emtcode OP_SWZ_SAT 0x3C\n"\r
-".emtcode OP_TEX 0x3D\n"\r
-".emtcode OP_TEX_SAT 0x3E\n"\r
-".emtcode OP_TXB 0x3F\n"\r
-".emtcode OP_TXB_SAT 0x40\n"\r
-".emtcode OP_TXP 0x41\n"\r
-".emtcode OP_TXP_SAT 0x42\n"\r
-".emtcode OP_KIL 0x28\n"\r
-".emtcode OP_ARL 0x02\n"\r
-".emtcode OP_EXP 0x08\n"\r
-".emtcode OP_LOG 0x0D\n"\r
-".emtcode FRAGMENT_ATTRIB_COLOR 0x01\n"\r
-".emtcode FRAGMENT_ATTRIB_TEXCOORD 0x02\n"\r
-".emtcode FRAGMENT_ATTRIB_FOGCOORD 0x03\n"\r
-".emtcode FRAGMENT_ATTRIB_POSITION 0x04\n"\r
-".emtcode VERTEX_ATTRIB_POSITION 0x01\n"\r
-".emtcode VERTEX_ATTRIB_WEIGHT 0x02\n"\r
-".emtcode VERTEX_ATTRIB_NORMAL 0x03\n"\r
-".emtcode VERTEX_ATTRIB_COLOR 0x04\n"\r
-".emtcode VERTEX_ATTRIB_FOGCOORD 0x05\n"\r
-".emtcode VERTEX_ATTRIB_TEXCOORD 0x06\n"\r
-".emtcode VERTEX_ATTRIB_MATRIXINDEX 0x07\n"\r
-".emtcode VERTEX_ATTRIB_GENERIC 0x08\n"\r
-".emtcode FRAGMENT_RESULT_COLOR 0x01\n"\r
-".emtcode FRAGMENT_RESULT_DEPTH 0x02\n"\r
-".emtcode VERTEX_RESULT_POSITION 0x01\n"\r
-".emtcode VERTEX_RESULT_COLOR 0x02\n"\r
-".emtcode VERTEX_RESULT_FOGCOORD 0x03\n"\r
-".emtcode VERTEX_RESULT_POINTSIZE 0x04\n"\r
-".emtcode VERTEX_RESULT_TEXCOORD 0x05\n"\r
-".emtcode TEXTARGET_1D 0x01\n"\r
-".emtcode TEXTARGET_2D 0x02\n"\r
-".emtcode TEXTARGET_3D 0x03\n"\r
-".emtcode TEXTARGET_RECT 0x04\n"\r
-".emtcode TEXTARGET_CUBE 0x05\n"\r
-".emtcode TEXTARGET_SHADOW1D 0x06\n"\r
-".emtcode TEXTARGET_SHADOW2D 0x07\n"\r
-".emtcode TEXTARGET_SHADOWRECT 0x08\n"\r
-".emtcode FACE_FRONT 0x00\n"\r
-".emtcode FACE_BACK 0x01\n"\r
-".emtcode COLOR_PRIMARY 0x00\n"\r
-".emtcode COLOR_SECONDARY 0x01\n"\r
-".emtcode COMPONENT_X 0x00\n"\r
-".emtcode COMPONENT_Y 0x01\n"\r
-".emtcode COMPONENT_Z 0x02\n"\r
-".emtcode COMPONENT_W 0x03\n"\r
-".emtcode COMPONENT_0 0x04\n"\r
-".emtcode COMPONENT_1 0x05\n"\r
-".emtcode ARRAY_INDEX_ABSOLUTE 0x00\n"\r
-".emtcode ARRAY_INDEX_RELATIVE 0x01\n"\r
-".emtcode MATRIX_MODELVIEW 0x01\n"\r
-".emtcode MATRIX_PROJECTION 0x02\n"\r
-".emtcode MATRIX_MVP 0x03\n"\r
-".emtcode MATRIX_TEXTURE 0x04\n"\r
-".emtcode MATRIX_PALETTE 0x05\n"\r
-".emtcode MATRIX_PROGRAM 0x06\n"\r
-".emtcode MATRIX_MODIFIER_IDENTITY 0x00\n"\r
-".emtcode MATRIX_MODIFIER_INVERSE 0x01\n"\r
-".emtcode MATRIX_MODIFIER_TRANSPOSE 0x02\n"\r
-".emtcode MATRIX_MODIFIER_INVTRANS 0x03\n"\r
-".emtcode CONSTANT_SCALAR 0x01\n"\r
-".emtcode CONSTANT_VECTOR 0x02\n"\r
-".emtcode PROGRAM_PARAM_ENV 0x01\n"\r
-".emtcode PROGRAM_PARAM_LOCAL 0x02\n"\r
-".emtcode REGISTER_ATTRIB 0x01\n"\r
-".emtcode REGISTER_PARAM 0x02\n"\r
-".emtcode REGISTER_RESULT 0x03\n"\r
-".emtcode REGISTER_ESTABLISHED_NAME 0x04\n"\r
-".emtcode PARAM_NULL 0x00\n"\r
-".emtcode PARAM_ARRAY_ELEMENT 0x01\n"\r
-".emtcode PARAM_STATE_ELEMENT 0x02\n"\r
-".emtcode PARAM_PROGRAM_ELEMENT 0x03\n"\r
-".emtcode PARAM_PROGRAM_ELEMENTS 0x04\n"\r
-".emtcode PARAM_CONSTANT 0x05\n"\r
-".emtcode STATE_MATERIAL 0x01\n"\r
-".emtcode STATE_LIGHT 0x02\n"\r
-".emtcode STATE_LIGHT_MODEL 0x03\n"\r
-".emtcode STATE_LIGHT_PROD 0x04\n"\r
-".emtcode STATE_FOG 0x05\n"\r
-".emtcode STATE_MATRIX_ROWS 0x06\n"\r
-".emtcode STATE_TEX_ENV 0x07\n"\r
-".emtcode STATE_DEPTH 0x08\n"\r
-".emtcode STATE_TEX_GEN 0x09\n"\r
-".emtcode STATE_CLIP_PLANE 0x0A\n"\r
-".emtcode STATE_POINT 0x0B\n"\r
-".emtcode MATERIAL_AMBIENT 0x01\n"\r
-".emtcode MATERIAL_DIFFUSE 0x02\n"\r
-".emtcode MATERIAL_SPECULAR 0x03\n"\r
-".emtcode MATERIAL_EMISSION 0x04\n"\r
-".emtcode MATERIAL_SHININESS 0x05\n"\r
-".emtcode LIGHT_AMBIENT 0x01\n"\r
-".emtcode LIGHT_DIFFUSE 0x02\n"\r
-".emtcode LIGHT_SPECULAR 0x03\n"\r
-".emtcode LIGHT_POSITION 0x04\n"\r
-".emtcode LIGHT_ATTENUATION 0x05\n"\r
-".emtcode LIGHT_HALF 0x06\n"\r
-".emtcode LIGHT_SPOT_DIRECTION 0x07\n"\r
-".emtcode LIGHT_MODEL_AMBIENT 0x01\n"\r
-".emtcode LIGHT_MODEL_SCENECOLOR 0x02\n"\r
-".emtcode LIGHT_PROD_AMBIENT 0x01\n"\r
-".emtcode LIGHT_PROD_DIFFUSE 0x02\n"\r
-".emtcode LIGHT_PROD_SPECULAR 0x03\n"\r
-".emtcode TEX_ENV_COLOR 0x01\n"\r
-".emtcode TEX_GEN_EYE 0x01\n"\r
-".emtcode TEX_GEN_OBJECT 0x02\n"\r
-".emtcode FOG_COLOR 0x01\n"\r
-".emtcode FOG_PARAMS 0x02\n"\r
-".emtcode DEPTH_RANGE 0x01\n"\r
-".emtcode POINT_SIZE 0x01\n"\r
-".emtcode POINT_ATTENUATION 0x02\n"\r
-".emtcode ATTRIB 0x01\n"\r
-".emtcode PARAM 0x02\n"\r
-".emtcode TEMP 0x03\n"\r
-".emtcode OUTPUT 0x04\n"\r
-".emtcode ALIAS 0x05\n"\r
-".emtcode ADDRESS 0x06\n"\r
-".errtext UNKNOWN_PROGRAM_SIGNATURE \"1001: '$e_signature$': unknown program signature\"\n"\r
-".errtext MISSING_END_OR_INVALID_STATEMENT \"1002: '$e_statement$': invalid statement\"\n"\r
-".errtext CODE_AFTER_END \"1003: '$e_statement$': code after 'END' keyword\"\n"\r
-".errtext INVALID_PROGRAM_OPTION \"1004: '$e_identifier$': invalid program option\"\n"\r
-".errtext EXT_SWIZ_COMP_EXPECTED \"1005: extended swizzle component expected but '$e_token$' found\"\n"\r
-".errtext TEX_TARGET_EXPECTED \"1006: texture target expected but '$e_token$' found\"\n"\r
-".errtext TEXTURE_EXPECTED \"1007: 'texture' expected but '$e_identifier$' found\"\n"\r
-".errtext SOURCE_REGISTER_EXPECTED \"1008: source register expected but '$e_token$' found\"\n"\r
-".errtext DESTINATION_REGISTER_EXPECTED \"1009: destination register expected but '$e_token$' found\"\n"\r
-".errtext INVALID_ADDRESS_COMPONENT \"1010: '$e_identifier$': invalid address component\"\n"\r
-".errtext INVALID_ADDRESS_WRITEMASK \"1011: '$e_identifier$': invalid address writemask\"\n"\r
-".errtext INVALID_COMPONENT \"1012: '$e_charordigit$': invalid component\"\n"\r
-".errtext INVALID_SUFFIX \"1013: '$e_identifier$': invalid suffix\"\n"\r
-".errtext INVALID_WRITEMASK \"1014: '$e_identifier$': invalid writemask\"\n"\r
-".errtext FRAGMENT_EXPECTED \"1015: 'fragment' expected but '$e_identifier$' found\"\n"\r
-".errtext VERTEX_EXPECTED \"1016: 'vertex' expected but '$e_identifier$' found\"\n"\r
-".errtext INVALID_FRAGMENT_PROPERTY \"1017: '$e_identifier$': invalid fragment property\"\n"\r
-".errtext INVALID_VERTEX_PROPERTY \"1018: '$e_identifier$': invalid vertex property\"\n"\r
-".errtext INVALID_STATE_PROPERTY \"1019: '$e_identifier$': invalid state property\"\n"\r
-".errtext INVALID_MATERIAL_PROPERTY \"1020: '$e_identifier$': invalid material property\"\n"\r
-".errtext INVALID_LIGHT_PROPERTY \"1021: '$e_identifier$': invalid light property\"\n"\r
-".errtext INVALID_SPOT_PROPERTY \"1022: '$e_identifier$': invalid spot property\"\n"\r
-".errtext INVALID_LIGHTMODEL_PROPERTY \"1023: '$e_identifier$': invalid light model property\"\n"\r
-".errtext INVALID_LIGHTPROD_PROPERTY \"1024: '$e_identifier$': invalid light product property\"\n"\r
-".errtext INVALID_TEXENV_PROPERTY \"1025: '$e_identifier$': invalid texture environment property\"\n"\r
-".errtext INVALID_TEXGEN_PROPERTY \"1026: '$e_identifier$': invalid texture generating property\"\n"\r
-".errtext INVALID_TEXGEN_COORD \"1027: '$e_identifier$': invalid texture generating coord\"\n"\r
-".errtext INVALID_FOG_PROPERTY \"1028: '$e_identifier$': invalid fog property\"\n"\r
-".errtext INVALID_DEPTH_PROPERTY \"1029: '$e_identifier$': invalid depth property\"\n"\r
-".errtext INVALID_CLIPPLANE_PROPERTY \"1030: '$e_identifier$': invalid clip plane property\"\n"\r
-".errtext INVALID_POINT_PROPERTY \"1031: '$e_identifier$': invalid point property\"\n"\r
-".errtext MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED \"1032: matrix row selector or modifier expected but '$e_token$' found\"\n"\r
-".errtext INVALID_MATRIX_NAME \"1033: '$e_identifier$': invalid matrix name\"\n"\r
-".errtext INVALID_PROGRAM_PROPERTY \"1034: '$e_identifier$': invalid program property\"\n"\r
-".errtext RESULT_EXPECTED \"1035: 'result' expected but '$e_token$' found\"\n"\r
-".errtext INVALID_RESULT_PROPERTY \"1036: '$e_identifier$': invalid result property\"\n"\r
-".errtext INVALID_FACE_PROPERTY \"1037: '$e_identifier$': invalid face property\"\n"\r
-".errtext INVALID_COLOR_PROPERTY \"1038: '$e_identifier$': invalid color property\"\n"\r
-".errtext IDENTIFIER_EXPECTED \"1039: identifier expected but '$e_token$' found\"\n"\r
-".errtext RESERVED_KEYWORD \"1040: use of reserved keyword as an identifier\"\n"\r
-".errtext INTEGER_EXPECTED \"1041: integer value expected but '$e_token$' found\"\n"\r
-".errtext MISSING_SEMICOLON \"1042: ';' expected but '$e_token$' found\"\n"\r
-".errtext MISSING_COMMA \"1043: ',' expected but '$e_token$' found\"\n"\r
-".errtext MISSING_LBRACKET \"1044: '[' expected but '$e_token$' found\"\n"\r
-".errtext MISSING_RBRACKET \"1045: ']' expected but '$e_token$' found\"\n"\r
-".errtext MISSING_DOT \"1046: '.' expected but '$e_token$' found\"\n"\r
-".errtext MISSING_EQUAL \"1047: '=' expected but '$e_token$' found\"\n"\r
-".errtext MISSING_LBRACE \"1048: '{' expected but '$e_token$' found\"\n"\r
-".errtext MISSING_RBRACE \"1049: '}' expected but '$e_token$' found\"\n"\r
-".errtext MISSING_DOTDOT \"1050: '..' expected but '$e_token$' found\"\n"\r
-".errtext MISSING_FRACTION_OR_EXPONENT \"1051: missing fraction part or exponent\"\n"\r
-".errtext MISSING_DOT_OR_EXPONENT \"1052: missing '.' or exponent\"\n"\r
-".errtext EXPONENT_VALUE_EXPECTED \"1053: exponent value expected\"\n"\r
-".errtext INTEGER_OUT_OF_RANGE \"1054: integer value out of range\"\n"\r
-".errtext OPERATION_NEEDS_DESTINATION_VARIABLE \"1055: operation needs destination variable\"\n"\r
-".errtext OPERATION_NEEDS_SOURCE_VARIABLE \"1056: operation needs source variable\"\n"\r
-".errtext ADDRESS_REGISTER_EXPECTED \"1057: address register expected but '$e_token$' found\"\n"\r
-".errtext ADDRESS_REGISTER_OR_INTEGER_EXPECTED \"1058: address register or integer literal expected but '$e_token$' found\"\n"\r
-".regbyte vertex_blend 0x00\n"\r
-".regbyte matrix_palette 0x00\n"\r
-".regbyte point_parameters 0x01\n"\r
-".regbyte secondary_color 0x01\n"\r
-".regbyte fog_coord 0x01\n"\r
-".regbyte texture_rectangle 0x01\n"\r
-".regbyte fragment_program_shadow 0x00\n"\r
-".regbyte ARB_precision_hint_fastest 0x00\n"\r
-".regbyte ARB_precision_hint_nicest 0x00\n"\r
-".regbyte ARB_fog_exp 0x00\n"\r
-".regbyte ARB_fog_exp2 0x00\n"\r
-".regbyte ARB_fog_linear 0x00\n"\r
-".regbyte ARB_position_invariant 0x00\n"\r
-".regbyte ARB_fragment_program_shadow 0x00\n"\r
-".regbyte program_target 0x00\n"\r
-"program\n"\r
-" programs .error UNKNOWN_PROGRAM_SIGNATURE .emit REVISION;\n"\r
-"programs\n"\r
-" .if (program_target == 0x10) frag_program_1_0 .emit FRAGMENT_PROGRAM .emit 0x01 .emit 0x00 .or\n"\r
-" .if (program_target == 0x20) vert_program_1_0 .emit VERTEX_PROGRAM .emit 0x01 .emit 0x00;\n"\r
-"frag_program_1_0\n"\r
-" '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'f' .and 'p' .and '1' .and '.' .and '0' .and\n"\r
-" optional_space .and fp_optionSequence .and fp_statementSequence .and\n"\r
-" \"END\" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and\n"\r
-" '\\0' .error CODE_AFTER_END;\n"\r
-"vert_program_1_0\n"\r
-" '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'v' .and 'p' .and '1' .and '.' .and '0' .and\n"\r
-" optional_space .and vp_optionSequence .and vp_statementSequence .and\n"\r
-" \"END\" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and\n"\r
-" '\\0' .error CODE_AFTER_END;\n"\r
-"fp_optionSequence\n"\r
-" .loop fp_option;\n"\r
-"vp_optionSequence\n"\r
-" .loop vp_option;\n"\r
-"fp_option\n"\r
-" \"OPTION\" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and\n"\r
-" fp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;\n"\r
-"vp_option\n"\r
-" \"OPTION\" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and\n"\r
-" vp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;\n"\r
-"fp_optionString\n"\r
-" .if (ARB_precision_hint_nicest == 0x00) \"ARB_precision_hint_fastest\"\n"\r
-" .emit ARB_PRECISION_HINT_FASTEST .load ARB_precision_hint_fastest 0x01 .or\n"\r
-" .if (ARB_precision_hint_fastest == 0x00) \"ARB_precision_hint_nicest\"\n"\r
-" .emit ARB_PRECISION_HINT_NICEST .load ARB_precision_hint_nicest 0x01 .or\n"\r
-" fp_ARB_fog_exp .emit ARB_FOG_EXP .load ARB_fog_exp 0x01 .or\n"\r
-" fp_ARB_fog_exp2 .emit ARB_FOG_EXP2 .load ARB_fog_exp2 0x01 .or\n"\r
-" fp_ARB_fog_linear .emit ARB_FOG_LINEAR .load ARB_fog_linear 0x01 .or\n"\r
-" .if (fragment_program_shadow != 0x00) \"ARB_fragment_program_shadow\"\n"\r
-" .emit ARB_FRAGMENT_PROGRAM_SHADOW .load ARB_fragment_program_shadow 0x01;\n"\r
-"vp_optionString\n"\r
-" \"ARB_position_invariant\" .emit ARB_POSITION_INVARIANT .load ARB_position_invariant 0x01;\n"\r
-"fp_ARB_fog_exp\n"\r
-" .if (ARB_fog_exp2 == 0x00) .true .and .if (ARB_fog_linear == 0x00) \"ARB_fog_exp\";\n"\r
-"fp_ARB_fog_exp2\n"\r
-" .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_linear == 0x00) \"ARB_fog_exp2\";\n"\r
-"fp_ARB_fog_linear\n"\r
-" .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_exp2 == 0x00) \"ARB_fog_linear\";\n"\r
-"fp_statementSequence\n"\r
-" .loop fp_statement;\n"\r
-"vp_statementSequence\n"\r
-" .loop vp_statement;\n"\r
-"fp_statement\n"\r
-" fp_statement_1 .or fp_statement_2;\n"\r
-"vp_statement\n"\r
-" vp_statement_1 .or vp_statement_2;\n"\r
-"fp_statement_1\n"\r
-" fp_instruction .emit INSTRUCTION .emit $ .and semicolon;\n"\r
-"fp_statement_2\n"\r
-" fp_namingStatement .emit DECLARATION .and semicolon;\n"\r
-"vp_statement_1\n"\r
-" vp_instruction .emit INSTRUCTION .emit $ .and semicolon;\n"\r
-"vp_statement_2\n"\r
-" vp_namingStatement .emit DECLARATION .and semicolon;\n"\r
-"fp_instruction\n"\r
-" ALUInstruction .emit OP_ALU_INST .or\n"\r
-" TexInstruction .emit OP_TEX_INST;\n"\r
-"vp_instruction\n"\r
-" ARL_instruction .emit OP_ALU_ARL .or\n"\r
-" vp_VECTORop_instruction .emit OP_ALU_VECTOR .or\n"\r
-" vp_SCALARop_instruction .emit OP_ALU_SCALAR .or\n"\r
-" vp_BINSCop_instruction .emit OP_ALU_BINSC .or\n"\r
-" vp_BINop_instruction .emit OP_ALU_BIN .or\n"\r
-" vp_TRIop_instruction .emit OP_ALU_TRI .or\n"\r
-" vp_SWZ_instruction .emit OP_ALU_SWZ;\n"\r
-"ALUInstruction\n"\r
-" fp_VECTORop_instruction .emit OP_ALU_VECTOR .or\n"\r
-" fp_SCALARop_instruction .emit OP_ALU_SCALAR .or\n"\r
-" fp_BINSCop_instruction .emit OP_ALU_BINSC .or\n"\r
-" fp_BINop_instruction .emit OP_ALU_BIN .or\n"\r
-" fp_TRIop_instruction .emit OP_ALU_TRI .or\n"\r
-" fp_SWZ_instruction .emit OP_ALU_SWZ;\n"\r
-"TexInstruction\n"\r
-" SAMPLE_instruction .emit OP_TEX_SAMPLE .or\n"\r
-" KIL_instruction .emit OP_TEX_KIL;\n"\r
-"ARL_instruction\n"\r
-" \"ARL\" .emit OP_ARL .and space_dst .and maskedAddrReg .and comma .and vp_scalarSrcReg;\n"\r
-"fp_VECTORop_instruction\n"\r
-" fp_VECTORop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg;\n"\r
-"vp_VECTORop_instruction\n"\r
-" vp_VECTORop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg;\n"\r
-"fp_VECTORop\n"\r
-" \"ABS\" .emit OP_ABS .or \"ABS_SAT\" .emit OP_ABS_SAT .or\n"\r
-" \"FLR\" .emit OP_FLR .or \"FLR_SAT\" .emit OP_FLR_SAT .or\n"\r
-" \"FRC\" .emit OP_FRC .or \"FRC_SAT\" .emit OP_FRC_SAT .or\n"\r
-" \"LIT\" .emit OP_LIT .or \"LIT_SAT\" .emit OP_LIT_SAT .or\n"\r
-" \"MOV\" .emit OP_MOV .or \"MOV_SAT\" .emit OP_MOV_SAT;\n"\r
-"vp_VECTORop\n"\r
-" \"ABS\" .emit OP_ABS .or\n"\r
-" \"FLR\" .emit OP_FLR .or\n"\r
-" \"FRC\" .emit OP_FRC .or\n"\r
-" \"LIT\" .emit OP_LIT .or\n"\r
-" \"MOV\" .emit OP_MOV;\n"\r
-"fp_SCALARop_instruction\n"\r
-" fp_SCALARop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg;\n"\r
-"vp_SCALARop_instruction\n"\r
-" vp_SCALARop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg;\n"\r
-"fp_SCALARop\n"\r
-" \"COS\" .emit OP_COS .or \"COS_SAT\" .emit OP_COS_SAT .or\n"\r
-" \"EX2\" .emit OP_EX2 .or \"EX2_SAT\" .emit OP_EX2_SAT .or\n"\r
-" \"LG2\" .emit OP_LG2 .or \"LG2_SAT\" .emit OP_LG2_SAT .or\n"\r
-" \"RCP\" .emit OP_RCP .or \"RCP_SAT\" .emit OP_RCP_SAT .or\n"\r
-" \"RSQ\" .emit OP_RSQ .or \"RSQ_SAT\" .emit OP_RSQ_SAT .or\n"\r
-" \"SIN\" .emit OP_SIN .or \"SIN_SAT\" .emit OP_SIN_SAT .or\n"\r
-" \"SCS\" .emit OP_SCS .or \"SCS_SAT\" .emit OP_SCS_SAT;\n"\r
-"vp_SCALARop\n"\r
-" \"EX2\" .emit OP_EX2 .or\n"\r
-" \"EXP\" .emit OP_EXP .or\n"\r
-" \"LG2\" .emit OP_LG2 .or\n"\r
-" \"LOG\" .emit OP_LOG .or\n"\r
-" \"RCP\" .emit OP_RCP .or\n"\r
-" \"RSQ\" .emit OP_RSQ;\n"\r
-"fp_BINSCop_instruction\n"\r
-" fp_BINSCop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg .and comma .and\n"\r
-" fp_scalarSrcReg;\n"\r
-"vp_BINSCop_instruction\n"\r
-" vp_BINSCop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg .and comma .and\n"\r
-" vp_scalarSrcReg;\n"\r
-"fp_BINSCop\n"\r
-" \"POW\" .emit OP_POW .or \"POW_SAT\" .emit OP_POW_SAT;\n"\r
-"vp_BINSCop\n"\r
-" \"POW\" .emit OP_POW;\n"\r
-"fp_BINop_instruction\n"\r
-" fp_BINop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n"\r
-" vectorSrcReg;\n"\r
-"vp_BINop_instruction\n"\r
-" vp_BINop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and\n"\r
-" swizzleSrcReg;\n"\r
-"fp_BINop\n"\r
-" \"ADD\" .emit OP_ADD .or \"ADD_SAT\" .emit OP_ADD_SAT .or\n"\r
-" \"DP3\" .emit OP_DP3 .or \"DP3_SAT\" .emit OP_DP3_SAT .or\n"\r
-" \"DP4\" .emit OP_DP4 .or \"DP4_SAT\" .emit OP_DP4_SAT .or\n"\r
-" \"DPH\" .emit OP_DPH .or \"DPH_SAT\" .emit OP_DPH_SAT .or\n"\r
-" \"DST\" .emit OP_DST .or \"DST_SAT\" .emit OP_DST_SAT .or\n"\r
-" \"MAX\" .emit OP_MAX .or \"MAX_SAT\" .emit OP_MAX_SAT .or\n"\r
-" \"MIN\" .emit OP_MIN .or \"MIN_SAT\" .emit OP_MIN_SAT .or\n"\r
-" \"MUL\" .emit OP_MUL .or \"MUL_SAT\" .emit OP_MUL_SAT .or\n"\r
-" \"SGE\" .emit OP_SGE .or \"SGE_SAT\" .emit OP_SGE_SAT .or\n"\r
-" \"SLT\" .emit OP_SLT .or \"SLT_SAT\" .emit OP_SLT_SAT .or\n"\r
-" \"SUB\" .emit OP_SUB .or \"SUB_SAT\" .emit OP_SUB_SAT .or\n"\r
-" \"XPD\" .emit OP_XPD .or \"XPD_SAT\" .emit OP_XPD_SAT;\n"\r
-"vp_BINop\n"\r
-" \"ADD\" .emit OP_ADD .or\n"\r
-" \"DP3\" .emit OP_DP3 .or\n"\r
-" \"DP4\" .emit OP_DP4 .or\n"\r
-" \"DPH\" .emit OP_DPH .or\n"\r
-" \"DST\" .emit OP_DST .or\n"\r
-" \"MAX\" .emit OP_MAX .or\n"\r
-" \"MIN\" .emit OP_MIN .or\n"\r
-" \"MUL\" .emit OP_MUL .or\n"\r
-" \"SGE\" .emit OP_SGE .or\n"\r
-" \"SLT\" .emit OP_SLT .or\n"\r
-" \"SUB\" .emit OP_SUB .or\n"\r
-" \"XPD\" .emit OP_XPD;\n"\r
-"fp_TRIop_instruction\n"\r
-" fp_TRIop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n"\r
-" vectorSrcReg .and comma .and vectorSrcReg;\n"\r
-"vp_TRIop_instruction\n"\r
-" vp_TRIop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and\n"\r
-" swizzleSrcReg .and comma .and swizzleSrcReg;\n"\r
-"fp_TRIop\n"\r
-" \"CMP\" .emit OP_CMP .or \"CMP_SAT\" .emit OP_CMP_SAT .or\n"\r
-" \"LRP\" .emit OP_LRP .or \"LRP_SAT\" .emit OP_LRP_SAT .or\n"\r
-" \"MAD\" .emit OP_MAD .or \"MAD_SAT\" .emit OP_MAD_SAT;\n"\r
-"vp_TRIop\n"\r
-" \"MAD\" .emit OP_MAD;\n"\r
-"fp_SWZ_instruction\n"\r
-" SWZop .and space_dst .and fp_maskedDstReg .and comma .and fp_srcReg .and comma .and\n"\r
-" fp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;\n"\r
-"vp_SWZ_instruction\n"\r
-" \"SWZ\" .emit OP_SWZ .and space_dst .and vp_maskedDstReg .and comma .and vp_srcReg .and comma .and\n"\r
-" vp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;\n"\r
-"SWZop\n"\r
-" \"SWZ\" .emit OP_SWZ .or \"SWZ_SAT\" .emit OP_SWZ_SAT;\n"\r
-"SAMPLE_instruction\n"\r
-" SAMPLEop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n"\r
-" texImageUnit .and comma .and texTarget .error TEX_TARGET_EXPECTED;\n"\r
-"SAMPLEop\n"\r
-" \"TEX\" .emit OP_TEX .or \"TEX_SAT\" .emit OP_TEX_SAT .or\n"\r
-" \"TXB\" .emit OP_TXB .or \"TXB_SAT\" .emit OP_TXB_SAT .or\n"\r
-" \"TXP\" .emit OP_TXP .or \"TXP_SAT\" .emit OP_TXP_SAT;\n"\r
-"KIL_instruction\n"\r
-" \"KIL\" .emit OP_KIL .and space_src .and vectorSrcReg;\n"\r
-"texImageUnit\n"\r
-" \"texture\" .error TEXTURE_EXPECTED .and optTexImageUnitNum;\n"\r
-"texTarget\n"\r
-" \"1D\" .emit TEXTARGET_1D .or\n"\r
-" \"2D\" .emit TEXTARGET_2D .or\n"\r
-" \"3D\" .emit TEXTARGET_3D .or\n"\r
-" .if (texture_rectangle != 0x00) \"RECT\" .emit TEXTARGET_RECT .or\n"\r
-" \"CUBE\" .emit TEXTARGET_CUBE .or\n"\r
-" .if (ARB_fragment_program_shadow != 0x00) shadowTarget;\n"\r
-"shadowTarget\n"\r
-" \"SHADOW1D\" .emit TEXTARGET_SHADOW1D .or\n"\r
-" \"SHADOW2D\" .emit TEXTARGET_SHADOW2D .or\n"\r
-" .if (texture_rectangle != 0x00) \"SHADOWRECT\" .emit TEXTARGET_SHADOWRECT;\n"\r
-"optTexImageUnitNum\n"\r
-" optTexImageUnitNum_1 .or .true .emit 0x00;\n"\r
-"optTexImageUnitNum_1\n"\r
-" lbracket_ne .and texImageUnitNum .and rbracket;\n"\r
-"texImageUnitNum\n"\r
-" integer;\n"\r
-"fp_scalarSrcReg\n"\r
-" optionalSign .and fp_srcReg .and fp_scalarSuffix;\n"\r
-"vp_scalarSrcReg\n"\r
-" optionalSign .and vp_srcReg .and vp_scalarSuffix;\n"\r
-"swizzleSrcReg\n"\r
-" optionalSign .and vp_srcReg .and swizzleSuffix;\n"\r
-"vectorSrcReg\n"\r
-" optionalSign .and fp_srcReg .and optionalSuffix;\n"\r
-"fp_maskedDstReg\n"\r
-" fp_dstReg .and fp_optionalMask;\n"\r
-"vp_maskedDstReg\n"\r
-" vp_dstReg .and vp_optionalMask;\n"\r
-"maskedAddrReg\n"\r
-" addrReg .error ADDRESS_REGISTER_EXPECTED .and addrWriteMask;\n"\r
-"fp_extendedSwizzle\n"\r
-" rgbaExtendedSwizzle .or xyzwExtendedSwizzle;\n"\r
-"vp_extendedSwizzle\n"\r
-" extSwizComp .and comma .and\n"\r
-" extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"\r
-" extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"\r
-" extSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"\r
-"xyzwExtendedSwizzle\n"\r
-" xyzwExtSwizComp .and comma .and\n"\r
-" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"\r
-" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"\r
-" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"\r
-"rgbaExtendedSwizzle\n"\r
-" rgbaExtendedSwizzle_1 .or rgbaExtendedSwizzle_2 .or rgbaExtendedSwizzle_3 .or\n"\r
-" rgbaExtendedSwizzle_4;\n"\r
-"rgbaExtendedSwizzle_1\n"\r
-" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and\n"\r
-" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp;\n"\r
-"rgbaExtendedSwizzle_2\n"\r
-" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and\n"\r
-" rgbaExtSwizComp_alpha .and comma .and rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"\r
-"rgbaExtendedSwizzle_3\n"\r
-" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_alpha .and comma .and\n"\r
-" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"\r
-" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"\r
-"rgbaExtendedSwizzle_4\n"\r
-" rgbaExtSwizComp_alpha .and comma .and \n"\r
-"rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"\r
-" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"\r
-" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"\r
-"xyzwExtSwizComp\n"\r
-" optionalSign .and xyzwExtSwizSel;\n"\r
-"rgbaExtSwizComp\n"\r
-" optionalSign .and rgbaExtSwizSel;\n"\r
-"rgbaExtSwizComp_digit\n"\r
-" optionalSign .and rgbaExtSwizSel_digit;\n"\r
-"rgbaExtSwizComp_alpha\n"\r
-" optionalSign .and rgbaExtSwizSel_alpha;\n"\r
-"extSwizComp\n"\r
-" optionalSign .and extSwizSel;\n"\r
-"xyzwExtSwizSel\n"\r
-" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1 .or xyzwComponent_single;\n"\r
-"rgbaExtSwizSel\n"\r
-" rgbaExtSwizSel_digit .or rgbaExtSwizSel_alpha;\n"\r
-"rgbaExtSwizSel_digit\n"\r
-" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1;\n"\r
-"rgbaExtSwizSel_alpha\n"\r
-" rgbaComponent_single;\n"\r
-"extSwizSel\n"\r
-" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1 .or vp_component_single;\n"\r
-"fp_srcReg\n"\r
-" fp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;\n"\r
-"vp_srcReg\n"\r
-" vp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;\n"\r
-"fp_srcReg_1\n"\r
-" fragmentAttribReg .emit REGISTER_ATTRIB .or\n"\r
-" fp_progParamReg .emit REGISTER_PARAM .or\n"\r
-" fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n"\r
-"vp_srcReg_1\n"\r
-" vertexAttribReg .emit REGISTER_ATTRIB .or\n"\r
-" vp_progParamReg .emit REGISTER_PARAM .or\n"\r
-" vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n"\r
-"fp_dstReg\n"\r
-" fp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;\n"\r
-"vp_dstReg\n"\r
-" vp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;\n"\r
-"fp_dstReg_1\n"\r
-" fragmentResultReg .emit REGISTER_RESULT .or\n"\r
-" fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n"\r
-"vp_dstReg_1\n"\r
-" vertexResultReg .emit REGISTER_RESULT .or\n"\r
-" vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n"\r
-"fragmentAttribReg\n"\r
-" fragAttribBinding;\n"\r
-"vertexAttribReg\n"\r
-" vtxAttribBinding;\n"\r
-"fp_temporaryReg\n"\r
-" fp_establishedName_no_error_on_identifier;\n"\r
-"vp_temporaryReg\n"\r
-" vp_establishedName_no_error_on_identifier;\n"\r
-"fp_progParamReg\n"\r
-" fp_paramSingleItemUse .or fp_progParamReg_1 .or fp_progParamSingle;\n"\r
-"vp_progParamReg\n"\r
-" vp_paramSingleItemUse .or vp_progParamReg_1 .or vp_progParamSingle;\n"\r
-"fp_progParamReg_1\n"\r
-" fp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayAbs .and\n"\r
-" rbracket;\n"\r
-"vp_progParamReg_1\n"\r
-" vp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayMem .and\n"\r
-" rbracket;\n"\r
-"fp_progParamSingle\n"\r
-" .false;\n"\r
-"vp_progParamSingle\n"\r
-" .false;\n"\r
-"fp_progParamArray\n"\r
-" fp_establishedName_no_error_on_identifier;\n"\r
-"vp_progParamArray\n"\r
-" vp_establishedName_no_error_on_identifier;\n"\r
-"progParamArrayMem\n"\r
-" progParamArrayAbs .or progParamArrayRel;\n"\r
-"progParamArrayAbs\n"\r
-" integer_ne .emit ARRAY_INDEX_ABSOLUTE;\n"\r
-"progParamArrayRel\n"\r
-" addrReg .error ADDRESS_REGISTER_OR_INTEGER_EXPECTED .emit ARRAY_INDEX_RELATIVE .and\n"\r
-" addrComponent .and addrRegRelOffset;\n"\r
-"addrRegRelOffset\n"\r
-" addrRegRelOffset_1 .or addrRegRelOffset_2 .or .true .emit 0x00;\n"\r
-"addrRegRelOffset_1\n"\r
-" plus_ne .and addrRegPosOffset;\n"\r
-"addrRegRelOffset_2\n"\r
-" minus_ne .and addrRegNegOffset;\n"\r
-"addrRegPosOffset\n"\r
-" integer_0_63;\n"\r
-"addrRegNegOffset\n"\r
-" integer_0_64;\n"\r
-"fragmentResultReg\n"\r
-" fp_resultBinding;\n"\r
-"vertexResultReg\n"\r
-" vp_resultBinding;\n"\r
-"addrReg\n"\r
-" vp_establishedName_no_error_on_identifier;\n"\r
-"addrComponent\n"\r
-" dot .and \"x\" .error INVALID_ADDRESS_COMPONENT .emit COMPONENT_X .emit COMPONENT_X\n"\r
-" .emit COMPONENT_X .emit COMPONENT_X;\n"\r
-"addrWriteMask\n"\r
-" dot .and \"x\" .error INVALID_ADDRESS_WRITEMASK .emit 0x08;\n"\r
-"fp_scalarSuffix\n"\r
-" dot .and fp_component_single .error INVALID_COMPONENT;\n"\r
-"vp_scalarSuffix\n"\r
-" dot .and vp_component_single .error INVALID_COMPONENT;\n"\r
-"swizzleSuffix\n"\r
-" swizzleSuffix_1 .or\n"\r
-" .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;\n"\r
-"swizzleSuffix_1\n"\r
-" dot_ne .and swizzleSuffix_2 .error INVALID_SUFFIX;\n"\r
-"swizzleSuffix_2\n"\r
-" swizzleSuffix_3 .or swizzleSuffix_4;\n"\r
-"swizzleSuffix_3\n"\r
-" vp_component_multi .and vp_component_multi .and vp_component_multi .error INVALID_COMPONENT .and\n"\r
-" vp_component_multi .error INVALID_COMPONENT;\n"\r
-"swizzleSuffix_4\n"\r
-" \"x\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n"\r
-" \"y\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n"\r
-" \"z\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n"\r
-" \"w\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;\n"\r
-"optionalSuffix\n"\r
-" optionalSuffix_1 .or\n"\r
-" .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;\n"\r
-"optionalSuffix_1\n"\r
-" dot_ne .and optionalSuffix_2 .error INVALID_SUFFIX;\n"\r
-"optionalSuffix_2\n"\r
-" optionalSuffix_3 .or optionalSuffix_4 .or optionalSuffix_5;\n"\r
-"optionalSuffix_3\n"\r
-" xyzwComponent_multi .and xyzwComponent_multi .and\n"\r
-" xyzwComponent_multi .error INVALID_COMPONENT .and xyzwComponent_multi .error INVALID_COMPONENT;\n"\r
-"optionalSuffix_4\n"\r
-" rgbaComponent_multi .and rgbaComponent_multi .and\n"\r
-" rgbaComponent_multi .error INVALID_COMPONENT .and rgbaComponent_multi .error INVALID_COMPONENT;\n"\r
-"optionalSuffix_5\n"\r
-" \"x\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n"\r
-" \"y\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n"\r
-" \"z\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n"\r
-" \"w\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .or\n"\r
-" \"r\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n"\r
-" \"g\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n"\r
-" \"b\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n"\r
-" \"a\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;\n"\r
-"fp_component_single\n"\r
-" xyzwComponent_single .or rgbaComponent_single;\n"\r
-"vp_component_multi\n"\r
-" 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or\n"\r
-" 'w' .emit COMPONENT_W;\n"\r
-"vp_component_single\n"\r
-" \"x\" .emit COMPONENT_X .or \"y\" .emit COMPONENT_Y .or \"z\" .emit COMPONENT_Z .or\n"\r
-" \"w\" .emit COMPONENT_W;\n"\r
-"xyzwComponent_multi\n"\r
-" 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or\n"\r
-" 'w' .emit COMPONENT_W;\n"\r
-"xyzwComponent_single\n"\r
-" \"x\" .emit COMPONENT_X .or \"y\" .emit COMPONENT_Y .or \"z\" .emit COMPONENT_Z .or\n"\r
-" \"w\" .emit COMPONENT_W;\n"\r
-"rgbaComponent_multi\n"\r
-" 'r' .emit COMPONENT_X .or 'g' .emit COMPONENT_Y .or 'b' .emit COMPONENT_Z .or\n"\r
-" 'a' .emit COMPONENT_W;\n"\r
-"rgbaComponent_single\n"\r
-" \"r\" .emit COMPONENT_X .or \"g\" .emit COMPONENT_Y .or \"b\" .emit COMPONENT_Z .or\n"\r
-" \"a\" .emit COMPONENT_W;\n"\r
-"fp_optionalMask\n"\r
-" rgbaMask .or xyzwMask .or .true .emit 0x0F;\n"\r
-"vp_optionalMask\n"\r
-" xyzwMask .or .true .emit 0x0F;\n"\r
-"xyzwMask\n"\r
-" dot_ne .and xyzwMask_1 .error INVALID_WRITEMASK;\n"\r
-"xyzwMask_1\n"\r
-" \"xyzw\" .emit 0x0F .or \"xyz\" .emit 0x0E .or \"xyw\" .emit 0x0D .or \"xy\" .emit 0x0C .or\n"\r
-" \"xzw\" .emit 0x0B .or \"xz\" .emit 0x0A .or \"xw\" .emit 0x09 .or \"x\" .emit 0x08 .or\n"\r
-" \"yzw\" .emit 0x07 .or \"yz\" .emit 0x06 .or \"yw\" .emit 0x05 .or \"y\" .emit 0x04 .or\n"\r
-" \"zw\" .emit 0x03 .or \"z\" .emit 0x02 .or \"w\" .emit 0x01;\n"\r
-"rgbaMask\n"\r
-" dot_ne .and rgbaMask_1;\n"\r
-"rgbaMask_1\n"\r
-" \"rgba\" .emit 0x0F .or \"rgb\" .emit 0x0E .or \"rga\" .emit 0x0D .or \"rg\" .emit 0x0C .or\n"\r
-" \"rba\" .emit 0x0B .or \"rb\" .emit 0x0A .or \"ra\" .emit 0x09 .or \"r\" .emit 0x08 .or\n"\r
-" \"gba\" .emit 0x07 .or \"gb\" .emit 0x06 .or \"ga\" .emit 0x05 .or \"g\" .emit 0x04 .or\n"\r
-" \"ba\" .emit 0x03 .or \"b\" .emit 0x02 .or \"a\" .emit 0x01;\n"\r
-"fp_namingStatement\n"\r
-" fp_ATTRIB_statement .emit ATTRIB .or\n"\r
-" fp_PARAM_statement .emit PARAM .or\n"\r
-" fp_TEMP_statement .emit TEMP .or\n"\r
-" fp_OUTPUT_statement .emit OUTPUT .or\n"\r
-" fp_ALIAS_statement .emit ALIAS;\n"\r
-"vp_namingStatement\n"\r
-" vp_ATTRIB_statement .emit ATTRIB .or\n"\r
-" vp_PARAM_statement .emit PARAM .or\n"\r
-" vp_TEMP_statement .emit TEMP .or\n"\r
-" ADDRESS_statement .emit ADDRESS .or\n"\r
-" vp_OUTPUT_statement .emit OUTPUT .or\n"\r
-" vp_ALIAS_statement .emit ALIAS;\n"\r
-"fp_ATTRIB_statement\n"\r
-" \"ATTRIB\" .and space .and fp_establishName .and equal .and\n"\r
-" fragAttribBinding .error FRAGMENT_EXPECTED;\n"\r
-"vp_ATTRIB_statement\n"\r
-" \"ATTRIB\" .and space .and vp_establishName .and equal .and\n"\r
-" vtxAttribBinding .error VERTEX_EXPECTED;\n"\r
-"fragAttribBinding\n"\r
-" \"fragment\" .and dot .and fragAttribItem .error INVALID_FRAGMENT_PROPERTY;\n"\r
-"vtxAttribBinding\n"\r
-" \"vertex\" .and dot .and vtxAttribItem .error INVALID_VERTEX_PROPERTY;\n"\r
-"fragAttribItem\n"\r
-" fragAttribItem_1 .emit FRAGMENT_ATTRIB_COLOR .or\n"\r
-" fragAttribItem_2 .emit FRAGMENT_ATTRIB_TEXCOORD .or\n"\r
-" .if (fog_coord != 0x00) \"fogcoord\" .emit FRAGMENT_ATTRIB_FOGCOORD .or\n"\r
-" \"position\" .emit FRAGMENT_ATTRIB_POSITION;\n"\r
-"fragAttribItem_1\n"\r
-" \"color\" .and optColorType;\n"\r
-"fragAttribItem_2\n"\r
-" \"texcoord\" .and optTexCoordNum;\n"\r
-"vtxAttribItem\n"\r
-" \"position\" .emit VERTEX_ATTRIB_POSITION .or\n"\r
-" .if (vertex_blend != 0x00) vtxAttribItem_1 .emit VERTEX_ATTRIB_WEIGHT .or\n"\r
-" \"normal\" .emit VERTEX_ATTRIB_NORMAL .or\n"\r
-" vtxAttribItem_2 .emit VERTEX_ATTRIB_COLOR .or\n"\r
-" \"fogcoord\" .emit VERTEX_ATTRIB_FOGCOORD .or\n"\r
-" vtxAttribItem_3 .emit VERTEX_ATTRIB_TEXCOORD .or\n"\r
-" .if (matrix_palette != 0x00) vtxAttribItem_4 .emit VERTEX_ATTRIB_MATRIXINDEX .or\n"\r
-" vtxAttribItem_5 .emit VERTEX_ATTRIB_GENERIC;\n"\r
-"vtxAttribItem_1\n"\r
-" \"weight\" .and vtxOptWeightNum;\n"\r
-"vtxAttribItem_2\n"\r
-" \"color\" .and optColorType;\n"\r
-"vtxAttribItem_3\n"\r
-" \"texcoord\" .and optTexCoordNum;\n"\r
-"vtxAttribItem_4\n"\r
-" \"matrixindex\" .and lbracket .and vtxWeightNum .and rbracket;\n"\r
-"vtxAttribItem_5\n"\r
-" \"attrib\" .and lbracket .and vtxAttribNum .and rbracket;\n"\r
-"vtxAttribNum\n"\r
-" integer;\n"\r
-"vtxOptWeightNum\n"\r
-" vtxOptWeightNum_1 .or .true .emit 0x00;\n"\r
-"vtxOptWeightNum_1\n"\r
-" lbracket_ne .and vtxWeightNum .and rbracket;\n"\r
-"vtxWeightNum\n"\r
-" integer;\n"\r
-"fp_PARAM_statement\n"\r
-" fp_PARAM_multipleStmt .or fp_PARAM_singleStmt;\n"\r
-"vp_PARAM_statement\n"\r
-" vp_PARAM_multipleStmt .or vp_PARAM_singleStmt;\n"\r
-"fp_PARAM_singleStmt\n"\r
-" \"PARAM\" .and space .and fp_establishName .and .true .emit 0x00 .and fp_paramSingleInit .and\n"\r
-" .true .emit PARAM_NULL;\n"\r
-"vp_PARAM_singleStmt\n"\r
-" \"PARAM\" .and space .and vp_establishName .and .true .emit 0x00 .and vp_paramSingleInit .and\n"\r
-" .true .emit PARAM_NULL;\n"\r
-"fp_PARAM_multipleStmt\n"\r
-" \"PARAM\" .and space .and fp_establishName .and lbracket_ne .and optArraySize .and rbracket .and\n"\r
-" fp_paramMultipleInit .and .true .emit PARAM_NULL;\n"\r
-"vp_PARAM_multipleStmt\n"\r
-" \"PARAM\" .and space .and vp_establishName .and lbracket_ne .and optArraySize .and rbracket .and\n"\r
-" vp_paramMultipleInit .and .true .emit PARAM_NULL;\n"\r
-"optArraySize\n"\r
-" optional_integer;\n"\r
-"fp_paramSingleInit\n"\r
-" equal .and fp_paramSingleItemDecl;\n"\r
-"vp_paramSingleInit\n"\r
-" equal .and vp_paramSingleItemDecl;\n"\r
-"fp_paramMultipleInit\n"\r
-" equal .and lbrace .and fp_paramMultInitList .and rbrace;\n"\r
-"vp_paramMultipleInit\n"\r
-" equal .and lbrace .and vp_paramMultInitList .and rbrace;\n"\r
-"fp_paramMultInitList\n"\r
-" fp_paramMultInitList_1 .or fp_paramMultipleItem;\n"\r
-"vp_paramMultInitList\n"\r
-" vp_paramMultInitList_1 .or vp_paramMultipleItem;\n"\r
-"fp_paramMultInitList_1\n"\r
-" fp_paramMultipleItem .and comma_ne .and fp_paramMultInitList;\n"\r
-"vp_paramMultInitList_1\n"\r
-" vp_paramMultipleItem .and comma_ne .and vp_paramMultInitList;\n"\r
-"fp_paramSingleItemDecl\n"\r
-" fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n"\r
-" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n"\r
-" paramConstDecl .emit PARAM_CONSTANT;\n"\r
-"vp_paramSingleItemDecl\n"\r
-" vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n"\r
-" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n"\r
-" paramConstDecl .emit PARAM_CONSTANT;\n"\r
-"fp_paramSingleItemUse\n"\r
-" fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n"\r
-" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n"\r
-" paramConstUse .emit PARAM_CONSTANT;\n"\r
-"vp_paramSingleItemUse\n"\r
-" vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n"\r
-" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n"\r
-" paramConstUse .emit PARAM_CONSTANT;\n"\r
-"fp_paramMultipleItem\n"\r
-" fp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or\n"\r
-" programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or\n"\r
-" paramConstDecl .emit PARAM_CONSTANT;\n"\r
-"vp_paramMultipleItem\n"\r
-" vp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or\n"\r
-" programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or\n"\r
-" paramConstDecl .emit PARAM_CONSTANT;\n"\r
-"fp_stateMultipleItem\n"\r
-" stateMultipleItem_1 .or fp_stateSingleItem;\n"\r
-"vp_stateMultipleItem\n"\r
-" stateMultipleItem_1 .or vp_stateSingleItem;\n"\r
-"stateMultipleItem_1\n"\r
-" \"state\" .and dot .and stateMatrixRows .emit STATE_MATRIX_ROWS;\n"\r
-"fp_stateSingleItem\n"\r
-" \"state\" .and dot .and fp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;\n"\r
-"vp_stateSingleItem\n"\r
-" \"state\" .and dot .and vp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;\n"\r
-"fp_stateSingleItem_1\n"\r
-" stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or\n"\r
-" stateSingleItem_5 .or stateSingleItem_7 .or stateSingleItem_8 .or stateSingleItem_11;\n"\r
-"vp_stateSingleItem_1\n"\r
-" stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or\n"\r
-" stateSingleItem_6 .or stateSingleItem_7 .or stateSingleItem_9 .or stateSingleItem_10 .or\n"\r
-" stateSingleItem_11;\n"\r
-"stateSingleItem_1\n"\r
-" stateMaterialItem .emit STATE_MATERIAL;\n"\r
-"stateSingleItem_2\n"\r
-" stateLightItem .emit STATE_LIGHT;\n"\r
-"stateSingleItem_3\n"\r
-" stateLightModelItem .emit STATE_LIGHT_MODEL;\n"\r
-"stateSingleItem_4\n"\r
-" stateLightProdItem .emit STATE_LIGHT_PROD;\n"\r
-"stateSingleItem_5\n"\r
-" stateTexEnvItem .emit STATE_TEX_ENV;\n"\r
-"stateSingleItem_6\n"\r
-" stateTexGenItem .emit STATE_TEX_GEN;\n"\r
-"stateSingleItem_7\n"\r
-" stateFogItem .emit STATE_FOG;\n"\r
-"stateSingleItem_8\n"\r
-" stateDepthItem .emit STATE_DEPTH;\n"\r
-"stateSingleItem_9\n"\r
-" stateClipPlaneItem .emit STATE_CLIP_PLANE;\n"\r
-"stateSingleItem_10\n"\r
-" statePointItem .emit STATE_POINT;\n"\r
-"stateSingleItem_11\n"\r
-" stateMatrixRow .emit STATE_MATRIX_ROWS;\n"\r
-"stateMaterialItem\n"\r
-" \"material\" .and optFaceType .and dot .and stateMatProperty .error INVALID_MATERIAL_PROPERTY;\n"\r
-"stateMatProperty\n"\r
-" \"ambient\" .emit MATERIAL_AMBIENT .or\n"\r
-" \"diffuse\" .emit MATERIAL_DIFFUSE .or\n"\r
-" \"specular\" .emit MATERIAL_SPECULAR .or\n"\r
-" \"emission\" .emit MATERIAL_EMISSION .or\n"\r
-" \"shininess\" .emit MATERIAL_SHININESS;\n"\r
-"stateLightItem\n"\r
-" \"light\" .and lbracket .and stateLightNumber .and rbracket .and dot .and\n"\r
-" stateLightProperty .error INVALID_LIGHT_PROPERTY;\n"\r
-"stateLightProperty\n"\r
-" \"ambient\" .emit LIGHT_AMBIENT .or\n"\r
-" \"diffuse\" .emit LIGHT_DIFFUSE .or\n"\r
-" \"specular\" .emit LIGHT_SPECULAR .or\n"\r
-" \"position\" .emit LIGHT_POSITION .or\n"\r
-" \"attenuation\" .emit LIGHT_ATTENUATION .or\n"\r
-" stateLightProperty_1 .emit LIGHT_SPOT_DIRECTION .or\n"\r
-" \"half\" .emit LIGHT_HALF;\n"\r
-"stateLightProperty_1\n"\r
-" \"spot\" .and dot .and stateSpotProperty .error INVALID_SPOT_PROPERTY;\n"\r
-"stateSpotProperty\n"\r
-" \"direction\";\n"\r
-"stateLightModelItem\n"\r
-" \"lightmodel\" .and stateLModProperty .error INVALID_LIGHTMODEL_PROPERTY;\n"\r
-"stateLModProperty\n"\r
-" stateLModProperty_1 .or stateLModProperty_2;\n"\r
-"stateLModProperty_1\n"\r
-" dot .and \"ambient\" .emit LIGHT_MODEL_AMBIENT;\n"\r
-"stateLModProperty_2\n"\r
-" stateLModProperty_3 .emit LIGHT_MODEL_SCENECOLOR;\n"\r
-"stateLModProperty_3\n"\r
-" optFaceType .and dot .and \"scenecolor\";\n"\r
-"stateLightProdItem\n"\r
-" \"lightprod\" .and lbracket .and stateLightNumber .and rbracket .and optFaceType .and dot .and\n"\r
-" stateLProdProperty .error INVALID_LIGHTPROD_PROPERTY;\n"\r
-"stateLProdProperty\n"\r
-" \"ambient\" .emit LIGHT_PROD_AMBIENT .or\n"\r
-" \"diffuse\" .emit LIGHT_PROD_DIFFUSE .or\n"\r
-" \"specular\" .emit LIGHT_PROD_SPECULAR;\n"\r
-"stateLightNumber\n"\r
-" integer;\n"\r
-"stateTexEnvItem\n"\r
-" \"texenv\" .and optLegacyTexUnitNum .and dot .and\n"\r
-" stateTexEnvProperty .error INVALID_TEXENV_PROPERTY;\n"\r
-"stateTexEnvProperty\n"\r
-" \"color\" .emit TEX_ENV_COLOR;\n"\r
-"optLegacyTexUnitNum\n"\r
-" lbracket_ne .and legacyTexUnitNum .and rbracket;\n"\r
-"legacyTexUnitNum\n"\r
-" integer;\n"\r
-"stateTexGenItem\n"\r
-" \"texgen\" .and optTexCoordNum .and dot .and stateTexGenType .error INVALID_TEXGEN_PROPERTY .and\n"\r
-" dot .and stateTexGenCoord .error INVALID_TEXGEN_COORD;\n"\r
-"stateTexGenType\n"\r
-" \"eye\" .emit TEX_GEN_EYE .or\n"\r
-" \"object\" .emit TEX_GEN_OBJECT;\n"\r
-"stateTexGenCoord\n"\r
-" \"s\" .emit COMPONENT_X .or\n"\r
-" \"t\" .emit COMPONENT_Y .or\n"\r
-" \"r\" .emit COMPONENT_Z .or\n"\r
-" \"q\" .emit COMPONENT_W;\n"\r
-"stateFogItem\n"\r
-" \"fog\" .and dot .and stateFogProperty .error INVALID_FOG_PROPERTY;\n"\r
-"stateFogProperty\n"\r
-" \"color\" .emit FOG_COLOR .or\n"\r
-" \"params\" .emit FOG_PARAMS;\n"\r
-"stateDepthItem\n"\r
-" \"depth\" .and dot .and stateDepthProperty .error INVALID_DEPTH_PROPERTY;\n"\r
-"stateDepthProperty\n"\r
-" \"range\" .emit DEPTH_RANGE;\n"\r
-"stateClipPlaneItem\n"\r
-" \"clip\" .and lbracket .and stateClipPlaneNum .and rbracket .and dot .and\n"\r
-" \"plane\" .error INVALID_CLIPPLANE_PROPERTY;\n"\r
-"stateClipPlaneNum\n"\r
-" integer;\n"\r
-"statePointItem\n"\r
-" \"point\" .and dot .and statePointProperty .error INVALID_POINT_PROPERTY;\n"\r
-"statePointProperty\n"\r
-" \"size\" .emit POINT_SIZE .or\n"\r
-" .if (point_parameters != 0x00) \"attenuation\" .emit POINT_ATTENUATION;\n"\r
-"stateMatrixRow\n"\r
-" stateMatrixItem .and dot .and \"row\" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and\n"\r
-" lbracket .and stateMatrixRowNum .and rbracket .emit 0x0;\n"\r
-"stateMatrixRows\n"\r
-" stateMatrixItem .and optMatrixRows;\n"\r
-"optMatrixRows\n"\r
-" optMatrixRows_1 .or .true .emit 0x0 .emit '3' .emit 0x0 .emit $;\n"\r
-"optMatrixRows_1\n"\r
-" dot_ne .and \"row\" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and lbracket .and\n"\r
-" stateMatrixRowNum .and dotdot .and stateMatrixRowNum .and rbracket;\n"\r
-"stateMatrixItem\n"\r
-" \"matrix\" .and dot .and stateMatrixName .error INVALID_MATRIX_NAME .and stateOptMatModifier;\n"\r
-"stateOptMatModifier\n"\r
-" stateOptMatModifier_1 .or .true .emit MATRIX_MODIFIER_IDENTITY;\n"\r
-"stateOptMatModifier_1\n"\r
-" dot_ne .and stateMatModifier;\n"\r
-"stateMatModifier\n"\r
-" \"inverse\" .emit MATRIX_MODIFIER_INVERSE .or\n"\r
-" \"transpose\" .emit MATRIX_MODIFIER_TRANSPOSE .or\n"\r
-" \"invtrans\" .emit MATRIX_MODIFIER_INVTRANS;\n"\r
-"stateMatrixRowNum\n"\r
-" integer_0_3;\n"\r
-"stateMatrixName\n"\r
-" stateMatrixName_1_1 .emit MATRIX_MODELVIEW .or\n"\r
-" \"projection\" .emit MATRIX_PROJECTION .or\n"\r
-" \"mvp\" .emit MATRIX_MVP .or\n"\r
-" stateMatrixName_1_2 .emit MATRIX_TEXTURE .or\n"\r
-" .if (matrix_palette != 0x00) stateMatrixName_1_3 .emit MATRIX_PALETTE .or\n"\r
-" stateMatrixName_1_4 .emit MATRIX_PROGRAM;\n"\r
-"stateMatrixName_1_1\n"\r
-" \"modelview\" .and stateOptModMatNum;\n"\r
-"stateMatrixName_1_2\n"\r
-" \"texture\" .and optTexCoordNum;\n"\r
-"stateMatrixName_1_3\n"\r
-" \"palette\" .and lbracket .and statePaletteMatNum .and rbracket;\n"\r
-"stateMatrixName_1_4\n"\r
-" \"program\" .and lbracket .and stateProgramMatNum .and rbracket;\n"\r
-"stateOptModMatNum\n"\r
-" .if (vertex_blend != 0x00) stateOptModMatNum_1 .or\n"\r
-" .true .emit 0x00;\n"\r
-"stateOptModMatNum_1\n"\r
-" lbracket_ne .and stateModMatNum .and rbracket;\n"\r
-"stateModMatNum\n"\r
-" integer;\n"\r
-"optTexCoordNum\n"\r
-" optTexCoordNum_1 .or .true .emit 0x00;\n"\r
-"optTexCoordNum_1\n"\r
-" lbracket_ne .and texCoordNum .and rbracket;\n"\r
-"texCoordNum\n"\r
-" integer;\n"\r
-"statePaletteMatNum\n"\r
-" integer;\n"\r
-"stateProgramMatNum\n"\r
-" integer;\n"\r
-"programSingleItem\n"\r
-" \"program\" .and dot .and programSingleItem_1 .error INVALID_PROGRAM_PROPERTY;\n"\r
-"programSingleItem_1\n"\r
-" progEnvParam .or progLocalParam;\n"\r
-"programMultipleItem\n"\r
-" \"program\" .and dot .and programMultipleItem_1 .error INVALID_PROGRAM_PROPERTY;\n"\r
-"programMultipleItem_1\n"\r
-" progEnvParams .or progLocalParams;\n"\r
-"progEnvParams\n"\r
-" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNums .and rbracket;\n"\r
-"progEnvParamNums\n"\r
-" progEnvParamNums_1 .or progEnvParamNums_2;\n"\r
-"progEnvParamNums_1\n"\r
-" progEnvParamNum .and dotdot_ne .and progEnvParamNum;\n"\r
-"progEnvParamNums_2\n"\r
-" progEnvParamNum .and .true .emit 0x00;\n"\r
-"progEnvParam\n"\r
-" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket .emit 0x00;\n"\r
-"progLocalParams\n"\r
-" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNums .and rbracket;\n"\r
-"progLocalParamNums\n"\r
-" progLocalParamNums_1 .or progLocalParamNums_2;\n"\r
-"progLocalParamNums_1\n"\r
-" progLocalParamNum .and dotdot_ne .and progLocalParamNum;\n"\r
-"progLocalParamNums_2\n"\r
-" progLocalParamNum .and .true .emit 0x00;\n"\r
-"progLocalParam\n"\r
-" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket .emit 0x00;\n"\r
-"progEnvParamNum\n"\r
-" integer;\n"\r
-"progLocalParamNum\n"\r
-" integer;\n"\r
-"paramConstDecl\n"\r
-" paramConstScalarDecl .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;\n"\r
-"paramConstUse\n"\r
-" paramConstScalarUse .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;\n"\r
-"paramConstScalarDecl\n"\r
-" signedFloatConstant;\n"\r
-"paramConstScalarUse\n"\r
-" floatConstant;\n"\r
-"paramConstVector\n"\r
-" paramConstVector_4 .emit 0x04 .or paramConstVector_3 .emit 0x03 .or\n"\r
-" paramConstVector_2 .emit 0x02 .or paramConstVector_1 .emit 0x01;\n"\r
-"paramConstVector_1\n"\r
-" lbrace_ne .and signedFloatConstant .and rbrace;\n"\r
-"paramConstVector_2\n"\r
-" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;\n"\r
-"paramConstVector_3\n"\r
-" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and\n"\r
-" signedFloatConstant .and rbrace;\n"\r
-"paramConstVector_4\n"\r
-" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and\n"\r
-" signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;\n"\r
-"signedFloatConstant\n"\r
-" optionalSign .and floatConstant;\n"\r
-"floatConstant\n"\r
-" float;\n"\r
-"optionalSign\n"\r
-" optional_sign_ne;\n"\r
-"fp_TEMP_statement\n"\r
-" \"TEMP\" .and space .and fp_varNameList .and .true .emit 0x00;\n"\r
-"vp_TEMP_statement\n"\r
-" \"TEMP\" .and space .and vp_varNameList .and .true .emit 0x00;\n"\r
-"ADDRESS_statement\n"\r
-" \"ADDRESS\" .and space .and vp_varNameList .and .true .emit 0x00;\n"\r
-"fp_varNameList\n"\r
-" fp_varNameList_1 .or fp_establishName;\n"\r
-"vp_varNameList\n"\r
-" vp_varNameList_1 .or vp_establishName;\n"\r
-"fp_varNameList_1\n"\r
-" fp_establishName .and comma_ne .and fp_varNameList;\n"\r
-"vp_varNameList_1\n"\r
-" vp_establishName .and comma_ne .and vp_varNameList;\n"\r
-"fp_OUTPUT_statement\n"\r
-" \"OUTPUT\" .and space .and fp_establishName .and equal .and\n"\r
-" fp_resultBinding .error RESULT_EXPECTED;\n"\r
-"vp_OUTPUT_statement\n"\r
-" \"OUTPUT\" .and space .and vp_establishName .and equal .and\n"\r
-" vp_resultBinding .error RESULT_EXPECTED;\n"\r
-"fp_resultBinding\n"\r
-" \"result\" .and dot .and fp_resultBinding_1 .error INVALID_RESULT_PROPERTY;\n"\r
-"vp_resultBinding\n"\r
-" \"result\" .and dot .and vp_resultBinding_1 .error INVALID_RESULT_PROPERTY;\n"\r
-"fp_resultBinding_1\n"\r
-" \"color\" .emit FRAGMENT_RESULT_COLOR .or\n"\r
-" \"depth\" .emit FRAGMENT_RESULT_DEPTH;\n"\r
-"vp_resultBinding_1\n"\r
-" .if (ARB_position_invariant == 0x00) \"position\" .emit VERTEX_RESULT_POSITION .or\n"\r
-" resultColBinding .emit VERTEX_RESULT_COLOR .or\n"\r
-" \"fogcoord\" .emit VERTEX_RESULT_FOGCOORD .or\n"\r
-" \"pointsize\" .emit VERTEX_RESULT_POINTSIZE .or\n"\r
-" vp_resultBinding_2 .emit VERTEX_RESULT_TEXCOORD;\n"\r
-"vp_resultBinding_2\n"\r
-" \"texcoord\" .and optTexCoordNum;\n"\r
-"resultColBinding\n"\r
-" \"color\" .and optFaceType .and optColorType;\n"\r
-"optFaceType\n"\r
-" FaceType .or .true .emit FACE_FRONT;\n"\r
-"FaceType\n"\r
-" dot_ne .and FaceProperty;\n"\r
-"FaceProperty\n"\r
-" \"front\" .emit FACE_FRONT .or \"back\" .emit FACE_BACK;\n"\r
-"optColorType\n"\r
-" ColorType .or .true .emit COLOR_PRIMARY;\n"\r
-"ColorType\n"\r
-" dot_ne .and ColorProperty;\n"\r
-"ColorProperty\n"\r
-" \"primary\" .emit COLOR_PRIMARY .or\n"\r
-" .if (secondary_color != 0x00) \"secondary\" .emit COLOR_SECONDARY;\n"\r
-"fp_ALIAS_statement\n"\r
-" \"ALIAS\" .and fp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and fp_establishedName;\n"\r
-"vp_ALIAS_statement\n"\r
-" \"ALIAS\" .and vp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and vp_establishedName;\n"\r
-"fp_ALIAS_statement_1\n"\r
-" space .and fp_establishName;\n"\r
-"vp_ALIAS_statement_1\n"\r
-" space .and vp_establishName;\n"\r
-"fp_establishName\n"\r
-" fp_identifier;\n"\r
-"vp_establishName\n"\r
-" vp_identifier;\n"\r
-"fp_establishedName\n"\r
-" fp_identifier;\n"\r
-"vp_establishedName\n"\r
-" vp_identifier;\n"\r
-"fp_establishedName_no_error_on_identifier\n"\r
-" fp_identifier_ne;\n"\r
-"vp_establishedName_no_error_on_identifier\n"\r
-" vp_identifier_ne;\n"\r
-"fp_identifier\n"\r
-" fp_identifier_ne .error IDENTIFIER_EXPECTED;\n"\r
-"vp_identifier\n"\r
-" vp_identifier_ne .error IDENTIFIER_EXPECTED;\n"\r
-"fp_identifier_ne\n"\r
-" fp_not_reserved_identifier .and identifier_ne;\n"\r
-"vp_identifier_ne\n"\r
-" vp_not_reserved_identifier .and identifier_ne;\n"\r
-"fp_not_reserved_identifier\n"\r
-" fp_not_reserved_identifier_1 .or .true;\n"\r
-"fp_not_reserved_identifier_1\n"\r
-" fp_reserved_identifier .and .false .error RESERVED_KEYWORD;\n"\r
-"vp_not_reserved_identifier\n"\r
-" vp_not_reserved_identifier_1 .or .true;\n"\r
-"vp_not_reserved_identifier_1\n"\r
-" vp_reserved_identifier .and .false .error RESERVED_KEYWORD;\n"\r
-"fp_reserved_identifier\n"\r
-" \"ABS\" .or \"ABS_SAT\" .or \"ADD\" .or \"ADD_SAT\" .or \"ALIAS\" .or \"ATTRIB\" .or \"CMP\" .or \"CMP_SAT\" .or\n"\r
-" \"COS\" .or \"COS_SAT\" .or \"DP3\" .or \"DP3_SAT\" .or \"DP4\" .or \"DP4_SAT\" .or \"DPH\" .or \"DPH_SAT\" .or\n"\r
-" \"DST\" .or \"DST_SAT\" .or \"END\" .or \"EX2\" .or \"EX2_SAT\" .or \"FLR\" .or \"FLR_SAT\" .or \"FRC\" .or\n"\r
-" \"FRC_SAT\" .or \"KIL\" .or \"LG2\" .or \"LG2_SAT\" .or \"LIT\" .or \"LIT_SAT\" .or \"LRP\" .or \"LRP_SAT\" .or\n"\r
-" \"MAD\" .or \"MAD_SAT\" .or \"MAX\" .or \"MAX_SAT\" .or \"MIN\" .or \"MIN_SAT\" .or \"MOV\" .or \"MOV_SAT\" .or\n"\r
-" \"MUL\" .or \"MUL_SAT\" .or \"OPTION\" .or \"OUTPUT\" .or \"PARAM\" .or \"POW\" .or \"POW_SAT\" .or \"RCP\" .or\n"\r
-" \"RCP_SAT\" .or \"RSQ\" .or \"RSQ_SAT\" .or \"SIN\" .or \"SIN_SAT\" .or \"SCS\" .or \"SCS_SAT\" .or \"SGE\" .or\n"\r
-" \"SGE_SAT\" .or \"SLT\" .or \"SLT_SAT\" .or \"SUB\" .or \"SUB_SAT\" .or \"SWZ\" .or \"SWZ_SAT\" .or \"TEMP\" .or\n"\r
-" \"TEX\" .or \"TEX_SAT\" .or \"TXB\" .or \"TXB_SAT\" .or \"TXP\" .or \"TXP_SAT\" .or \"XPD\" .or \"XPD_SAT\" .or\n"\r
-" \"fragment\" .or \"program\" .or \"result\" .or \"state\" .or \"texture\";\n"\r
-"vp_reserved_identifier\n"\r
-" \"ABS\" .or \"ADD\" .or \"ADDRESS\" .or \"ALIAS\" .or \"ARL\" .or \"ATTRIB\" .or \"DP3\" .or \"DP4\" .or\n"\r
-" \"DPH\" .or \"DST\" .or \"END\" .or \"EX2\" .or \"EXP\" .or \"FLR\" .or \"FRC\" .or \"LG2\" .or \"LIT\" .or\n"\r
-" \"LOG\" .or \"MAD\" .or \"MAX\" .or \"MIN\" .or \"MOV\" .or \"MUL\" .or \"OPTION\" .or \"OUTPUT\" .or\n"\r
-" \"PARAM\" .or \"POW\" .or \"RCP\" .or \"RSQ\" .or \"SGE\" .or \"SLT\" .or \"SUB\" .or \"SWZ\" .or \"TEMP\" .or\n"\r
-" \"XPD\" .or \"program\" .or \"result\" .or \"state\" .or \"vertex\";\n"\r
-"integer\n"\r
-" integer_ne .error INTEGER_EXPECTED;\n"\r
-"zero\n"\r
-" '0';\n"\r
-"leading_zeroes\n"\r
-" .loop zero;\n"\r
-"no_digit\n"\r
-" no_digit_1 .or .true;\n"\r
-"no_digit_1\n"\r
-" digit10 .and .false .error INTEGER_OUT_OF_RANGE;\n"\r
-"all_zeroes\n"\r
-" all_zeroes_1 .or no_digit_1;\n"\r
-"all_zeroes_1\n"\r
-" '0' .and .loop zero .and no_digit;\n"\r
-"integer_0_3\n"\r
-" integer_0_3_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n"\r
-"integer_0_3_1\n"\r
-" integer_0_3_2 .or all_zeroes .emit '0';\n"\r
-"integer_0_3_2 \n"\r
-" leading_zeroes .and '1'-'3' .emit * .and no_digit;\n"\r
-"integer_0_63\n"\r
-" integer_0_63_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n"\r
-"integer_0_63_1\n"\r
-" integer_0_63_2 .or integer_0_63_3 .or integer_0_63_4 .or integer_0_63_5 .or\n"\r
-" all_zeroes .emit '0';\n"\r
-"integer_0_63_2 \n"\r
-" leading_zeroes .and '7'-'9' .emit * .and no_digit;\n"\r
-"integer_0_63_3 \n"\r
-" leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;\n"\r
-"integer_0_63_4 \n"\r
-" leading_zeroes .and '6' .emit * .and '0'-'3' .emit * .and no_digit;\n"\r
-"integer_0_63_5 \n"\r
-" leading_zeroes .and '1'-'6' .emit * .and no_digit;\n"\r
-"integer_0_64\n"\r
-" integer_0_64_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n"\r
-"integer_0_64_1\n"\r
-" integer_0_64_2 .or integer_0_64_3 .or integer_0_64_4 .or integer_0_64_5 .or\n"\r
-" all_zeroes .emit '0';\n"\r
-"integer_0_64_2 \n"\r
-" leading_zeroes .and '7'-'9' .emit * .and no_digit;\n"\r
-"integer_0_64_3 \n"\r
-" leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;\n"\r
-"integer_0_64_4 \n"\r
-" leading_zeroes .and '6' .emit * .and '0'-'4' .emit * .and no_digit;\n"\r
-"integer_0_64_5 \n"\r
-" leading_zeroes .and '1'-'6' .emit * .and no_digit;\n"\r
-"optional_space\n"\r
-" space .or .true;\n"\r
-"space_dst\n"\r
-" space .error OPERATION_NEEDS_DESTINATION_VARIABLE;\n"\r
-"space_src\n"\r
-" space .error OPERATION_NEEDS_SOURCE_VARIABLE;\n"\r
-"space\n"\r
-" single_space .and .loop single_space;\n"\r
-"single_space\n"\r
-" white_char .or comment_block;\n"\r
-"white_char\n"\r
-" ' ' .or '\\t' .or '\\n' .or '\\r';\n"\r
-"comment_block\n"\r
-" '#' .and .loop comment_char .and new_line;\n"\r
-"comment_char\n"\r
-" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"\r
-"new_line\n"\r
-" '\\n' .or crlf .or '\\0';\n"\r
-"crlf\n"\r
-" '\\r' .and '\\n';\n"\r
-"semicolon\n"\r
-" optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;\n"\r
-"comma\n"\r
-" optional_space .and ',' .error MISSING_COMMA .and optional_space;\n"\r
-"comma_ne\n"\r
-" optional_space .and ',' .and optional_space;\n"\r
-"lbracket\n"\r
-" optional_space .and '[' .error MISSING_LBRACKET .and optional_space;\n"\r
-"lbracket_ne\n"\r
-" optional_space .and '[' .and optional_space;\n"\r
-"rbracket\n"\r
-" optional_space .and ']' .error MISSING_RBRACKET .and optional_space;\n"\r
-"dot\n"\r
-" optional_space .and '.' .error MISSING_DOT .and optional_space;\n"\r
-"dot_ne\n"\r
-" optional_space .and '.' .and optional_space;\n"\r
-"equal\n"\r
-" optional_space .and '=' .error MISSING_EQUAL .and optional_space;\n"\r
-"lbrace\n"\r
-" optional_space .and '{' .error MISSING_LBRACE .and optional_space;\n"\r
-"lbrace_ne\n"\r
-" optional_space .and '{' .and optional_space;\n"\r
-"rbrace\n"\r
-" optional_space .and '}' .error MISSING_RBRACE .and optional_space;\n"\r
-"dotdot\n"\r
-" optional_space .and '.' .and '.' .error MISSING_DOTDOT .and optional_space;\n"\r
-"dotdot_ne\n"\r
-" optional_space .and '.' .and '.' .and optional_space;\n"\r
-"float\n"\r
-" float_1 .or float_2 .or float_legacy;\n"\r
-"float_1\n"\r
-" '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent;\n"\r
-"float_2\n"\r
-" integer_ne .and float_3;\n"\r
-"float_3\n"\r
-" float_4 .or float_5;\n"\r
-"float_4\n"\r
-" '.' .and optional_integer .and optional_exponent;\n"\r
-"float_5\n"\r
-" exponent .emit 0x00;\n"\r
-"float_legacy\n"\r
-" integer_ne .and .true .emit 0x00 .emit 0x00;\n"\r
-"integer_ne\n"\r
-" integer_ne_1 .and .true .emit 0x00 .emit $;\n"\r
-"integer_ne_1\n"\r
-" digit10 .emit * .and .loop digit10 .emit *;\n"\r
-"optional_integer\n"\r
-" integer_ne .or .true .emit 0x00;\n"\r
-"optional_exponent\n"\r
-" exponent .or .true .emit 0x00;\n"\r
-"exponent\n"\r
-" exponent_1 .and optional_sign_ne .and integer_ne .error EXPONENT_VALUE_EXPECTED;\n"\r
-"exponent_1\n"\r
-" 'e' .or 'E';\n"\r
-"optional_sign_ne\n"\r
-" minus_ne .or plus_ne .or .true;\n"\r
-"plus_ne\n"\r
-" optional_space .and '+' .and optional_space;\n"\r
-"minus_ne\n"\r
-" optional_space .and '-' .emit '-' .and optional_space;\n"\r
-"identifier_ne\n"\r
-" first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit 0x00 .emit $;\n"\r
-"follow_idchar\n"\r
-" first_idchar .or digit10;\n"\r
-"first_idchar\n"\r
-" 'a'-'z' .or 'A'-'Z' .or '_' .or '$';\n"\r
-"digit10\n"\r
-" '0'-'9';\n"\r
-".string __string_filter;\n"\r
-"__string_filter\n"\r
-" .loop __identifier_char;\n"\r
-"__identifier_char\n"\r
-" 'a'-'z' .or 'A'-'Z' .or '_' .or '$' .or '0'-'9';\n"\r
-"e_signature\n"\r
-" e_signature_char .and .loop e_signature_char;\n"\r
-"e_signature_char\n"\r
-" '!' .or '.' .or 'A'-'Z' .or 'a'-'z' .or '0'-'9';\n"\r
-"e_statement\n"\r
-" .loop e_statement_not_term;\n"\r
-"e_statement_not_term\n"\r
-" '\\x3C'-'\\xFF' .or '\\x0E'-'\\x3A' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"\r
-"e_identifier\n"\r
-" e_identifier_first .and .loop e_identifier_next;\n"\r
-"e_identifier_first\n"\r
-" 'a'-'z' .or 'A'-'Z' .or '_' .or '$';\n"\r
-"e_identifier_next\n"\r
-" e_identifier_first .or '0'-'9';\n"\r
-"e_token\n"\r
-" e_identifier .or e_token_number .or '[' .or ']' .or '.' .or '{' .or '}' .or '=' .or '+' .or\n"\r
-" '-' .or ',' .or ';';\n"\r
-"e_token_number\n"\r
-" e_token_digit .and .loop e_token_digit;\n"\r
-"e_token_digit\n"\r
-" '0'-'9';\n"\r
-"e_charordigit\n"\r
-" 'A'-'Z' .or 'a'-'z' .or '0'-'9';\n"\r
-""
\ No newline at end of file
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.1
+ *
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file arbprogram_syn.h
+ * ARB_fragment_program/ARB_vertex_program syntax
+ * \author Michal Krol
+ */
+
+".syntax program;\n"
+".emtcode REVISION 0x07\n"
+".emtcode FRAGMENT_PROGRAM 0x01\n"
+".emtcode VERTEX_PROGRAM 0x02\n"
+".emtcode OPTION 0x01\n"
+".emtcode INSTRUCTION 0x02\n"
+".emtcode DECLARATION 0x03\n"
+".emtcode END 0x04\n"
+".emtcode ARB_PRECISION_HINT_FASTEST 0x01\n"
+".emtcode ARB_PRECISION_HINT_NICEST 0x02\n"
+".emtcode ARB_FOG_EXP 0x04\n"
+".emtcode ARB_FOG_EXP2 0x08\n"
+".emtcode ARB_FOG_LINEAR 0x10\n"
+".emtcode ARB_POSITION_INVARIANT 0x20\n"
+".emtcode ARB_FRAGMENT_PROGRAM_SHADOW 0x40\n"
+".emtcode OP_ALU_INST 0x00\n"
+".emtcode OP_TEX_INST 0x01\n"
+".emtcode OP_ALU_VECTOR 0x00\n"
+".emtcode OP_ALU_SCALAR 0x01\n"
+".emtcode OP_ALU_BINSC 0x02\n"
+".emtcode OP_ALU_BIN 0x03\n"
+".emtcode OP_ALU_TRI 0x04\n"
+".emtcode OP_ALU_SWZ 0x05\n"
+".emtcode OP_TEX_SAMPLE 0x06\n"
+".emtcode OP_TEX_KIL 0x07\n"
+".emtcode OP_ALU_ARL 0x08\n"
+".emtcode OP_ABS 0x00\n"
+".emtcode OP_ABS_SAT 0x1B\n"
+".emtcode OP_FLR 0x09\n"
+".emtcode OP_FLR_SAT 0x26\n"
+".emtcode OP_FRC 0x0A\n"
+".emtcode OP_FRC_SAT 0x27\n"
+".emtcode OP_LIT 0x0C\n"
+".emtcode OP_LIT_SAT 0x2A\n"
+".emtcode OP_MOV 0x11\n"
+".emtcode OP_MOV_SAT 0x30\n"
+".emtcode OP_COS 0x1F\n"
+".emtcode OP_COS_SAT 0x20\n"
+".emtcode OP_EX2 0x07\n"
+".emtcode OP_EX2_SAT 0x25\n"
+".emtcode OP_LG2 0x0B\n"
+".emtcode OP_LG2_SAT 0x29\n"
+".emtcode OP_RCP 0x14\n"
+".emtcode OP_RCP_SAT 0x33\n"
+".emtcode OP_RSQ 0x15\n"
+".emtcode OP_RSQ_SAT 0x34\n"
+".emtcode OP_SIN 0x38\n"
+".emtcode OP_SIN_SAT 0x39\n"
+".emtcode OP_SCS 0x35\n"
+".emtcode OP_SCS_SAT 0x36\n"
+".emtcode OP_POW 0x13\n"
+".emtcode OP_POW_SAT 0x32\n"
+".emtcode OP_ADD 0x01\n"
+".emtcode OP_ADD_SAT 0x1C\n"
+".emtcode OP_DP3 0x03\n"
+".emtcode OP_DP3_SAT 0x21\n"
+".emtcode OP_DP4 0x04\n"
+".emtcode OP_DP4_SAT 0x22\n"
+".emtcode OP_DPH 0x05\n"
+".emtcode OP_DPH_SAT 0x23\n"
+".emtcode OP_DST 0x06\n"
+".emtcode OP_DST_SAT 0x24\n"
+".emtcode OP_MAX 0x0F\n"
+".emtcode OP_MAX_SAT 0x2E\n"
+".emtcode OP_MIN 0x10\n"
+".emtcode OP_MIN_SAT 0x2F\n"
+".emtcode OP_MUL 0x12\n"
+".emtcode OP_MUL_SAT 0x31\n"
+".emtcode OP_SGE 0x16\n"
+".emtcode OP_SGE_SAT 0x37\n"
+".emtcode OP_SLT 0x17\n"
+".emtcode OP_SLT_SAT 0x3A\n"
+".emtcode OP_SUB 0x18\n"
+".emtcode OP_SUB_SAT 0x3B\n"
+".emtcode OP_XPD 0x1A\n"
+".emtcode OP_XPD_SAT 0x43\n"
+".emtcode OP_CMP 0x1D\n"
+".emtcode OP_CMP_SAT 0x1E\n"
+".emtcode OP_LRP 0x2B\n"
+".emtcode OP_LRP_SAT 0x2C\n"
+".emtcode OP_MAD 0x0E\n"
+".emtcode OP_MAD_SAT 0x2D\n"
+".emtcode OP_SWZ 0x19\n"
+".emtcode OP_SWZ_SAT 0x3C\n"
+".emtcode OP_TEX 0x3D\n"
+".emtcode OP_TEX_SAT 0x3E\n"
+".emtcode OP_TXB 0x3F\n"
+".emtcode OP_TXB_SAT 0x40\n"
+".emtcode OP_TXP 0x41\n"
+".emtcode OP_TXP_SAT 0x42\n"
+".emtcode OP_KIL 0x28\n"
+".emtcode OP_ARL 0x02\n"
+".emtcode OP_EXP 0x08\n"
+".emtcode OP_LOG 0x0D\n"
+".emtcode FRAGMENT_ATTRIB_COLOR 0x01\n"
+".emtcode FRAGMENT_ATTRIB_TEXCOORD 0x02\n"
+".emtcode FRAGMENT_ATTRIB_FOGCOORD 0x03\n"
+".emtcode FRAGMENT_ATTRIB_POSITION 0x04\n"
+".emtcode VERTEX_ATTRIB_POSITION 0x01\n"
+".emtcode VERTEX_ATTRIB_WEIGHT 0x02\n"
+".emtcode VERTEX_ATTRIB_NORMAL 0x03\n"
+".emtcode VERTEX_ATTRIB_COLOR 0x04\n"
+".emtcode VERTEX_ATTRIB_FOGCOORD 0x05\n"
+".emtcode VERTEX_ATTRIB_TEXCOORD 0x06\n"
+".emtcode VERTEX_ATTRIB_MATRIXINDEX 0x07\n"
+".emtcode VERTEX_ATTRIB_GENERIC 0x08\n"
+".emtcode FRAGMENT_RESULT_COLOR 0x01\n"
+".emtcode FRAGMENT_RESULT_DEPTH 0x02\n"
+".emtcode VERTEX_RESULT_POSITION 0x01\n"
+".emtcode VERTEX_RESULT_COLOR 0x02\n"
+".emtcode VERTEX_RESULT_FOGCOORD 0x03\n"
+".emtcode VERTEX_RESULT_POINTSIZE 0x04\n"
+".emtcode VERTEX_RESULT_TEXCOORD 0x05\n"
+".emtcode TEXTARGET_1D 0x01\n"
+".emtcode TEXTARGET_2D 0x02\n"
+".emtcode TEXTARGET_3D 0x03\n"
+".emtcode TEXTARGET_RECT 0x04\n"
+".emtcode TEXTARGET_CUBE 0x05\n"
+".emtcode TEXTARGET_SHADOW1D 0x06\n"
+".emtcode TEXTARGET_SHADOW2D 0x07\n"
+".emtcode TEXTARGET_SHADOWRECT 0x08\n"
+".emtcode FACE_FRONT 0x00\n"
+".emtcode FACE_BACK 0x01\n"
+".emtcode COLOR_PRIMARY 0x00\n"
+".emtcode COLOR_SECONDARY 0x01\n"
+".emtcode COMPONENT_X 0x00\n"
+".emtcode COMPONENT_Y 0x01\n"
+".emtcode COMPONENT_Z 0x02\n"
+".emtcode COMPONENT_W 0x03\n"
+".emtcode COMPONENT_0 0x04\n"
+".emtcode COMPONENT_1 0x05\n"
+".emtcode ARRAY_INDEX_ABSOLUTE 0x00\n"
+".emtcode ARRAY_INDEX_RELATIVE 0x01\n"
+".emtcode MATRIX_MODELVIEW 0x01\n"
+".emtcode MATRIX_PROJECTION 0x02\n"
+".emtcode MATRIX_MVP 0x03\n"
+".emtcode MATRIX_TEXTURE 0x04\n"
+".emtcode MATRIX_PALETTE 0x05\n"
+".emtcode MATRIX_PROGRAM 0x06\n"
+".emtcode MATRIX_MODIFIER_IDENTITY 0x00\n"
+".emtcode MATRIX_MODIFIER_INVERSE 0x01\n"
+".emtcode MATRIX_MODIFIER_TRANSPOSE 0x02\n"
+".emtcode MATRIX_MODIFIER_INVTRANS 0x03\n"
+".emtcode CONSTANT_SCALAR 0x01\n"
+".emtcode CONSTANT_VECTOR 0x02\n"
+".emtcode PROGRAM_PARAM_ENV 0x01\n"
+".emtcode PROGRAM_PARAM_LOCAL 0x02\n"
+".emtcode REGISTER_ATTRIB 0x01\n"
+".emtcode REGISTER_PARAM 0x02\n"
+".emtcode REGISTER_RESULT 0x03\n"
+".emtcode REGISTER_ESTABLISHED_NAME 0x04\n"
+".emtcode PARAM_NULL 0x00\n"
+".emtcode PARAM_ARRAY_ELEMENT 0x01\n"
+".emtcode PARAM_STATE_ELEMENT 0x02\n"
+".emtcode PARAM_PROGRAM_ELEMENT 0x03\n"
+".emtcode PARAM_PROGRAM_ELEMENTS 0x04\n"
+".emtcode PARAM_CONSTANT 0x05\n"
+".emtcode STATE_MATERIAL 0x01\n"
+".emtcode STATE_LIGHT 0x02\n"
+".emtcode STATE_LIGHT_MODEL 0x03\n"
+".emtcode STATE_LIGHT_PROD 0x04\n"
+".emtcode STATE_FOG 0x05\n"
+".emtcode STATE_MATRIX_ROWS 0x06\n"
+".emtcode STATE_TEX_ENV 0x07\n"
+".emtcode STATE_DEPTH 0x08\n"
+".emtcode STATE_TEX_GEN 0x09\n"
+".emtcode STATE_CLIP_PLANE 0x0A\n"
+".emtcode STATE_POINT 0x0B\n"
+".emtcode MATERIAL_AMBIENT 0x01\n"
+".emtcode MATERIAL_DIFFUSE 0x02\n"
+".emtcode MATERIAL_SPECULAR 0x03\n"
+".emtcode MATERIAL_EMISSION 0x04\n"
+".emtcode MATERIAL_SHININESS 0x05\n"
+".emtcode LIGHT_AMBIENT 0x01\n"
+".emtcode LIGHT_DIFFUSE 0x02\n"
+".emtcode LIGHT_SPECULAR 0x03\n"
+".emtcode LIGHT_POSITION 0x04\n"
+".emtcode LIGHT_ATTENUATION 0x05\n"
+".emtcode LIGHT_HALF 0x06\n"
+".emtcode LIGHT_SPOT_DIRECTION 0x07\n"
+".emtcode LIGHT_MODEL_AMBIENT 0x01\n"
+".emtcode LIGHT_MODEL_SCENECOLOR 0x02\n"
+".emtcode LIGHT_PROD_AMBIENT 0x01\n"
+".emtcode LIGHT_PROD_DIFFUSE 0x02\n"
+".emtcode LIGHT_PROD_SPECULAR 0x03\n"
+".emtcode TEX_ENV_COLOR 0x01\n"
+".emtcode TEX_GEN_EYE 0x01\n"
+".emtcode TEX_GEN_OBJECT 0x02\n"
+".emtcode FOG_COLOR 0x01\n"
+".emtcode FOG_PARAMS 0x02\n"
+".emtcode DEPTH_RANGE 0x01\n"
+".emtcode POINT_SIZE 0x01\n"
+".emtcode POINT_ATTENUATION 0x02\n"
+".emtcode ATTRIB 0x01\n"
+".emtcode PARAM 0x02\n"
+".emtcode TEMP 0x03\n"
+".emtcode OUTPUT 0x04\n"
+".emtcode ALIAS 0x05\n"
+".emtcode ADDRESS 0x06\n"
+".errtext UNKNOWN_PROGRAM_SIGNATURE \"1001: '$e_signature$': unknown program signature\"\n"
+".errtext MISSING_END_OR_INVALID_STATEMENT \"1002: '$e_statement$': invalid statement\"\n"
+".errtext CODE_AFTER_END \"1003: '$e_statement$': code after 'END' keyword\"\n"
+".errtext INVALID_PROGRAM_OPTION \"1004: '$e_identifier$': invalid program option\"\n"
+".errtext EXT_SWIZ_COMP_EXPECTED \"1005: extended swizzle component expected but '$e_token$' found\"\n"
+".errtext TEX_TARGET_EXPECTED \"1006: texture target expected but '$e_token$' found\"\n"
+".errtext TEXTURE_EXPECTED \"1007: 'texture' expected but '$e_identifier$' found\"\n"
+".errtext SOURCE_REGISTER_EXPECTED \"1008: source register expected but '$e_token$' found\"\n"
+".errtext DESTINATION_REGISTER_EXPECTED \"1009: destination register expected but '$e_token$' found\"\n"
+".errtext INVALID_ADDRESS_COMPONENT \"1010: '$e_identifier$': invalid address component\"\n"
+".errtext INVALID_ADDRESS_WRITEMASK \"1011: '$e_identifier$': invalid address writemask\"\n"
+".errtext INVALID_COMPONENT \"1012: '$e_charordigit$': invalid component\"\n"
+".errtext INVALID_SUFFIX \"1013: '$e_identifier$': invalid suffix\"\n"
+".errtext INVALID_WRITEMASK \"1014: '$e_identifier$': invalid writemask\"\n"
+".errtext FRAGMENT_EXPECTED \"1015: 'fragment' expected but '$e_identifier$' found\"\n"
+".errtext VERTEX_EXPECTED \"1016: 'vertex' expected but '$e_identifier$' found\"\n"
+".errtext INVALID_FRAGMENT_PROPERTY \"1017: '$e_identifier$': invalid fragment property\"\n"
+".errtext INVALID_VERTEX_PROPERTY \"1018: '$e_identifier$': invalid vertex property\"\n"
+".errtext INVALID_STATE_PROPERTY \"1019: '$e_identifier$': invalid state property\"\n"
+".errtext INVALID_MATERIAL_PROPERTY \"1020: '$e_identifier$': invalid material property\"\n"
+".errtext INVALID_LIGHT_PROPERTY \"1021: '$e_identifier$': invalid light property\"\n"
+".errtext INVALID_SPOT_PROPERTY \"1022: '$e_identifier$': invalid spot property\"\n"
+".errtext INVALID_LIGHTMODEL_PROPERTY \"1023: '$e_identifier$': invalid light model property\"\n"
+".errtext INVALID_LIGHTPROD_PROPERTY \"1024: '$e_identifier$': invalid light product property\"\n"
+".errtext INVALID_TEXENV_PROPERTY \"1025: '$e_identifier$': invalid texture environment property\"\n"
+".errtext INVALID_TEXGEN_PROPERTY \"1026: '$e_identifier$': invalid texture generating property\"\n"
+".errtext INVALID_TEXGEN_COORD \"1027: '$e_identifier$': invalid texture generating coord\"\n"
+".errtext INVALID_FOG_PROPERTY \"1028: '$e_identifier$': invalid fog property\"\n"
+".errtext INVALID_DEPTH_PROPERTY \"1029: '$e_identifier$': invalid depth property\"\n"
+".errtext INVALID_CLIPPLANE_PROPERTY \"1030: '$e_identifier$': invalid clip plane property\"\n"
+".errtext INVALID_POINT_PROPERTY \"1031: '$e_identifier$': invalid point property\"\n"
+".errtext MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED \"1032: matrix row selector or modifier expected but '$e_token$' found\"\n"
+".errtext INVALID_MATRIX_NAME \"1033: '$e_identifier$': invalid matrix name\"\n"
+".errtext INVALID_PROGRAM_PROPERTY \"1034: '$e_identifier$': invalid program property\"\n"
+".errtext RESULT_EXPECTED \"1035: 'result' expected but '$e_token$' found\"\n"
+".errtext INVALID_RESULT_PROPERTY \"1036: '$e_identifier$': invalid result property\"\n"
+".errtext INVALID_FACE_PROPERTY \"1037: '$e_identifier$': invalid face property\"\n"
+".errtext INVALID_COLOR_PROPERTY \"1038: '$e_identifier$': invalid color property\"\n"
+".errtext IDENTIFIER_EXPECTED \"1039: identifier expected but '$e_token$' found\"\n"
+".errtext RESERVED_KEYWORD \"1040: use of reserved keyword as an identifier\"\n"
+".errtext INTEGER_EXPECTED \"1041: integer value expected but '$e_token$' found\"\n"
+".errtext MISSING_SEMICOLON \"1042: ';' expected but '$e_token$' found\"\n"
+".errtext MISSING_COMMA \"1043: ',' expected but '$e_token$' found\"\n"
+".errtext MISSING_LBRACKET \"1044: '[' expected but '$e_token$' found\"\n"
+".errtext MISSING_RBRACKET \"1045: ']' expected but '$e_token$' found\"\n"
+".errtext MISSING_DOT \"1046: '.' expected but '$e_token$' found\"\n"
+".errtext MISSING_EQUAL \"1047: '=' expected but '$e_token$' found\"\n"
+".errtext MISSING_LBRACE \"1048: '{' expected but '$e_token$' found\"\n"
+".errtext MISSING_RBRACE \"1049: '}' expected but '$e_token$' found\"\n"
+".errtext MISSING_DOTDOT \"1050: '..' expected but '$e_token$' found\"\n"
+".errtext MISSING_FRACTION_OR_EXPONENT \"1051: missing fraction part or exponent\"\n"
+".errtext MISSING_DOT_OR_EXPONENT \"1052: missing '.' or exponent\"\n"
+".errtext EXPONENT_VALUE_EXPECTED \"1053: exponent value expected\"\n"
+".errtext INTEGER_OUT_OF_RANGE \"1054: integer value out of range\"\n"
+".errtext OPERATION_NEEDS_DESTINATION_VARIABLE \"1055: operation needs destination variable\"\n"
+".errtext OPERATION_NEEDS_SOURCE_VARIABLE \"1056: operation needs source variable\"\n"
+".errtext ADDRESS_REGISTER_EXPECTED \"1057: address register expected but '$e_token$' found\"\n"
+".errtext ADDRESS_REGISTER_OR_INTEGER_EXPECTED \"1058: address register or integer literal expected but '$e_token$' found\"\n"
+".regbyte vertex_blend 0x00\n"
+".regbyte matrix_palette 0x00\n"
+".regbyte point_parameters 0x00\n"
+".regbyte secondary_color 0x00\n"
+".regbyte fog_coord 0x00\n"
+".regbyte texture_rectangle 0x00\n"
+".regbyte fragment_program_shadow 0x00\n"
+".regbyte ARB_precision_hint_fastest 0x00\n"
+".regbyte ARB_precision_hint_nicest 0x00\n"
+".regbyte ARB_fog_exp 0x00\n"
+".regbyte ARB_fog_exp2 0x00\n"
+".regbyte ARB_fog_linear 0x00\n"
+".regbyte ARB_position_invariant 0x00\n"
+".regbyte ARB_fragment_program_shadow 0x00\n"
+".regbyte program_target 0x00\n"
+"program\n"
+" programs .error UNKNOWN_PROGRAM_SIGNATURE .emit REVISION;\n"
+"programs\n"
+" .if (program_target == 0x10) frag_program_1_0 .emit FRAGMENT_PROGRAM .emit 0x01 .emit 0x00 .or\n"
+" .if (program_target == 0x20) vert_program_1_0 .emit VERTEX_PROGRAM .emit 0x01 .emit 0x00;\n"
+"frag_program_1_0\n"
+" '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'f' .and 'p' .and '1' .and '.' .and '0' .and\n"
+" optional_space .and fp_optionSequence .and fp_statementSequence .and\n"
+" \"END\" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and\n"
+" '\\0' .error CODE_AFTER_END;\n"
+"vert_program_1_0\n"
+" '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'v' .and 'p' .and '1' .and '.' .and '0' .and\n"
+" optional_space .and vp_optionSequence .and vp_statementSequence .and\n"
+" \"END\" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and\n"
+" '\\0' .error CODE_AFTER_END;\n"
+"fp_optionSequence\n"
+" .loop fp_option;\n"
+"vp_optionSequence\n"
+" .loop vp_option;\n"
+"fp_option\n"
+" \"OPTION\" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and\n"
+" fp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;\n"
+"vp_option\n"
+" \"OPTION\" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and\n"
+" vp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;\n"
+"fp_optionString\n"
+" .if (ARB_precision_hint_nicest == 0x00) \"ARB_precision_hint_fastest\"\n"
+" .emit ARB_PRECISION_HINT_FASTEST .load ARB_precision_hint_fastest 0x01 .or\n"
+" .if (ARB_precision_hint_fastest == 0x00) \"ARB_precision_hint_nicest\"\n"
+" .emit ARB_PRECISION_HINT_NICEST .load ARB_precision_hint_nicest 0x01 .or\n"
+" fp_ARB_fog_exp .emit ARB_FOG_EXP .load ARB_fog_exp 0x01 .or\n"
+" fp_ARB_fog_exp2 .emit ARB_FOG_EXP2 .load ARB_fog_exp2 0x01 .or\n"
+" fp_ARB_fog_linear .emit ARB_FOG_LINEAR .load ARB_fog_linear 0x01 .or\n"
+" .if (fragment_program_shadow != 0x00) \"ARB_fragment_program_shadow\"\n"
+" .emit ARB_FRAGMENT_PROGRAM_SHADOW .load ARB_fragment_program_shadow 0x01;\n"
+"vp_optionString\n"
+" \"ARB_position_invariant\" .emit ARB_POSITION_INVARIANT .load ARB_position_invariant 0x01;\n"
+"fp_ARB_fog_exp\n"
+" .if (ARB_fog_exp2 == 0x00) .true .and .if (ARB_fog_linear == 0x00) \"ARB_fog_exp\";\n"
+"fp_ARB_fog_exp2\n"
+" .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_linear == 0x00) \"ARB_fog_exp2\";\n"
+"fp_ARB_fog_linear\n"
+" .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_exp2 == 0x00) \"ARB_fog_linear\";\n"
+"fp_statementSequence\n"
+" .loop fp_statement;\n"
+"vp_statementSequence\n"
+" .loop vp_statement;\n"
+"fp_statement\n"
+" fp_statement_1 .or fp_statement_2;\n"
+"vp_statement\n"
+" vp_statement_1 .or vp_statement_2;\n"
+"fp_statement_1\n"
+" fp_instruction .emit INSTRUCTION .emit $ .and semicolon;\n"
+"fp_statement_2\n"
+" fp_namingStatement .emit DECLARATION .and semicolon;\n"
+"vp_statement_1\n"
+" vp_instruction .emit INSTRUCTION .emit $ .and semicolon;\n"
+"vp_statement_2\n"
+" vp_namingStatement .emit DECLARATION .and semicolon;\n"
+"fp_instruction\n"
+" ALUInstruction .emit OP_ALU_INST .or\n"
+" TexInstruction .emit OP_TEX_INST;\n"
+"vp_instruction\n"
+" ARL_instruction .emit OP_ALU_ARL .or\n"
+" vp_VECTORop_instruction .emit OP_ALU_VECTOR .or\n"
+" vp_SCALARop_instruction .emit OP_ALU_SCALAR .or\n"
+" vp_BINSCop_instruction .emit OP_ALU_BINSC .or\n"
+" vp_BINop_instruction .emit OP_ALU_BIN .or\n"
+" vp_TRIop_instruction .emit OP_ALU_TRI .or\n"
+" vp_SWZ_instruction .emit OP_ALU_SWZ;\n"
+"ALUInstruction\n"
+" fp_VECTORop_instruction .emit OP_ALU_VECTOR .or\n"
+" fp_SCALARop_instruction .emit OP_ALU_SCALAR .or\n"
+" fp_BINSCop_instruction .emit OP_ALU_BINSC .or\n"
+" fp_BINop_instruction .emit OP_ALU_BIN .or\n"
+" fp_TRIop_instruction .emit OP_ALU_TRI .or\n"
+" fp_SWZ_instruction .emit OP_ALU_SWZ;\n"
+"TexInstruction\n"
+" SAMPLE_instruction .emit OP_TEX_SAMPLE .or\n"
+" KIL_instruction .emit OP_TEX_KIL;\n"
+"ARL_instruction\n"
+" \"ARL\" .emit OP_ARL .and space_dst .and maskedAddrReg .and comma .and vp_scalarSrcReg;\n"
+"fp_VECTORop_instruction\n"
+" fp_VECTORop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg;\n"
+"vp_VECTORop_instruction\n"
+" vp_VECTORop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg;\n"
+"fp_VECTORop\n"
+" \"ABS\" .emit OP_ABS .or \"ABS_SAT\" .emit OP_ABS_SAT .or\n"
+" \"FLR\" .emit OP_FLR .or \"FLR_SAT\" .emit OP_FLR_SAT .or\n"
+" \"FRC\" .emit OP_FRC .or \"FRC_SAT\" .emit OP_FRC_SAT .or\n"
+" \"LIT\" .emit OP_LIT .or \"LIT_SAT\" .emit OP_LIT_SAT .or\n"
+" \"MOV\" .emit OP_MOV .or \"MOV_SAT\" .emit OP_MOV_SAT;\n"
+"vp_VECTORop\n"
+" \"ABS\" .emit OP_ABS .or\n"
+" \"FLR\" .emit OP_FLR .or\n"
+" \"FRC\" .emit OP_FRC .or\n"
+" \"LIT\" .emit OP_LIT .or\n"
+" \"MOV\" .emit OP_MOV;\n"
+"fp_SCALARop_instruction\n"
+" fp_SCALARop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg;\n"
+"vp_SCALARop_instruction\n"
+" vp_SCALARop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg;\n"
+"fp_SCALARop\n"
+" \"COS\" .emit OP_COS .or \"COS_SAT\" .emit OP_COS_SAT .or\n"
+" \"EX2\" .emit OP_EX2 .or \"EX2_SAT\" .emit OP_EX2_SAT .or\n"
+" \"LG2\" .emit OP_LG2 .or \"LG2_SAT\" .emit OP_LG2_SAT .or\n"
+" \"RCP\" .emit OP_RCP .or \"RCP_SAT\" .emit OP_RCP_SAT .or\n"
+" \"RSQ\" .emit OP_RSQ .or \"RSQ_SAT\" .emit OP_RSQ_SAT .or\n"
+" \"SIN\" .emit OP_SIN .or \"SIN_SAT\" .emit OP_SIN_SAT .or\n"
+" \"SCS\" .emit OP_SCS .or \"SCS_SAT\" .emit OP_SCS_SAT;\n"
+"vp_SCALARop\n"
+" \"EX2\" .emit OP_EX2 .or\n"
+" \"EXP\" .emit OP_EXP .or\n"
+" \"LG2\" .emit OP_LG2 .or\n"
+" \"LOG\" .emit OP_LOG .or\n"
+" \"RCP\" .emit OP_RCP .or\n"
+" \"RSQ\" .emit OP_RSQ;\n"
+"fp_BINSCop_instruction\n"
+" fp_BINSCop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg .and comma .and\n"
+" fp_scalarSrcReg;\n"
+"vp_BINSCop_instruction\n"
+" vp_BINSCop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg .and comma .and\n"
+" vp_scalarSrcReg;\n"
+"fp_BINSCop\n"
+" \"POW\" .emit OP_POW .or \"POW_SAT\" .emit OP_POW_SAT;\n"
+"vp_BINSCop\n"
+" \"POW\" .emit OP_POW;\n"
+"fp_BINop_instruction\n"
+" fp_BINop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n"
+" vectorSrcReg;\n"
+"vp_BINop_instruction\n"
+" vp_BINop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and\n"
+" swizzleSrcReg;\n"
+"fp_BINop\n"
+" \"ADD\" .emit OP_ADD .or \"ADD_SAT\" .emit OP_ADD_SAT .or\n"
+" \"DP3\" .emit OP_DP3 .or \"DP3_SAT\" .emit OP_DP3_SAT .or\n"
+" \"DP4\" .emit OP_DP4 .or \"DP4_SAT\" .emit OP_DP4_SAT .or\n"
+" \"DPH\" .emit OP_DPH .or \"DPH_SAT\" .emit OP_DPH_SAT .or\n"
+" \"DST\" .emit OP_DST .or \"DST_SAT\" .emit OP_DST_SAT .or\n"
+" \"MAX\" .emit OP_MAX .or \"MAX_SAT\" .emit OP_MAX_SAT .or\n"
+" \"MIN\" .emit OP_MIN .or \"MIN_SAT\" .emit OP_MIN_SAT .or\n"
+" \"MUL\" .emit OP_MUL .or \"MUL_SAT\" .emit OP_MUL_SAT .or\n"
+" \"SGE\" .emit OP_SGE .or \"SGE_SAT\" .emit OP_SGE_SAT .or\n"
+" \"SLT\" .emit OP_SLT .or \"SLT_SAT\" .emit OP_SLT_SAT .or\n"
+" \"SUB\" .emit OP_SUB .or \"SUB_SAT\" .emit OP_SUB_SAT .or\n"
+" \"XPD\" .emit OP_XPD .or \"XPD_SAT\" .emit OP_XPD_SAT;\n"
+"vp_BINop\n"
+" \"ADD\" .emit OP_ADD .or\n"
+" \"DP3\" .emit OP_DP3 .or\n"
+" \"DP4\" .emit OP_DP4 .or\n"
+" \"DPH\" .emit OP_DPH .or\n"
+" \"DST\" .emit OP_DST .or\n"
+" \"MAX\" .emit OP_MAX .or\n"
+" \"MIN\" .emit OP_MIN .or\n"
+" \"MUL\" .emit OP_MUL .or\n"
+" \"SGE\" .emit OP_SGE .or\n"
+" \"SLT\" .emit OP_SLT .or\n"
+" \"SUB\" .emit OP_SUB .or\n"
+" \"XPD\" .emit OP_XPD;\n"
+"fp_TRIop_instruction\n"
+" fp_TRIop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n"
+" vectorSrcReg .and comma .and vectorSrcReg;\n"
+"vp_TRIop_instruction\n"
+" vp_TRIop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and\n"
+" swizzleSrcReg .and comma .and swizzleSrcReg;\n"
+"fp_TRIop\n"
+" \"CMP\" .emit OP_CMP .or \"CMP_SAT\" .emit OP_CMP_SAT .or\n"
+" \"LRP\" .emit OP_LRP .or \"LRP_SAT\" .emit OP_LRP_SAT .or\n"
+" \"MAD\" .emit OP_MAD .or \"MAD_SAT\" .emit OP_MAD_SAT;\n"
+"vp_TRIop\n"
+" \"MAD\" .emit OP_MAD;\n"
+"fp_SWZ_instruction\n"
+" SWZop .and space_dst .and fp_maskedDstReg .and comma .and fp_srcReg .and comma .and\n"
+" fp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;\n"
+"vp_SWZ_instruction\n"
+" \"SWZ\" .emit OP_SWZ .and space_dst .and vp_maskedDstReg .and comma .and vp_srcReg .and comma .and\n"
+" vp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;\n"
+"SWZop\n"
+" \"SWZ\" .emit OP_SWZ .or \"SWZ_SAT\" .emit OP_SWZ_SAT;\n"
+"SAMPLE_instruction\n"
+" SAMPLEop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n"
+" texImageUnit .and comma .and texTarget .error TEX_TARGET_EXPECTED;\n"
+"SAMPLEop\n"
+" \"TEX\" .emit OP_TEX .or \"TEX_SAT\" .emit OP_TEX_SAT .or\n"
+" \"TXB\" .emit OP_TXB .or \"TXB_SAT\" .emit OP_TXB_SAT .or\n"
+" \"TXP\" .emit OP_TXP .or \"TXP_SAT\" .emit OP_TXP_SAT;\n"
+"KIL_instruction\n"
+" \"KIL\" .emit OP_KIL .and space_src .and vectorSrcReg;\n"
+"texImageUnit\n"
+" \"texture\" .error TEXTURE_EXPECTED .and optTexImageUnitNum;\n"
+"texTarget\n"
+" \"1D\" .emit TEXTARGET_1D .or\n"
+" \"2D\" .emit TEXTARGET_2D .or\n"
+" \"3D\" .emit TEXTARGET_3D .or\n"
+" .if (texture_rectangle != 0x00) \"RECT\" .emit TEXTARGET_RECT .or\n"
+" \"CUBE\" .emit TEXTARGET_CUBE .or\n"
+" .if (ARB_fragment_program_shadow != 0x00) shadowTarget;\n"
+"shadowTarget\n"
+" \"SHADOW1D\" .emit TEXTARGET_SHADOW1D .or\n"
+" \"SHADOW2D\" .emit TEXTARGET_SHADOW2D .or\n"
+" .if (texture_rectangle != 0x00) \"SHADOWRECT\" .emit TEXTARGET_SHADOWRECT;\n"
+"optTexImageUnitNum\n"
+" optTexImageUnitNum_1 .or .true .emit 0x00;\n"
+"optTexImageUnitNum_1\n"
+" lbracket_ne .and texImageUnitNum .and rbracket;\n"
+"texImageUnitNum\n"
+" integer;\n"
+"fp_scalarSrcReg\n"
+" optionalSign .and fp_srcReg .and fp_scalarSuffix;\n"
+"vp_scalarSrcReg\n"
+" optionalSign .and vp_srcReg .and vp_scalarSuffix;\n"
+"swizzleSrcReg\n"
+" optionalSign .and vp_srcReg .and swizzleSuffix;\n"
+"vectorSrcReg\n"
+" optionalSign .and fp_srcReg .and optionalSuffix;\n"
+"fp_maskedDstReg\n"
+" fp_dstReg .and fp_optionalMask;\n"
+"vp_maskedDstReg\n"
+" vp_dstReg .and vp_optionalMask;\n"
+"maskedAddrReg\n"
+" addrReg .error ADDRESS_REGISTER_EXPECTED .and addrWriteMask;\n"
+"fp_extendedSwizzle\n"
+" rgbaExtendedSwizzle .or xyzwExtendedSwizzle;\n"
+"vp_extendedSwizzle\n"
+" extSwizComp .and comma .and\n"
+" extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
+" extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
+" extSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"
+"xyzwExtendedSwizzle\n"
+" xyzwExtSwizComp .and comma .and\n"
+" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
+" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
+" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"
+"rgbaExtendedSwizzle\n"
+" rgbaExtendedSwizzle_1 .or rgbaExtendedSwizzle_2 .or rgbaExtendedSwizzle_3 .or\n"
+" rgbaExtendedSwizzle_4;\n"
+"rgbaExtendedSwizzle_1\n"
+" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and\n"
+" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp;\n"
+"rgbaExtendedSwizzle_2\n"
+" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and\n"
+" rgbaExtSwizComp_alpha .and comma .and rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"
+"rgbaExtendedSwizzle_3\n"
+" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_alpha .and comma .and\n"
+" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
+" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"
+"rgbaExtendedSwizzle_4\n"
+" rgbaExtSwizComp_alpha .and comma .and \n"
+"rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
+" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
+" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"
+"xyzwExtSwizComp\n"
+" optionalSign .and xyzwExtSwizSel;\n"
+"rgbaExtSwizComp\n"
+" optionalSign .and rgbaExtSwizSel;\n"
+"rgbaExtSwizComp_digit\n"
+" optionalSign .and rgbaExtSwizSel_digit;\n"
+"rgbaExtSwizComp_alpha\n"
+" optionalSign .and rgbaExtSwizSel_alpha;\n"
+"extSwizComp\n"
+" optionalSign .and extSwizSel;\n"
+"xyzwExtSwizSel\n"
+" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1 .or xyzwComponent_single;\n"
+"rgbaExtSwizSel\n"
+" rgbaExtSwizSel_digit .or rgbaExtSwizSel_alpha;\n"
+"rgbaExtSwizSel_digit\n"
+" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1;\n"
+"rgbaExtSwizSel_alpha\n"
+" rgbaComponent_single;\n"
+"extSwizSel\n"
+" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1 .or vp_component_single;\n"
+"fp_srcReg\n"
+" fp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;\n"
+"vp_srcReg\n"
+" vp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;\n"
+"fp_srcReg_1\n"
+" fragmentAttribReg .emit REGISTER_ATTRIB .or\n"
+" fp_progParamReg .emit REGISTER_PARAM .or\n"
+" fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n"
+"vp_srcReg_1\n"
+" vertexAttribReg .emit REGISTER_ATTRIB .or\n"
+" vp_progParamReg .emit REGISTER_PARAM .or\n"
+" vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n"
+"fp_dstReg\n"
+" fp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;\n"
+"vp_dstReg\n"
+" vp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;\n"
+"fp_dstReg_1\n"
+" fragmentResultReg .emit REGISTER_RESULT .or\n"
+" fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n"
+"vp_dstReg_1\n"
+" vertexResultReg .emit REGISTER_RESULT .or\n"
+" vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n"
+"fragmentAttribReg\n"
+" fragAttribBinding;\n"
+"vertexAttribReg\n"
+" vtxAttribBinding;\n"
+"fp_temporaryReg\n"
+" fp_establishedName_no_error_on_identifier;\n"
+"vp_temporaryReg\n"
+" vp_establishedName_no_error_on_identifier;\n"
+"fp_progParamReg\n"
+" fp_paramSingleItemUse .or fp_progParamReg_1 .or fp_progParamSingle;\n"
+"vp_progParamReg\n"
+" vp_paramSingleItemUse .or vp_progParamReg_1 .or vp_progParamSingle;\n"
+"fp_progParamReg_1\n"
+" fp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayAbs .and\n"
+" rbracket;\n"
+"vp_progParamReg_1\n"
+" vp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayMem .and\n"
+" rbracket;\n"
+"fp_progParamSingle\n"
+" .false;\n"
+"vp_progParamSingle\n"
+" .false;\n"
+"fp_progParamArray\n"
+" fp_establishedName_no_error_on_identifier;\n"
+"vp_progParamArray\n"
+" vp_establishedName_no_error_on_identifier;\n"
+"progParamArrayMem\n"
+" progParamArrayAbs .or progParamArrayRel;\n"
+"progParamArrayAbs\n"
+" integer_ne .emit ARRAY_INDEX_ABSOLUTE;\n"
+"progParamArrayRel\n"
+" addrReg .error ADDRESS_REGISTER_OR_INTEGER_EXPECTED .emit ARRAY_INDEX_RELATIVE .and\n"
+" addrComponent .and addrRegRelOffset;\n"
+"addrRegRelOffset\n"
+" addrRegRelOffset_1 .or addrRegRelOffset_2 .or .true .emit 0x00;\n"
+"addrRegRelOffset_1\n"
+" plus_ne .and addrRegPosOffset;\n"
+"addrRegRelOffset_2\n"
+" minus_ne .and addrRegNegOffset;\n"
+"addrRegPosOffset\n"
+" integer_0_63;\n"
+"addrRegNegOffset\n"
+" integer_0_64;\n"
+"fragmentResultReg\n"
+" fp_resultBinding;\n"
+"vertexResultReg\n"
+" vp_resultBinding;\n"
+"addrReg\n"
+" vp_establishedName_no_error_on_identifier;\n"
+"addrComponent\n"
+" dot .and \"x\" .error INVALID_ADDRESS_COMPONENT .emit COMPONENT_X .emit COMPONENT_X\n"
+" .emit COMPONENT_X .emit COMPONENT_X;\n"
+"addrWriteMask\n"
+" dot .and \"x\" .error INVALID_ADDRESS_WRITEMASK .emit 0x08;\n"
+"fp_scalarSuffix\n"
+" dot .and fp_component_single .error INVALID_COMPONENT;\n"
+"vp_scalarSuffix\n"
+" dot .and vp_component_single .error INVALID_COMPONENT;\n"
+"swizzleSuffix\n"
+" swizzleSuffix_1 .or\n"
+" .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;\n"
+"swizzleSuffix_1\n"
+" dot_ne .and swizzleSuffix_2 .error INVALID_SUFFIX;\n"
+"swizzleSuffix_2\n"
+" swizzleSuffix_3 .or swizzleSuffix_4;\n"
+"swizzleSuffix_3\n"
+" vp_component_multi .and vp_component_multi .and vp_component_multi .error INVALID_COMPONENT .and\n"
+" vp_component_multi .error INVALID_COMPONENT;\n"
+"swizzleSuffix_4\n"
+" \"x\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n"
+" \"y\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n"
+" \"z\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n"
+" \"w\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;\n"
+"optionalSuffix\n"
+" optionalSuffix_1 .or\n"
+" .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;\n"
+"optionalSuffix_1\n"
+" dot_ne .and optionalSuffix_2 .error INVALID_SUFFIX;\n"
+"optionalSuffix_2\n"
+" optionalSuffix_3 .or optionalSuffix_4 .or optionalSuffix_5;\n"
+"optionalSuffix_3\n"
+" xyzwComponent_multi .and xyzwComponent_multi .and\n"
+" xyzwComponent_multi .error INVALID_COMPONENT .and xyzwComponent_multi .error INVALID_COMPONENT;\n"
+"optionalSuffix_4\n"
+" rgbaComponent_multi .and rgbaComponent_multi .and\n"
+" rgbaComponent_multi .error INVALID_COMPONENT .and rgbaComponent_multi .error INVALID_COMPONENT;\n"
+"optionalSuffix_5\n"
+" \"x\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n"
+" \"y\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n"
+" \"z\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n"
+" \"w\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .or\n"
+" \"r\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n"
+" \"g\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n"
+" \"b\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n"
+" \"a\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;\n"
+"fp_component_single\n"
+" xyzwComponent_single .or rgbaComponent_single;\n"
+"vp_component_multi\n"
+" 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or\n"
+" 'w' .emit COMPONENT_W;\n"
+"vp_component_single\n"
+" \"x\" .emit COMPONENT_X .or \"y\" .emit COMPONENT_Y .or \"z\" .emit COMPONENT_Z .or\n"
+" \"w\" .emit COMPONENT_W;\n"
+"xyzwComponent_multi\n"
+" 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or\n"
+" 'w' .emit COMPONENT_W;\n"
+"xyzwComponent_single\n"
+" \"x\" .emit COMPONENT_X .or \"y\" .emit COMPONENT_Y .or \"z\" .emit COMPONENT_Z .or\n"
+" \"w\" .emit COMPONENT_W;\n"
+"rgbaComponent_multi\n"
+" 'r' .emit COMPONENT_X .or 'g' .emit COMPONENT_Y .or 'b' .emit COMPONENT_Z .or\n"
+" 'a' .emit COMPONENT_W;\n"
+"rgbaComponent_single\n"
+" \"r\" .emit COMPONENT_X .or \"g\" .emit COMPONENT_Y .or \"b\" .emit COMPONENT_Z .or\n"
+" \"a\" .emit COMPONENT_W;\n"
+"fp_optionalMask\n"
+" rgbaMask .or xyzwMask .or .true .emit 0x0F;\n"
+"vp_optionalMask\n"
+" xyzwMask .or .true .emit 0x0F;\n"
+"xyzwMask\n"
+" dot_ne .and xyzwMask_1 .error INVALID_WRITEMASK;\n"
+"xyzwMask_1\n"
+" \"xyzw\" .emit 0x0F .or \"xyz\" .emit 0x0E .or \"xyw\" .emit 0x0D .or \"xy\" .emit 0x0C .or\n"
+" \"xzw\" .emit 0x0B .or \"xz\" .emit 0x0A .or \"xw\" .emit 0x09 .or \"x\" .emit 0x08 .or\n"
+" \"yzw\" .emit 0x07 .or \"yz\" .emit 0x06 .or \"yw\" .emit 0x05 .or \"y\" .emit 0x04 .or\n"
+" \"zw\" .emit 0x03 .or \"z\" .emit 0x02 .or \"w\" .emit 0x01;\n"
+"rgbaMask\n"
+" dot_ne .and rgbaMask_1;\n"
+"rgbaMask_1\n"
+" \"rgba\" .emit 0x0F .or \"rgb\" .emit 0x0E .or \"rga\" .emit 0x0D .or \"rg\" .emit 0x0C .or\n"
+" \"rba\" .emit 0x0B .or \"rb\" .emit 0x0A .or \"ra\" .emit 0x09 .or \"r\" .emit 0x08 .or\n"
+" \"gba\" .emit 0x07 .or \"gb\" .emit 0x06 .or \"ga\" .emit 0x05 .or \"g\" .emit 0x04 .or\n"
+" \"ba\" .emit 0x03 .or \"b\" .emit 0x02 .or \"a\" .emit 0x01;\n"
+"fp_namingStatement\n"
+" fp_ATTRIB_statement .emit ATTRIB .or\n"
+" fp_PARAM_statement .emit PARAM .or\n"
+" fp_TEMP_statement .emit TEMP .or\n"
+" fp_OUTPUT_statement .emit OUTPUT .or\n"
+" fp_ALIAS_statement .emit ALIAS;\n"
+"vp_namingStatement\n"
+" vp_ATTRIB_statement .emit ATTRIB .or\n"
+" vp_PARAM_statement .emit PARAM .or\n"
+" vp_TEMP_statement .emit TEMP .or\n"
+" ADDRESS_statement .emit ADDRESS .or\n"
+" vp_OUTPUT_statement .emit OUTPUT .or\n"
+" vp_ALIAS_statement .emit ALIAS;\n"
+"fp_ATTRIB_statement\n"
+" \"ATTRIB\" .and space .and fp_establishName .and equal .and\n"
+" fragAttribBinding .error FRAGMENT_EXPECTED;\n"
+"vp_ATTRIB_statement\n"
+" \"ATTRIB\" .and space .and vp_establishName .and equal .and\n"
+" vtxAttribBinding .error VERTEX_EXPECTED;\n"
+"fragAttribBinding\n"
+" \"fragment\" .and dot .and fragAttribItem .error INVALID_FRAGMENT_PROPERTY;\n"
+"vtxAttribBinding\n"
+" \"vertex\" .and dot .and vtxAttribItem .error INVALID_VERTEX_PROPERTY;\n"
+"fragAttribItem\n"
+" fragAttribItem_1 .emit FRAGMENT_ATTRIB_COLOR .or\n"
+" fragAttribItem_2 .emit FRAGMENT_ATTRIB_TEXCOORD .or\n"
+" .if (fog_coord != 0x00) \"fogcoord\" .emit FRAGMENT_ATTRIB_FOGCOORD .or\n"
+" \"position\" .emit FRAGMENT_ATTRIB_POSITION;\n"
+"fragAttribItem_1\n"
+" \"color\" .and optColorType;\n"
+"fragAttribItem_2\n"
+" \"texcoord\" .and optTexCoordNum;\n"
+"vtxAttribItem\n"
+" \"position\" .emit VERTEX_ATTRIB_POSITION .or\n"
+" .if (vertex_blend != 0x00) vtxAttribItem_1 .emit VERTEX_ATTRIB_WEIGHT .or\n"
+" \"normal\" .emit VERTEX_ATTRIB_NORMAL .or\n"
+" vtxAttribItem_2 .emit VERTEX_ATTRIB_COLOR .or\n"
+" \"fogcoord\" .emit VERTEX_ATTRIB_FOGCOORD .or\n"
+" vtxAttribItem_3 .emit VERTEX_ATTRIB_TEXCOORD .or\n"
+" .if (matrix_palette != 0x00) vtxAttribItem_4 .emit VERTEX_ATTRIB_MATRIXINDEX .or\n"
+" vtxAttribItem_5 .emit VERTEX_ATTRIB_GENERIC;\n"
+"vtxAttribItem_1\n"
+" \"weight\" .and vtxOptWeightNum;\n"
+"vtxAttribItem_2\n"
+" \"color\" .and optColorType;\n"
+"vtxAttribItem_3\n"
+" \"texcoord\" .and optTexCoordNum;\n"
+"vtxAttribItem_4\n"
+" \"matrixindex\" .and lbracket .and vtxWeightNum .and rbracket;\n"
+"vtxAttribItem_5\n"
+" \"attrib\" .and lbracket .and vtxAttribNum .and rbracket;\n"
+"vtxAttribNum\n"
+" integer;\n"
+"vtxOptWeightNum\n"
+" vtxOptWeightNum_1 .or .true .emit 0x00;\n"
+"vtxOptWeightNum_1\n"
+" lbracket_ne .and vtxWeightNum .and rbracket;\n"
+"vtxWeightNum\n"
+" integer;\n"
+"fp_PARAM_statement\n"
+" fp_PARAM_multipleStmt .or fp_PARAM_singleStmt;\n"
+"vp_PARAM_statement\n"
+" vp_PARAM_multipleStmt .or vp_PARAM_singleStmt;\n"
+"fp_PARAM_singleStmt\n"
+" \"PARAM\" .and space .and fp_establishName .and .true .emit 0x00 .and fp_paramSingleInit .and\n"
+" .true .emit PARAM_NULL;\n"
+"vp_PARAM_singleStmt\n"
+" \"PARAM\" .and space .and vp_establishName .and .true .emit 0x00 .and vp_paramSingleInit .and\n"
+" .true .emit PARAM_NULL;\n"
+"fp_PARAM_multipleStmt\n"
+" \"PARAM\" .and space .and fp_establishName .and lbracket_ne .and optArraySize .and rbracket .and\n"
+" fp_paramMultipleInit .and .true .emit PARAM_NULL;\n"
+"vp_PARAM_multipleStmt\n"
+" \"PARAM\" .and space .and vp_establishName .and lbracket_ne .and optArraySize .and rbracket .and\n"
+" vp_paramMultipleInit .and .true .emit PARAM_NULL;\n"
+"optArraySize\n"
+" optional_integer;\n"
+"fp_paramSingleInit\n"
+" equal .and fp_paramSingleItemDecl;\n"
+"vp_paramSingleInit\n"
+" equal .and vp_paramSingleItemDecl;\n"
+"fp_paramMultipleInit\n"
+" equal .and lbrace .and fp_paramMultInitList .and rbrace;\n"
+"vp_paramMultipleInit\n"
+" equal .and lbrace .and vp_paramMultInitList .and rbrace;\n"
+"fp_paramMultInitList\n"
+" fp_paramMultInitList_1 .or fp_paramMultipleItem;\n"
+"vp_paramMultInitList\n"
+" vp_paramMultInitList_1 .or vp_paramMultipleItem;\n"
+"fp_paramMultInitList_1\n"
+" fp_paramMultipleItem .and comma_ne .and fp_paramMultInitList;\n"
+"vp_paramMultInitList_1\n"
+" vp_paramMultipleItem .and comma_ne .and vp_paramMultInitList;\n"
+"fp_paramSingleItemDecl\n"
+" fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n"
+" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n"
+" paramConstDecl .emit PARAM_CONSTANT;\n"
+"vp_paramSingleItemDecl\n"
+" vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n"
+" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n"
+" paramConstDecl .emit PARAM_CONSTANT;\n"
+"fp_paramSingleItemUse\n"
+" fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n"
+" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n"
+" paramConstUse .emit PARAM_CONSTANT;\n"
+"vp_paramSingleItemUse\n"
+" vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n"
+" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n"
+" paramConstUse .emit PARAM_CONSTANT;\n"
+"fp_paramMultipleItem\n"
+" fp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or\n"
+" programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or\n"
+" paramConstDecl .emit PARAM_CONSTANT;\n"
+"vp_paramMultipleItem\n"
+" vp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or\n"
+" programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or\n"
+" paramConstDecl .emit PARAM_CONSTANT;\n"
+"fp_stateMultipleItem\n"
+" stateMultipleItem_1 .or fp_stateSingleItem;\n"
+"vp_stateMultipleItem\n"
+" stateMultipleItem_1 .or vp_stateSingleItem;\n"
+"stateMultipleItem_1\n"
+" \"state\" .and dot .and stateMatrixRows .emit STATE_MATRIX_ROWS;\n"
+"fp_stateSingleItem\n"
+" \"state\" .and dot .and fp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;\n"
+"vp_stateSingleItem\n"
+" \"state\" .and dot .and vp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;\n"
+"fp_stateSingleItem_1\n"
+" stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or\n"
+" stateSingleItem_5 .or stateSingleItem_7 .or stateSingleItem_8 .or stateSingleItem_11;\n"
+"vp_stateSingleItem_1\n"
+" stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or\n"
+" stateSingleItem_6 .or stateSingleItem_7 .or stateSingleItem_9 .or stateSingleItem_10 .or\n"
+" stateSingleItem_11;\n"
+"stateSingleItem_1\n"
+" stateMaterialItem .emit STATE_MATERIAL;\n"
+"stateSingleItem_2\n"
+" stateLightItem .emit STATE_LIGHT;\n"
+"stateSingleItem_3\n"
+" stateLightModelItem .emit STATE_LIGHT_MODEL;\n"
+"stateSingleItem_4\n"
+" stateLightProdItem .emit STATE_LIGHT_PROD;\n"
+"stateSingleItem_5\n"
+" stateTexEnvItem .emit STATE_TEX_ENV;\n"
+"stateSingleItem_6\n"
+" stateTexGenItem .emit STATE_TEX_GEN;\n"
+"stateSingleItem_7\n"
+" stateFogItem .emit STATE_FOG;\n"
+"stateSingleItem_8\n"
+" stateDepthItem .emit STATE_DEPTH;\n"
+"stateSingleItem_9\n"
+" stateClipPlaneItem .emit STATE_CLIP_PLANE;\n"
+"stateSingleItem_10\n"
+" statePointItem .emit STATE_POINT;\n"
+"stateSingleItem_11\n"
+" stateMatrixRow .emit STATE_MATRIX_ROWS;\n"
+"stateMaterialItem\n"
+" \"material\" .and optFaceType .and dot .and stateMatProperty .error INVALID_MATERIAL_PROPERTY;\n"
+"stateMatProperty\n"
+" \"ambient\" .emit MATERIAL_AMBIENT .or\n"
+" \"diffuse\" .emit MATERIAL_DIFFUSE .or\n"
+" \"specular\" .emit MATERIAL_SPECULAR .or\n"
+" \"emission\" .emit MATERIAL_EMISSION .or\n"
+" \"shininess\" .emit MATERIAL_SHININESS;\n"
+"stateLightItem\n"
+" \"light\" .and lbracket .and stateLightNumber .and rbracket .and dot .and\n"
+" stateLightProperty .error INVALID_LIGHT_PROPERTY;\n"
+"stateLightProperty\n"
+" \"ambient\" .emit LIGHT_AMBIENT .or\n"
+" \"diffuse\" .emit LIGHT_DIFFUSE .or\n"
+" \"specular\" .emit LIGHT_SPECULAR .or\n"
+" \"position\" .emit LIGHT_POSITION .or\n"
+" \"attenuation\" .emit LIGHT_ATTENUATION .or\n"
+" stateLightProperty_1 .emit LIGHT_SPOT_DIRECTION .or\n"
+" \"half\" .emit LIGHT_HALF;\n"
+"stateLightProperty_1\n"
+" \"spot\" .and dot .and stateSpotProperty .error INVALID_SPOT_PROPERTY;\n"
+"stateSpotProperty\n"
+" \"direction\";\n"
+"stateLightModelItem\n"
+" \"lightmodel\" .and stateLModProperty .error INVALID_LIGHTMODEL_PROPERTY;\n"
+"stateLModProperty\n"
+" stateLModProperty_1 .or stateLModProperty_2;\n"
+"stateLModProperty_1\n"
+" dot .and \"ambient\" .emit LIGHT_MODEL_AMBIENT;\n"
+"stateLModProperty_2\n"
+" stateLModProperty_3 .emit LIGHT_MODEL_SCENECOLOR;\n"
+"stateLModProperty_3\n"
+" optFaceType .and dot .and \"scenecolor\";\n"
+"stateLightProdItem\n"
+" \"lightprod\" .and lbracket .and stateLightNumber .and rbracket .and optFaceType .and dot .and\n"
+" stateLProdProperty .error INVALID_LIGHTPROD_PROPERTY;\n"
+"stateLProdProperty\n"
+" \"ambient\" .emit LIGHT_PROD_AMBIENT .or\n"
+" \"diffuse\" .emit LIGHT_PROD_DIFFUSE .or\n"
+" \"specular\" .emit LIGHT_PROD_SPECULAR;\n"
+"stateLightNumber\n"
+" integer;\n"
+"stateTexEnvItem\n"
+" \"texenv\" .and optLegacyTexUnitNum .and dot .and\n"
+" stateTexEnvProperty .error INVALID_TEXENV_PROPERTY;\n"
+"stateTexEnvProperty\n"
+" \"color\" .emit TEX_ENV_COLOR;\n"
+"optLegacyTexUnitNum\n"
+" lbracket_ne .and legacyTexUnitNum .and rbracket;\n"
+"legacyTexUnitNum\n"
+" integer;\n"
+"stateTexGenItem\n"
+" \"texgen\" .and optTexCoordNum .and dot .and stateTexGenType .error INVALID_TEXGEN_PROPERTY .and\n"
+" dot .and stateTexGenCoord .error INVALID_TEXGEN_COORD;\n"
+"stateTexGenType\n"
+" \"eye\" .emit TEX_GEN_EYE .or\n"
+" \"object\" .emit TEX_GEN_OBJECT;\n"
+"stateTexGenCoord\n"
+" \"s\" .emit COMPONENT_X .or\n"
+" \"t\" .emit COMPONENT_Y .or\n"
+" \"r\" .emit COMPONENT_Z .or\n"
+" \"q\" .emit COMPONENT_W;\n"
+"stateFogItem\n"
+" \"fog\" .and dot .and stateFogProperty .error INVALID_FOG_PROPERTY;\n"
+"stateFogProperty\n"
+" \"color\" .emit FOG_COLOR .or\n"
+" \"params\" .emit FOG_PARAMS;\n"
+"stateDepthItem\n"
+" \"depth\" .and dot .and stateDepthProperty .error INVALID_DEPTH_PROPERTY;\n"
+"stateDepthProperty\n"
+" \"range\" .emit DEPTH_RANGE;\n"
+"stateClipPlaneItem\n"
+" \"clip\" .and lbracket .and stateClipPlaneNum .and rbracket .and dot .and\n"
+" \"plane\" .error INVALID_CLIPPLANE_PROPERTY;\n"
+"stateClipPlaneNum\n"
+" integer;\n"
+"statePointItem\n"
+" \"point\" .and dot .and statePointProperty .error INVALID_POINT_PROPERTY;\n"
+"statePointProperty\n"
+" \"size\" .emit POINT_SIZE .or\n"
+" .if (point_parameters != 0x00) \"attenuation\" .emit POINT_ATTENUATION;\n"
+"stateMatrixRow\n"
+" stateMatrixItem .and dot .and \"row\" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and\n"
+" lbracket .and stateMatrixRowNum .and rbracket .emit 0x0;\n"
+"stateMatrixRows\n"
+" stateMatrixItem .and optMatrixRows;\n"
+"optMatrixRows\n"
+" optMatrixRows_1 .or .true .emit 0x0 .emit '3' .emit 0x0 .emit $;\n"
+"optMatrixRows_1\n"
+" dot_ne .and \"row\" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and lbracket .and\n"
+" stateMatrixRowNum .and dotdot .and stateMatrixRowNum .and rbracket;\n"
+"stateMatrixItem\n"
+" \"matrix\" .and dot .and stateMatrixName .error INVALID_MATRIX_NAME .and stateOptMatModifier;\n"
+"stateOptMatModifier\n"
+" stateOptMatModifier_1 .or .true .emit MATRIX_MODIFIER_IDENTITY;\n"
+"stateOptMatModifier_1\n"
+" dot_ne .and stateMatModifier;\n"
+"stateMatModifier\n"
+" \"inverse\" .emit MATRIX_MODIFIER_INVERSE .or\n"
+" \"transpose\" .emit MATRIX_MODIFIER_TRANSPOSE .or\n"
+" \"invtrans\" .emit MATRIX_MODIFIER_INVTRANS;\n"
+"stateMatrixRowNum\n"
+" integer_0_3;\n"
+"stateMatrixName\n"
+" stateMatrixName_1_1 .emit MATRIX_MODELVIEW .or\n"
+" \"projection\" .emit MATRIX_PROJECTION .or\n"
+" \"mvp\" .emit MATRIX_MVP .or\n"
+" stateMatrixName_1_2 .emit MATRIX_TEXTURE .or\n"
+" .if (matrix_palette != 0x00) stateMatrixName_1_3 .emit MATRIX_PALETTE .or\n"
+" stateMatrixName_1_4 .emit MATRIX_PROGRAM;\n"
+"stateMatrixName_1_1\n"
+" \"modelview\" .and stateOptModMatNum;\n"
+"stateMatrixName_1_2\n"
+" \"texture\" .and optTexCoordNum;\n"
+"stateMatrixName_1_3\n"
+" \"palette\" .and lbracket .and statePaletteMatNum .and rbracket;\n"
+"stateMatrixName_1_4\n"
+" \"program\" .and lbracket .and stateProgramMatNum .and rbracket;\n"
+"stateOptModMatNum\n"
+" .if (vertex_blend != 0x00) stateOptModMatNum_1 .or\n"
+" .true .emit 0x00;\n"
+"stateOptModMatNum_1\n"
+" lbracket_ne .and stateModMatNum .and rbracket;\n"
+"stateModMatNum\n"
+" integer;\n"
+"optTexCoordNum\n"
+" optTexCoordNum_1 .or .true .emit 0x00;\n"
+"optTexCoordNum_1\n"
+" lbracket_ne .and texCoordNum .and rbracket;\n"
+"texCoordNum\n"
+" integer;\n"
+"statePaletteMatNum\n"
+" integer;\n"
+"stateProgramMatNum\n"
+" integer;\n"
+"programSingleItem\n"
+" \"program\" .and dot .and programSingleItem_1 .error INVALID_PROGRAM_PROPERTY;\n"
+"programSingleItem_1\n"
+" progEnvParam .or progLocalParam;\n"
+"programMultipleItem\n"
+" \"program\" .and dot .and programMultipleItem_1 .error INVALID_PROGRAM_PROPERTY;\n"
+"programMultipleItem_1\n"
+" progEnvParams .or progLocalParams;\n"
+"progEnvParams\n"
+" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNums .and rbracket;\n"
+"progEnvParamNums\n"
+" progEnvParamNums_1 .or progEnvParamNums_2;\n"
+"progEnvParamNums_1\n"
+" progEnvParamNum .and dotdot_ne .and progEnvParamNum;\n"
+"progEnvParamNums_2\n"
+" progEnvParamNum .and .true .emit 0x00;\n"
+"progEnvParam\n"
+" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket .emit 0x00;\n"
+"progLocalParams\n"
+" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNums .and rbracket;\n"
+"progLocalParamNums\n"
+" progLocalParamNums_1 .or progLocalParamNums_2;\n"
+"progLocalParamNums_1\n"
+" progLocalParamNum .and dotdot_ne .and progLocalParamNum;\n"
+"progLocalParamNums_2\n"
+" progLocalParamNum .and .true .emit 0x00;\n"
+"progLocalParam\n"
+" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket .emit 0x00;\n"
+"progEnvParamNum\n"
+" integer;\n"
+"progLocalParamNum\n"
+" integer;\n"
+"paramConstDecl\n"
+" paramConstScalarDecl .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;\n"
+"paramConstUse\n"
+" paramConstScalarUse .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;\n"
+"paramConstScalarDecl\n"
+" signedFloatConstant;\n"
+"paramConstScalarUse\n"
+" floatConstant;\n"
+"paramConstVector\n"
+" paramConstVector_4 .emit 0x04 .or paramConstVector_3 .emit 0x03 .or\n"
+" paramConstVector_2 .emit 0x02 .or paramConstVector_1 .emit 0x01;\n"
+"paramConstVector_1\n"
+" lbrace_ne .and signedFloatConstant .and rbrace;\n"
+"paramConstVector_2\n"
+" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;\n"
+"paramConstVector_3\n"
+" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and\n"
+" signedFloatConstant .and rbrace;\n"
+"paramConstVector_4\n"
+" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and\n"
+" signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;\n"
+"signedFloatConstant\n"
+" optionalSign .and floatConstant;\n"
+"floatConstant\n"
+" float;\n"
+"optionalSign\n"
+" optional_sign_ne;\n"
+"fp_TEMP_statement\n"
+" \"TEMP\" .and space .and fp_varNameList .and .true .emit 0x00;\n"
+"vp_TEMP_statement\n"
+" \"TEMP\" .and space .and vp_varNameList .and .true .emit 0x00;\n"
+"ADDRESS_statement\n"
+" \"ADDRESS\" .and space .and vp_varNameList .and .true .emit 0x00;\n"
+"fp_varNameList\n"
+" fp_varNameList_1 .or fp_establishName;\n"
+"vp_varNameList\n"
+" vp_varNameList_1 .or vp_establishName;\n"
+"fp_varNameList_1\n"
+" fp_establishName .and comma_ne .and fp_varNameList;\n"
+"vp_varNameList_1\n"
+" vp_establishName .and comma_ne .and vp_varNameList;\n"
+"fp_OUTPUT_statement\n"
+" \"OUTPUT\" .and space .and fp_establishName .and equal .and\n"
+" fp_resultBinding .error RESULT_EXPECTED;\n"
+"vp_OUTPUT_statement\n"
+" \"OUTPUT\" .and space .and vp_establishName .and equal .and\n"
+" vp_resultBinding .error RESULT_EXPECTED;\n"
+"fp_resultBinding\n"
+" \"result\" .and dot .and fp_resultBinding_1 .error INVALID_RESULT_PROPERTY;\n"
+"vp_resultBinding\n"
+" \"result\" .and dot .and vp_resultBinding_1 .error INVALID_RESULT_PROPERTY;\n"
+"fp_resultBinding_1\n"
+" \"color\" .emit FRAGMENT_RESULT_COLOR .or\n"
+" \"depth\" .emit FRAGMENT_RESULT_DEPTH;\n"
+"vp_resultBinding_1\n"
+" .if (ARB_position_invariant == 0x00) \"position\" .emit VERTEX_RESULT_POSITION .or\n"
+" resultColBinding .emit VERTEX_RESULT_COLOR .or\n"
+" \"fogcoord\" .emit VERTEX_RESULT_FOGCOORD .or\n"
+" \"pointsize\" .emit VERTEX_RESULT_POINTSIZE .or\n"
+" vp_resultBinding_2 .emit VERTEX_RESULT_TEXCOORD;\n"
+"vp_resultBinding_2\n"
+" \"texcoord\" .and optTexCoordNum;\n"
+"resultColBinding\n"
+" \"color\" .and optFaceType .and optColorType;\n"
+"optFaceType\n"
+" FaceType .or .true .emit FACE_FRONT;\n"
+"FaceType\n"
+" dot_ne .and FaceProperty;\n"
+"FaceProperty\n"
+" \"front\" .emit FACE_FRONT .or \"back\" .emit FACE_BACK;\n"
+"optColorType\n"
+" ColorType .or .true .emit COLOR_PRIMARY;\n"
+"ColorType\n"
+" dot_ne .and ColorProperty;\n"
+"ColorProperty\n"
+" \"primary\" .emit COLOR_PRIMARY .or\n"
+" .if (secondary_color != 0x00) \"secondary\" .emit COLOR_SECONDARY;\n"
+"fp_ALIAS_statement\n"
+" \"ALIAS\" .and fp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and fp_establishedName;\n"
+"vp_ALIAS_statement\n"
+" \"ALIAS\" .and vp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and vp_establishedName;\n"
+"fp_ALIAS_statement_1\n"
+" space .and fp_establishName;\n"
+"vp_ALIAS_statement_1\n"
+" space .and vp_establishName;\n"
+"fp_establishName\n"
+" fp_identifier;\n"
+"vp_establishName\n"
+" vp_identifier;\n"
+"fp_establishedName\n"
+" fp_identifier;\n"
+"vp_establishedName\n"
+" vp_identifier;\n"
+"fp_establishedName_no_error_on_identifier\n"
+" fp_identifier_ne;\n"
+"vp_establishedName_no_error_on_identifier\n"
+" vp_identifier_ne;\n"
+"fp_identifier\n"
+" fp_identifier_ne .error IDENTIFIER_EXPECTED;\n"
+"vp_identifier\n"
+" vp_identifier_ne .error IDENTIFIER_EXPECTED;\n"
+"fp_identifier_ne\n"
+" fp_not_reserved_identifier .and identifier_ne;\n"
+"vp_identifier_ne\n"
+" vp_not_reserved_identifier .and identifier_ne;\n"
+"fp_not_reserved_identifier\n"
+" fp_not_reserved_identifier_1 .or .true;\n"
+"fp_not_reserved_identifier_1\n"
+" fp_reserved_identifier .and .false .error RESERVED_KEYWORD;\n"
+"vp_not_reserved_identifier\n"
+" vp_not_reserved_identifier_1 .or .true;\n"
+"vp_not_reserved_identifier_1\n"
+" vp_reserved_identifier .and .false .error RESERVED_KEYWORD;\n"
+"fp_reserved_identifier\n"
+" \"ABS\" .or \"ABS_SAT\" .or \"ADD\" .or \"ADD_SAT\" .or \"ALIAS\" .or \"ATTRIB\" .or \"CMP\" .or \"CMP_SAT\" .or\n"
+" \"COS\" .or \"COS_SAT\" .or \"DP3\" .or \"DP3_SAT\" .or \"DP4\" .or \"DP4_SAT\" .or \"DPH\" .or \"DPH_SAT\" .or\n"
+" \"DST\" .or \"DST_SAT\" .or \"END\" .or \"EX2\" .or \"EX2_SAT\" .or \"FLR\" .or \"FLR_SAT\" .or \"FRC\" .or\n"
+" \"FRC_SAT\" .or \"KIL\" .or \"LG2\" .or \"LG2_SAT\" .or \"LIT\" .or \"LIT_SAT\" .or \"LRP\" .or \"LRP_SAT\" .or\n"
+" \"MAD\" .or \"MAD_SAT\" .or \"MAX\" .or \"MAX_SAT\" .or \"MIN\" .or \"MIN_SAT\" .or \"MOV\" .or \"MOV_SAT\" .or\n"
+" \"MUL\" .or \"MUL_SAT\" .or \"OPTION\" .or \"OUTPUT\" .or \"PARAM\" .or \"POW\" .or \"POW_SAT\" .or \"RCP\" .or\n"
+" \"RCP_SAT\" .or \"RSQ\" .or \"RSQ_SAT\" .or \"SIN\" .or \"SIN_SAT\" .or \"SCS\" .or \"SCS_SAT\" .or \"SGE\" .or\n"
+" \"SGE_SAT\" .or \"SLT\" .or \"SLT_SAT\" .or \"SUB\" .or \"SUB_SAT\" .or \"SWZ\" .or \"SWZ_SAT\" .or \"TEMP\" .or\n"
+" \"TEX\" .or \"TEX_SAT\" .or \"TXB\" .or \"TXB_SAT\" .or \"TXP\" .or \"TXP_SAT\" .or \"XPD\" .or \"XPD_SAT\" .or\n"
+" \"fragment\" .or \"program\" .or \"result\" .or \"state\" .or \"texture\";\n"
+"vp_reserved_identifier\n"
+" \"ABS\" .or \"ADD\" .or \"ADDRESS\" .or \"ALIAS\" .or \"ARL\" .or \"ATTRIB\" .or \"DP3\" .or \"DP4\" .or\n"
+" \"DPH\" .or \"DST\" .or \"END\" .or \"EX2\" .or \"EXP\" .or \"FLR\" .or \"FRC\" .or \"LG2\" .or \"LIT\" .or\n"
+" \"LOG\" .or \"MAD\" .or \"MAX\" .or \"MIN\" .or \"MOV\" .or \"MUL\" .or \"OPTION\" .or \"OUTPUT\" .or\n"
+" \"PARAM\" .or \"POW\" .or \"RCP\" .or \"RSQ\" .or \"SGE\" .or \"SLT\" .or \"SUB\" .or \"SWZ\" .or \"TEMP\" .or\n"
+" \"XPD\" .or \"program\" .or \"result\" .or \"state\" .or \"vertex\";\n"
+"integer\n"
+" integer_ne .error INTEGER_EXPECTED;\n"
+"zero\n"
+" '0';\n"
+"leading_zeroes\n"
+" .loop zero;\n"
+"no_digit\n"
+" no_digit_1 .or .true;\n"
+"no_digit_1\n"
+" digit10 .and .false .error INTEGER_OUT_OF_RANGE;\n"
+"all_zeroes\n"
+" all_zeroes_1 .or no_digit_1;\n"
+"all_zeroes_1\n"
+" '0' .and .loop zero .and no_digit;\n"
+"integer_0_3\n"
+" integer_0_3_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n"
+"integer_0_3_1\n"
+" integer_0_3_2 .or all_zeroes .emit '0';\n"
+"integer_0_3_2 \n"
+" leading_zeroes .and '1'-'3' .emit * .and no_digit;\n"
+"integer_0_63\n"
+" integer_0_63_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n"
+"integer_0_63_1\n"
+" integer_0_63_2 .or integer_0_63_3 .or integer_0_63_4 .or integer_0_63_5 .or\n"
+" all_zeroes .emit '0';\n"
+"integer_0_63_2 \n"
+" leading_zeroes .and '7'-'9' .emit * .and no_digit;\n"
+"integer_0_63_3 \n"
+" leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;\n"
+"integer_0_63_4 \n"
+" leading_zeroes .and '6' .emit * .and '0'-'3' .emit * .and no_digit;\n"
+"integer_0_63_5 \n"
+" leading_zeroes .and '1'-'6' .emit * .and no_digit;\n"
+"integer_0_64\n"
+" integer_0_64_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n"
+"integer_0_64_1\n"
+" integer_0_64_2 .or integer_0_64_3 .or integer_0_64_4 .or integer_0_64_5 .or\n"
+" all_zeroes .emit '0';\n"
+"integer_0_64_2 \n"
+" leading_zeroes .and '7'-'9' .emit * .and no_digit;\n"
+"integer_0_64_3 \n"
+" leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;\n"
+"integer_0_64_4 \n"
+" leading_zeroes .and '6' .emit * .and '0'-'4' .emit * .and no_digit;\n"
+"integer_0_64_5 \n"
+" leading_zeroes .and '1'-'6' .emit * .and no_digit;\n"
+"optional_space\n"
+" space .or .true;\n"
+"space_dst\n"
+" space .error OPERATION_NEEDS_DESTINATION_VARIABLE;\n"
+"space_src\n"
+" space .error OPERATION_NEEDS_SOURCE_VARIABLE;\n"
+"space\n"
+" single_space .and .loop single_space;\n"
+"single_space\n"
+" white_char .or comment_block;\n"
+"white_char\n"
+" ' ' .or '\\t' .or '\\n' .or '\\r';\n"
+"comment_block\n"
+" '#' .and .loop comment_char .and new_line;\n"
+"comment_char\n"
+" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
+"new_line\n"
+" '\\n' .or crlf .or '\\0';\n"
+"crlf\n"
+" '\\r' .and '\\n';\n"
+"semicolon\n"
+" optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;\n"
+"comma\n"
+" optional_space .and ',' .error MISSING_COMMA .and optional_space;\n"
+"comma_ne\n"
+" optional_space .and ',' .and optional_space;\n"
+"lbracket\n"
+" optional_space .and '[' .error MISSING_LBRACKET .and optional_space;\n"
+"lbracket_ne\n"
+" optional_space .and '[' .and optional_space;\n"
+"rbracket\n"
+" optional_space .and ']' .error MISSING_RBRACKET .and optional_space;\n"
+"dot\n"
+" optional_space .and '.' .error MISSING_DOT .and optional_space;\n"
+"dot_ne\n"
+" optional_space .and '.' .and optional_space;\n"
+"equal\n"
+" optional_space .and '=' .error MISSING_EQUAL .and optional_space;\n"
+"lbrace\n"
+" optional_space .and '{' .error MISSING_LBRACE .and optional_space;\n"
+"lbrace_ne\n"
+" optional_space .and '{' .and optional_space;\n"
+"rbrace\n"
+" optional_space .and '}' .error MISSING_RBRACE .and optional_space;\n"
+"dotdot\n"
+" optional_space .and '.' .and '.' .error MISSING_DOTDOT .and optional_space;\n"
+"dotdot_ne\n"
+" optional_space .and '.' .and '.' .and optional_space;\n"
+"float\n"
+" float_1 .or float_2 .or float_legacy;\n"
+"float_1\n"
+" '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent;\n"
+"float_2\n"
+" integer_ne .and float_3;\n"
+"float_3\n"
+" float_4 .or float_5;\n"
+"float_4\n"
+" '.' .and optional_integer .and optional_exponent;\n"
+"float_5\n"
+" exponent .emit 0x00;\n"
+"float_legacy\n"
+" integer_ne .and .true .emit 0x00 .emit 0x00;\n"
+"integer_ne\n"
+" integer_ne_1 .and .true .emit 0x00 .emit $;\n"
+"integer_ne_1\n"
+" digit10 .emit * .and .loop digit10 .emit *;\n"
+"optional_integer\n"
+" integer_ne .or .true .emit 0x00;\n"
+"optional_exponent\n"
+" exponent .or .true .emit 0x00;\n"
+"exponent\n"
+" exponent_1 .and optional_sign_ne .and integer_ne .error EXPONENT_VALUE_EXPECTED;\n"
+"exponent_1\n"
+" 'e' .or 'E';\n"
+"optional_sign_ne\n"
+" minus_ne .or plus_ne .or .true;\n"
+"plus_ne\n"
+" optional_space .and '+' .and optional_space;\n"
+"minus_ne\n"
+" optional_space .and '-' .emit '-' .and optional_space;\n"
+"identifier_ne\n"
+" first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit 0x00 .emit $;\n"
+"follow_idchar\n"
+" first_idchar .or digit10;\n"
+"first_idchar\n"
+" 'a'-'z' .or 'A'-'Z' .or '_' .or '$';\n"
+"digit10\n"
+" '0'-'9';\n"
+".string __string_filter;\n"
+"__string_filter\n"
+" .loop __identifier_char;\n"
+"__identifier_char\n"
+" 'a'-'z' .or 'A'-'Z' .or '_' .or '$' .or '0'-'9';\n"
+"e_signature\n"
+" e_signature_char .and .loop e_signature_char;\n"
+"e_signature_char\n"
+" '!' .or '.' .or 'A'-'Z' .or 'a'-'z' .or '0'-'9';\n"
+"e_statement\n"
+" .loop e_statement_not_term;\n"
+"e_statement_not_term\n"
+" '\\x3C'-'\\xFF' .or '\\x0E'-'\\x3A' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
+"e_identifier\n"
+" e_identifier_first .and .loop e_identifier_next;\n"
+"e_identifier_first\n"
+" 'a'-'z' .or 'A'-'Z' .or '_' .or '$';\n"
+"e_identifier_next\n"
+" e_identifier_first .or '0'-'9';\n"
+"e_token\n"
+" e_identifier .or e_token_number .or '[' .or ']' .or '.' .or '{' .or '}' .or '=' .or '+' .or\n"
+" '-' .or ',' .or ';';\n"
+"e_token_number\n"
+" e_token_digit .and .loop e_token_digit;\n"
+"e_token_digit\n"
+" '0'-'9';\n"
+"e_charordigit\n"
+" 'A'-'Z' .or 'a'-'z' .or '0'-'9';\n"
+""
index 964497845710886643d265cabbfcffb8471d2a28..0ed347bad51ef9c35103784a1fc5d9c88ee0c379 100644 (file)
-#ifndef GRAMMAR_PORT_BUILD\r
-#error Do not build this file directly, build your grammar_XXX.c instead, which includes this file\r
-#endif\r
-\r
-/*\r
-    Last Modified: 2004-II-8\r
-*/\r
-\r
-/*\r
-    INTRODUCTION\r
-    ------------\r
-\r
-    The task is to check the syntax of an input string. Input string is a stream of ASCII\r
-    characters terminated with a null-character ('\0'). Checking it using C language is\r
-    difficult and hard to implement without bugs. It is hard to maintain and make changes when\r
-    the syntax changes.\r
-\r
-    This is because of a high redundancy of the C code. Large blocks of code are duplicated with\r
-    only small changes. Even use of macros does not solve the problem because macros cannot\r
-    erase the complexity of the problem.\r
-\r
-    The resolution is to create a new language that will be highly oriented to our task. Once\r
-    we describe a particular syntax, we are done. We can then focus on the code that implements\r
-    the language. The size and complexity of it is relatively small than the code that directly\r
-    checks the syntax.\r
-\r
-    First, we must implement our new language. Here, the language is implemented in C, but it\r
-    could also be implemented in any other language. The code is listed below. We must take\r
-    a good care that it is bug free. This is simple because the code is simple and clean.\r
-\r
-    Next, we must describe the syntax of our new language in itself. Once created and checked\r
-    manually that it is correct, we can use it to check another scripts.\r
-\r
-    Note that our new language loading code does not have to check the syntax. It is because we\r
-    assume that the script describing itself is correct, and other scripts can be syntactically\r
-    checked by the former script. The loading code must only do semantic checking which leads us to\r
-    simple resolving references.\r
-\r
-    THE LANGUAGE\r
-    ------------\r
-\r
-    Here I will describe the syntax of the new language (further called "Synek"). It is mainly a\r
-    sequence of declarations terminated by a semicolon. The declaration consists of a symbol,\r
-    which is an identifier, and its definition. A definition is in turn a sequence of specifiers\r
-    connected with ".and" or ".or" operator. These operators cannot be mixed together in a one\r
-    definition. Specifier can be a symbol, string, character, character range or a special\r
-    keyword ".true" or ".false".\r
-\r
-    On the very beginning of the script there is a declaration of a root symbol and is in the form:\r
-        .syntax <root_symbol>;\r
-    The <root_symbol> must be on of the symbols in declaration sequence. The syntax is correct if\r
-    the root symbol evaluates to true. A symbol evaluates to true if the definition associated with\r
-    the symbol evaluates to true. Definition evaluation depends on the operator used to connect\r
-    specifiers in the definition. If ".and" operator is used, definition evaluates to true if and\r
-    only if all the specifiers evaluate to true. If ".or" operator is used, definition evalutes to\r
-    true if any of the specifiers evaluates to true. If definition contains only one specifier,\r
-    it is evaluated as if it was connected with ".true" keyword by ".and" operator.\r
-\r
-    If specifier is a ".true" keyword, it always evaluates to true.\r
-\r
-    If specifier is a ".false" keyword, it always evaluates to false. Specifier evaluates to false\r
-    when it does not evaluate to true.\r
-\r
-    Character range specifier is in the form:\r
-        '<first_character>' - '<second_character>'\r
-    If specifier is a character range, it evaluates to true if character in the stream is greater\r
-    or equal to <first_character> and less or equal to <second_character>. In that situation \r
-    the stream pointer is advanced to point to next character in the stream. All C-style escape\r
-    sequences are supported although trigraph sequences are not. The comparisions are performed\r
-    on 8-bit unsigned integers.\r
-\r
-    Character specifier is in the form:\r
-        '<single_character>'\r
-    It evaluates to true if the following character range specifier evaluates to true:\r
-        '<single_character>' - '<single_character>'\r
-\r
-    String specifier is in the form:\r
-        "<string>"\r
-    Let N be the number of characters in <string>. Let <string>[i] designate i-th character in\r
-    <string>. Then the string specifier evaluates to true if and only if for i in the range [0, N)\r
-    the following character specifier evaluates to true:\r
-        '<string>[i]'\r
-    If <string>[i] is a quotation mark, '<string>[i]' is replaced with '\<string>[i]'.\r
-\r
-    Symbol specifier can be optionally preceded by a ".loop" keyword in the form:\r
-        .loop <symbol>                  (1)\r
-    where <symbol> is defined as follows:\r
-        <symbol> <definition>;          (2)\r
-    Construction (1) is replaced by the following code:\r
-        <symbol$1>\r
-    and declaration (2) is replaced by the following:\r
-        <symbol$1> <symbol$2> .or .true;\r
-        <symbol$2> <symbol> .and <symbol$1>;\r
-        <symbol> <definition>;\r
-\r
-    ESCAPE SEQUENCES\r
-    ----------------\r
-\r
-    Synek supports all escape sequences in character specifiers. The mapping table is listed below.\r
-    All occurences of the characters in the first column are replaced with the corresponding\r
-    character in the second column.\r
-\r
-        Escape sequence         Represents\r
-    ------------------------------------------------------------------------------------------------\r
-        \a                      Bell (alert)\r
-        \b                      Backspace\r
-        \f                      Formfeed\r
-        \n                      New line\r
-        \r                      Carriage return\r
-        \t                      Horizontal tab\r
-        \v                      Vertical tab\r
-        \'                      Single quotation mark\r
-        \"                      Double quotation mark\r
-        \\                      Backslash\r
-        \?                      Literal question mark\r
-        \ooo                    ASCII character in octal notation\r
-        \xhhh                   ASCII character in hexadecimal notation\r
-    ------------------------------------------------------------------------------------------------\r
-\r
-    RAISING ERRORS\r
-    --------------\r
-\r
-    Any specifier can be followed by a special construction that is executed when the specifier\r
-    evaluates to false. The construction is in the form:\r
-        .error <ERROR_TEXT>\r
-    <ERROR_TEXT> is an identifier declared earlier by error text declaration. The declaration is\r
-    in the form:\r
-        .errtext <ERROR_TEXT> "<error_desc>"\r
-    When specifier evaluates to false and this construction is present, parsing is stopped\r
-    immediately and <error_desc> is returned as a result of parsing. The error position is also\r
-    returned and it is meant as an offset from the beggining of the stream to the character that\r
-    was valid so far. Example:\r
-\r
-        (**** syntax script ****)\r
-\r
-        .syntax program;\r
-        .errtext MISSING_SEMICOLON      "missing ';'"\r
-        program         declaration .and .loop space .and ';' .error MISSING_SEMICOLON .and\r
-                        .loop space .and '\0';\r
-        declaration     "declare" .and .loop space .and identifier;\r
-        space           ' ';\r
-\r
-        (**** sample code ****)\r
-\r
-        declare foo ,\r
-\r
-    In the example above checking the sample code will result in error message "missing ';'" and\r
-    error position 12. The sample code is not correct. Note the presence of '\0' specifier to\r
-    assure that there is no code after semicolon - only spaces.\r
-    <error_desc> can optionally contain identifier surrounded by dollar signs $. In such a case,\r
-    the identifier and dollar signs are replaced by a string retrieved by invoking symbol with\r
-    the identifier name. The starting position is the error position. The lenght of the resulting\r
-    string is the position after invoking the symbol.\r
-\r
-    PRODUCTION\r
-    ----------\r
-\r
-    Synek not only checks the syntax but it can also produce (emit) bytes associated with specifiers\r
-    that evaluate to true. That is, every specifier and optional error construction can be followed\r
-    by a number of emit constructions that are in the form:\r
-        .emit <parameter>\r
-    <paramater> can be a HEX number, identifier, a star * or a dollar $. HEX number is preceded by\r
-    0x or 0X. If <parameter> is an identifier, it must be earlier declared by emit code declaration\r
-    in the form:\r
-        .emtcode <identifier> <hex_number>\r
-\r
-    When given specifier evaluates to true, all emits associated with the specifier are output\r
-    in order they were declared. A star means that last-read character should be output instead\r
-    of constant value. Example:\r
-\r
-        (**** syntax script ****)\r
-\r
-        .syntax foobar;\r
-        .emtcode WORD_FOO       0x01\r
-        .emtcode WORD_BAR       0x02\r
-        foobar      FOO .emit WORD_FOO .or BAR .emit WORD_BAR .or .true .emit 0x00;\r
-        FOO         "foo" .and SPACE;\r
-        BAR         "bar" .and SPACE;\r
-        SPACE       ' ' .or '\0';\r
-\r
-        (**** sample text 1 ****)\r
-\r
-        foo\r
-\r
-        (**** sample text 2 ****)\r
-\r
-        foobar\r
-\r
-    For both samples the result will be one-element array. For first sample text it will be\r
-    value 1, for second - 0. Note that every text will be accepted because of presence of\r
-    .true as an alternative.\r
-\r
-    Another example:\r
-\r
-        (**** syntax script ****)\r
-\r
-        .syntax declaration;\r
-        .emtcode VARIABLE       0x01\r
-        declaration     "declare" .and .loop space .and\r
-                        identifier .emit VARIABLE .and          (1)\r
-                        .true .emit 0x00 .and                   (2)\r
-                        .loop space .and ';';\r
-        space           ' ' .or '\t';\r
-        identifier      .loop id_char .emit *;                  (3)\r
-        id_char         'a'-'z' .or 'A'-'Z' .or '_';\r
-\r
-        (**** sample code ****)\r
-\r
-        declare    fubar;\r
-\r
-    In specifier (1) symbol <identifier> is followed by .emit VARIABLE. If it evaluates to\r
-    true, VARIABLE constant and then production of the symbol is output. Specifier (2) is used\r
-    to terminate the string with null to signal when the string ends. Specifier (3) outputs\r
-    all characters that make declared identifier. The result of sample code will be the\r
-    following array:\r
-        { 1, 'f', 'u', 'b', 'a', 'r', 0 }\r
-\r
-    If .emit is followed by dollar $, it means that current position should be output. Current\r
-    position is a 32-bit unsigned integer distance from the very beginning of the parsed string to\r
-    first character consumed by the specifier associated with the .emit instruction. Current\r
-    position is stored in the output buffer in Little-Endian convention (the lowest byte comes\r
-    first).\r
-*/\r
-\r
-static void mem_free (void **);\r
-\r
-/*\r
-    internal error messages\r
-*/\r
-static const byte *OUT_OF_MEMORY =          (byte *) "internal error 1001: out of physical memory";\r
-static const byte *UNRESOLVED_REFERENCE =   (byte *) "internal error 1002: unresolved reference '$'";\r
-static const byte *INVALID_GRAMMAR_ID =     (byte *) "internal error 1003: invalid grammar object";\r
-static const byte *INVALID_REGISTER_NAME =  (byte *) "internal error 1004: invalid register name: '$'";\r
-\r
-static const byte *error_message = NULL;\r
-static byte *error_param = NULL;        /* this is inserted into error_message in place of $ */\r
-static int error_position = -1;\r
-\r
-static byte *unknown = (byte *) "???";\r
-\r
-static void clear_last_error ()\r
-{\r
-    /* reset error message */\r
-    error_message = NULL;\r
-\r
-    /* free error parameter - if error_param is a "???" don't free it - it's static */\r
-    if (error_param != unknown)\r
-        mem_free ((void **) &error_param);\r
-    else\r
-        error_param = NULL;\r
-\r
-    /* reset error position */\r
-    error_position = -1;\r
-}\r
-\r
-static void set_last_error (const byte *msg, byte *param, int pos)\r
-{\r
-    /* error message can only be set only once */\r
-    if (error_message != NULL)\r
-    {\r
-        mem_free (&param);\r
-        return;\r
-    }\r
-\r
-    error_message = msg;\r
-\r
-    if (param != NULL)\r
-        error_param = param;\r
-    else\r
-        error_param = unknown;\r
-\r
-    error_position = pos;\r
-}\r
-\r
-/*\r
-    memory management routines\r
-*/\r
-static void *mem_alloc (size_t size)\r
-{\r
-    void *ptr = grammar_alloc_malloc (size);\r
-    if (ptr == NULL)\r
-        set_last_error (OUT_OF_MEMORY, NULL, -1);\r
-    return ptr;\r
-}\r
-\r
-static void *mem_copy (void *dst, const void *src, size_t size)\r
-{\r
-    return grammar_memory_copy (dst, src, size);\r
-}\r
-\r
-static void mem_free (void **ptr)\r
-{\r
-    grammar_alloc_free (*ptr);\r
-    *ptr = NULL;\r
-}\r
-\r
-static void *mem_realloc (void *ptr, size_t old_size, size_t new_size)\r
-{\r
-    void *ptr2 = grammar_alloc_realloc (ptr, old_size, new_size);\r
-    if (ptr2 == NULL)\r
-        set_last_error (OUT_OF_MEMORY, NULL, -1);\r
-    return ptr2;\r
-}\r
-\r
-static byte *str_copy_n (byte *dst, const byte *src, size_t max_len)\r
-{\r
-    return grammar_string_copy_n (dst, src, max_len);\r
-}\r
-\r
-static byte *str_duplicate (const byte *str)\r
-{\r
-    byte *new_str = grammar_string_duplicate (str);\r
-    if (new_str == NULL)\r
-        set_last_error (OUT_OF_MEMORY, NULL, -1);\r
-    return new_str;\r
-}\r
-\r
-static int str_equal (const byte *str1, const byte *str2)\r
-{\r
-    return grammar_string_compare (str1, str2) == 0;\r
-}\r
-\r
-static int str_equal_n (const byte *str1, const byte *str2, unsigned int n)\r
-{\r
-    return grammar_string_compare_n (str1, str2, n) == 0;\r
-}\r
-\r
-static unsigned int str_length (const byte *str)\r
-{\r
-    return grammar_string_length (str);\r
-}\r
-\r
-/*\r
-    string to byte map typedef\r
-*/\r
-typedef struct map_byte_\r
-{\r
-    byte *key;\r
-    byte data;\r
-    struct map_byte_ *next;\r
-} map_byte;\r
-\r
-static void map_byte_create (map_byte **ma)\r
-{\r
-    *ma = mem_alloc (sizeof (map_byte));\r
-    if (*ma)\r
-    {\r
-        (**ma).key = NULL;\r
-        (**ma).data = '\0';\r
-        (**ma).next = NULL;\r
-    }\r
-}\r
-\r
-/* XXX unfold the recursion */\r
-static void map_byte_destroy (map_byte **ma)\r
-{\r
-    if (*ma)\r
-    {\r
-        map_byte_destroy (&(**ma).next);\r
-        mem_free ((void **) &(**ma).key);\r
-        mem_free ((void **) ma);\r
-    }\r
-}\r
-\r
-static void map_byte_append (map_byte **ma, map_byte **nm)\r
-{\r
-    while (*ma)\r
-        ma = &(**ma).next;\r
-    *ma = *nm;\r
-}\r
-\r
-/*\r
-    searches the map for the specified key,\r
-    returns pointer to the element with the specified key if it exists\r
-    returns NULL otherwise\r
-*/\r
-map_byte *map_byte_locate (map_byte **ma, const byte *key)\r
-{\r
-    while (*ma)\r
-    {\r
-        if (str_equal ((**ma).key, key))\r
-            return *ma;\r
-\r
-        ma = &(**ma).next;\r
-    }\r
-\r
-    set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);\r
-    return NULL;\r
-}\r
-\r
-/*\r
-    searches the map for specified key,\r
-    if the key is matched, *data is filled with data associated with the key,\r
-    returns 0 if the key is matched,\r
-    returns 1 otherwise\r
-*/\r
-static int map_byte_find (map_byte **ma, const byte *key, byte *data)\r
-{\r
-    map_byte *found = map_byte_locate (ma, key);\r
-    if (found != NULL)\r
-    {\r
-        *data = found->data;\r
-\r
-        return 0;\r
-    }\r
-\r
-    return 1;\r
-}\r
-\r
-/*\r
-    regbyte context typedef\r
-\r
-    Each regbyte consists of its name and a default value. These are static and created at\r
-    grammar script compile-time, for example the following line:\r
-        .regbyte vertex_blend      0x00\r
-    adds a new regbyte named "vertex_blend" to the static list and initializes it to 0.\r
-    When the script is executed, this regbyte can be accessed by name for read and write. When a\r
-    particular regbyte is written, a new regbyte_ctx entry is added to the top of the regbyte_ctx\r
-    stack. The new entry contains information abot which regbyte it references and its new value.\r
-    When a given regbyte is accessed for read, the stack is searched top-down to find an\r
-    entry that references the regbyte. The first matching entry is used to return the current\r
-    value it holds. If no entry is found, the default value is returned.\r
-*/\r
-typedef struct regbyte_ctx_\r
-{\r
-    map_byte *m_regbyte;\r
-    byte m_current_value;\r
-    struct regbyte_ctx_ *m_prev;\r
-} regbyte_ctx;\r
-\r
-static void regbyte_ctx_create (regbyte_ctx **re)\r
-{\r
-    *re = mem_alloc (sizeof (regbyte_ctx));\r
-    if (*re)\r
-    {\r
-        (**re).m_regbyte = NULL;\r
-        (**re).m_prev = NULL;\r
-    }\r
-}\r
-\r
-static void regbyte_ctx_destroy (regbyte_ctx **re)\r
-{\r
-    if (*re)\r
-    {\r
-        mem_free ((void **) re);\r
-    }\r
-}\r
-\r
-static byte regbyte_ctx_extract (regbyte_ctx **re, map_byte *reg)\r
-{\r
-    /* first lookup in the register stack */\r
-    while (*re != NULL)\r
-    {\r
-        if ((**re).m_regbyte == reg)\r
-            return (**re).m_current_value;\r
-\r
-        re = &(**re).m_prev;\r
-    }\r
-\r
-    /* if not found - return the default value */\r
-    return reg->data;\r
-}\r
-\r
-/*\r
-    emit type typedef\r
-*/\r
-typedef enum emit_type_\r
-{\r
-    et_byte,            /* explicit number */\r
-    et_stream,          /* eaten character */\r
-    et_position         /* current position */\r
-} emit_type;\r
-\r
-/*\r
-    emit destination typedef\r
-*/\r
-typedef enum emit_dest_\r
-{\r
-    ed_output,          /* write to the output buffer */\r
-    ed_regbyte          /* write a particular regbyte */\r
-} emit_dest;\r
-\r
-/*\r
-    emit typedef\r
-*/\r
-typedef struct emit_\r
-{\r
-    emit_dest m_emit_dest;\r
-    emit_type m_emit_type;      /* ed_output */\r
-    byte m_byte;                /* et_byte */\r
-    map_byte *m_regbyte;        /* ed_regbyte */\r
-    byte *m_regname;            /* ed_regbyte - temporary */\r
-    struct emit_ *m_next;\r
-} emit;\r
-\r
-static void emit_create (emit **em)\r
-{\r
-    *em = mem_alloc (sizeof (emit));\r
-    if (*em)\r
-    {\r
-        (**em).m_emit_dest = ed_output;\r
-        (**em).m_emit_type = et_byte;\r
-        (**em).m_byte = '\0';\r
-        (**em).m_regbyte = NULL;\r
-        (**em).m_regname = NULL;\r
-        (**em).m_next = NULL;\r
-    }\r
-}\r
-\r
-static void emit_destroy (emit **em)\r
-{\r
-    if (*em)\r
-    {\r
-        emit_destroy (&(**em).m_next);\r
-        mem_free ((void **) &(**em).m_regname);\r
-        mem_free ((void **) em);\r
-    }\r
-}\r
-\r
-/*\r
-    error typedef\r
-*/\r
-typedef struct error_\r
-{\r
-    byte *m_text;\r
-    byte *m_token_name;\r
-    struct rule_ *m_token;\r
-} error;\r
-\r
-static void error_create (error **er)\r
-{\r
-    *er = mem_alloc (sizeof (error));\r
-    if (*er)\r
-    {\r
-        (**er).m_text = NULL;\r
-        (**er).m_token_name = NULL;\r
-        (**er).m_token = NULL;\r
-    }\r
-}\r
-\r
-static void error_destroy (error **er)\r
-{\r
-    if (*er)\r
-    {\r
-        mem_free ((void **) &(**er).m_text);\r
-        mem_free ((void **) &(**er).m_token_name);\r
-        mem_free ((void **) er);\r
-    }\r
-}\r
-\r
-struct dict_;\r
-static byte *error_get_token (error *, struct dict_ *, const byte *, unsigned int);\r
-\r
-/*\r
-    condition operand type typedef\r
-*/\r
-typedef enum cond_oper_type_\r
-{\r
-    cot_byte,               /* constant 8-bit unsigned integer */\r
-    cot_regbyte             /* pointer to byte register containing the current value */\r
-} cond_oper_type;\r
-\r
-/*\r
-    condition operand typedef\r
-*/\r
-typedef struct cond_oper_\r
-{\r
-    cond_oper_type m_type;\r
-    byte m_byte;            /* cot_byte */\r
-    map_byte *m_regbyte;    /* cot_regbyte */\r
-    byte *m_regname;        /* cot_regbyte - temporary */\r
-} cond_oper;\r
-\r
-/*\r
-    condition type typedef\r
-*/\r
-typedef enum cond_type_\r
-{\r
-    ct_equal,\r
-    ct_not_equal\r
-} cond_type;\r
-\r
-/*\r
-    condition typedef\r
-*/\r
-typedef struct cond_\r
-{\r
-    cond_type m_type;\r
-    cond_oper m_operands[2];\r
-} cond;\r
-\r
-static void cond_create (cond **co)\r
-{\r
-    *co = mem_alloc (sizeof (cond));\r
-    if (*co)\r
-    {\r
-        (**co).m_operands[0].m_regname = NULL;\r
-        (**co).m_operands[1].m_regname = NULL;\r
-    }\r
-}\r
-\r
-static void cond_destroy (cond **co)\r
-{\r
-    if (*co)\r
-    {\r
-        mem_free ((void **) &(**co).m_operands[0].m_regname);\r
-        mem_free ((void **) &(**co).m_operands[1].m_regname);\r
-        mem_free ((void **) co);\r
-    }\r
-}\r
-\r
-/*\r
-    specifier type typedef\r
-*/\r
-typedef enum spec_type_\r
-{\r
-    st_false,\r
-    st_true,\r
-    st_byte,\r
-    st_byte_range,\r
-    st_string,\r
-    st_identifier,\r
-    st_identifier_loop,\r
-    st_debug\r
-} spec_type;\r
-\r
-/*\r
-    specifier typedef\r
-*/\r
-typedef struct spec_\r
-{\r
-    spec_type m_spec_type;\r
-    byte m_byte[2];                 /* st_byte, st_byte_range */\r
-    byte *m_string;                 /* st_string */\r
-    struct rule_ *m_rule;           /* st_identifier, st_identifier_loop */\r
-    emit *m_emits;\r
-    error *m_errtext;\r
-    cond *m_cond;\r
-    struct spec_ *m_next;\r
-} spec;\r
-\r
-static void spec_create (spec **sp)\r
-{\r
-    *sp = mem_alloc (sizeof (spec));\r
-    if (*sp)\r
-    {\r
-        (**sp).m_spec_type = st_false;\r
-        (**sp).m_byte[0] = '\0';\r
-        (**sp).m_byte[1] = '\0';\r
-        (**sp).m_string = NULL;\r
-        (**sp).m_rule = NULL;\r
-        (**sp).m_emits = NULL;\r
-        (**sp).m_errtext = NULL;\r
-        (**sp).m_cond = NULL;\r
-        (**sp).m_next = NULL;\r
-    }\r
-}\r
-\r
-static void spec_destroy (spec **sp)\r
-{\r
-    if (*sp)\r
-    {\r
-        spec_destroy (&(**sp).m_next);\r
-        emit_destroy (&(**sp).m_emits);\r
-        error_destroy (&(**sp).m_errtext);\r
-        mem_free ((void **) &(**sp).m_string);\r
-        cond_destroy (&(**sp).m_cond);\r
-        mem_free ((void **) sp);\r
-    }\r
-}\r
-\r
-static void spec_append (spec **sp, spec **ns)\r
-{\r
-    while (*sp)\r
-        sp = &(**sp).m_next;\r
-    *sp = *ns;\r
-}\r
-\r
-/*\r
-    operator typedef\r
-*/\r
-typedef enum oper_\r
-{\r
-    op_none,\r
-    op_and,\r
-    op_or\r
-} oper;\r
-\r
-/*\r
-    rule typedef\r
-*/\r
-typedef struct rule_\r
-{\r
-    oper m_oper;\r
-    spec *m_specs;\r
-    struct rule_ *m_next;\r
-/*  int m_referenced; */            /* for debugging purposes */\r
-} rule;\r
-\r
-static void rule_create (rule **ru)\r
-{\r
-    *ru = mem_alloc (sizeof (rule));\r
-    if (*ru)\r
-    {\r
-        (**ru).m_oper = op_none;\r
-        (**ru).m_specs = NULL;\r
-        (**ru).m_next = NULL;\r
-/*      (**ru).m_referenced = 0; */\r
-    }\r
-}\r
-\r
-static void rule_destroy (rule **ru)\r
-{\r
-    if (*ru)\r
-    {\r
-        rule_destroy (&(**ru).m_next);\r
-        spec_destroy (&(**ru).m_specs);\r
-        mem_free ((void **) ru);\r
-    }\r
-}\r
-\r
-static void rule_append (rule **ru, rule **nr)\r
-{\r
-    while (*ru)\r
-        ru = &(**ru).m_next;\r
-    *ru = *nr;\r
-}\r
-\r
-/*\r
-    returns unique grammar id\r
-*/\r
-static grammar next_valid_grammar_id ()\r
-{\r
-    static grammar id = 0;\r
-\r
-    return ++id;\r
-}\r
-\r
-/*\r
-    dictionary typedef\r
-*/\r
-typedef struct dict_\r
-{\r
-    rule *m_rulez;\r
-    rule *m_syntax;\r
-    rule *m_string;\r
-    map_byte *m_regbytes;\r
-    grammar m_id;\r
-    struct dict_ *m_next;\r
-} dict;\r
-\r
-static void dict_create (dict **di)\r
-{\r
-    *di = mem_alloc (sizeof (dict));\r
-    if (*di)\r
-    {\r
-        (**di).m_rulez = NULL;\r
-        (**di).m_syntax = NULL;\r
-        (**di).m_string = NULL;\r
-        (**di).m_regbytes = NULL;\r
-        (**di).m_id = next_valid_grammar_id ();\r
-        (**di).m_next = NULL;\r
-    }\r
-}\r
-\r
-static void dict_destroy (dict **di)\r
-{\r
-    if (*di)\r
-    {\r
-        rule_destroy (&(**di).m_rulez);\r
-        map_byte_destroy (&(**di).m_regbytes);\r
-        mem_free ((void **) di);\r
-    }\r
-}\r
-\r
-static void dict_append (dict **di, dict **nd)\r
-{\r
-    while (*di)\r
-        di = &(**di).m_next;\r
-    *di = *nd;\r
-}\r
-\r
-static void dict_find (dict **di, grammar key, dict **data)\r
-{\r
-    while (*di)\r
-    {\r
-        if ((**di).m_id == key)\r
-        {\r
-            *data = *di;\r
-            return;\r
-        }\r
-\r
-        di = &(**di).m_next;\r
-    }\r
-\r
-    *data = NULL;\r
-}\r
-\r
-static dict *g_dicts = NULL;\r
-\r
-/*\r
-    byte array typedef\r
-\r
-    XXX this class is going to be replaced by a faster one, soon\r
-*/\r
-typedef struct barray_\r
-{\r
-    byte *data;\r
-    unsigned int len;\r
-} barray;\r
-\r
-static void barray_create (barray **ba)\r
-{\r
-    *ba = mem_alloc (sizeof (barray));\r
-    if (*ba)\r
-    {\r
-        (**ba).data = NULL;\r
-        (**ba).len = 0;\r
-    }\r
-}\r
-\r
-static void barray_destroy (barray **ba)\r
-{\r
-    if (*ba)\r
-    {\r
-        mem_free ((void **) &(**ba).data);\r
-        mem_free ((void **) ba);\r
-    }\r
-}\r
-\r
-/*\r
-    reallocates byte array to requested size,\r
-    returns 0 on success,\r
-    returns 1 otherwise\r
-*/\r
-static int barray_resize (barray **ba, unsigned int nlen)\r
-{\r
-    byte *new_pointer;\r
-\r
-    if (nlen == 0)\r
-    {\r
-        mem_free ((void **) &(**ba).data);\r
-        (**ba).data = NULL;\r
-        (**ba).len = 0;\r
-\r
-        return 0;\r
-    }\r
-    else\r
-    {\r
-        new_pointer = mem_realloc ((**ba).data, (**ba).len * sizeof (byte), nlen * sizeof (byte));\r
-        if (new_pointer)\r
-        {\r
-            (**ba).data = new_pointer;\r
-            (**ba).len = nlen;\r
-\r
-            return 0;\r
-        }\r
-    }\r
-\r
-    return 1;\r
-}\r
-\r
-/*\r
-    adds byte array pointed by *nb to the end of array pointed by *ba,\r
-    returns 0 on success,\r
-    returns 1 otherwise\r
-*/\r
-static int barray_append (barray **ba, barray **nb)\r
-{\r
-    const unsigned int len = (**ba).len;\r
-\r
-    if (barray_resize (ba, (**ba).len + (**nb).len))\r
-        return 1;\r
-\r
-    mem_copy ((**ba).data + len, (**nb).data, (**nb).len);\r
-\r
-    return 0;\r
-}\r
-\r
-/*\r
-    adds emit chain pointed by em to the end of array pointed by *ba,\r
-    returns 0 on success,\r
-    returns 1 otherwise\r
-*/\r
-static int barray_push (barray **ba, emit *em, byte c, unsigned int pos, regbyte_ctx **rbc)\r
-{\r
-    emit *temp = em;\r
-    unsigned int count = 0;\r
-\r
-    while (temp)\r
-    {\r
-        if (temp->m_emit_dest == ed_output)\r
-            if (temp->m_emit_type == et_position)\r
-                count += 4;     /* position is a 32-bit unsigned integer */\r
-            else\r
-                count++;\r
-\r
-        temp = temp->m_next;\r
-    }\r
-\r
-    if (barray_resize (ba, (**ba).len + count))\r
-        return 1;\r
-\r
-    while (em)\r
-    {\r
-        if (em->m_emit_dest == ed_output)\r
-        {\r
-            if (em->m_emit_type == et_byte)\r
-                (**ba).data[(**ba).len - count--] = em->m_byte;\r
-            else if (em->m_emit_type == et_stream)\r
-                (**ba).data[(**ba).len - count--] = c;\r
-            else // em->type == et_position\r
-                (**ba).data[(**ba).len - count--] = (byte) pos,\r
-                (**ba).data[(**ba).len - count--] = (byte) (pos >> 8),\r
-                (**ba).data[(**ba).len - count--] = (byte) (pos >> 16),\r
-                (**ba).data[(**ba).len - count--] = (byte) (pos >> 24);\r
-        }\r
-        else\r
-        {\r
-            regbyte_ctx *new_rbc;\r
-            regbyte_ctx_create (&new_rbc);\r
-            if (new_rbc == NULL)\r
-                return 1;\r
-\r
-            new_rbc->m_prev = *rbc;\r
-            new_rbc->m_regbyte = em->m_regbyte;\r
-            *rbc = new_rbc;\r
-\r
-            if (em->m_emit_type == et_byte)\r
-                new_rbc->m_current_value = em->m_byte;\r
-            else if (em->m_emit_type == et_stream)\r
-                new_rbc->m_current_value = c;\r
-        }\r
-\r
-        em = em->m_next;\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-/*\r
-    string to string map typedef\r
-*/\r
-typedef struct map_str_\r
-{\r
-    byte *key;\r
-    byte *data;\r
-    struct map_str_ *next;\r
-} map_str;\r
-\r
-static void map_str_create (map_str **ma)\r
-{\r
-    *ma = mem_alloc (sizeof (map_str));\r
-    if (*ma)\r
-    {\r
-        (**ma).key = NULL;\r
-        (**ma).data = NULL;\r
-        (**ma).next = NULL;\r
-    }\r
-}\r
-\r
-static void map_str_destroy (map_str **ma)\r
-{\r
-    if (*ma)\r
-    {\r
-        map_str_destroy (&(**ma).next);\r
-        mem_free ((void **) &(**ma).key);\r
-        mem_free ((void **) &(**ma).data);\r
-        mem_free ((void **) ma);\r
-    }\r
-}\r
-\r
-static void map_str_append (map_str **ma, map_str **nm)\r
-{\r
-    while (*ma)\r
-        ma = &(**ma).next;\r
-    *ma = *nm;\r
-}\r
-\r
-/*\r
-    searches the map for specified key,\r
-    if the key is matched, *data is filled with data associated with the key,\r
-    returns 0 if the key is matched,\r
-    returns 1 otherwise\r
-*/\r
-static int map_str_find (map_str **ma, const byte *key, byte **data)\r
-{\r
-    while (*ma)\r
-    {\r
-        if (str_equal ((**ma).key, key))\r
-        {\r
-            *data = str_duplicate ((**ma).data);\r
-            if (*data == NULL)\r
-                return 1;\r
-\r
-            return 0;\r
-        }\r
-\r
-        ma = &(**ma).next;\r
-    }\r
-\r
-    set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);\r
-    return 1;\r
-}\r
-\r
-/*\r
-    string to rule map typedef\r
-*/\r
-typedef struct map_rule_\r
-{\r
-    byte *key;\r
-    rule *data;\r
-    struct map_rule_ *next;\r
-} map_rule;\r
-\r
-static void map_rule_create (map_rule **ma)\r
-{\r
-    *ma = mem_alloc (sizeof (map_rule));\r
-    if (*ma)\r
-    {\r
-        (**ma).key = NULL;\r
-        (**ma).data = NULL;\r
-        (**ma).next = NULL;\r
-    }\r
-}\r
-\r
-static void map_rule_destroy (map_rule **ma)\r
-{\r
-    if (*ma)\r
-    {\r
-        map_rule_destroy (&(**ma).next);\r
-        mem_free ((void **) &(**ma).key);\r
-        mem_free ((void **) ma);\r
-    }\r
-}\r
-\r
-static void map_rule_append (map_rule **ma, map_rule **nm)\r
-{\r
-    while (*ma)\r
-        ma = &(**ma).next;\r
-    *ma = *nm;\r
-}\r
-\r
-/*\r
-    searches the map for specified key,\r
-    if the key is matched, *data is filled with data associated with the key,\r
-    returns 0 if the is matched,\r
-    returns 1 otherwise\r
-*/\r
-static int map_rule_find (map_rule **ma, const byte *key, rule **data)\r
-{\r
-    while (*ma)\r
-    {\r
-        if (str_equal ((**ma).key, key))\r
-        {\r
-            *data = (**ma).data;\r
-\r
-            return 0;\r
-        }\r
-\r
-        ma = &(**ma).next;\r
-    }\r
-\r
-    set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);\r
-    return 1;\r
-}\r
-\r
-/*\r
-    returns 1 if given character is a white space,\r
-    returns 0 otherwise\r
-*/\r
-static int is_space (byte c)\r
-{\r
-    return c == ' ' || c == '\t' || c == '\n' || c == '\r';\r
-}\r
-\r
-/*\r
-    advances text pointer by 1 if character pointed by *text is a space,\r
-    returns 1 if a space has been eaten,\r
-    returns 0 otherwise\r
-*/\r
-static int eat_space (const byte **text)\r
-{\r
-    if (is_space (**text))\r
-    {\r
-        (*text)++;\r
-\r
-        return 1;\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-/*\r
-    returns 1 if text points to C-style comment start string "/*",\r
-    returns 0 otherwise\r
-*/\r
-static int is_comment_start (const byte *text)\r
-{\r
-    return text[0] == '/' && text[1] == '*';\r
-}\r
-\r
-/*\r
-    advances text pointer to first character after C-style comment block - if any,\r
-    returns 1 if C-style comment block has been encountered and eaten,\r
-    returns 0 otherwise\r
-*/\r
-static int eat_comment (const byte **text)\r
-{\r
-    if (is_comment_start (*text))\r
-    {\r
-        /* *text points to comment block - skip two characters to enter comment body */\r
-        *text += 2;\r
-        /* skip any character except consecutive '*' and '/' */\r
-        while (!((*text)[0] == '*' && (*text)[1] == '/'))\r
-            (*text)++;\r
-        /* skip those two terminating characters */\r
-        *text += 2;\r
-\r
-        return 1;\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-/*\r
-    advances text pointer to first character that is neither space nor C-style comment block\r
-*/\r
-static void eat_spaces (const byte **text)\r
-{\r
-    while (eat_space (text) || eat_comment (text))\r
-        ;\r
-}\r
-\r
-/*\r
-    resizes string pointed by *ptr to successfully add character c to the end of the string,\r
-    returns 0 on success,\r
-    returns 1 otherwise\r
-*/\r
-static int string_grow (byte **ptr, unsigned int *len, byte c)\r
-{\r
-    /* reallocate the string in 16-byte increments */\r
-    if ((*len & 0x0F) == 0x0F || *ptr == NULL)\r
-    {\r
-        byte *tmp = mem_realloc (*ptr, ((*len + 1) & ~0x0F) * sizeof (byte),\r
-            ((*len + 1 + 0x10) & ~0x0F) * sizeof (byte));\r
-        if (tmp == NULL)\r
-            return 1;\r
-\r
-        *ptr = tmp;\r
-    }\r
-\r
-    if (c)\r
-    {\r
-        /* append given character */\r
-        (*ptr)[*len] = c;\r
-        (*len)++;\r
-    }\r
-    (*ptr)[*len] = '\0';\r
-\r
-    return 0;\r
-}\r
-\r
-/*\r
-    returns 1 if given character is a valid identifier character a-z, A-Z, 0-9 or _\r
-    returns 0 otherwise\r
-*/\r
-static int is_identifier (byte c)\r
-{\r
-    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';\r
-}\r
-\r
-/*\r
-    copies characters from *text to *id until non-identifier character is encountered,\r
-    assumes that *id points to NULL object - caller is responsible for later freeing the string,\r
-    text pointer is advanced to point past the copied identifier,\r
-    returns 0 if identifier was successfully copied,\r
-    returns 1 otherwise\r
-*/\r
-static int get_identifier (const byte **text, byte **id)\r
-{\r
-    const byte *t = *text;\r
-    byte *p = NULL;\r
-    unsigned int len = 0;\r
-\r
-    if (string_grow (&p, &len, '\0'))\r
-        return 1;\r
-\r
-    /* loop while next character in buffer is valid for identifiers */\r
-    while (is_identifier (*t))\r
-    {\r
-        if (string_grow (&p, &len, *t++))\r
-        {\r
-            mem_free ((void **) &p);\r
-            return 1;\r
-        }\r
-    }\r
-\r
-    *text = t;\r
-    *id = p;\r
-\r
-    return 0;\r
-}\r
-\r
-/*\r
-    returns 1 if given character is HEX digit 0-9, A-F or a-f,\r
-    returns 0 otherwise\r
-*/\r
-static int is_hex (byte c)\r
-{\r
-    return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');\r
-}\r
-\r
-/*\r
-    returns value of passed character as if it was HEX digit\r
-*/\r
-static unsigned int hex2dec (byte c)\r
-{\r
-    if (c >= '0' && c <= '9')\r
-        return c - '0';\r
-    if (c >= 'A' && c <= 'F')\r
-        return c - 'A' + 10;\r
-    return c - 'a' + 10;\r
-}\r
-\r
-/*\r
-    converts sequence of HEX digits pointed by *text until non-HEX digit is encountered,\r
-    advances text pointer past the converted sequence,\r
-    returns the converted value\r
-*/\r
-static unsigned int hex_convert (const byte **text)\r
-{\r
-    unsigned int value = 0;\r
-\r
-    while (is_hex (**text))\r
-    {\r
-        value = value * 0x10 + hex2dec (**text);\r
-        (*text)++;\r
-    }\r
-\r
-    return value;\r
-}\r
-\r
-/*\r
-    returns 1 if given character is OCT digit 0-7,\r
-    returns 0 otherwise\r
-*/\r
-static int is_oct (byte c)\r
-{\r
-    return c >= '0' && c <= '7';\r
-}\r
-\r
-/*\r
-    returns value of passed character as if it was OCT digit\r
-*/\r
-static int oct2dec (byte c)\r
-{\r
-    return c - '0';\r
-}\r
-\r
-static byte get_escape_sequence (const byte **text)\r
-{\r
-    int value = 0;\r
-\r
-    /* skip '\' character */\r
-    (*text)++;\r
-\r
-    switch (*(*text)++)\r
-    {\r
-    case '\'':\r
-        return '\'';\r
-    case '"':\r
-        return '\"';\r
-    case '?':\r
-        return '\?';\r
-    case '\\':\r
-        return '\\';\r
-    case 'a':\r
-        return '\a';\r
-    case 'b':\r
-        return '\b';\r
-    case 'f':\r
-        return '\f';\r
-    case 'n':\r
-        return '\n';\r
-    case 'r':\r
-        return '\r';\r
-    case 't':\r
-        return '\t';\r
-    case 'v':\r
-        return '\v';\r
-    case 'x':\r
-        return (byte) hex_convert (text);\r
-    }\r
-\r
-    (*text)--;\r
-    if (is_oct (**text))\r
-    {\r
-        value = oct2dec (*(*text)++);\r
-        if (is_oct (**text))\r
-        {\r
-            value = value * 010 + oct2dec (*(*text)++);\r
-            if (is_oct (**text))\r
-                value = value * 010 + oct2dec (*(*text)++);\r
-        }\r
-    }\r
-\r
-    return (byte) value;\r
-}\r
-\r
-/*\r
-    copies characters from *text to *str until " or ' character is encountered,\r
-    assumes that *str points to NULL object - caller is responsible for later freeing the string,\r
-    assumes that *text points to " or ' character that starts the string,\r
-    text pointer is advanced to point past the " or ' character,\r
-    returns 0 if string was successfully copied,\r
-    returns 1 otherwise\r
-*/\r
-static int get_string (const byte **text, byte **str)\r
-{\r
-    const byte *t = *text;\r
-    byte *p = NULL;\r
-    unsigned int len = 0;\r
-    byte term_char;\r
-\r
-    if (string_grow (&p, &len, '\0'))\r
-        return 1;\r
-\r
-    /* read " or ' character that starts the string */\r
-    term_char = *t++;\r
-    /* while next character is not the terminating character */\r
-    while (*t && *t != term_char)\r
-    {\r
-        byte c;\r
-\r
-        if (*t == '\\')\r
-            c = get_escape_sequence (&t);\r
-        else\r
-            c = *t++;\r
-\r
-        if (string_grow (&p, &len, c))\r
-        {\r
-            mem_free ((void **) &p);\r
-            return 1;\r
-        }\r
-    }\r
-    /* skip " or ' character that ends the string */\r
-    t++;\r
-\r
-    *text = t;\r
-    *str = p;\r
-    return 0;\r
-}\r
-\r
-/*\r
-    gets emit code, the syntax is: ".emtcode" " " <symbol> " " ("0x" | "0X") <hex_value>\r
-    assumes that *text already points to <symbol>,\r
-    returns 0 if emit code is successfully read,\r
-    returns 1 otherwise\r
-*/\r
-static int get_emtcode (const byte **text, map_byte **ma)\r
-{\r
-    const byte *t = *text;\r
-    map_byte *m = NULL;\r
-\r
-    map_byte_create (&m);\r
-    if (m == NULL)\r
-        return 1;\r
-\r
-    if (get_identifier (&t, &m->key))\r
-    {\r
-        map_byte_destroy (&m);\r
-        return 1;\r
-    }\r
-    eat_spaces (&t);\r
-\r
-    if (*t == '\'')\r
-    {\r
-        byte *c;\r
-\r
-        if (get_string (&t, &c))\r
-        {\r
-            map_byte_destroy (&m);\r
-            return 1;\r
-        }\r
-\r
-        m->data = (byte) c[0];\r
-        mem_free ((void **) &c);\r
-    }\r
-    else\r
-    {\r
-        /* skip HEX "0x" or "0X" prefix */\r
-        t += 2;\r
-        m->data = (byte) hex_convert (&t);\r
-    }\r
-\r
-    eat_spaces (&t);\r
-\r
-    *text = t;\r
-    *ma = m;\r
-    return 0;\r
-}\r
-\r
-/*\r
-    gets regbyte declaration, the syntax is: ".regbyte" " " <symbol> " " ("0x" | "0X") <hex_value>\r
-    assumes that *text already points to <symbol>,\r
-    returns 0 if regbyte is successfully read,\r
-    returns 1 otherwise\r
-*/\r
-static int get_regbyte (const byte **text, map_byte **ma)\r
-{\r
-    return get_emtcode (text, ma);\r
-}\r
-\r
-/*\r
-    returns 0 on success,\r
-    returns 1 otherwise\r
-*/\r
-static int get_errtext (const byte **text, map_str **ma)\r
-{\r
-    const byte *t = *text;\r
-    map_str *m = NULL;\r
-\r
-    map_str_create (&m);\r
-    if (m == NULL)\r
-        return 1;\r
-\r
-    if (get_identifier (&t, &m->key))\r
-    {\r
-        map_str_destroy (&m);\r
-        return 1;\r
-    }\r
-    eat_spaces (&t);\r
-\r
-    if (get_string (&t, &m->data))\r
-    {\r
-        map_str_destroy (&m);\r
-        return 1;\r
-    }\r
-    eat_spaces (&t);\r
-\r
-    *text = t;\r
-    *ma = m;\r
-    return 0;\r
-}\r
-\r
-/*\r
-    returns 0 on success,\r
-    returns 1 otherwise,\r
-*/\r
-static int get_error (const byte **text, error **er, map_str *maps)\r
-{\r
-    const byte *t = *text;\r
-    byte *temp = NULL;\r
-\r
-    if (*t != '.')\r
-        return 0;\r
-\r
-    t++;\r
-    if (get_identifier (&t, &temp))\r
-        return 1;\r
-    eat_spaces (&t);\r
-\r
-    if (!str_equal ((byte *) "error", temp))\r
-    {\r
-        mem_free ((void **) &temp);\r
-        return 0;\r
-    }\r
-\r
-    mem_free ((void **) &temp);\r
-\r
-    error_create (er);\r
-    if (*er == NULL)\r
-        return 1;\r
-\r
-    if (*t == '\"')\r
-    {\r
-        if (get_string (&t, &(**er).m_text))\r
-        {\r
-            error_destroy (er);\r
-            return 1;\r
-        }\r
-        eat_spaces (&t);\r
-    }\r
-    else\r
-    {\r
-        if (get_identifier (&t, &temp))\r
-        {\r
-            error_destroy (er);\r
-            return 1;\r
-        }\r
-        eat_spaces (&t);\r
-\r
-        if (map_str_find (&maps, temp, &(**er).m_text))\r
-        {\r
-            mem_free ((void **) &temp);\r
-            error_destroy (er);\r
-            return 1;\r
-        }\r
-\r
-        mem_free ((void **) &temp);\r
-    }\r
-\r
-    /* try to extract "token" from "...$token$..." */\r
-    {\r
-        byte *processed = NULL;\r
-        unsigned int len = 0, i = 0;\r
-\r
-        if (string_grow (&processed, &len, '\0'))\r
-        {\r
-            error_destroy (er);\r
-            return 1;\r
-        }\r
-\r
-        while (i < str_length ((**er).m_text))\r
-        {\r
-            /* check if the dollar sign is repeated - if so skip it */\r
-            if ((**er).m_text[i] == '$' && (**er).m_text[i + 1] == '$')\r
-            {\r
-                if (string_grow (&processed, &len, '$'))\r
-                {\r
-                    mem_free ((void **) &processed);\r
-                    error_destroy (er);\r
-                    return 1;\r
-                }\r
-\r
-                i += 2;\r
-            }\r
-            else if ((**er).m_text[i] != '$')\r
-            {\r
-                if (string_grow (&processed, &len, (**er).m_text[i]))\r
-                {\r
-                    mem_free ((void **) &processed);\r
-                    error_destroy (er);\r
-                    return 1;\r
-                }\r
-\r
-                i++;\r
-            }\r
-            else\r
-            {\r
-                if (string_grow (&processed, &len, '$'))\r
-                {\r
-                    mem_free ((void **) &processed);\r
-                    error_destroy (er);\r
-                    return 1;\r
-                }\r
-\r
-                {\r
-                    /* length of token being extracted */\r
-                    unsigned int tlen = 0;\r
-\r
-                    if (string_grow (&(**er).m_token_name, &tlen, '\0'))\r
-                    {\r
-                        mem_free ((void **) &processed);\r
-                        error_destroy (er);\r
-                        return 1;\r
-                    }\r
-\r
-                    /* skip the dollar sign */\r
-                    i++;\r
-\r
-                    while ((**er).m_text[i] != '$')\r
-                    {\r
-                        if (string_grow (&(**er).m_token_name, &tlen, (**er).m_text[i]))\r
-                        {\r
-                            mem_free ((void **) &processed);\r
-                            error_destroy (er);\r
-                            return 1;\r
-                        }\r
-\r
-                        i++;\r
-                    }\r
-\r
-                    /* skip the dollar sign */\r
-                    i++;\r
-                }\r
-            }\r
-        }\r
-\r
-        mem_free ((void **) &(**er).m_text);\r
-        (**er).m_text = processed;\r
-    }\r
-\r
-    *text = t;\r
-    return 0;\r
-}\r
-\r
-/*\r
-    returns 0 on success,\r
-    returns 1 otherwise,\r
-*/\r
-static int get_emits (const byte **text, emit **em, map_byte *mapb)\r
-{\r
-    const byte *t = *text;\r
-    byte *temp = NULL;\r
-    emit *e = NULL;\r
-    emit_dest dest;\r
-\r
-    if (*t != '.')\r
-        return 0;\r
-\r
-    t++;\r
-    if (get_identifier (&t, &temp))\r
-        return 1;\r
-    eat_spaces (&t);\r
-\r
-    /* .emit */\r
-    if (str_equal ((byte *) "emit", temp))\r
-        dest = ed_output;\r
-    /* .load */\r
-    else if (str_equal ((byte *) "load", temp))\r
-        dest = ed_regbyte;\r
-    else\r
-    {\r
-        mem_free ((void **) &temp);\r
-        return 0;\r
-    }\r
-\r
-    mem_free ((void **) &temp);\r
-\r
-    emit_create (&e);\r
-    if (e == NULL)\r
-        return 1;\r
-\r
-    e->m_emit_dest = dest;\r
-\r
-    if (dest == ed_regbyte)\r
-    {\r
-        if (get_identifier (&t, &e->m_regname))\r
-        {\r
-            emit_destroy (&e);\r
-            return 1;\r
-        }\r
-        eat_spaces (&t);\r
-    }\r
-\r
-    /* 0xNN */\r
-    if (*t == '0')\r
-    {\r
-        t += 2;\r
-        e->m_byte = (byte) hex_convert (&t);\r
-\r
-        e->m_emit_type = et_byte;\r
-    }\r
-    /* * */\r
-    else if (*t == '*')\r
-    {\r
-        t++;\r
-\r
-        e->m_emit_type = et_stream;\r
-    }\r
-    /* $ */\r
-    else if (*t == '$')\r
-    {\r
-        t++;\r
-\r
-        e->m_emit_type = et_position;\r
-    }\r
-    /* 'c' */\r
-    else if (*t == '\'')\r
-    {\r
-        if (get_string (&t, &temp))\r
-        {\r
-            emit_destroy (&e);\r
-            return 1;\r
-        }\r
-        e->m_byte = (byte) temp[0];\r
-\r
-        mem_free ((void **) &temp);\r
-\r
-        e->m_emit_type = et_byte;\r
-    }\r
-    else\r
-    {\r
-        if (get_identifier (&t, &temp))\r
-        {\r
-            emit_destroy (&e);\r
-            return 1;\r
-        }\r
-\r
-        if (map_byte_find (&mapb, temp, &e->m_byte))\r
-        {\r
-            mem_free ((void **) &temp);\r
-            emit_destroy (&e);\r
-            return 1;\r
-        }\r
-\r
-        mem_free ((void **) &temp);\r
-\r
-        e->m_emit_type = et_byte;\r
-    }\r
-\r
-    eat_spaces (&t);\r
-\r
-    if (get_emits (&t, &e->m_next, mapb))\r
-    {\r
-        emit_destroy (&e);\r
-        return 1;\r
-    }\r
-\r
-    *text = t;\r
-    *em = e;\r
-    return 0;\r
-}\r
-\r
-/*\r
-    returns 0 on success,\r
-    returns 1 otherwise,\r
-*/\r
-static int get_spec (const byte **text, spec **sp, map_str *maps, map_byte *mapb)\r
-{\r
-    const byte *t = *text;\r
-    spec *s = NULL;\r
-\r
-    spec_create (&s);\r
-    if (s == NULL)\r
-        return 1;\r
-\r
-    /* first - read optional .if statement */\r
-    if (*t == '.')\r
-    {\r
-        const byte *u = t;\r
-        byte *keyword = NULL;\r
-\r
-        /* skip the dot */\r
-        u++;\r
-\r
-        if (get_identifier (&u, &keyword))\r
-        {\r
-            spec_destroy (&s);\r
-            return 1;\r
-        }\r
-\r
-        /* .if */\r
-        if (str_equal ((byte *) "if", keyword))\r
-        {\r
-            cond_create (&s->m_cond);\r
-            if (s->m_cond == NULL)\r
-            {\r
-                spec_destroy (&s);\r
-                return 1;\r
-            }\r
-\r
-            /* skip the left paren */\r
-            eat_spaces (&u);\r
-            u++;\r
-\r
-            /* get the left operand */\r
-            eat_spaces (&u);\r
-            if (get_identifier (&u, &s->m_cond->m_operands[0].m_regname))\r
-            {\r
-                spec_destroy (&s);\r
-                return 1;\r
-            }\r
-            s->m_cond->m_operands[0].m_type = cot_regbyte;\r
-\r
-            /* get the operator (!= or ==) */\r
-            eat_spaces (&u);\r
-            if (*u == '!')\r
-                s->m_cond->m_type = ct_not_equal;\r
-            else\r
-                s->m_cond->m_type = ct_equal;\r
-            u += 2;\r
-\r
-            /* skip the 0x prefix */\r
-            eat_spaces (&u);\r
-            u += 2;\r
-\r
-            /* get the right operand */\r
-            s->m_cond->m_operands[1].m_byte = hex_convert (&u);\r
-            s->m_cond->m_operands[1].m_type = cot_byte;\r
-\r
-            /* skip the right paren */\r
-            eat_spaces (&u);\r
-            u++;\r
-\r
-            eat_spaces (&u);\r
-\r
-            t = u;\r
-        }\r
-\r
-        mem_free ((void **) &keyword);\r
-    }\r
-\r
-    if (*t == '\'')\r
-    {\r
-        byte *temp = NULL;\r
-\r
-        if (get_string (&t, &temp))\r
-        {\r
-            spec_destroy (&s);\r
-            return 1;\r
-        }\r
-        eat_spaces (&t);\r
-\r
-        if (*t == '-')\r
-        {\r
-            byte *temp2 = NULL;\r
-\r
-            /* skip the '-' character */\r
-            t++;\r
-            eat_spaces (&t);\r
-\r
-            if (get_string (&t, &temp2))\r
-            {\r
-                mem_free ((void **) &temp);\r
-                spec_destroy (&s);\r
-                return 1;\r
-            }\r
-            eat_spaces (&t);\r
-\r
-            s->m_spec_type = st_byte_range;\r
-            s->m_byte[0] = *temp;\r
-            s->m_byte[1] = *temp2;\r
-\r
-            mem_free ((void **) &temp2);\r
-        }\r
-        else\r
-        {\r
-            s->m_spec_type = st_byte;\r
-            *s->m_byte = *temp;\r
-        }\r
-\r
-        mem_free ((void **) &temp);\r
-    }\r
-    else if (*t == '"')\r
-    {\r
-        if (get_string (&t, &s->m_string))\r
-        {\r
-            spec_destroy (&s);\r
-            return 1;\r
-        }\r
-        eat_spaces (&t);\r
-\r
-        s->m_spec_type = st_string;\r
-    }\r
-    else if (*t == '.')\r
-    {\r
-        byte *keyword = NULL;\r
-\r
-        /* skip the dot */\r
-        t++;\r
-\r
-        if (get_identifier (&t, &keyword))\r
-        {\r
-            spec_destroy (&s);\r
-            return 1;\r
-        }\r
-        eat_spaces (&t);\r
-\r
-        /* .true */\r
-        if (str_equal ((byte *) "true", keyword))\r
-        {\r
-            s->m_spec_type = st_true;\r
-        }\r
-        /* .false */\r
-        else if (str_equal ((byte *) "false", keyword))\r
-        {\r
-            s->m_spec_type = st_false;\r
-        }\r
-        /* .debug */\r
-        else if (str_equal ((byte *) "debug", keyword))\r
-        {\r
-            s->m_spec_type = st_debug;\r
-        }\r
-        /* .loop */\r
-        else if (str_equal ((byte *) "loop", keyword))\r
-        {\r
-            if (get_identifier (&t, &s->m_string))\r
-            {\r
-                mem_free ((void **) &keyword);\r
-                spec_destroy (&s);\r
-                return 1;\r
-            }\r
-            eat_spaces (&t);\r
-\r
-            s->m_spec_type = st_identifier_loop;\r
-        }\r
-\r
-        mem_free ((void **) &keyword);\r
-    }\r
-    else\r
-    {\r
-        if (get_identifier (&t, &s->m_string))\r
-        {\r
-            spec_destroy (&s);\r
-            return 1;\r
-        }\r
-        eat_spaces (&t);\r
-\r
-        s->m_spec_type = st_identifier;\r
-    }\r
-\r
-    if (get_error (&t, &s->m_errtext, maps))\r
-    {\r
-        spec_destroy (&s);\r
-        return 1;\r
-    }\r
-\r
-    if (get_emits (&t, &s->m_emits, mapb))\r
-    {\r
-        spec_destroy (&s);\r
-        return 1;\r
-    }\r
-\r
-    *text = t;\r
-    *sp = s;\r
-    return 0;\r
-}\r
-\r
-/*\r
-    returns 0 on success,\r
-    returns 1 otherwise,\r
-*/\r
-static int get_rule (const byte **text, rule **ru, map_str *maps, map_byte *mapb)\r
-{\r
-    const byte *t = *text;\r
-    rule *r = NULL;\r
-\r
-    rule_create (&r);\r
-    if (r == NULL)\r
-        return 1;\r
-\r
-    if (get_spec (&t, &r->m_specs, maps, mapb))\r
-    {\r
-        rule_destroy (&r);\r
-        return 1;\r
-    }\r
-\r
-    while (*t != ';')\r
-    {\r
-        byte *op = NULL;\r
-        spec *sp = NULL;\r
-\r
-        /* skip the dot that precedes "and" or "or" */\r
-        t++;\r
-\r
-        /* read "and" or "or" keyword */\r
-        if (get_identifier (&t, &op))\r
-        {\r
-            rule_destroy (&r);\r
-            return 1;\r
-        }\r
-        eat_spaces (&t);\r
-\r
-        if (r->m_oper == op_none)\r
-        {\r
-            /* .and */\r
-            if (str_equal ((byte *) "and", op))\r
-                r->m_oper = op_and;\r
-            /* .or */\r
-            else\r
-                r->m_oper = op_or;\r
-        }\r
-\r
-        mem_free ((void **) &op);\r
-\r
-        if (get_spec (&t, &sp, maps, mapb))\r
-        {\r
-            rule_destroy (&r);\r
-            return 1;\r
-        }\r
-\r
-        spec_append (&r->m_specs, &sp);\r
-    }\r
-\r
-    /* skip the semicolon */\r
-    t++;\r
-    eat_spaces (&t);\r
-\r
-    *text = t;\r
-    *ru = r;\r
-    return 0;\r
-}\r
-\r
-/*\r
-    returns 0 on success,\r
-    returns 1 otherwise,\r
-*/\r
-static int update_dependency (map_rule *mapr, byte *symbol, rule **ru)\r
-{\r
-    if (map_rule_find (&mapr, symbol, ru))\r
-        return 1;\r
-\r
-/*  (**ru).m_referenced = 1; */\r
-\r
-    return 0;\r
-}\r
-\r
-/*\r
-    returns 0 on success,\r
-    returns 1 otherwise,\r
-*/\r
-static int update_dependencies (dict *di, map_rule *mapr, byte **syntax_symbol,\r
-    byte **string_symbol, map_byte *regbytes)\r
-{\r
-    rule *rulez = di->m_rulez;\r
-\r
-    /* update dependecies for the root and lexer symbols */\r
-    if (update_dependency (mapr, *syntax_symbol, &di->m_syntax) ||\r
-        (*string_symbol != NULL && update_dependency (mapr, *string_symbol, &di->m_string)))\r
-        return 1;\r
-\r
-    mem_free ((void **) syntax_symbol);\r
-    mem_free ((void **) string_symbol);\r
-\r
-    /* update dependecies for the rest of the rules */\r
-    while (rulez)\r
-    {\r
-        spec *sp = rulez->m_specs;\r
-\r
-        /* iterate through all the specifiers */\r
-        while (sp)\r
-        {\r
-            /* update dependency for identifier */\r
-            if (sp->m_spec_type == st_identifier || sp->m_spec_type == st_identifier_loop)\r
-            {\r
-                if (update_dependency (mapr, sp->m_string, &sp->m_rule))\r
-                    return 1;\r
-\r
-                mem_free ((void **) &sp->m_string);\r
-            }\r
-\r
-            /* some errtexts reference to a rule */\r
-            if (sp->m_errtext && sp->m_errtext->m_token_name)\r
-            {\r
-                if (update_dependency (mapr, sp->m_errtext->m_token_name, &sp->m_errtext->m_token))\r
-                    return 1;\r
-\r
-                mem_free ((void **) &sp->m_errtext->m_token_name);\r
-            }\r
-\r
-            /* update dependency for condition */\r
-            if (sp->m_cond)\r
-            {\r
-                int i;\r
-                for (i = 0; i < 2; i++)\r
-                    if (sp->m_cond->m_operands[i].m_type == cot_regbyte)\r
-                    {\r
-                        sp->m_cond->m_operands[i].m_regbyte = map_byte_locate (&regbytes,\r
-                            sp->m_cond->m_operands[i].m_regname);\r
-\r
-                        if (sp->m_cond->m_operands[i].m_regbyte == NULL)\r
-                            return 1;\r
-\r
-                        mem_free ((void **) &sp->m_cond->m_operands[i].m_regname);\r
-                    }\r
-            }\r
-\r
-            /* update dependency for all .load instructions */\r
-            if (sp->m_emits)\r
-            {\r
-                emit *em = sp->m_emits;\r
-                while (em != NULL)\r
-                {\r
-                    if (em->m_emit_dest == ed_regbyte)\r
-                    {\r
-                        em->m_regbyte = map_byte_locate (&regbytes, em->m_regname);\r
-\r
-                        if (em->m_regbyte == NULL)\r
-                            return 1;\r
-\r
-                        mem_free ((void **) &em->m_regname);\r
-                    }\r
-\r
-                    em = em->m_next;\r
-                }\r
-            }\r
-\r
-            sp = sp->m_next;\r
-        }\r
-\r
-        rulez = rulez->m_next;\r
-    }\r
-\r
-/* check for unreferenced symbols */\r
-/*  de = di->m_defntns;\r
-    while (de)\r
-    {\r
-        if (!de->m_referenced)\r
-        {\r
-            map_def *ma = mapd;\r
-            while (ma)\r
-            {\r
-                if (ma->data == de)\r
-                {\r
-                    assert (0);\r
-                    break;\r
-                }\r
-                ma = ma->next;\r
-            }\r
-        }\r
-        de = de->m_next;\r
-    }\r
-*/\r
-    return 0;\r
-}\r
-\r
-static int satisfies_condition (cond *co, regbyte_ctx *ctx)\r
-{\r
-    byte values[2];\r
-    int i;\r
-\r
-    if (co == NULL)\r
-        return 1;\r
-\r
-    for (i = 0; i < 2; i++)\r
-        switch (co->m_operands[i].m_type)\r
-        {\r
-        case cot_byte:\r
-            values[i] = co->m_operands[i].m_byte;\r
-            break;\r
-        case cot_regbyte:\r
-            values[i] = regbyte_ctx_extract (&ctx, co->m_operands[i].m_regbyte);\r
-            break;\r
-        }\r
-\r
-    switch (co->m_type)\r
-    {\r
-    case ct_equal:\r
-        return values[0] == values[1];\r
-    case ct_not_equal:\r
-        return values[0] != values[1];\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-static void free_regbyte_ctx_stack (regbyte_ctx *top, regbyte_ctx *limit)\r
-{\r
-    while (top != limit)\r
-    {\r
-        regbyte_ctx *rbc = top->m_prev;\r
-        regbyte_ctx_destroy (&top);\r
-        top = rbc;\r
-    }\r
-}\r
-\r
-typedef enum match_result_\r
-{\r
-    mr_not_matched,     /* the examined string does not match */\r
-    mr_matched,         /* the examined string matches */\r
-    mr_error_raised,    /* mr_not_matched + error has been raised */\r
-    mr_dont_emit,       /* used by identifier loops only */\r
-    mr_internal_error   /* an internal error has occured such as out of memory */\r
-} match_result;\r
-\r
-/*\r
-    This function does the main job. It parses the text and generates output data.\r
-\r
-    XXX optimize it - the barray seems to be the bottleneck\r
-*/\r
-static match_result match (dict *di, const byte *text, unsigned int *index, rule *ru, barray **ba,\r
-    int filtering_string, regbyte_ctx **rbc)\r
-{\r
-    unsigned int ind = *index;\r
-    match_result status = mr_not_matched;\r
-    spec *sp = ru->m_specs;\r
-    regbyte_ctx *ctx = *rbc;\r
-\r
-    /* for every specifier in the rule */\r
-    while (sp)\r
-    {\r
-        unsigned int i, len, save_ind = ind;\r
-        barray *array = NULL;\r
-\r
-        if (satisfies_condition (sp->m_cond, ctx))\r
-        {\r
-            switch (sp->m_spec_type)\r
-            {\r
-            case st_identifier:\r
-                barray_create (&array);\r
-                if (array == NULL)\r
-                {\r
-                    free_regbyte_ctx_stack (ctx, *rbc);\r
-                    return mr_internal_error;\r
-                }\r
-\r
-                status = match (di, text, &ind, sp->m_rule, &array, filtering_string, &ctx);\r
-                if (status == mr_internal_error)\r
-                {\r
-                    free_regbyte_ctx_stack (ctx, *rbc);\r
-                    barray_destroy (&array);\r
-                    return mr_internal_error;\r
-                }\r
-                break;\r
-            case st_string:\r
-                len = str_length (sp->m_string);\r
-\r
-                /* prefilter the stream */\r
-                if (!filtering_string && di->m_string)\r
-                {\r
-                    barray *ba;\r
-                    unsigned int filter_index = 0;\r
-                    match_result result;\r
-                    regbyte_ctx *null_ctx = NULL;\r
-\r
-                    barray_create (&ba);\r
-                    if (ba == NULL)\r
-                    {\r
-                        free_regbyte_ctx_stack (ctx, *rbc);\r
-                        return mr_internal_error;\r
-                    }\r
-\r
-                    result = match (di, text + ind, &filter_index, di->m_string, &ba, 1, &null_ctx);\r
-\r
-                    if (result == mr_internal_error)\r
-                    {\r
-                        free_regbyte_ctx_stack (ctx, *rbc);\r
-                        barray_destroy (&ba);\r
-                        return mr_internal_error;\r
-                    }\r
-\r
-                    if (result != mr_matched)\r
-                    {\r
-                        barray_destroy (&ba);\r
-                        status = mr_not_matched;\r
-                        break;\r
-                    }\r
-\r
-                    barray_destroy (&ba);\r
-\r
-                    if (filter_index != len || !str_equal_n (sp->m_string, text + ind, len))\r
-                    {\r
-                        status = mr_not_matched;\r
-                        break;\r
-                    }\r
-\r
-                    status = mr_matched;\r
-                    ind += len;\r
-                }\r
-                else\r
-                {\r
-                    status = mr_matched;\r
-                    for (i = 0; status == mr_matched && i < len; i++)\r
-                        if (text[ind + i] != sp->m_string[i])\r
-                            status = mr_not_matched;\r
-                    if (status == mr_matched)\r
-                        ind += len;\r
-                }\r
-                break;\r
-            case st_byte:\r
-                status = text[ind] == *sp->m_byte ? mr_matched : mr_not_matched;\r
-                if (status == mr_matched)\r
-                    ind++;\r
-                break;\r
-            case st_byte_range:\r
-                status = (text[ind] >= sp->m_byte[0] && text[ind] <= sp->m_byte[1]) ?\r
-                    mr_matched : mr_not_matched;\r
-                if (status == mr_matched)\r
-                    ind++;\r
-                break;\r
-            case st_true:\r
-                status = mr_matched;\r
-                break;\r
-            case st_false:\r
-                status = mr_not_matched;\r
-                break;\r
-            case st_debug:\r
-                status = ru->m_oper == op_and ? mr_matched : mr_not_matched;\r
-                break;\r
-            case st_identifier_loop:\r
-                barray_create (&array);\r
-                if (array == NULL)\r
-                {\r
-                    free_regbyte_ctx_stack (ctx, *rbc);\r
-                    return mr_internal_error;\r
-                }\r
-\r
-                status = mr_dont_emit;\r
-                for (;;)\r
-                {\r
-                    match_result result;\r
-\r
-                    save_ind = ind;\r
-                    result = match (di, text, &ind, sp->m_rule, &array, filtering_string, &ctx);\r
-\r
-                    if (result == mr_error_raised)\r
-                    {\r
-                        status = result;\r
-                        break;\r
-                    }\r
-                    else if (result == mr_matched)\r
-                    {\r
-                        if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind, &ctx) ||\r
-                            barray_append (ba, &array))\r
-                        {\r
-                            free_regbyte_ctx_stack (ctx, *rbc);\r
-                            barray_destroy (&array);\r
-                            return mr_internal_error;\r
-                        }\r
-                        barray_destroy (&array);\r
-                        barray_create (&array);\r
-                        if (array == NULL)\r
-                        {\r
-                            free_regbyte_ctx_stack (ctx, *rbc);\r
-                            return mr_internal_error;\r
-                        }\r
-                    }\r
-                    else if (result == mr_internal_error)\r
-                    {\r
-                        free_regbyte_ctx_stack (ctx, *rbc);\r
-                        barray_destroy (&array);\r
-                        return mr_internal_error;\r
-                    }\r
-                    else\r
-                        break;\r
-                }\r
-                break;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            status = mr_not_matched;\r
-        }\r
-\r
-        if (status == mr_error_raised)\r
-        {\r
-            free_regbyte_ctx_stack (ctx, *rbc);\r
-            barray_destroy (&array);\r
-\r
-            return mr_error_raised;\r
-        }\r
-\r
-        if (ru->m_oper == op_and && status != mr_matched && status != mr_dont_emit)\r
-        {\r
-            free_regbyte_ctx_stack (ctx, *rbc);\r
-            barray_destroy (&array);\r
-\r
-            if (sp->m_errtext)\r
-            {\r
-                set_last_error (sp->m_errtext->m_text, error_get_token (sp->m_errtext, di, text,\r
-                    ind), ind);\r
-\r
-                return mr_error_raised;\r
-            }\r
-\r
-            return mr_not_matched;\r
-        }\r
-\r
-        if (status == mr_matched)\r
-        {\r
-            if (sp->m_emits)\r
-                if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind, &ctx))\r
-                {\r
-                    free_regbyte_ctx_stack (ctx, *rbc);\r
-                    barray_destroy (&array);\r
-                    return mr_internal_error;\r
-                }\r
-\r
-            if (array)\r
-                if (barray_append (ba, &array))\r
-                {\r
-                    free_regbyte_ctx_stack (ctx, *rbc);\r
-                    barray_destroy (&array);\r
-                    return mr_internal_error;\r
-                }\r
-        }\r
-\r
-        barray_destroy (&array);\r
-\r
-        /* if the rule operator is a logical or, we pick up the first matching specifier */\r
-        if (ru->m_oper == op_or && (status == mr_matched || status == mr_dont_emit))\r
-        {\r
-            *index = ind;\r
-            *rbc = ctx;\r
-            return mr_matched;\r
-        }\r
-\r
-        sp = sp->m_next;\r
-    }\r
-\r
-    /* everything went fine - all specifiers match up */\r
-    if (ru->m_oper == op_and && (status == mr_matched || status == mr_dont_emit))\r
-    {\r
-        *index = ind;\r
-        *rbc = ctx;\r
-        return mr_matched;\r
-    }\r
-\r
-    free_regbyte_ctx_stack (ctx, *rbc);\r
-    return mr_not_matched;\r
-}\r
-\r
-static byte *error_get_token (error *er, dict *di, const byte *text, unsigned int ind)\r
-{\r
-    byte *str = NULL;\r
-\r
-    if (er->m_token)\r
-    {\r
-        barray *ba;\r
-        unsigned int filter_index = 0;\r
-        regbyte_ctx *ctx = NULL;\r
-\r
-        barray_create (&ba);\r
-        if (ba != NULL)\r
-        {\r
-            if (match (di, text + ind, &filter_index, er->m_token, &ba, 0, &ctx) == mr_matched &&\r
-                filter_index)\r
-            {\r
-                str = mem_alloc (filter_index + 1);\r
-                if (str != NULL)\r
-                {\r
-                    str_copy_n (str, text + ind, filter_index);\r
-                    str[filter_index] = '\0';\r
-                }\r
-            }\r
-            barray_destroy (&ba);\r
-        }\r
-    }\r
-\r
-    return str;\r
-}\r
-\r
-typedef struct grammar_load_state_\r
-{\r
-    dict *di;\r
-    byte *syntax_symbol;\r
-    byte *string_symbol;\r
-    map_str *maps;\r
-    map_byte *mapb;\r
-    map_rule *mapr;\r
-} grammar_load_state;\r
-\r
-static void grammar_load_state_create (grammar_load_state **gr)\r
-{\r
-    *gr = mem_alloc (sizeof (grammar_load_state));\r
-    if (*gr)\r
-    {\r
-        (**gr).di = NULL;\r
-        (**gr).syntax_symbol = NULL;\r
-        (**gr).string_symbol = NULL;\r
-        (**gr).maps = NULL;\r
-        (**gr).mapb = NULL;\r
-        (**gr).mapr = NULL;\r
-    }\r
-}\r
-\r
-static void grammar_load_state_destroy (grammar_load_state **gr)\r
-{\r
-    if (*gr)\r
-    {\r
-        dict_destroy (&(**gr).di);\r
-        mem_free ((void **) &(**gr).syntax_symbol);\r
-        mem_free ((void **) &(**gr).string_symbol);\r
-        map_str_destroy (&(**gr).maps);\r
-        map_byte_destroy (&(**gr).mapb);\r
-        map_rule_destroy (&(**gr).mapr);\r
-        mem_free ((void **) gr);\r
-    }\r
-}\r
-\r
-/*\r
-    the API\r
-*/\r
-\r
-grammar grammar_load_from_text (const byte *text)\r
-{\r
-    grammar_load_state *g = NULL;\r
-    grammar id = 0;\r
-\r
-    clear_last_error ();\r
-\r
-    grammar_load_state_create (&g);\r
-    if (g == NULL)\r
-        return 0;\r
-\r
-    dict_create (&g->di);\r
-    if (g->di == NULL)\r
-    {\r
-        grammar_load_state_destroy (&g);\r
-        return 0;\r
-    }\r
-\r
-    eat_spaces (&text);\r
-\r
-    /* skip ".syntax" keyword */\r
-    text += 7;\r
-    eat_spaces (&text);\r
-\r
-    /* retrieve root symbol */\r
-    if (get_identifier (&text, &g->syntax_symbol))\r
-    {\r
-        grammar_load_state_destroy (&g);\r
-        return 0;\r
-    }\r
-    eat_spaces (&text);\r
-\r
-    /* skip semicolon */\r
-    text++;\r
-    eat_spaces (&text);\r
-\r
-    while (*text)\r
-    {\r
-        byte *symbol = NULL;\r
-        int is_dot = *text == '.';\r
-\r
-        if (is_dot)\r
-            text++;\r
-\r
-        if (get_identifier (&text, &symbol))\r
-        {\r
-            grammar_load_state_destroy (&g);\r
-            return 0;\r
-        }\r
-        eat_spaces (&text);\r
-\r
-        /* .emtcode */\r
-        if (is_dot && str_equal (symbol, (byte *) "emtcode"))\r
-        {\r
-            map_byte *ma = NULL;\r
-\r
-            mem_free ((void **) &symbol);\r
-\r
-            if (get_emtcode (&text, &ma))\r
-            {\r
-                grammar_load_state_destroy (&g);\r
-                return 0;\r
-            }\r
-\r
-            map_byte_append (&g->mapb, &ma);\r
-        }\r
-        /* .regbyte */\r
-        else if (is_dot && str_equal (symbol, (byte *) "regbyte"))\r
-        {\r
-            map_byte *ma = NULL;\r
-\r
-            mem_free ((void **) &symbol);\r
-\r
-            if (get_regbyte (&text, &ma))\r
-            {\r
-                grammar_load_state_destroy (&g);\r
-                return 0;\r
-            }\r
-\r
-            map_byte_append (&g->di->m_regbytes, &ma);\r
-        }\r
-        /* .errtext */\r
-        else if (is_dot && str_equal (symbol, (byte *) "errtext"))\r
-        {\r
-            map_str *ma = NULL;\r
-\r
-            mem_free ((void **) &symbol);\r
-\r
-            if (get_errtext (&text, &ma))\r
-            {\r
-                grammar_load_state_destroy (&g);\r
-                return 0;\r
-            }\r
-\r
-            map_str_append (&g->maps, &ma);\r
-        }\r
-        /* .string */\r
-        else if (is_dot && str_equal (symbol, (byte *) "string"))\r
-        {\r
-            mem_free ((void **) &symbol);\r
-\r
-            if (g->di->m_string != NULL)\r
-            {\r
-                grammar_load_state_destroy (&g);\r
-                return 0;\r
-            }\r
-\r
-            if (get_identifier (&text, &g->string_symbol))\r
-            {\r
-                grammar_load_state_destroy (&g);\r
-                return 0;\r
-            }\r
-\r
-            /* skip semicolon */\r
-            eat_spaces (&text);\r
-            text++;\r
-            eat_spaces (&text);\r
-        }\r
-        else\r
-        {\r
-            rule *ru = NULL;\r
-            map_rule *ma = NULL;\r
-\r
-            if (get_rule (&text, &ru, g->maps, g->mapb))\r
-            {\r
-                grammar_load_state_destroy (&g);\r
-                return 0;\r
-            }\r
-\r
-            rule_append (&g->di->m_rulez, &ru);\r
-\r
-            /* if a rule consist of only one specifier, give it an ".and" operator */\r
-            if (ru->m_oper == op_none)\r
-                ru->m_oper = op_and;\r
-\r
-            map_rule_create (&ma);\r
-            if (ma == NULL)\r
-            {\r
-                grammar_load_state_destroy (&g);\r
-                return 0;\r
-            }\r
-\r
-            ma->key = symbol;\r
-            ma->data = ru;\r
-            map_rule_append (&g->mapr, &ma);\r
-        }\r
-    }\r
-\r
-    if (update_dependencies (g->di, g->mapr, &g->syntax_symbol, &g->string_symbol,\r
-        g->di->m_regbytes))\r
-    {\r
-        grammar_load_state_destroy (&g);\r
-        return 0;\r
-    }\r
-\r
-    dict_append (&g_dicts, &g->di);\r
-    id = g->di->m_id;\r
-    g->di = NULL;\r
-\r
-    grammar_load_state_destroy (&g);\r
-\r
-    return id;\r
-}\r
-\r
-int grammar_set_reg8 (grammar id, const byte *name, byte value)\r
-{\r
-    dict *di = NULL;\r
-    map_byte *reg = NULL;\r
-\r
-    clear_last_error ();\r
-\r
-    dict_find (&g_dicts, id, &di);\r
-    if (di == NULL)\r
-    {\r
-        set_last_error (INVALID_GRAMMAR_ID, NULL, -1);\r
-        return 0;\r
-    }\r
-\r
-    reg = map_byte_locate (&di->m_regbytes, name);\r
-    if (reg == NULL)\r
-    {\r
-        set_last_error (INVALID_REGISTER_NAME, str_duplicate (name), -1);\r
-        return 0;\r
-    }\r
-\r
-    reg->data = value;\r
-    return 1;\r
-}\r
-\r
-int grammar_check (grammar id, const byte *text, byte **prod, unsigned int *size)\r
-{\r
-    dict *di = NULL;\r
-    barray *ba = NULL;\r
-    unsigned int index = 0;\r
-    regbyte_ctx *rbc = NULL;\r
-\r
-    clear_last_error ();\r
-\r
-    dict_find (&g_dicts, id, &di);\r
-    if (di == NULL)\r
-    {\r
-        set_last_error (INVALID_GRAMMAR_ID, NULL, -1);\r
-        return 0;\r
-    }\r
-\r
-    barray_create (&ba);\r
-    if (ba == NULL)\r
-        return 0;\r
-\r
-    *prod = NULL;\r
-    *size = 0;\r
-\r
-    if (match (di, text, &index, di->m_syntax, &ba, 0, &rbc) != mr_matched)\r
-    {\r
-        barray_destroy (&ba);\r
-        free_regbyte_ctx_stack (rbc, NULL);\r
-        return 0;\r
-    }\r
-\r
-    free_regbyte_ctx_stack (rbc, NULL);\r
-\r
-    *prod = mem_alloc (ba->len * sizeof (byte));\r
-    if (*prod == NULL)\r
-    {\r
-        barray_destroy (&ba);\r
-        return 0;\r
-    }\r
-\r
-    mem_copy (*prod, ba->data, ba->len * sizeof (byte));\r
-    *size = ba->len;\r
-    barray_destroy (&ba);\r
-\r
-    return 1;\r
-}\r
-\r
-int grammar_destroy (grammar id)\r
-{\r
-    dict **di = &g_dicts;\r
-\r
-    clear_last_error ();\r
-\r
-    while (*di != NULL)\r
-    {\r
-        if ((**di).m_id == id)\r
-        {\r
-            dict *tmp = *di;\r
-            *di = (**di).m_next;\r
-            dict_destroy (&tmp);\r
-            return 1;\r
-        }\r
-\r
-        di = &(**di).m_next;\r
-    }\r
-\r
-    set_last_error (INVALID_GRAMMAR_ID, NULL, -1);\r
-    return 0;\r
-}\r
-\r
-void grammar_get_last_error (byte *text, unsigned int size, int *pos)\r
-{\r
-    unsigned int len = 0, dots_made = 0;\r
-    const byte *p = error_message;\r
-\r
-    *text = '\0';\r
-\r
-#define APPEND_CHARACTER(x) if (dots_made == 0) {\\r
-                                if (len < size - 1) {\\r
-                                    text[len++] = (x); text[len] = '\0';\\r
-                                } else {\\r
-                                    int i;\\r
-                                    for (i = 0; i < 3; i++)\\r
-                                        if (--len >= 0)\\r
-                                            text[len] = '.';\\r
-                                    dots_made = 1;\\r
-                                }\\r
-                            }\r
-\r
-    if (p)\r
-        while (*p)\r
-            if (*p == '$')\r
-            {\r
-                const byte *r = error_param;\r
-\r
-                while (*r)\r
-                {\r
-                    APPEND_CHARACTER(*r)\r
-                    r++;\r
-                }\r
-\r
-                p++;\r
-            }\r
-            else\r
-            {\r
-                APPEND_CHARACTER(*p)\r
-                p++;\r
-            }\r
-\r
-    *pos = error_position;\r
-\r
-#undef APPEND_CHARACTER\r
-\r
-}\r
-\r
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.1
+ *
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file grammar.c
+ * syntax parsing engine
+ * \author Michal Krol
+ */
+
+#ifndef GRAMMAR_PORT_BUILD
+#error Do not build this file directly, build your grammar_XXX.c instead, which includes this file
+#endif
+
+/*
+    Last Modified: 2004-II-8
+*/
+
+/*
+    INTRODUCTION
+    ------------
+
+    The task is to check the syntax of an input string. Input string is a stream of ASCII
+    characters terminated with a null-character ('\0'). Checking it using C language is
+    difficult and hard to implement without bugs. It is hard to maintain and make changes when
+    the syntax changes.
+
+    This is because of a high redundancy of the C code. Large blocks of code are duplicated with
+    only small changes. Even use of macros does not solve the problem because macros cannot
+    erase the complexity of the problem.
+
+    The resolution is to create a new language that will be highly oriented to our task. Once
+    we describe a particular syntax, we are done. We can then focus on the code that implements
+    the language. The size and complexity of it is relatively small than the code that directly
+    checks the syntax.
+
+    First, we must implement our new language. Here, the language is implemented in C, but it
+    could also be implemented in any other language. The code is listed below. We must take
+    a good care that it is bug free. This is simple because the code is simple and clean.
+
+    Next, we must describe the syntax of our new language in itself. Once created and checked
+    manually that it is correct, we can use it to check another scripts.
+
+    Note that our new language loading code does not have to check the syntax. It is because we
+    assume that the script describing itself is correct, and other scripts can be syntactically
+    checked by the former script. The loading code must only do semantic checking which leads us to
+    simple resolving references.
+
+    THE LANGUAGE
+    ------------
+
+    Here I will describe the syntax of the new language (further called "Synek"). It is mainly a
+    sequence of declarations terminated by a semicolon. The declaration consists of a symbol,
+    which is an identifier, and its definition. A definition is in turn a sequence of specifiers
+    connected with ".and" or ".or" operator. These operators cannot be mixed together in a one
+    definition. Specifier can be a symbol, string, character, character range or a special
+    keyword ".true" or ".false".
+
+    On the very beginning of the script there is a declaration of a root symbol and is in the form:
+        .syntax <root_symbol>;
+    The <root_symbol> must be on of the symbols in declaration sequence. The syntax is correct if
+    the root symbol evaluates to true. A symbol evaluates to true if the definition associated with
+    the symbol evaluates to true. Definition evaluation depends on the operator used to connect
+    specifiers in the definition. If ".and" operator is used, definition evaluates to true if and
+    only if all the specifiers evaluate to true. If ".or" operator is used, definition evalutes to
+    true if any of the specifiers evaluates to true. If definition contains only one specifier,
+    it is evaluated as if it was connected with ".true" keyword by ".and" operator.
+
+    If specifier is a ".true" keyword, it always evaluates to true.
+
+    If specifier is a ".false" keyword, it always evaluates to false. Specifier evaluates to false
+    when it does not evaluate to true.
+
+    Character range specifier is in the form:
+        '<first_character>' - '<second_character>'
+    If specifier is a character range, it evaluates to true if character in the stream is greater
+    or equal to <first_character> and less or equal to <second_character>. In that situation 
+    the stream pointer is advanced to point to next character in the stream. All C-style escape
+    sequences are supported although trigraph sequences are not. The comparisions are performed
+    on 8-bit unsigned integers.
+
+    Character specifier is in the form:
+        '<single_character>'
+    It evaluates to true if the following character range specifier evaluates to true:
+        '<single_character>' - '<single_character>'
+
+    String specifier is in the form:
+        "<string>"
+    Let N be the number of characters in <string>. Let <string>[i] designate i-th character in
+    <string>. Then the string specifier evaluates to true if and only if for i in the range [0, N)
+    the following character specifier evaluates to true:
+        '<string>[i]'
+    If <string>[i] is a quotation mark, '<string>[i]' is replaced with '\<string>[i]'.
+
+    Symbol specifier can be optionally preceded by a ".loop" keyword in the form:
+        .loop <symbol>                  (1)
+    where <symbol> is defined as follows:
+        <symbol> <definition>;          (2)
+    Construction (1) is replaced by the following code:
+        <symbol$1>
+    and declaration (2) is replaced by the following:
+        <symbol$1> <symbol$2> .or .true;
+        <symbol$2> <symbol> .and <symbol$1>;
+        <symbol> <definition>;
+
+    Synek supports also a register mechanizm. User can, in its SYN file, declare a number of
+    registers that can be accessed in the syn body. Each reg has its name and a default value.
+    The register is one byte wide. The C code can change the default value by calling
+    grammar_set_reg8() with grammar id, register name and a new value. As we know, each rule is
+    a sequence of specifiers joined with .and or .or operator. And now each specifier can be
+    prefixed with a condition expression in a form ".if (<reg_name> <operator> <hex_literal>)"
+    where <operator> can be == or !=. If the condition evaluates to false, the specifier
+    evaluates to .false. Otherwise it evalutes to the specifier.
+
+    ESCAPE SEQUENCES
+    ----------------
+
+    Synek supports all escape sequences in character specifiers. The mapping table is listed below.
+    All occurences of the characters in the first column are replaced with the corresponding
+    character in the second column.
+
+        Escape sequence         Represents
+    ------------------------------------------------------------------------------------------------
+        \a                      Bell (alert)
+        \b                      Backspace
+        \f                      Formfeed
+        \n                      New line
+        \r                      Carriage return
+        \t                      Horizontal tab
+        \v                      Vertical tab
+        \'                      Single quotation mark
+        \"                      Double quotation mark
+        \\                      Backslash
+        \?                      Literal question mark
+        \ooo                    ASCII character in octal notation
+        \xhhh                   ASCII character in hexadecimal notation
+    ------------------------------------------------------------------------------------------------
+
+    RAISING ERRORS
+    --------------
+
+    Any specifier can be followed by a special construction that is executed when the specifier
+    evaluates to false. The construction is in the form:
+        .error <ERROR_TEXT>
+    <ERROR_TEXT> is an identifier declared earlier by error text declaration. The declaration is
+    in the form:
+        .errtext <ERROR_TEXT> "<error_desc>"
+    When specifier evaluates to false and this construction is present, parsing is stopped
+    immediately and <error_desc> is returned as a result of parsing. The error position is also
+    returned and it is meant as an offset from the beggining of the stream to the character that
+    was valid so far. Example:
+
+        (**** syntax script ****)
+
+        .syntax program;
+        .errtext MISSING_SEMICOLON      "missing ';'"
+        program         declaration .and .loop space .and ';' .error MISSING_SEMICOLON .and
+                        .loop space .and '\0';
+        declaration     "declare" .and .loop space .and identifier;
+        space           ' ';
+
+        (**** sample code ****)
+
+        declare foo ,
+
+    In the example above checking the sample code will result in error message "missing ';'" and
+    error position 12. The sample code is not correct. Note the presence of '\0' specifier to
+    assure that there is no code after semicolon - only spaces.
+    <error_desc> can optionally contain identifier surrounded by dollar signs $. In such a case,
+    the identifier and dollar signs are replaced by a string retrieved by invoking symbol with
+    the identifier name. The starting position is the error position. The lenght of the resulting
+    string is the position after invoking the symbol.
+
+    PRODUCTION
+    ----------
+
+    Synek not only checks the syntax but it can also produce (emit) bytes associated with specifiers
+    that evaluate to true. That is, every specifier and optional error construction can be followed
+    by a number of emit constructions that are in the form:
+        .emit <parameter>
+    <paramater> can be a HEX number, identifier, a star * or a dollar $. HEX number is preceded by
+    0x or 0X. If <parameter> is an identifier, it must be earlier declared by emit code declaration
+    in the form:
+        .emtcode <identifier> <hex_number>
+
+    When given specifier evaluates to true, all emits associated with the specifier are output
+    in order they were declared. A star means that last-read character should be output instead
+    of constant value. Example:
+
+        (**** syntax script ****)
+
+        .syntax foobar;
+        .emtcode WORD_FOO       0x01
+        .emtcode WORD_BAR       0x02
+        foobar      FOO .emit WORD_FOO .or BAR .emit WORD_BAR .or .true .emit 0x00;
+        FOO         "foo" .and SPACE;
+        BAR         "bar" .and SPACE;
+        SPACE       ' ' .or '\0';
+
+        (**** sample text 1 ****)
+
+        foo
+
+        (**** sample text 2 ****)
+
+        foobar
+
+    For both samples the result will be one-element array. For first sample text it will be
+    value 1, for second - 0. Note that every text will be accepted because of presence of
+    .true as an alternative.
+
+    Another example:
+
+        (**** syntax script ****)
+
+        .syntax declaration;
+        .emtcode VARIABLE       0x01
+        declaration     "declare" .and .loop space .and
+                        identifier .emit VARIABLE .and          (1)
+                        .true .emit 0x00 .and                   (2)
+                        .loop space .and ';';
+        space           ' ' .or '\t';
+        identifier      .loop id_char .emit *;                  (3)
+        id_char         'a'-'z' .or 'A'-'Z' .or '_';
+
+        (**** sample code ****)
+
+        declare    fubar;
+
+    In specifier (1) symbol <identifier> is followed by .emit VARIABLE. If it evaluates to
+    true, VARIABLE constant and then production of the symbol is output. Specifier (2) is used
+    to terminate the string with null to signal when the string ends. Specifier (3) outputs
+    all characters that make declared identifier. The result of sample code will be the
+    following array:
+        { 1, 'f', 'u', 'b', 'a', 'r', 0 }
+
+    If .emit is followed by dollar $, it means that current position should be output. Current
+    position is a 32-bit unsigned integer distance from the very beginning of the parsed string to
+    first character consumed by the specifier associated with the .emit instruction. Current
+    position is stored in the output buffer in Little-Endian convention (the lowest byte comes
+    first).
+*/
+
+static void mem_free (void **);
+
+/*
+    internal error messages
+*/
+static const byte *OUT_OF_MEMORY =          (byte *) "internal error 1001: out of physical memory";
+static const byte *UNRESOLVED_REFERENCE =   (byte *) "internal error 1002: unresolved reference '$'";
+static const byte *INVALID_GRAMMAR_ID =     (byte *) "internal error 1003: invalid grammar object";
+static const byte *INVALID_REGISTER_NAME =  (byte *) "internal error 1004: invalid register name: '$'";
+
+static const byte *error_message = NULL;
+static byte *error_param = NULL;        /* this is inserted into error_message in place of $ */
+static int error_position = -1;
+
+static byte *unknown = (byte *) "???";
+
+static void clear_last_error ()
+{
+    /* reset error message */
+    error_message = NULL;
+
+    /* free error parameter - if error_param is a "???" don't free it - it's static */
+    if (error_param != unknown)
+        mem_free ((void **) &error_param);
+    else
+        error_param = NULL;
+
+    /* reset error position */
+    error_position = -1;
+}
+
+static void set_last_error (const byte *msg, byte *param, int pos)
+{
+    /* error message can only be set only once */
+    if (error_message != NULL)
+    {
+        mem_free (&param);
+        return;
+    }
+
+    error_message = msg;
+
+    if (param != NULL)
+        error_param = param;
+    else
+        error_param = unknown;
+
+    error_position = pos;
+}
+
+/*
+    memory management routines
+*/
+static void *mem_alloc (size_t size)
+{
+    void *ptr = grammar_alloc_malloc (size);
+    if (ptr == NULL)
+        set_last_error (OUT_OF_MEMORY, NULL, -1);
+    return ptr;
+}
+
+static void *mem_copy (void *dst, const void *src, size_t size)
+{
+    return grammar_memory_copy (dst, src, size);
+}
+
+static void mem_free (void **ptr)
+{
+    grammar_alloc_free (*ptr);
+    *ptr = NULL;
+}
+
+static void *mem_realloc (void *ptr, size_t old_size, size_t new_size)
+{
+    void *ptr2 = grammar_alloc_realloc (ptr, old_size, new_size);
+    if (ptr2 == NULL)
+        set_last_error (OUT_OF_MEMORY, NULL, -1);
+    return ptr2;
+}
+
+static byte *str_copy_n (byte *dst, const byte *src, size_t max_len)
+{
+    return grammar_string_copy_n (dst, src, max_len);
+}
+
+static byte *str_duplicate (const byte *str)
+{
+    byte *new_str = grammar_string_duplicate (str);
+    if (new_str == NULL)
+        set_last_error (OUT_OF_MEMORY, NULL, -1);
+    return new_str;
+}
+
+static int str_equal (const byte *str1, const byte *str2)
+{
+    return grammar_string_compare (str1, str2) == 0;
+}
+
+static int str_equal_n (const byte *str1, const byte *str2, unsigned int n)
+{
+    return grammar_string_compare_n (str1, str2, n) == 0;
+}
+
+static unsigned int str_length (const byte *str)
+{
+    return grammar_string_length (str);
+}
+
+/*
+    string to byte map typedef
+*/
+typedef struct map_byte_
+{
+    byte *key;
+    byte data;
+    struct map_byte_ *next;
+} map_byte;
+
+static void map_byte_create (map_byte **ma)
+{
+    *ma = mem_alloc (sizeof (map_byte));
+    if (*ma)
+    {
+        (**ma).key = NULL;
+        (**ma).data = '\0';
+        (**ma).next = NULL;
+    }
+}
+
+/* XXX unfold the recursion */
+static void map_byte_destroy (map_byte **ma)
+{
+    if (*ma)
+    {
+        map_byte_destroy (&(**ma).next);
+        mem_free ((void **) &(**ma).key);
+        mem_free ((void **) ma);
+    }
+}
+
+static void map_byte_append (map_byte **ma, map_byte **nm)
+{
+    while (*ma)
+        ma = &(**ma).next;
+    *ma = *nm;
+}
+
+/*
+    searches the map for the specified key,
+    returns pointer to the element with the specified key if it exists
+    returns NULL otherwise
+*/
+map_byte *map_byte_locate (map_byte **ma, const byte *key)
+{
+    while (*ma)
+    {
+        if (str_equal ((**ma).key, key))
+            return *ma;
+
+        ma = &(**ma).next;
+    }
+
+    set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);
+    return NULL;
+}
+
+/*
+    searches the map for specified key,
+    if the key is matched, *data is filled with data associated with the key,
+    returns 0 if the key is matched,
+    returns 1 otherwise
+*/
+static int map_byte_find (map_byte **ma, const byte *key, byte *data)
+{
+    map_byte *found = map_byte_locate (ma, key);
+    if (found != NULL)
+    {
+        *data = found->data;
+
+        return 0;
+    }
+
+    return 1;
+}
+
+/*
+    regbyte context typedef
+
+    Each regbyte consists of its name and a default value. These are static and created at
+    grammar script compile-time, for example the following line:
+        .regbyte vertex_blend      0x00
+    adds a new regbyte named "vertex_blend" to the static list and initializes it to 0.
+    When the script is executed, this regbyte can be accessed by name for read and write. When a
+    particular regbyte is written, a new regbyte_ctx entry is added to the top of the regbyte_ctx
+    stack. The new entry contains information abot which regbyte it references and its new value.
+    When a given regbyte is accessed for read, the stack is searched top-down to find an
+    entry that references the regbyte. The first matching entry is used to return the current
+    value it holds. If no entry is found, the default value is returned.
+*/
+typedef struct regbyte_ctx_
+{
+    map_byte *m_regbyte;
+    byte m_current_value;
+    struct regbyte_ctx_ *m_prev;
+} regbyte_ctx;
+
+static void regbyte_ctx_create (regbyte_ctx **re)
+{
+    *re = mem_alloc (sizeof (regbyte_ctx));
+    if (*re)
+    {
+        (**re).m_regbyte = NULL;
+        (**re).m_prev = NULL;
+    }
+}
+
+static void regbyte_ctx_destroy (regbyte_ctx **re)
+{
+    if (*re)
+    {
+        mem_free ((void **) re);
+    }
+}
+
+static byte regbyte_ctx_extract (regbyte_ctx **re, map_byte *reg)
+{
+    /* first lookup in the register stack */
+    while (*re != NULL)
+    {
+        if ((**re).m_regbyte == reg)
+            return (**re).m_current_value;
+
+        re = &(**re).m_prev;
+    }
+
+    /* if not found - return the default value */
+    return reg->data;
+}
+
+/*
+    emit type typedef
+*/
+typedef enum emit_type_
+{
+    et_byte,            /* explicit number */
+    et_stream,          /* eaten character */
+    et_position         /* current position */
+} emit_type;
+
+/*
+    emit destination typedef
+*/
+typedef enum emit_dest_
+{
+    ed_output,          /* write to the output buffer */
+    ed_regbyte          /* write a particular regbyte */
+} emit_dest;
+
+/*
+    emit typedef
+*/
+typedef struct emit_
+{
+    emit_dest m_emit_dest;
+    emit_type m_emit_type;      /* ed_output */
+    byte m_byte;                /* et_byte */
+    map_byte *m_regbyte;        /* ed_regbyte */
+    byte *m_regname;            /* ed_regbyte - temporary */
+    struct emit_ *m_next;
+} emit;
+
+static void emit_create (emit **em)
+{
+    *em = mem_alloc (sizeof (emit));
+    if (*em)
+    {
+        (**em).m_emit_dest = ed_output;
+        (**em).m_emit_type = et_byte;
+        (**em).m_byte = '\0';
+        (**em).m_regbyte = NULL;
+        (**em).m_regname = NULL;
+        (**em).m_next = NULL;
+    }
+}
+
+static void emit_destroy (emit **em)
+{
+    if (*em)
+    {
+        emit_destroy (&(**em).m_next);
+        mem_free ((void **) &(**em).m_regname);
+        mem_free ((void **) em);
+    }
+}
+
+/*
+    error typedef
+*/
+typedef struct error_
+{
+    byte *m_text;
+    byte *m_token_name;
+    struct rule_ *m_token;
+} error;
+
+static void error_create (error **er)
+{
+    *er = mem_alloc (sizeof (error));
+    if (*er)
+    {
+        (**er).m_text = NULL;
+        (**er).m_token_name = NULL;
+        (**er).m_token = NULL;
+    }
+}
+
+static void error_destroy (error **er)
+{
+    if (*er)
+    {
+        mem_free ((void **) &(**er).m_text);
+        mem_free ((void **) &(**er).m_token_name);
+        mem_free ((void **) er);
+    }
+}
+
+struct dict_;
+static byte *error_get_token (error *, struct dict_ *, const byte *, unsigned int);
+
+/*
+    condition operand type typedef
+*/
+typedef enum cond_oper_type_
+{
+    cot_byte,               /* constant 8-bit unsigned integer */
+    cot_regbyte             /* pointer to byte register containing the current value */
+} cond_oper_type;
+
+/*
+    condition operand typedef
+*/
+typedef struct cond_oper_
+{
+    cond_oper_type m_type;
+    byte m_byte;            /* cot_byte */
+    map_byte *m_regbyte;    /* cot_regbyte */
+    byte *m_regname;        /* cot_regbyte - temporary */
+} cond_oper;
+
+/*
+    condition type typedef
+*/
+typedef enum cond_type_
+{
+    ct_equal,
+    ct_not_equal
+} cond_type;
+
+/*
+    condition typedef
+*/
+typedef struct cond_
+{
+    cond_type m_type;
+    cond_oper m_operands[2];
+} cond;
+
+static void cond_create (cond **co)
+{
+    *co = mem_alloc (sizeof (cond));
+    if (*co)
+    {
+        (**co).m_operands[0].m_regname = NULL;
+        (**co).m_operands[1].m_regname = NULL;
+    }
+}
+
+static void cond_destroy (cond **co)
+{
+    if (*co)
+    {
+        mem_free ((void **) &(**co).m_operands[0].m_regname);
+        mem_free ((void **) &(**co).m_operands[1].m_regname);
+        mem_free ((void **) co);
+    }
+}
+
+/*
+    specifier type typedef
+*/
+typedef enum spec_type_
+{
+    st_false,
+    st_true,
+    st_byte,
+    st_byte_range,
+    st_string,
+    st_identifier,
+    st_identifier_loop,
+    st_debug
+} spec_type;
+
+/*
+    specifier typedef
+*/
+typedef struct spec_
+{
+    spec_type m_spec_type;
+    byte m_byte[2];                 /* st_byte, st_byte_range */
+    byte *m_string;                 /* st_string */
+    struct rule_ *m_rule;           /* st_identifier, st_identifier_loop */
+    emit *m_emits;
+    error *m_errtext;
+    cond *m_cond;
+    struct spec_ *m_next;
+} spec;
+
+static void spec_create (spec **sp)
+{
+    *sp = mem_alloc (sizeof (spec));
+    if (*sp)
+    {
+        (**sp).m_spec_type = st_false;
+        (**sp).m_byte[0] = '\0';
+        (**sp).m_byte[1] = '\0';
+        (**sp).m_string = NULL;
+        (**sp).m_rule = NULL;
+        (**sp).m_emits = NULL;
+        (**sp).m_errtext = NULL;
+        (**sp).m_cond = NULL;
+        (**sp).m_next = NULL;
+    }
+}
+
+static void spec_destroy (spec **sp)
+{
+    if (*sp)
+    {
+        spec_destroy (&(**sp).m_next);
+        emit_destroy (&(**sp).m_emits);
+        error_destroy (&(**sp).m_errtext);
+        mem_free ((void **) &(**sp).m_string);
+        cond_destroy (&(**sp).m_cond);
+        mem_free ((void **) sp);
+    }
+}
+
+static void spec_append (spec **sp, spec **ns)
+{
+    while (*sp)
+        sp = &(**sp).m_next;
+    *sp = *ns;
+}
+
+/*
+    operator typedef
+*/
+typedef enum oper_
+{
+    op_none,
+    op_and,
+    op_or
+} oper;
+
+/*
+    rule typedef
+*/
+typedef struct rule_
+{
+    oper m_oper;
+    spec *m_specs;
+    struct rule_ *m_next;
+/*  int m_referenced; */            /* for debugging purposes */
+} rule;
+
+static void rule_create (rule **ru)
+{
+    *ru = mem_alloc (sizeof (rule));
+    if (*ru)
+    {
+        (**ru).m_oper = op_none;
+        (**ru).m_specs = NULL;
+        (**ru).m_next = NULL;
+/*      (**ru).m_referenced = 0; */
+    }
+}
+
+static void rule_destroy (rule **ru)
+{
+    if (*ru)
+    {
+        rule_destroy (&(**ru).m_next);
+        spec_destroy (&(**ru).m_specs);
+        mem_free ((void **) ru);
+    }
+}
+
+static void rule_append (rule **ru, rule **nr)
+{
+    while (*ru)
+        ru = &(**ru).m_next;
+    *ru = *nr;
+}
+
+/*
+    returns unique grammar id
+*/
+static grammar next_valid_grammar_id ()
+{
+    static grammar id = 0;
+
+    return ++id;
+}
+
+/*
+    dictionary typedef
+*/
+typedef struct dict_
+{
+    rule *m_rulez;
+    rule *m_syntax;
+    rule *m_string;
+    map_byte *m_regbytes;
+    grammar m_id;
+    struct dict_ *m_next;
+} dict;
+
+static void dict_create (dict **di)
+{
+    *di = mem_alloc (sizeof (dict));
+    if (*di)
+    {
+        (**di).m_rulez = NULL;
+        (**di).m_syntax = NULL;
+        (**di).m_string = NULL;
+        (**di).m_regbytes = NULL;
+        (**di).m_id = next_valid_grammar_id ();
+        (**di).m_next = NULL;
+    }
+}
+
+static void dict_destroy (dict **di)
+{
+    if (*di)
+    {
+        rule_destroy (&(**di).m_rulez);
+        map_byte_destroy (&(**di).m_regbytes);
+        mem_free ((void **) di);
+    }
+}
+
+static void dict_append (dict **di, dict **nd)
+{
+    while (*di)
+        di = &(**di).m_next;
+    *di = *nd;
+}
+
+static void dict_find (dict **di, grammar key, dict **data)
+{
+    while (*di)
+    {
+        if ((**di).m_id == key)
+        {
+            *data = *di;
+            return;
+        }
+
+        di = &(**di).m_next;
+    }
+
+    *data = NULL;
+}
+
+static dict *g_dicts = NULL;
+
+/*
+    byte array typedef
+
+    XXX this class is going to be replaced by a faster one, soon
+*/
+typedef struct barray_
+{
+    byte *data;
+    unsigned int len;
+} barray;
+
+static void barray_create (barray **ba)
+{
+    *ba = mem_alloc (sizeof (barray));
+    if (*ba)
+    {
+        (**ba).data = NULL;
+        (**ba).len = 0;
+    }
+}
+
+static void barray_destroy (barray **ba)
+{
+    if (*ba)
+    {
+        mem_free ((void **) &(**ba).data);
+        mem_free ((void **) ba);
+    }
+}
+
+/*
+    reallocates byte array to requested size,
+    returns 0 on success,
+    returns 1 otherwise
+*/
+static int barray_resize (barray **ba, unsigned int nlen)
+{
+    byte *new_pointer;
+
+    if (nlen == 0)
+    {
+        mem_free ((void **) &(**ba).data);
+        (**ba).data = NULL;
+        (**ba).len = 0;
+
+        return 0;
+    }
+    else
+    {
+        new_pointer = mem_realloc ((**ba).data, (**ba).len * sizeof (byte), nlen * sizeof (byte));
+        if (new_pointer)
+        {
+            (**ba).data = new_pointer;
+            (**ba).len = nlen;
+
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+/*
+    adds byte array pointed by *nb to the end of array pointed by *ba,
+    returns 0 on success,
+    returns 1 otherwise
+*/
+static int barray_append (barray **ba, barray **nb)
+{
+    const unsigned int len = (**ba).len;
+
+    if (barray_resize (ba, (**ba).len + (**nb).len))
+        return 1;
+
+    mem_copy ((**ba).data + len, (**nb).data, (**nb).len);
+
+    return 0;
+}
+
+/*
+    adds emit chain pointed by em to the end of array pointed by *ba,
+    returns 0 on success,
+    returns 1 otherwise
+*/
+static int barray_push (barray **ba, emit *em, byte c, unsigned int pos, regbyte_ctx **rbc)
+{
+    emit *temp = em;
+    unsigned int count = 0;
+
+    while (temp)
+    {
+        if (temp->m_emit_dest == ed_output)
+            if (temp->m_emit_type == et_position)
+                count += 4;     /* position is a 32-bit unsigned integer */
+            else
+                count++;
+
+        temp = temp->m_next;
+    }
+
+    if (barray_resize (ba, (**ba).len + count))
+        return 1;
+
+    while (em)
+    {
+        if (em->m_emit_dest == ed_output)
+        {
+            if (em->m_emit_type == et_byte)
+                (**ba).data[(**ba).len - count--] = em->m_byte;
+            else if (em->m_emit_type == et_stream)
+                (**ba).data[(**ba).len - count--] = c;
+            else // em->type == et_position
+                (**ba).data[(**ba).len - count--] = (byte) pos,
+                (**ba).data[(**ba).len - count--] = (byte) (pos >> 8),
+                (**ba).data[(**ba).len - count--] = (byte) (pos >> 16),
+                (**ba).data[(**ba).len - count--] = (byte) (pos >> 24);
+        }
+        else
+        {
+            regbyte_ctx *new_rbc;
+            regbyte_ctx_create (&new_rbc);
+            if (new_rbc == NULL)
+                return 1;
+
+            new_rbc->m_prev = *rbc;
+            new_rbc->m_regbyte = em->m_regbyte;
+            *rbc = new_rbc;
+
+            if (em->m_emit_type == et_byte)
+                new_rbc->m_current_value = em->m_byte;
+            else if (em->m_emit_type == et_stream)
+                new_rbc->m_current_value = c;
+        }
+
+        em = em->m_next;
+    }
+
+    return 0;
+}
+
+/*
+    string to string map typedef
+*/
+typedef struct map_str_
+{
+    byte *key;
+    byte *data;
+    struct map_str_ *next;
+} map_str;
+
+static void map_str_create (map_str **ma)
+{
+    *ma = mem_alloc (sizeof (map_str));
+    if (*ma)
+    {
+        (**ma).key = NULL;
+        (**ma).data = NULL;
+        (**ma).next = NULL;
+    }
+}
+
+static void map_str_destroy (map_str **ma)
+{
+    if (*ma)
+    {
+        map_str_destroy (&(**ma).next);
+        mem_free ((void **) &(**ma).key);
+        mem_free ((void **) &(**ma).data);
+        mem_free ((void **) ma);
+    }
+}
+
+static void map_str_append (map_str **ma, map_str **nm)
+{
+    while (*ma)
+        ma = &(**ma).next;
+    *ma = *nm;
+}
+
+/*
+    searches the map for specified key,
+    if the key is matched, *data is filled with data associated with the key,
+    returns 0 if the key is matched,
+    returns 1 otherwise
+*/
+static int map_str_find (map_str **ma, const byte *key, byte **data)
+{
+    while (*ma)
+    {
+        if (str_equal ((**ma).key, key))
+        {
+            *data = str_duplicate ((**ma).data);
+            if (*data == NULL)
+                return 1;
+
+            return 0;
+        }
+
+        ma = &(**ma).next;
+    }
+
+    set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);
+    return 1;
+}
+
+/*
+    string to rule map typedef
+*/
+typedef struct map_rule_
+{
+    byte *key;
+    rule *data;
+    struct map_rule_ *next;
+} map_rule;
+
+static void map_rule_create (map_rule **ma)
+{
+    *ma = mem_alloc (sizeof (map_rule));
+    if (*ma)
+    {
+        (**ma).key = NULL;
+        (**ma).data = NULL;
+        (**ma).next = NULL;
+    }
+}
+
+static void map_rule_destroy (map_rule **ma)
+{
+    if (*ma)
+    {
+        map_rule_destroy (&(**ma).next);
+        mem_free ((void **) &(**ma).key);
+        mem_free ((void **) ma);
+    }
+}
+
+static void map_rule_append (map_rule **ma, map_rule **nm)
+{
+    while (*ma)
+        ma = &(**ma).next;
+    *ma = *nm;
+}
+
+/*
+    searches the map for specified key,
+    if the key is matched, *data is filled with data associated with the key,
+    returns 0 if the is matched,
+    returns 1 otherwise
+*/
+static int map_rule_find (map_rule **ma, const byte *key, rule **data)
+{
+    while (*ma)
+    {
+        if (str_equal ((**ma).key, key))
+        {
+            *data = (**ma).data;
+
+            return 0;
+        }
+
+        ma = &(**ma).next;
+    }
+
+    set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);
+    return 1;
+}
+
+/*
+    returns 1 if given character is a white space,
+    returns 0 otherwise
+*/
+static int is_space (byte c)
+{
+    return c == ' ' || c == '\t' || c == '\n' || c == '\r';
+}
+
+/*
+    advances text pointer by 1 if character pointed by *text is a space,
+    returns 1 if a space has been eaten,
+    returns 0 otherwise
+*/
+static int eat_space (const byte **text)
+{
+    if (is_space (**text))
+    {
+        (*text)++;
+
+        return 1;
+    }
+
+    return 0;
+}
+
+/*
+    returns 1 if text points to C-style comment start string "/*",
+    returns 0 otherwise
+*/
+static int is_comment_start (const byte *text)
+{
+    return text[0] == '/' && text[1] == '*';
+}
+
+/*
+    advances text pointer to first character after C-style comment block - if any,
+    returns 1 if C-style comment block has been encountered and eaten,
+    returns 0 otherwise
+*/
+static int eat_comment (const byte **text)
+{
+    if (is_comment_start (*text))
+    {
+        /* *text points to comment block - skip two characters to enter comment body */
+        *text += 2;
+        /* skip any character except consecutive '*' and '/' */
+        while (!((*text)[0] == '*' && (*text)[1] == '/'))
+            (*text)++;
+        /* skip those two terminating characters */
+        *text += 2;
+
+        return 1;
+    }
+
+    return 0;
+}
+
+/*
+    advances text pointer to first character that is neither space nor C-style comment block
+*/
+static void eat_spaces (const byte **text)
+{
+    while (eat_space (text) || eat_comment (text))
+        ;
+}
+
+/*
+    resizes string pointed by *ptr to successfully add character c to the end of the string,
+    returns 0 on success,
+    returns 1 otherwise
+*/
+static int string_grow (byte **ptr, unsigned int *len, byte c)
+{
+    /* reallocate the string in 16-byte increments */
+    if ((*len & 0x0F) == 0x0F || *ptr == NULL)
+    {
+        byte *tmp = mem_realloc (*ptr, ((*len + 1) & ~0x0F) * sizeof (byte),
+            ((*len + 1 + 0x10) & ~0x0F) * sizeof (byte));
+        if (tmp == NULL)
+            return 1;
+
+        *ptr = tmp;
+    }
+
+    if (c)
+    {
+        /* append given character */
+        (*ptr)[*len] = c;
+        (*len)++;
+    }
+    (*ptr)[*len] = '\0';
+
+    return 0;
+}
+
+/*
+    returns 1 if given character is a valid identifier character a-z, A-Z, 0-9 or _
+    returns 0 otherwise
+*/
+static int is_identifier (byte c)
+{
+    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
+}
+
+/*
+    copies characters from *text to *id until non-identifier character is encountered,
+    assumes that *id points to NULL object - caller is responsible for later freeing the string,
+    text pointer is advanced to point past the copied identifier,
+    returns 0 if identifier was successfully copied,
+    returns 1 otherwise
+*/
+static int get_identifier (const byte **text, byte **id)
+{
+    const byte *t = *text;
+    byte *p = NULL;
+    unsigned int len = 0;
+
+    if (string_grow (&p, &len, '\0'))
+        return 1;
+
+    /* loop while next character in buffer is valid for identifiers */
+    while (is_identifier (*t))
+    {
+        if (string_grow (&p, &len, *t++))
+        {
+            mem_free ((void **) &p);
+            return 1;
+        }
+    }
+
+    *text = t;
+    *id = p;
+
+    return 0;
+}
+
+/*
+    returns 1 if given character is HEX digit 0-9, A-F or a-f,
+    returns 0 otherwise
+*/
+static int is_hex (byte c)
+{
+    return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
+}
+
+/*
+    returns value of passed character as if it was HEX digit
+*/
+static unsigned int hex2dec (byte c)
+{
+    if (c >= '0' && c <= '9')
+        return c - '0';
+    if (c >= 'A' && c <= 'F')
+        return c - 'A' + 10;
+    return c - 'a' + 10;
+}
+
+/*
+    converts sequence of HEX digits pointed by *text until non-HEX digit is encountered,
+    advances text pointer past the converted sequence,
+    returns the converted value
+*/
+static unsigned int hex_convert (const byte **text)
+{
+    unsigned int value = 0;
+
+    while (is_hex (**text))
+    {
+        value = value * 0x10 + hex2dec (**text);
+        (*text)++;
+    }
+
+    return value;
+}
+
+/*
+    returns 1 if given character is OCT digit 0-7,
+    returns 0 otherwise
+*/
+static int is_oct (byte c)
+{
+    return c >= '0' && c <= '7';
+}
+
+/*
+    returns value of passed character as if it was OCT digit
+*/
+static int oct2dec (byte c)
+{
+    return c - '0';
+}
+
+static byte get_escape_sequence (const byte **text)
+{
+    int value = 0;
+
+    /* skip '\' character */
+    (*text)++;
+
+    switch (*(*text)++)
+    {
+    case '\'':
+        return '\'';
+    case '"':
+        return '\"';
+    case '?':
+        return '\?';
+    case '\\':
+        return '\\';
+    case 'a':
+        return '\a';
+    case 'b':
+        return '\b';
+    case 'f':
+        return '\f';
+    case 'n':
+        return '\n';
+    case 'r':
+        return '\r';
+    case 't':
+        return '\t';
+    case 'v':
+        return '\v';
+    case 'x':
+        return (byte) hex_convert (text);
+    }
+
+    (*text)--;
+    if (is_oct (**text))
+    {
+        value = oct2dec (*(*text)++);
+        if (is_oct (**text))
+        {
+            value = value * 010 + oct2dec (*(*text)++);
+            if (is_oct (**text))
+                value = value * 010 + oct2dec (*(*text)++);
+        }
+    }
+
+    return (byte) value;
+}
+
+/*
+    copies characters from *text to *str until " or ' character is encountered,
+    assumes that *str points to NULL object - caller is responsible for later freeing the string,
+    assumes that *text points to " or ' character that starts the string,
+    text pointer is advanced to point past the " or ' character,
+    returns 0 if string was successfully copied,
+    returns 1 otherwise
+*/
+static int get_string (const byte **text, byte **str)
+{
+    const byte *t = *text;
+    byte *p = NULL;
+    unsigned int len = 0;
+    byte term_char;
+
+    if (string_grow (&p, &len, '\0'))
+        return 1;
+
+    /* read " or ' character that starts the string */
+    term_char = *t++;
+    /* while next character is not the terminating character */
+    while (*t && *t != term_char)
+    {
+        byte c;
+
+        if (*t == '\\')
+            c = get_escape_sequence (&t);
+        else
+            c = *t++;
+
+        if (string_grow (&p, &len, c))
+        {
+            mem_free ((void **) &p);
+            return 1;
+        }
+    }
+    /* skip " or ' character that ends the string */
+    t++;
+
+    *text = t;
+    *str = p;
+    return 0;
+}
+
+/*
+    gets emit code, the syntax is: ".emtcode" " " <symbol> " " ("0x" | "0X") <hex_value>
+    assumes that *text already points to <symbol>,
+    returns 0 if emit code is successfully read,
+    returns 1 otherwise
+*/
+static int get_emtcode (const byte **text, map_byte **ma)
+{
+    const byte *t = *text;
+    map_byte *m = NULL;
+
+    map_byte_create (&m);
+    if (m == NULL)
+        return 1;
+
+    if (get_identifier (&t, &m->key))
+    {
+        map_byte_destroy (&m);
+        return 1;
+    }
+    eat_spaces (&t);
+
+    if (*t == '\'')
+    {
+        byte *c;
+
+        if (get_string (&t, &c))
+        {
+            map_byte_destroy (&m);
+            return 1;
+        }
+
+        m->data = (byte) c[0];
+        mem_free ((void **) &c);
+    }
+    else
+    {
+        /* skip HEX "0x" or "0X" prefix */
+        t += 2;
+        m->data = (byte) hex_convert (&t);
+    }
+
+    eat_spaces (&t);
+
+    *text = t;
+    *ma = m;
+    return 0;
+}
+
+/*
+    gets regbyte declaration, the syntax is: ".regbyte" " " <symbol> " " ("0x" | "0X") <hex_value>
+    assumes that *text already points to <symbol>,
+    returns 0 if regbyte is successfully read,
+    returns 1 otherwise
+*/
+static int get_regbyte (const byte **text, map_byte **ma)
+{
+    return get_emtcode (text, ma);
+}
+
+/*
+    returns 0 on success,
+    returns 1 otherwise
+*/
+static int get_errtext (const byte **text, map_str **ma)
+{
+    const byte *t = *text;
+    map_str *m = NULL;
+
+    map_str_create (&m);
+    if (m == NULL)
+        return 1;
+
+    if (get_identifier (&t, &m->key))
+    {
+        map_str_destroy (&m);
+        return 1;
+    }
+    eat_spaces (&t);
+
+    if (get_string (&t, &m->data))
+    {
+        map_str_destroy (&m);
+        return 1;
+    }
+    eat_spaces (&t);
+
+    *text = t;
+    *ma = m;
+    return 0;
+}
+
+/*
+    returns 0 on success,
+    returns 1 otherwise,
+*/
+static int get_error (const byte **text, error **er, map_str *maps)
+{
+    const byte *t = *text;
+    byte *temp = NULL;
+
+    if (*t != '.')
+        return 0;
+
+    t++;
+    if (get_identifier (&t, &temp))
+        return 1;
+    eat_spaces (&t);
+
+    if (!str_equal ((byte *) "error", temp))
+    {
+        mem_free ((void **) &temp);
+        return 0;
+    }
+
+    mem_free ((void **) &temp);
+
+    error_create (er);
+    if (*er == NULL)
+        return 1;
+
+    if (*t == '\"')
+    {
+        if (get_string (&t, &(**er).m_text))
+        {
+            error_destroy (er);
+            return 1;
+        }
+        eat_spaces (&t);
+    }
+    else
+    {
+        if (get_identifier (&t, &temp))
+        {
+            error_destroy (er);
+            return 1;
+        }
+        eat_spaces (&t);
+
+        if (map_str_find (&maps, temp, &(**er).m_text))
+        {
+            mem_free ((void **) &temp);
+            error_destroy (er);
+            return 1;
+        }
+
+        mem_free ((void **) &temp);
+    }
+
+    /* try to extract "token" from "...$token$..." */
+    {
+        byte *processed = NULL;
+        unsigned int len = 0, i = 0;
+
+        if (string_grow (&processed, &len, '\0'))
+        {
+            error_destroy (er);
+            return 1;
+        }
+
+        while (i < str_length ((**er).m_text))
+        {
+            /* check if the dollar sign is repeated - if so skip it */
+            if ((**er).m_text[i] == '$' && (**er).m_text[i + 1] == '$')
+            {
+                if (string_grow (&processed, &len, '$'))
+                {
+                    mem_free ((void **) &processed);
+                    error_destroy (er);
+                    return 1;
+                }
+
+                i += 2;
+            }
+            else if ((**er).m_text[i] != '$')
+            {
+                if (string_grow (&processed, &len, (**er).m_text[i]))
+                {
+                    mem_free ((void **) &processed);
+                    error_destroy (er);
+                    return 1;
+                }
+
+                i++;
+            }
+            else
+            {
+                if (string_grow (&processed, &len, '$'))
+                {
+                    mem_free ((void **) &processed);
+                    error_destroy (er);
+                    return 1;
+                }
+
+                {
+                    /* length of token being extracted */
+                    unsigned int tlen = 0;
+
+                    if (string_grow (&(**er).m_token_name, &tlen, '\0'))
+                    {
+                        mem_free ((void **) &processed);
+                        error_destroy (er);
+                        return 1;
+                    }
+
+                    /* skip the dollar sign */
+                    i++;
+
+                    while ((**er).m_text[i] != '$')
+                    {
+                        if (string_grow (&(**er).m_token_name, &tlen, (**er).m_text[i]))
+                        {
+                            mem_free ((void **) &processed);
+                            error_destroy (er);
+                            return 1;
+                        }
+
+                        i++;
+                    }
+
+                    /* skip the dollar sign */
+                    i++;
+                }
+            }
+        }
+
+        mem_free ((void **) &(**er).m_text);
+        (**er).m_text = processed;
+    }
+
+    *text = t;
+    return 0;
+}
+
+/*
+    returns 0 on success,
+    returns 1 otherwise,
+*/
+static int get_emits (const byte **text, emit **em, map_byte *mapb)
+{
+    const byte *t = *text;
+    byte *temp = NULL;
+    emit *e = NULL;
+    emit_dest dest;
+
+    if (*t != '.')
+        return 0;
+
+    t++;
+    if (get_identifier (&t, &temp))
+        return 1;
+    eat_spaces (&t);
+
+    /* .emit */
+    if (str_equal ((byte *) "emit", temp))
+        dest = ed_output;
+    /* .load */
+    else if (str_equal ((byte *) "load", temp))
+        dest = ed_regbyte;
+    else
+    {
+        mem_free ((void **) &temp);
+        return 0;
+    }
+
+    mem_free ((void **) &temp);
+
+    emit_create (&e);
+    if (e == NULL)
+        return 1;
+
+    e->m_emit_dest = dest;
+
+    if (dest == ed_regbyte)
+    {
+        if (get_identifier (&t, &e->m_regname))
+        {
+            emit_destroy (&e);
+            return 1;
+        }
+        eat_spaces (&t);
+    }
+
+    /* 0xNN */
+    if (*t == '0')
+    {
+        t += 2;
+        e->m_byte = (byte) hex_convert (&t);
+
+        e->m_emit_type = et_byte;
+    }
+    /* * */
+    else if (*t == '*')
+    {
+        t++;
+
+        e->m_emit_type = et_stream;
+    }
+    /* $ */
+    else if (*t == '$')
+    {
+        t++;
+
+        e->m_emit_type = et_position;
+    }
+    /* 'c' */
+    else if (*t == '\'')
+    {
+        if (get_string (&t, &temp))
+        {
+            emit_destroy (&e);
+            return 1;
+        }
+        e->m_byte = (byte) temp[0];
+
+        mem_free ((void **) &temp);
+
+        e->m_emit_type = et_byte;
+    }
+    else
+    {
+        if (get_identifier (&t, &temp))
+        {
+            emit_destroy (&e);
+            return 1;
+        }
+
+        if (map_byte_find (&mapb, temp, &e->m_byte))
+        {
+            mem_free ((void **) &temp);
+            emit_destroy (&e);
+            return 1;
+        }
+
+        mem_free ((void **) &temp);
+
+        e->m_emit_type = et_byte;
+    }
+
+    eat_spaces (&t);
+
+    if (get_emits (&t, &e->m_next, mapb))
+    {
+        emit_destroy (&e);
+        return 1;
+    }
+
+    *text = t;
+    *em = e;
+    return 0;
+}
+
+/*
+    returns 0 on success,
+    returns 1 otherwise,
+*/
+static int get_spec (const byte **text, spec **sp, map_str *maps, map_byte *mapb)
+{
+    const byte *t = *text;
+    spec *s = NULL;
+
+    spec_create (&s);
+    if (s == NULL)
+        return 1;
+
+    /* first - read optional .if statement */
+    if (*t == '.')
+    {
+        const byte *u = t;
+        byte *keyword = NULL;
+
+        /* skip the dot */
+        u++;
+
+        if (get_identifier (&u, &keyword))
+        {
+            spec_destroy (&s);
+            return 1;
+        }
+
+        /* .if */
+        if (str_equal ((byte *) "if", keyword))
+        {
+            cond_create (&s->m_cond);
+            if (s->m_cond == NULL)
+            {
+                spec_destroy (&s);
+                return 1;
+            }
+
+            /* skip the left paren */
+            eat_spaces (&u);
+            u++;
+
+            /* get the left operand */
+            eat_spaces (&u);
+            if (get_identifier (&u, &s->m_cond->m_operands[0].m_regname))
+            {
+                spec_destroy (&s);
+                return 1;
+            }
+            s->m_cond->m_operands[0].m_type = cot_regbyte;
+
+            /* get the operator (!= or ==) */
+            eat_spaces (&u);
+            if (*u == '!')
+                s->m_cond->m_type = ct_not_equal;
+            else
+                s->m_cond->m_type = ct_equal;
+            u += 2;
+
+            /* skip the 0x prefix */
+            eat_spaces (&u);
+            u += 2;
+
+            /* get the right operand */
+            s->m_cond->m_operands[1].m_byte = hex_convert (&u);
+            s->m_cond->m_operands[1].m_type = cot_byte;
+
+            /* skip the right paren */
+            eat_spaces (&u);
+            u++;
+
+            eat_spaces (&u);
+
+            t = u;
+        }
+
+        mem_free ((void **) &keyword);
+    }
+
+    if (*t == '\'')
+    {
+        byte *temp = NULL;
+
+        if (get_string (&t, &temp))
+        {
+            spec_destroy (&s);
+            return 1;
+        }
+        eat_spaces (&t);
+
+        if (*t == '-')
+        {
+            byte *temp2 = NULL;
+
+            /* skip the '-' character */
+            t++;
+            eat_spaces (&t);
+
+            if (get_string (&t, &temp2))
+            {
+                mem_free ((void **) &temp);
+                spec_destroy (&s);
+                return 1;
+            }
+            eat_spaces (&t);
+
+            s->m_spec_type = st_byte_range;
+            s->m_byte[0] = *temp;
+            s->m_byte[1] = *temp2;
+
+            mem_free ((void **) &temp2);
+        }
+        else
+        {
+            s->m_spec_type = st_byte;
+            *s->m_byte = *temp;
+        }
+
+        mem_free ((void **) &temp);
+    }
+    else if (*t == '"')
+    {
+        if (get_string (&t, &s->m_string))
+        {
+            spec_destroy (&s);
+            return 1;
+        }
+        eat_spaces (&t);
+
+        s->m_spec_type = st_string;
+    }
+    else if (*t == '.')
+    {
+        byte *keyword = NULL;
+
+        /* skip the dot */
+        t++;
+
+        if (get_identifier (&t, &keyword))
+        {
+            spec_destroy (&s);
+            return 1;
+        }
+        eat_spaces (&t);
+
+        /* .true */
+        if (str_equal ((byte *) "true", keyword))
+        {
+            s->m_spec_type = st_true;
+        }
+        /* .false */
+        else if (str_equal ((byte *) "false", keyword))
+        {
+            s->m_spec_type = st_false;
+        }
+        /* .debug */
+        else if (str_equal ((byte *) "debug", keyword))
+        {
+            s->m_spec_type = st_debug;
+        }
+        /* .loop */
+        else if (str_equal ((byte *) "loop", keyword))
+        {
+            if (get_identifier (&t, &s->m_string))
+            {
+                mem_free ((void **) &keyword);
+                spec_destroy (&s);
+                return 1;
+            }
+            eat_spaces (&t);
+
+            s->m_spec_type = st_identifier_loop;
+        }
+
+        mem_free ((void **) &keyword);
+    }
+    else
+    {
+        if (get_identifier (&t, &s->m_string))
+        {
+            spec_destroy (&s);
+            return 1;
+        }
+        eat_spaces (&t);
+
+        s->m_spec_type = st_identifier;
+    }
+
+    if (get_error (&t, &s->m_errtext, maps))
+    {
+        spec_destroy (&s);
+        return 1;
+    }
+
+    if (get_emits (&t, &s->m_emits, mapb))
+    {
+        spec_destroy (&s);
+        return 1;
+    }
+
+    *text = t;
+    *sp = s;
+    return 0;
+}
+
+/*
+    returns 0 on success,
+    returns 1 otherwise,
+*/
+static int get_rule (const byte **text, rule **ru, map_str *maps, map_byte *mapb)
+{
+    const byte *t = *text;
+    rule *r = NULL;
+
+    rule_create (&r);
+    if (r == NULL)
+        return 1;
+
+    if (get_spec (&t, &r->m_specs, maps, mapb))
+    {
+        rule_destroy (&r);
+        return 1;
+    }
+
+    while (*t != ';')
+    {
+        byte *op = NULL;
+        spec *sp = NULL;
+
+        /* skip the dot that precedes "and" or "or" */
+        t++;
+
+        /* read "and" or "or" keyword */
+        if (get_identifier (&t, &op))
+        {
+            rule_destroy (&r);
+            return 1;
+        }
+        eat_spaces (&t);
+
+        if (r->m_oper == op_none)
+        {
+            /* .and */
+            if (str_equal ((byte *) "and", op))
+                r->m_oper = op_and;
+            /* .or */
+            else
+                r->m_oper = op_or;
+        }
+
+        mem_free ((void **) &op);
+
+        if (get_spec (&t, &sp, maps, mapb))
+        {
+            rule_destroy (&r);
+            return 1;
+        }
+
+        spec_append (&r->m_specs, &sp);
+    }
+
+    /* skip the semicolon */
+    t++;
+    eat_spaces (&t);
+
+    *text = t;
+    *ru = r;
+    return 0;
+}
+
+/*
+    returns 0 on success,
+    returns 1 otherwise,
+*/
+static int update_dependency (map_rule *mapr, byte *symbol, rule **ru)
+{
+    if (map_rule_find (&mapr, symbol, ru))
+        return 1;
+
+/*  (**ru).m_referenced = 1; */
+
+    return 0;
+}
+
+/*
+    returns 0 on success,
+    returns 1 otherwise,
+*/
+static int update_dependencies (dict *di, map_rule *mapr, byte **syntax_symbol,
+    byte **string_symbol, map_byte *regbytes)
+{
+    rule *rulez = di->m_rulez;
+
+    /* update dependecies for the root and lexer symbols */
+    if (update_dependency (mapr, *syntax_symbol, &di->m_syntax) ||
+        (*string_symbol != NULL && update_dependency (mapr, *string_symbol, &di->m_string)))
+        return 1;
+
+    mem_free ((void **) syntax_symbol);
+    mem_free ((void **) string_symbol);
+
+    /* update dependecies for the rest of the rules */
+    while (rulez)
+    {
+        spec *sp = rulez->m_specs;
+
+        /* iterate through all the specifiers */
+        while (sp)
+        {
+            /* update dependency for identifier */
+            if (sp->m_spec_type == st_identifier || sp->m_spec_type == st_identifier_loop)
+            {
+                if (update_dependency (mapr, sp->m_string, &sp->m_rule))
+                    return 1;
+
+                mem_free ((void **) &sp->m_string);
+            }
+
+            /* some errtexts reference to a rule */
+            if (sp->m_errtext && sp->m_errtext->m_token_name)
+            {
+                if (update_dependency (mapr, sp->m_errtext->m_token_name, &sp->m_errtext->m_token))
+                    return 1;
+
+                mem_free ((void **) &sp->m_errtext->m_token_name);
+            }
+
+            /* update dependency for condition */
+            if (sp->m_cond)
+            {
+                int i;
+                for (i = 0; i < 2; i++)
+                    if (sp->m_cond->m_operands[i].m_type == cot_regbyte)
+                    {
+                        sp->m_cond->m_operands[i].m_regbyte = map_byte_locate (&regbytes,
+                            sp->m_cond->m_operands[i].m_regname);
+
+                        if (sp->m_cond->m_operands[i].m_regbyte == NULL)
+                            return 1;
+
+                        mem_free ((void **) &sp->m_cond->m_operands[i].m_regname);
+                    }
+            }
+
+            /* update dependency for all .load instructions */
+            if (sp->m_emits)
+            {
+                emit *em = sp->m_emits;
+                while (em != NULL)
+                {
+                    if (em->m_emit_dest == ed_regbyte)
+                    {
+                        em->m_regbyte = map_byte_locate (&regbytes, em->m_regname);
+
+                        if (em->m_regbyte == NULL)
+                            return 1;
+
+                        mem_free ((void **) &em->m_regname);
+                    }
+
+                    em = em->m_next;
+                }
+            }
+
+            sp = sp->m_next;
+        }
+
+        rulez = rulez->m_next;
+    }
+
+/* check for unreferenced symbols */
+/*  de = di->m_defntns;
+    while (de)
+    {
+        if (!de->m_referenced)
+        {
+            map_def *ma = mapd;
+            while (ma)
+            {
+                if (ma->data == de)
+                {
+                    assert (0);
+                    break;
+                }
+                ma = ma->next;
+            }
+        }
+        de = de->m_next;
+    }
+*/
+    return 0;
+}
+
+static int satisfies_condition (cond *co, regbyte_ctx *ctx)
+{
+    byte values[2];
+    int i;
+
+    if (co == NULL)
+        return 1;
+
+    for (i = 0; i < 2; i++)
+        switch (co->m_operands[i].m_type)
+        {
+        case cot_byte:
+            values[i] = co->m_operands[i].m_byte;
+            break;
+        case cot_regbyte:
+            values[i] = regbyte_ctx_extract (&ctx, co->m_operands[i].m_regbyte);
+            break;
+        }
+
+    switch (co->m_type)
+    {
+    case ct_equal:
+        return values[0] == values[1];
+    case ct_not_equal:
+        return values[0] != values[1];
+    }
+
+    return 0;
+}
+
+static void free_regbyte_ctx_stack (regbyte_ctx *top, regbyte_ctx *limit)
+{
+    while (top != limit)
+    {
+        regbyte_ctx *rbc = top->m_prev;
+        regbyte_ctx_destroy (&top);
+        top = rbc;
+    }
+}
+
+typedef enum match_result_
+{
+    mr_not_matched,     /* the examined string does not match */
+    mr_matched,         /* the examined string matches */
+    mr_error_raised,    /* mr_not_matched + error has been raised */
+    mr_dont_emit,       /* used by identifier loops only */
+    mr_internal_error   /* an internal error has occured such as out of memory */
+} match_result;
+
+/*
+    This function does the main job. It parses the text and generates output data.
+
+    XXX optimize it - the barray seems to be the bottleneck
+*/
+static match_result match (dict *di, const byte *text, unsigned int *index, rule *ru, barray **ba,
+    int filtering_string, regbyte_ctx **rbc)
+{
+    unsigned int ind = *index;
+    match_result status = mr_not_matched;
+    spec *sp = ru->m_specs;
+    regbyte_ctx *ctx = *rbc;
+
+    /* for every specifier in the rule */
+    while (sp)
+    {
+        unsigned int i, len, save_ind = ind;
+        barray *array = NULL;
+
+        if (satisfies_condition (sp->m_cond, ctx))
+        {
+            switch (sp->m_spec_type)
+            {
+            case st_identifier:
+                barray_create (&array);
+                if (array == NULL)
+                {
+                    free_regbyte_ctx_stack (ctx, *rbc);
+                    return mr_internal_error;
+                }
+
+                status = match (di, text, &ind, sp->m_rule, &array, filtering_string, &ctx);
+                if (status == mr_internal_error)
+                {
+                    free_regbyte_ctx_stack (ctx, *rbc);
+                    barray_destroy (&array);
+                    return mr_internal_error;
+                }
+                break;
+            case st_string:
+                len = str_length (sp->m_string);
+
+                /* prefilter the stream */
+                if (!filtering_string && di->m_string)
+                {
+                    barray *ba;
+                    unsigned int filter_index = 0;
+                    match_result result;
+                    regbyte_ctx *null_ctx = NULL;
+
+                    barray_create (&ba);
+                    if (ba == NULL)
+                    {
+                        free_regbyte_ctx_stack (ctx, *rbc);
+                        return mr_internal_error;
+                    }
+
+                    result = match (di, text + ind, &filter_index, di->m_string, &ba, 1, &null_ctx);
+
+                    if (result == mr_internal_error)
+                    {
+                        free_regbyte_ctx_stack (ctx, *rbc);
+                        barray_destroy (&ba);
+                        return mr_internal_error;
+                    }
+
+                    if (result != mr_matched)
+                    {
+                        barray_destroy (&ba);
+                        status = mr_not_matched;
+                        break;
+                    }
+
+                    barray_destroy (&ba);
+
+                    if (filter_index != len || !str_equal_n (sp->m_string, text + ind, len))
+                    {
+                        status = mr_not_matched;
+                        break;
+                    }
+
+                    status = mr_matched;
+                    ind += len;
+                }
+                else
+                {
+                    status = mr_matched;
+                    for (i = 0; status == mr_matched && i < len; i++)
+                        if (text[ind + i] != sp->m_string[i])
+                            status = mr_not_matched;
+                    if (status == mr_matched)
+                        ind += len;
+                }
+                break;
+            case st_byte:
+                status = text[ind] == *sp->m_byte ? mr_matched : mr_not_matched;
+                if (status == mr_matched)
+                    ind++;
+                break;
+            case st_byte_range:
+                status = (text[ind] >= sp->m_byte[0] && text[ind] <= sp->m_byte[1]) ?
+                    mr_matched : mr_not_matched;
+                if (status == mr_matched)
+                    ind++;
+                break;
+            case st_true:
+                status = mr_matched;
+                break;
+            case st_false:
+                status = mr_not_matched;
+                break;
+            case st_debug:
+                status = ru->m_oper == op_and ? mr_matched : mr_not_matched;
+                break;
+            case st_identifier_loop:
+                barray_create (&array);
+                if (array == NULL)
+                {
+                    free_regbyte_ctx_stack (ctx, *rbc);
+                    return mr_internal_error;
+                }
+
+                status = mr_dont_emit;
+                for (;;)
+                {
+                    match_result result;
+
+                    save_ind = ind;
+                    result = match (di, text, &ind, sp->m_rule, &array, filtering_string, &ctx);
+
+                    if (result == mr_error_raised)
+                    {
+                        status = result;
+                        break;
+                    }
+                    else if (result == mr_matched)
+                    {
+                        if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind, &ctx) ||
+                            barray_append (ba, &array))
+                        {
+                            free_regbyte_ctx_stack (ctx, *rbc);
+                            barray_destroy (&array);
+                            return mr_internal_error;
+                        }
+                        barray_destroy (&array);
+                        barray_create (&array);
+                        if (array == NULL)
+                        {
+                            free_regbyte_ctx_stack (ctx, *rbc);
+                            return mr_internal_error;
+                        }
+                    }
+                    else if (result == mr_internal_error)
+                    {
+                        free_regbyte_ctx_stack (ctx, *rbc);
+                        barray_destroy (&array);
+                        return mr_internal_error;
+                    }
+                    else
+                        break;
+                }
+                break;
+            }
+        }
+        else
+        {
+            status = mr_not_matched;
+        }
+
+        if (status == mr_error_raised)
+        {
+            free_regbyte_ctx_stack (ctx, *rbc);
+            barray_destroy (&array);
+
+            return mr_error_raised;
+        }
+
+        if (ru->m_oper == op_and && status != mr_matched && status != mr_dont_emit)
+        {
+            free_regbyte_ctx_stack (ctx, *rbc);
+            barray_destroy (&array);
+
+            if (sp->m_errtext)
+            {
+                set_last_error (sp->m_errtext->m_text, error_get_token (sp->m_errtext, di, text,
+                    ind), ind);
+
+                return mr_error_raised;
+            }
+
+            return mr_not_matched;
+        }
+
+        if (status == mr_matched)
+        {
+            if (sp->m_emits)
+                if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind, &ctx))
+                {
+                    free_regbyte_ctx_stack (ctx, *rbc);
+                    barray_destroy (&array);
+                    return mr_internal_error;
+                }
+
+            if (array)
+                if (barray_append (ba, &array))
+                {
+                    free_regbyte_ctx_stack (ctx, *rbc);
+                    barray_destroy (&array);
+                    return mr_internal_error;
+                }
+        }
+
+        barray_destroy (&array);
+
+        /* if the rule operator is a logical or, we pick up the first matching specifier */
+        if (ru->m_oper == op_or && (status == mr_matched || status == mr_dont_emit))
+        {
+            *index = ind;
+            *rbc = ctx;
+            return mr_matched;
+        }
+
+        sp = sp->m_next;
+    }
+
+    /* everything went fine - all specifiers match up */
+    if (ru->m_oper == op_and && (status == mr_matched || status == mr_dont_emit))
+    {
+        *index = ind;
+        *rbc = ctx;
+        return mr_matched;
+    }
+
+    free_regbyte_ctx_stack (ctx, *rbc);
+    return mr_not_matched;
+}
+
+static byte *error_get_token (error *er, dict *di, const byte *text, unsigned int ind)
+{
+    byte *str = NULL;
+
+    if (er->m_token)
+    {
+        barray *ba;
+        unsigned int filter_index = 0;
+        regbyte_ctx *ctx = NULL;
+
+        barray_create (&ba);
+        if (ba != NULL)
+        {
+            if (match (di, text + ind, &filter_index, er->m_token, &ba, 0, &ctx) == mr_matched &&
+                filter_index)
+            {
+                str = mem_alloc (filter_index + 1);
+                if (str != NULL)
+                {
+                    str_copy_n (str, text + ind, filter_index);
+                    str[filter_index] = '\0';
+                }
+            }
+            barray_destroy (&ba);
+        }
+    }
+
+    return str;
+}
+
+typedef struct grammar_load_state_
+{
+    dict *di;
+    byte *syntax_symbol;
+    byte *string_symbol;
+    map_str *maps;
+    map_byte *mapb;
+    map_rule *mapr;
+} grammar_load_state;
+
+static void grammar_load_state_create (grammar_load_state **gr)
+{
+    *gr = mem_alloc (sizeof (grammar_load_state));
+    if (*gr)
+    {
+        (**gr).di = NULL;
+        (**gr).syntax_symbol = NULL;
+        (**gr).string_symbol = NULL;
+        (**gr).maps = NULL;
+        (**gr).mapb = NULL;
+        (**gr).mapr = NULL;
+    }
+}
+
+static void grammar_load_state_destroy (grammar_load_state **gr)
+{
+    if (*gr)
+    {
+        dict_destroy (&(**gr).di);
+        mem_free ((void **) &(**gr).syntax_symbol);
+        mem_free ((void **) &(**gr).string_symbol);
+        map_str_destroy (&(**gr).maps);
+        map_byte_destroy (&(**gr).mapb);
+        map_rule_destroy (&(**gr).mapr);
+        mem_free ((void **) gr);
+    }
+}
+
+/*
+    the API
+*/
+
+grammar grammar_load_from_text (const byte *text)
+{
+    grammar_load_state *g = NULL;
+    grammar id = 0;
+
+    clear_last_error ();
+
+    grammar_load_state_create (&g);
+    if (g == NULL)
+        return 0;
+
+    dict_create (&g->di);
+    if (g->di == NULL)
+    {
+        grammar_load_state_destroy (&g);
+        return 0;
+    }
+
+    eat_spaces (&text);
+
+    /* skip ".syntax" keyword */
+    text += 7;
+    eat_spaces (&text);
+
+    /* retrieve root symbol */
+    if (get_identifier (&text, &g->syntax_symbol))
+    {
+        grammar_load_state_destroy (&g);
+        return 0;
+    }
+    eat_spaces (&text);
+
+    /* skip semicolon */
+    text++;
+    eat_spaces (&text);
+
+    while (*text)
+    {
+        byte *symbol = NULL;
+        int is_dot = *text == '.';
+
+        if (is_dot)
+            text++;
+
+        if (get_identifier (&text, &symbol))
+        {
+            grammar_load_state_destroy (&g);
+            return 0;
+        }
+        eat_spaces (&text);
+
+        /* .emtcode */
+        if (is_dot && str_equal (symbol, (byte *) "emtcode"))
+        {
+            map_byte *ma = NULL;
+
+            mem_free ((void **) &symbol);
+
+            if (get_emtcode (&text, &ma))
+            {
+                grammar_load_state_destroy (&g);
+                return 0;
+            }
+
+            map_byte_append (&g->mapb, &ma);
+        }
+        /* .regbyte */
+        else if (is_dot && str_equal (symbol, (byte *) "regbyte"))
+        {
+            map_byte *ma = NULL;
+
+            mem_free ((void **) &symbol);
+
+            if (get_regbyte (&text, &ma))
+            {
+                grammar_load_state_destroy (&g);
+                return 0;
+            }
+
+            map_byte_append (&g->di->m_regbytes, &ma);
+        }
+        /* .errtext */
+        else if (is_dot && str_equal (symbol, (byte *) "errtext"))
+        {
+            map_str *ma = NULL;
+
+            mem_free ((void **) &symbol);
+
+            if (get_errtext (&text, &ma))
+            {
+                grammar_load_state_destroy (&g);
+                return 0;
+            }
+
+            map_str_append (&g->maps, &ma);
+        }
+        /* .string */
+        else if (is_dot && str_equal (symbol, (byte *) "string"))
+        {
+            mem_free ((void **) &symbol);
+
+            if (g->di->m_string != NULL)
+            {
+                grammar_load_state_destroy (&g);
+                return 0;
+            }
+
+            if (get_identifier (&text, &g->string_symbol))
+            {
+                grammar_load_state_destroy (&g);
+                return 0;
+            }
+
+            /* skip semicolon */
+            eat_spaces (&text);
+            text++;
+            eat_spaces (&text);
+        }
+        else
+        {
+            rule *ru = NULL;
+            map_rule *ma = NULL;
+
+            if (get_rule (&text, &ru, g->maps, g->mapb))
+            {
+                grammar_load_state_destroy (&g);
+                return 0;
+            }
+
+            rule_append (&g->di->m_rulez, &ru);
+
+            /* if a rule consist of only one specifier, give it an ".and" operator */
+            if (ru->m_oper == op_none)
+                ru->m_oper = op_and;
+
+            map_rule_create (&ma);
+            if (ma == NULL)
+            {
+                grammar_load_state_destroy (&g);
+                return 0;
+            }
+
+            ma->key = symbol;
+            ma->data = ru;
+            map_rule_append (&g->mapr, &ma);
+        }
+    }
+
+    if (update_dependencies (g->di, g->mapr, &g->syntax_symbol, &g->string_symbol,
+        g->di->m_regbytes))
+    {
+        grammar_load_state_destroy (&g);
+        return 0;
+    }
+
+    dict_append (&g_dicts, &g->di);
+    id = g->di->m_id;
+    g->di = NULL;
+
+    grammar_load_state_destroy (&g);
+
+    return id;
+}
+
+int grammar_set_reg8 (grammar id, const byte *name, byte value)
+{
+    dict *di = NULL;
+    map_byte *reg = NULL;
+
+    clear_last_error ();
+
+    dict_find (&g_dicts, id, &di);
+    if (di == NULL)
+    {
+        set_last_error (INVALID_GRAMMAR_ID, NULL, -1);
+        return 0;
+    }
+
+    reg = map_byte_locate (&di->m_regbytes, name);
+    if (reg == NULL)
+    {
+        set_last_error (INVALID_REGISTER_NAME, str_duplicate (name), -1);
+        return 0;
+    }
+
+    reg->data = value;
+    return 1;
+}
+
+int grammar_check (grammar id, const byte *text, byte **prod, unsigned int *size)
+{
+    dict *di = NULL;
+    barray *ba = NULL;
+    unsigned int index = 0;
+    regbyte_ctx *rbc = NULL;
+
+    clear_last_error ();
+
+    dict_find (&g_dicts, id, &di);
+    if (di == NULL)
+    {
+        set_last_error (INVALID_GRAMMAR_ID, NULL, -1);
+        return 0;
+    }
+
+    barray_create (&ba);
+    if (ba == NULL)
+        return 0;
+
+    *prod = NULL;
+    *size = 0;
+
+    if (match (di, text, &index, di->m_syntax, &ba, 0, &rbc) != mr_matched)
+    {
+        barray_destroy (&ba);
+        free_regbyte_ctx_stack (rbc, NULL);
+        return 0;
+    }
+
+    free_regbyte_ctx_stack (rbc, NULL);
+
+    *prod = mem_alloc (ba->len * sizeof (byte));
+    if (*prod == NULL)
+    {
+        barray_destroy (&ba);
+        return 0;
+    }
+
+    mem_copy (*prod, ba->data, ba->len * sizeof (byte));
+    *size = ba->len;
+    barray_destroy (&ba);
+
+    return 1;
+}
+
+int grammar_destroy (grammar id)
+{
+    dict **di = &g_dicts;
+
+    clear_last_error ();
+
+    while (*di != NULL)
+    {
+        if ((**di).m_id == id)
+        {
+            dict *tmp = *di;
+            *di = (**di).m_next;
+            dict_destroy (&tmp);
+            return 1;
+        }
+
+        di = &(**di).m_next;
+    }
+
+    set_last_error (INVALID_GRAMMAR_ID, NULL, -1);
+    return 0;
+}
+
+void grammar_get_last_error (byte *text, unsigned int size, int *pos)
+{
+    unsigned int len = 0, dots_made = 0;
+    const byte *p = error_message;
+
+    *text = '\0';
+
+#define APPEND_CHARACTER(x) if (dots_made == 0) {\
+                                if (len < size - 1) {\
+                                    text[len++] = (x); text[len] = '\0';\
+                                } else {\
+                                    int i;\
+                                    for (i = 0; i < 3; i++)\
+                                        if (--len >= 0)\
+                                            text[len] = '.';\
+                                    dots_made = 1;\
+                                }\
+                            }
+
+    if (p)
+        while (*p)
+            if (*p == '$')
+            {
+                const byte *r = error_param;
+
+                while (*r)
+                {
+                    APPEND_CHARACTER(*r)
+                    r++;
+                }
+
+                p++;
+            }
+            else
+            {
+                APPEND_CHARACTER(*p)
+                p++;
+            }
+
+    *pos = error_position;
+
+#undef APPEND_CHARACTER
+
+}
+
index 152ebc1086ae9a80fffffe31390bf3d10ba7615d..41a484e69c5cb1b964f00567fd86d5d0fa99d369 100644 (file)
@@ -1,68 +1,92 @@
-#ifndef GRAMMAR_H\r
-#define GRAMMAR_H\r
-\r
-\r
-#ifndef GRAMMAR_PORT_INCLUDE\r
-#error Do not include this file directly, include your grammar_XXX.h instead\r
-#endif\r
-\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-void grammar_alloc_free (void *);\r
-void *grammar_alloc_malloc (unsigned int);\r
-void *grammar_alloc_realloc (void *, unsigned int, unsigned int);\r
-void *grammar_memory_copy (void *, const void *, unsigned int);\r
-int grammar_string_compare (const byte *, const byte *);\r
-int grammar_string_compare_n (const byte *, const byte *, unsigned int);\r
-byte *grammar_string_copy (byte *, const byte *);\r
-byte *grammar_string_copy_n (byte *, const byte *, unsigned int);\r
-byte *grammar_string_duplicate (const byte *);\r
-unsigned int grammar_string_length (const byte *);\r
-\r
-/*\r
-    loads grammar script from null-terminated ASCII <text>\r
-    returns unique grammar id to grammar object\r
-    returns 0 if an error occurs (call grammar_get_last_error to retrieve the error text)\r
-*/\r
-grammar grammar_load_from_text (const byte *text);\r
-\r
-/*\r
-    sets a new <value> to a register <name> for grammar <id>\r
-    returns 0 on error (call grammar_get_last_error to retrieve the error text)\r
-    returns 1 on success\r
-*/\r
-int grammar_set_reg8 (grammar id, const byte *name, byte value);\r
-\r
-/*\r
-    checks if a null-terminated <text> matches given grammar <id>\r
-    returns 0 on error (call grammar_get_last_error to retrieve the error text)\r
-    returns 1 on success, the <prod> points to newly allocated buffer with production and <size>\r
-    is filled with the production size\r
-    call grammar_alloc_free to free the memory block pointed by <prod>\r
-*/\r
-int grammar_check (grammar id, const byte *text, byte **prod, unsigned int *size);\r
-\r
-/*\r
-    destroys grammar object identified by <id>\r
-    returns 0 on error (call grammar_get_last_error to retrieve the error text)\r
-    returns 1 on success\r
-*/\r
-int grammar_destroy (grammar id);\r
-\r
-/*\r
-    retrieves last grammar error reported either by grammar_load_from_text, grammar_check\r
-    or grammar_destroy\r
-    the user allocated <text> buffer receives error description, <pos> points to error position,\r
-    <size> is the size of the text buffer to fill in - it must be at least 4 bytes long,\r
-*/\r
-void grammar_get_last_error (byte *text, unsigned int size, int *pos);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.1
+ *
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef GRAMMAR_H
+#define GRAMMAR_H
+
+
+#ifndef GRAMMAR_PORT_INCLUDE
+#error Do not include this file directly, include your grammar_XXX.h instead
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void grammar_alloc_free (void *);
+void *grammar_alloc_malloc (unsigned int);
+void *grammar_alloc_realloc (void *, unsigned int, unsigned int);
+void *grammar_memory_copy (void *, const void *, unsigned int);
+int grammar_string_compare (const byte *, const byte *);
+int grammar_string_compare_n (const byte *, const byte *, unsigned int);
+byte *grammar_string_copy (byte *, const byte *);
+byte *grammar_string_copy_n (byte *, const byte *, unsigned int);
+byte *grammar_string_duplicate (const byte *);
+unsigned int grammar_string_length (const byte *);
+
+/*
+    loads grammar script from null-terminated ASCII <text>
+    returns unique grammar id to grammar object
+    returns 0 if an error occurs (call grammar_get_last_error to retrieve the error text)
+*/
+grammar grammar_load_from_text (const byte *text);
+
+/*
+    sets a new <value> to a register <name> for grammar <id>
+    returns 0 on error (call grammar_get_last_error to retrieve the error text)
+    returns 1 on success
+*/
+int grammar_set_reg8 (grammar id, const byte *name, byte value);
+
+/*
+    checks if a null-terminated <text> matches given grammar <id>
+    returns 0 on error (call grammar_get_last_error to retrieve the error text)
+    returns 1 on success, the <prod> points to newly allocated buffer with production and <size>
+    is filled with the production size
+    call grammar_alloc_free to free the memory block pointed by <prod>
+*/
+int grammar_check (grammar id, const byte *text, byte **prod, unsigned int *size);
+
+/*
+    destroys grammar object identified by <id>
+    returns 0 on error (call grammar_get_last_error to retrieve the error text)
+    returns 1 on success
+*/
+int grammar_destroy (grammar id);
+
+/*
+    retrieves last grammar error reported either by grammar_load_from_text, grammar_check
+    or grammar_destroy
+    the user allocated <text> buffer receives error description, <pos> points to error position,
+    <size> is the size of the text buffer to fill in - it must be at least 4 bytes long,
+*/
+void grammar_get_last_error (byte *text, unsigned int size, int *pos);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
index b9cb17fc382a5c3d6e37dc43c606e1f8735dc03f..0aadac58bc51fd33612d5c38b82161e71db3281e 100644 (file)
@@ -1,57 +1,87 @@
-#include "grammar_mesa.h"\r
-\r
-#define GRAMMAR_PORT_BUILD 1\r
-#include "grammar.c"\r
-#undef GRAMMAR_PORT_BUILD\r
-\r
-\r
-void grammar_alloc_free (void *ptr)\r
-{\r
-    _mesa_free (ptr);\r
-}\r
-\r
-void *grammar_alloc_malloc (unsigned int size)\r
-{\r
-    return _mesa_malloc (size);\r
-}\r
-\r
-void *grammar_alloc_realloc (void *ptr, unsigned int old_size, unsigned int size)\r
-{\r
-    return _mesa_realloc (ptr, old_size, size);\r
-}\r
-\r
-void *grammar_memory_copy (void *dst, const void * src, unsigned int size)\r
-{\r
-    return _mesa_memcpy (dst, src, size);\r
-}\r
-\r
-int grammar_string_compare (const byte *str1, const byte *str2)\r
-{\r
-    return _mesa_strcmp ((const char *) str1, (const char *) str2);\r
-}\r
-\r
-int grammar_string_compare_n (const byte *str1, const byte *str2, unsigned int n)\r
-{\r
-    return _mesa_strncmp ((const char *) str1, (const char *) str2, n);\r
-}\r
-\r
-byte *grammar_string_copy (byte *dst, const byte *src)\r
-{\r
-    return (byte *) _mesa_strcpy ((char *) dst, (const char *) src);\r
-}\r
-\r
-byte *grammar_string_copy_n (byte *dst, const byte *src, unsigned int n)\r
-{\r
-    return (byte *) _mesa_strncpy ((char *) dst, (const char *) src, n);\r
-}\r
-\r
-byte *grammar_string_duplicate (const byte *src)\r
-{\r
-    return (byte *) _mesa_strdup ((const char *) src);\r
-}\r
-\r
-unsigned int grammar_string_length (const byte *str)\r
-{\r
-    return _mesa_strlen ((const char *) str);\r
-}\r
-\r
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.1
+ *
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file grammar_mesa.c
+ * mesa3d port to syntax parsing engine
+ * \author Michal Krol
+ */
+
+#include "grammar_mesa.h"
+
+#define GRAMMAR_PORT_BUILD 1
+#include "grammar.c"
+#undef GRAMMAR_PORT_BUILD
+
+
+void grammar_alloc_free (void *ptr)
+{
+    _mesa_free (ptr);
+}
+
+void *grammar_alloc_malloc (unsigned int size)
+{
+    return _mesa_malloc (size);
+}
+
+void *grammar_alloc_realloc (void *ptr, unsigned int old_size, unsigned int size)
+{
+    return _mesa_realloc (ptr, old_size, size);
+}
+
+void *grammar_memory_copy (void *dst, const void * src, unsigned int size)
+{
+    return _mesa_memcpy (dst, src, size);
+}
+
+int grammar_string_compare (const byte *str1, const byte *str2)
+{
+    return _mesa_strcmp ((const char *) str1, (const char *) str2);
+}
+
+int grammar_string_compare_n (const byte *str1, const byte *str2, unsigned int n)
+{
+    return _mesa_strncmp ((const char *) str1, (const char *) str2, n);
+}
+
+byte *grammar_string_copy (byte *dst, const byte *src)
+{
+    return (byte *) _mesa_strcpy ((char *) dst, (const char *) src);
+}
+
+byte *grammar_string_copy_n (byte *dst, const byte *src, unsigned int n)
+{
+    return (byte *) _mesa_strncpy ((char *) dst, (const char *) src, n);
+}
+
+byte *grammar_string_duplicate (const byte *src)
+{
+    return (byte *) _mesa_strdup ((const char *) src);
+}
+
+unsigned int grammar_string_length (const byte *str)
+{
+    return _mesa_strlen ((const char *) str);
+}
+
index 77a8804636ee44d4b27ffcd27c89a827e7b52702..c14033a9d45779676bd59de50d86c17d2ac8f5fb 100644 (file)
@@ -1,19 +1,43 @@
-#ifndef GRAMMAR_MESA_H\r
-#define GRAMMAR_MESA_H\r
-\r
-\r
-#include "imports.h"\r
-/* NOTE: include Mesa 3-D specific headers here */\r
-\r
-\r
-typedef GLuint grammar;\r
-typedef GLubyte byte;\r
-\r
-\r
-#define GRAMMAR_PORT_INCLUDE 1\r
-#include "grammar.h"\r
-#undef GRAMMAR_PORT_INCLUDE\r
-\r
-\r
-#endif\r
-\r
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.1
+ *
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef GRAMMAR_MESA_H
+#define GRAMMAR_MESA_H
+
+
+#include "imports.h"
+/* NOTE: include Mesa 3-D specific headers here */
+
+
+typedef GLuint grammar;
+typedef GLubyte byte;
+
+
+#define GRAMMAR_PORT_INCLUDE 1
+#include "grammar.h"
+#undef GRAMMAR_PORT_INCLUDE
+
+
+#endif
+
index 766196ad3fd50903a8344e8fd41d8d2a4fa040cb..9c3419ece82beb0e8a80ace717d21609c76467a6 100644 (file)
-".syntax grammar;\n"\r
-".emtcode DECLARATION_END 0x00\n"\r
-".emtcode DECLARATION_EMITCODE 0x01\n"\r
-".emtcode DECLARATION_ERRORTEXT 0x02\n"\r
-".emtcode DECLARATION_REGBYTE 0x03\n"\r
-".emtcode DECLARATION_LEXER 0x04\n"\r
-".emtcode DECLARATION_RULE 0x05\n"\r
-".emtcode SPECIFIER_END 0x00\n"\r
-".emtcode SPECIFIER_AND_TAG 0x01\n"\r
-".emtcode SPECIFIER_OR_TAG 0x02\n"\r
-".emtcode SPECIFIER_CHARACTER_RANGE 0x03\n"\r
-".emtcode SPECIFIER_CHARACTER 0x04\n"\r
-".emtcode SPECIFIER_STRING 0x05\n"\r
-".emtcode SPECIFIER_IDENTIFIER 0x06\n"\r
-".emtcode SPECIFIER_TRUE 0x07\n"\r
-".emtcode SPECIFIER_FALSE 0x08\n"\r
-".emtcode SPECIFIER_DEBUG 0x09\n"\r
-".emtcode IDENTIFIER_NO_LOOP 0x00\n"\r
-".emtcode IDENTIFIER_LOOP 0x01\n"\r
-".emtcode ERROR_NOT_PRESENT 0x00\n"\r
-".emtcode ERROR_PRESENT 0x01\n"\r
-".emtcode EMIT_NULL 0x00\n"\r
-".emtcode EMIT_INTEGER 0x01\n"\r
-".emtcode EMIT_IDENTIFIER 0x02\n"\r
-".emtcode EMIT_CHARACTER 0x03\n"\r
-".emtcode EMIT_LAST_CHARACTER 0x04\n"\r
-".emtcode EMIT_CURRENT_POSITION 0x05\n"\r
-".errtext INVALID_GRAMMAR \"internal error 2001: invalid grammar script\"\n"\r
-".errtext SYNTAX_EXPECTED \"internal error 2002: '.syntax' keyword expected\"\n"\r
-".errtext IDENTIFIER_EXPECTED \"internal error 2003: identifier expected\"\n"\r
-".errtext MISSING_SEMICOLON \"internal error 2004: missing ';'\"\n"\r
-".errtext INTEGER_EXPECTED \"internal error 2005: integer value expected\"\n"\r
-".errtext STRING_EXPECTED \"internal error 2006: string expected\"\n"\r
-"grammar\n"\r
-" grammar_1 .error INVALID_GRAMMAR;\n"\r
-"grammar_1\n"\r
-" optional_space .and \".syntax\" .error SYNTAX_EXPECTED .and space .and identifier .and\n"\r
-" semicolon .and declaration_list .and optional_space .and '\\0' .emit DECLARATION_END;\n"\r
-"optional_space\n"\r
-" space .or .true;\n"\r
-"space\n"\r
-" single_space .and .loop single_space;\n"\r
-"single_space\n"\r
-" white_char .or comment_block;\n"\r
-"white_char\n"\r
-" ' ' .or '\\t' .or '\\n' .or '\\r';\n"\r
-"comment_block\n"\r
-" '/' .and '*' .and .loop comment_char .and '*' .and '/';\n"\r
-"comment_char\n"\r
-" comment_char_no_star .or comment_char_1;\n"\r
-"comment_char_1\n"\r
-" '*' .and comment_char_no_slash;\n"\r
-"comment_char_no_star\n"\r
-" '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n"\r
-"comment_char_no_slash\n"\r
-" '\\x30'-'\\xFF' .or '\\x01'-'\\x2E';\n"\r
-"identifier\n"\r
-" identifier_ne .error IDENTIFIER_EXPECTED;\n"\r
-"identifier_ne\n"\r
-" first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit '\\0';\n"\r
-"first_idchar\n"\r
-" 'a'-'z' .or 'A'-'Z' .or '_';\n"\r
-"follow_idchar\n"\r
-" first_idchar .or digit_dec;\n"\r
-"digit_dec\n"\r
-" '0'-'9';\n"\r
-"semicolon\n"\r
-" optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;\n"\r
-"declaration_list\n"\r
-" declaration .and .loop declaration;\n"\r
-"declaration\n"\r
-" emitcode_definition .emit DECLARATION_EMITCODE .or\n"\r
-" errortext_definition .emit DECLARATION_ERRORTEXT .or\n"\r
-" regbyte_definition .emit DECLARATION_REGBYTE .or\n"\r
-" lexer_definition .emit DECLARATION_LEXER .or\n"\r
-" rule_definition .emit DECLARATION_RULE;\n"\r
-"emitcode_definition\n"\r
-" \".emtcode\" .and space .and identifier .and space .and integer .and space_or_null;\n"\r
-"integer\n"\r
-" integer_ne .error INTEGER_EXPECTED;\n"\r
-"integer_ne\n"\r
-" hex_prefix .and digit_hex .emit * .and .loop digit_hex .emit * .and .true .emit '\\0';\n"\r
-"hex_prefix\n"\r
-" '0' .and hex_prefix_1;\n"\r
-"hex_prefix_1\n"\r
-" 'x' .or 'X';\n"\r
-"digit_hex\n"\r
-" '0'-'9' .or 'a'-'f' .or 'A'-'F';\n"\r
-"space_or_null\n"\r
-" space .or '\\0';\n"\r
-"errortext_definition\n"\r
-" \".errtext\" .and space .and identifier .and space .and string .and space_or_null;\n"\r
-"string\n"\r
-" string_ne .error STRING_EXPECTED;\n"\r
-"string_ne\n"\r
-" '\"' .and .loop string_char_double_quotes .and '\"' .emit '\\0';\n"\r
-"string_char_double_quotes\n"\r
-" escape_sequence .or string_char .emit * .or '\\'' .emit *;\n"\r
-"string_char\n"\r
-" '\\x5D'-'\\xFF' .or '\\x28'-'\\x5B' .or '\\x23'-'\\x26' .or '\\x0E'-'\\x21' .or '\\x0B'-'\\x0C' .or\n"\r
-" '\\x01'-'\\x09';\n"\r
-"escape_sequence\n"\r
-" '\\\\' .emit * .and escape_code;\n"\r
-"escape_code\n"\r
-" simple_escape_code .emit * .or hex_escape_code .or oct_escape_code;\n"\r
-"simple_escape_code\n"\r
-" '\\'' .or '\"' .or '?' .or '\\\\' .or 'a' .or 'b' .or 'f' .or 'n' .or 'r' .or 't' .or 'v';\n"\r
-"hex_escape_code\n"\r
-" 'x' .emit * .and digit_hex .emit * .and .loop digit_hex .emit *;\n"\r
-"oct_escape_code\n"\r
-" digit_oct .emit * .and optional_digit_oct .and optional_digit_oct;\n"\r
-"digit_oct\n"\r
-" '0'-'7';\n"\r
-"optional_digit_oct\n"\r
-" digit_oct .emit * .or .true;\n"\r
-"regbyte_definition\n"\r
-" \".regbyte\" .and space .and identifier .and space .and integer .and space_or_null;\n"\r
-"lexer_definition\n"\r
-" \".string\" .and space .and identifier .and semicolon;\n"\r
-"rule_definition\n"\r
-" identifier_ne .and space .and definition;\n"\r
-"definition\n"\r
-" specifier .and optional_specifiers_and_or .and semicolon .emit SPECIFIER_END;\n"\r
-"optional_specifiers_and_or\n"\r
-" and_specifiers .emit SPECIFIER_AND_TAG .or or_specifiers .emit SPECIFIER_OR_TAG .or .true;\n"\r
-"specifier\n"\r
-" specifier_condition .and optional_space .and specifier_rule;\n"\r
-"specifier_condition\n"\r
-" specifier_condition_1 .or .true;\n"\r
-"specifier_condition_1\n"\r
-" \".if\" .and optional_space .and '(' .and optional_space .and left_operand .and operator .and\n"\r
-" right_operand .and optional_space .and ')';\n"\r
-"left_operand\n"\r
-" identifier;\n"\r
-"operator\n"\r
-" operator_1 .or operator_2;\n"\r
-"operator_1\n"\r
-" optional_space .and '!' .and '=' .and optional_space;\n"\r
-"operator_2\n"\r
-" optional_space .and '=' .and '=' .and optional_space;\n"\r
-"right_operand\n"\r
-" integer;\n"\r
-"specifier_rule\n"\r
-" specifier_rule_1 .and optional_error .and .loop emit .and .true .emit EMIT_NULL;\n"\r
-"specifier_rule_1\n"\r
-" character_range .emit SPECIFIER_CHARACTER_RANGE .or\n"\r
-" character .emit SPECIFIER_CHARACTER .or\n"\r
-" string_ne .emit SPECIFIER_STRING .or\n"\r
-" \".true\" .emit SPECIFIER_TRUE .or\n"\r
-" \".false\" .emit SPECIFIER_FALSE .or\n"\r
-" \".debug\" .emit SPECIFIER_DEBUG .or\n"\r
-" loop_identifier .emit SPECIFIER_IDENTIFIER;\n"\r
-"character\n"\r
-" '\\'' .and string_char_single_quotes .and '\\'' .emit '\\0';\n"\r
-"string_char_single_quotes\n"\r
-" escape_sequence .or string_char .emit * .or '\"' .emit *;\n"\r
-"character_range\n"\r
-" character .and optional_space .and '-' .and optional_space .and character;\n"\r
-"loop_identifier\n"\r
-" optional_loop .and identifier;\n"\r
-"optional_loop\n"\r
-" optional_loop_1 .emit IDENTIFIER_LOOP .or .true .emit IDENTIFIER_NO_LOOP;\n"\r
-"optional_loop_1\n"\r
-" \".loop\" .and space;\n"\r
-"optional_error\n"\r
-" error .emit ERROR_PRESENT .or .true .emit ERROR_NOT_PRESENT;\n"\r
-"error\n"\r
-" space .and \".error\" .and space .and identifier;\n"\r
-"emit\n"\r
-" emit_output .or emit_regbyte;\n"\r
-"emit_output\n"\r
-" space .and \".emit\" .and space .and emit_param;\n"\r
-"emit_param\n"\r
-" integer_ne .emit EMIT_INTEGER .or\n"\r
-" identifier_ne .emit EMIT_IDENTIFIER .or\n"\r
-" character .emit EMIT_CHARACTER .or\n"\r
-" '*' .emit EMIT_LAST_CHARACTER .or\n"\r
-" '$' .emit EMIT_CURRENT_POSITION;\n"\r
-"emit_regbyte\n"\r
-" space .and \".load\" .and space .and identifier .and space .and emit_param;\n"\r
-"and_specifiers\n"\r
-" and_specifier .and .loop and_specifier;\n"\r
-"or_specifiers\n"\r
-" or_specifier .and .loop or_specifier;\n"\r
-"and_specifier\n"\r
-" space .and \".and\" .and space .and specifier;\n"\r
-"or_specifier\n"\r
-" space .and \".or\" .and space .and specifier;\n"\r
-".string __string_filter;\n"\r
-"__string_filter\n"\r
-" __first_identifier_char .and .loop __next_identifier_char;\n"\r
-"__first_identifier_char\n"\r
-" 'a'-'z' .or 'A'-'Z' .or '_' .or '.';\n"\r
-"__next_identifier_char\n"\r
-" 'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9';\n"\r
-""
\ No newline at end of file
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.1
+ *
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file grammar_syn.h
+ * syntax parsing engine language syntax
+ * \author Michal Krol
+ */
+
+".syntax grammar;\n"
+".emtcode DECLARATION_END 0x00\n"
+".emtcode DECLARATION_EMITCODE 0x01\n"
+".emtcode DECLARATION_ERRORTEXT 0x02\n"
+".emtcode DECLARATION_REGBYTE 0x03\n"
+".emtcode DECLARATION_LEXER 0x04\n"
+".emtcode DECLARATION_RULE 0x05\n"
+".emtcode SPECIFIER_END 0x00\n"
+".emtcode SPECIFIER_AND_TAG 0x01\n"
+".emtcode SPECIFIER_OR_TAG 0x02\n"
+".emtcode SPECIFIER_CHARACTER_RANGE 0x03\n"
+".emtcode SPECIFIER_CHARACTER 0x04\n"
+".emtcode SPECIFIER_STRING 0x05\n"
+".emtcode SPECIFIER_IDENTIFIER 0x06\n"
+".emtcode SPECIFIER_TRUE 0x07\n"
+".emtcode SPECIFIER_FALSE 0x08\n"
+".emtcode SPECIFIER_DEBUG 0x09\n"
+".emtcode IDENTIFIER_NO_LOOP 0x00\n"
+".emtcode IDENTIFIER_LOOP 0x01\n"
+".emtcode ERROR_NOT_PRESENT 0x00\n"
+".emtcode ERROR_PRESENT 0x01\n"
+".emtcode EMIT_NULL 0x00\n"
+".emtcode EMIT_INTEGER 0x01\n"
+".emtcode EMIT_IDENTIFIER 0x02\n"
+".emtcode EMIT_CHARACTER 0x03\n"
+".emtcode EMIT_LAST_CHARACTER 0x04\n"
+".emtcode EMIT_CURRENT_POSITION 0x05\n"
+".errtext INVALID_GRAMMAR \"internal error 2001: invalid grammar script\"\n"
+".errtext SYNTAX_EXPECTED \"internal error 2002: '.syntax' keyword expected\"\n"
+".errtext IDENTIFIER_EXPECTED \"internal error 2003: identifier expected\"\n"
+".errtext MISSING_SEMICOLON \"internal error 2004: missing ';'\"\n"
+".errtext INTEGER_EXPECTED \"internal error 2005: integer value expected\"\n"
+".errtext STRING_EXPECTED \"internal error 2006: string expected\"\n"
+"grammar\n"
+" grammar_1 .error INVALID_GRAMMAR;\n"
+"grammar_1\n"
+" optional_space .and \".syntax\" .error SYNTAX_EXPECTED .and space .and identifier .and\n"
+" semicolon .and declaration_list .and optional_space .and '\\0' .emit DECLARATION_END;\n"
+"optional_space\n"
+" space .or .true;\n"
+"space\n"
+" single_space .and .loop single_space;\n"
+"single_space\n"
+" white_char .or comment_block;\n"
+"white_char\n"
+" ' ' .or '\\t' .or '\\n' .or '\\r';\n"
+"comment_block\n"
+" '/' .and '*' .and .loop comment_char .and '*' .and '/';\n"
+"comment_char\n"
+" comment_char_no_star .or comment_char_1;\n"
+"comment_char_1\n"
+" '*' .and comment_char_no_slash;\n"
+"comment_char_no_star\n"
+" '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n"
+"comment_char_no_slash\n"
+" '\\x30'-'\\xFF' .or '\\x01'-'\\x2E';\n"
+"identifier\n"
+" identifier_ne .error IDENTIFIER_EXPECTED;\n"
+"identifier_ne\n"
+" first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit '\\0';\n"
+"first_idchar\n"
+" 'a'-'z' .or 'A'-'Z' .or '_';\n"
+"follow_idchar\n"
+" first_idchar .or digit_dec;\n"
+"digit_dec\n"
+" '0'-'9';\n"
+"semicolon\n"
+" optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;\n"
+"declaration_list\n"
+" declaration .and .loop declaration;\n"
+"declaration\n"
+" emitcode_definition .emit DECLARATION_EMITCODE .or\n"
+" errortext_definition .emit DECLARATION_ERRORTEXT .or\n"
+" regbyte_definition .emit DECLARATION_REGBYTE .or\n"
+" lexer_definition .emit DECLARATION_LEXER .or\n"
+" rule_definition .emit DECLARATION_RULE;\n"
+"emitcode_definition\n"
+" \".emtcode\" .and space .and identifier .and space .and integer .and space_or_null;\n"
+"integer\n"
+" integer_ne .error INTEGER_EXPECTED;\n"
+"integer_ne\n"
+" hex_prefix .and digit_hex .emit * .and .loop digit_hex .emit * .and .true .emit '\\0';\n"
+"hex_prefix\n"
+" '0' .and hex_prefix_1;\n"
+"hex_prefix_1\n"
+" 'x' .or 'X';\n"
+"digit_hex\n"
+" '0'-'9' .or 'a'-'f' .or 'A'-'F';\n"
+"space_or_null\n"
+" space .or '\\0';\n"
+"errortext_definition\n"
+" \".errtext\" .and space .and identifier .and space .and string .and space_or_null;\n"
+"string\n"
+" string_ne .error STRING_EXPECTED;\n"
+"string_ne\n"
+" '\"' .and .loop string_char_double_quotes .and '\"' .emit '\\0';\n"
+"string_char_double_quotes\n"
+" escape_sequence .or string_char .emit * .or '\\'' .emit *;\n"
+"string_char\n"
+" '\\x5D'-'\\xFF' .or '\\x28'-'\\x5B' .or '\\x23'-'\\x26' .or '\\x0E'-'\\x21' .or '\\x0B'-'\\x0C' .or\n"
+" '\\x01'-'\\x09';\n"
+"escape_sequence\n"
+" '\\\\' .emit * .and escape_code;\n"
+"escape_code\n"
+" simple_escape_code .emit * .or hex_escape_code .or oct_escape_code;\n"
+"simple_escape_code\n"
+" '\\'' .or '\"' .or '?' .or '\\\\' .or 'a' .or 'b' .or 'f' .or 'n' .or 'r' .or 't' .or 'v';\n"
+"hex_escape_code\n"
+" 'x' .emit * .and digit_hex .emit * .and .loop digit_hex .emit *;\n"
+"oct_escape_code\n"
+" digit_oct .emit * .and optional_digit_oct .and optional_digit_oct;\n"
+"digit_oct\n"
+" '0'-'7';\n"
+"optional_digit_oct\n"
+" digit_oct .emit * .or .true;\n"
+"regbyte_definition\n"
+" \".regbyte\" .and space .and identifier .and space .and integer .and space_or_null;\n"
+"lexer_definition\n"
+" \".string\" .and space .and identifier .and semicolon;\n"
+"rule_definition\n"
+" identifier_ne .and space .and definition;\n"
+"definition\n"
+" specifier .and optional_specifiers_and_or .and semicolon .emit SPECIFIER_END;\n"
+"optional_specifiers_and_or\n"
+" and_specifiers .emit SPECIFIER_AND_TAG .or or_specifiers .emit SPECIFIER_OR_TAG .or .true;\n"
+"specifier\n"
+" specifier_condition .and optional_space .and specifier_rule;\n"
+"specifier_condition\n"
+" specifier_condition_1 .or .true;\n"
+"specifier_condition_1\n"
+" \".if\" .and optional_space .and '(' .and optional_space .and left_operand .and operator .and\n"
+" right_operand .and optional_space .and ')';\n"
+"left_operand\n"
+" identifier;\n"
+"operator\n"
+" operator_1 .or operator_2;\n"
+"operator_1\n"
+" optional_space .and '!' .and '=' .and optional_space;\n"
+"operator_2\n"
+" optional_space .and '=' .and '=' .and optional_space;\n"
+"right_operand\n"
+" integer;\n"
+"specifier_rule\n"
+" specifier_rule_1 .and optional_error .and .loop emit .and .true .emit EMIT_NULL;\n"
+"specifier_rule_1\n"
+" character_range .emit SPECIFIER_CHARACTER_RANGE .or\n"
+" character .emit SPECIFIER_CHARACTER .or\n"
+" string_ne .emit SPECIFIER_STRING .or\n"
+" \".true\" .emit SPECIFIER_TRUE .or\n"
+" \".false\" .emit SPECIFIER_FALSE .or\n"
+" \".debug\" .emit SPECIFIER_DEBUG .or\n"
+" loop_identifier .emit SPECIFIER_IDENTIFIER;\n"
+"character\n"
+" '\\'' .and string_char_single_quotes .and '\\'' .emit '\\0';\n"
+"string_char_single_quotes\n"
+" escape_sequence .or string_char .emit * .or '\"' .emit *;\n"
+"character_range\n"
+" character .and optional_space .and '-' .and optional_space .and character;\n"
+"loop_identifier\n"
+" optional_loop .and identifier;\n"
+"optional_loop\n"
+" optional_loop_1 .emit IDENTIFIER_LOOP .or .true .emit IDENTIFIER_NO_LOOP;\n"
+"optional_loop_1\n"
+" \".loop\" .and space;\n"
+"optional_error\n"
+" error .emit ERROR_PRESENT .or .true .emit ERROR_NOT_PRESENT;\n"
+"error\n"
+" space .and \".error\" .and space .and identifier;\n"
+"emit\n"
+" emit_output .or emit_regbyte;\n"
+"emit_output\n"
+" space .and \".emit\" .and space .and emit_param;\n"
+"emit_param\n"
+" integer_ne .emit EMIT_INTEGER .or\n"
+" identifier_ne .emit EMIT_IDENTIFIER .or\n"
+" character .emit EMIT_CHARACTER .or\n"
+" '*' .emit EMIT_LAST_CHARACTER .or\n"
+" '$' .emit EMIT_CURRENT_POSITION;\n"
+"emit_regbyte\n"
+" space .and \".load\" .and space .and identifier .and space .and emit_param;\n"
+"and_specifiers\n"
+" and_specifier .and .loop and_specifier;\n"
+"or_specifiers\n"
+" or_specifier .and .loop or_specifier;\n"
+"and_specifier\n"
+" space .and \".and\" .and space .and specifier;\n"
+"or_specifier\n"
+" space .and \".or\" .and space .and specifier;\n"
+".string __string_filter;\n"
+"__string_filter\n"
+" __first_identifier_char .and .loop __next_identifier_char;\n"
+"__first_identifier_char\n"
+" 'a'-'z' .or 'A'-'Z' .or '_' .or '.';\n"
+"__next_identifier_char\n"
+" 'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9';\n"
+""