%start VS10Program %name-prefix="vs10_" %{ void yyerror(char *s); int yylex(void); #include #include #include #include "vs1.0_inst_list.h" #include "nvparse_errors.h" #include "nvparse_externs.h" //extern bool gbTempInsideMacro; //extern unsigned int &base_linenumber; void LexError(char *format, ...); extern int line_incr; #define do_linenum_incr() { line_number+=line_incr; line_incr = 0; } //int get_linenum() { return( gbTempInsideMacro ? base_linenumber : line_number ); } int get_linenum() { return( line_number ); } #define YYDEBUG 1 %} %union { int ival; unsigned int lval; float fval; char mask[4]; char *comment; VS10Reg reg; VS10InstPtr inst; VS10InstListPtr instList; }; %token VERTEX_SHADER %token ADD_INSTR %token DP3_INSTR %token DP4_INSTR %token DST_INSTR %token EXP_INSTR %token EXPP_INSTR %token FRC_INSTR %token LIT_INSTR %token LOG_INSTR %token LOGP_INSTR %token M3X2_INSTR %token M3X3_INSTR %token M3X4_INSTR %token M4X3_INSTR %token M4X4_INSTR %token MAD_INSTR %token MAX_INSTR %token MIN_INSTR %token MOV_INSTR %token MUL_INSTR %token NOP_INSTR %token RCP_INSTR %token RSQ_INSTR %token SGE_INSTR %token SLT_INSTR %token SUB_INSTR %token ILLEGAL %token UNKNOWN_STRING %token INTVAL %token REGISTER %token XYZW_MODIFIER %token COMMENT %type InstSequence %type InstLine %type Instruction %type VECTORopinstruction %type SCALARopinstruction %type UNARYopinstruction %type BINopinstruction %type TRIopinstruction %type VECTORop %type SCALARop %type UNARYop %type BINop %type TRIop %type genericReg %type genReg %type constantReg %% /*beginning of rules section */ VS10Program: InstSequence { $1->Validate(); $1->Translate(); delete $1; } ; InstSequence: InstSequence InstLine { *($1) += $2; delete $2; $$ = $1 } | InstLine { VS10InstListPtr instList = new VS10InstList; if ( $1 != NULL ) { *instList += $1; delete $1; } $$ = instList; } ; InstLine: Instruction { $$ = $1; do_linenum_incr(); } | '\n' { $$ = new VS10Inst( get_linenum() ); do_linenum_incr(); } ; Instruction: VECTORopinstruction | SCALARopinstruction | UNARYopinstruction | BINopinstruction | TRIopinstruction | NOP_INSTR { $$ = new VS10Inst( get_linenum(), VS10_NOP ); } | COMMENT { $$ = new VS10Inst( get_linenum(), VS10_COMMENT, $1 ); } | VERTEX_SHADER { $$ = new VS10Inst( get_linenum(), VS10_HEADER ); } ; VECTORopinstruction: VECTORop genericReg ',' genericReg { $$ = new VS10Inst( get_linenum(), $1, $2, $4 ); } ; genericReg : '-' genReg '.' XYZW_MODIFIER { VS10Reg reg; reg = $2; reg.sign = -1; reg.type = $2.type; reg.index = $2.index; for ( int i = 0; i < 4; i++ ) reg.mask[i] = $4[i]; $$ = reg; } | genReg '.' XYZW_MODIFIER { VS10Reg reg; reg = $1; reg.sign = 1; reg.type = $1.type; reg.index = $1.index; for ( int i = 0; i < 4; i++ ) reg.mask[i] = $3[i]; $$ = reg; } | '-' genReg { VS10Reg reg; reg = $2; reg.sign = -1; reg.type = $2.type; reg.index = $2.index; for ( int i = 0; i < 4; i++ ) reg.mask[i] = 0; $$ = reg; } | genReg { VS10Reg reg; reg = $1; reg.sign = 1; reg.type = $1.type; reg.index = $1.index; for ( int i = 0; i < 4; i++ ) reg.mask[i] = 0; $$ = reg; } ; genReg: REGISTER | constantReg { } ; constantReg: 'c' '[' INTVAL ']' { VS10Reg reg; reg.type = TYPE_CONSTANT_MEM_REG; reg.index = $3; $$ = reg; } | 'c' '[' REGISTER '.' XYZW_MODIFIER ']' { // Register is valid only if // type = TYPE_ADDRESS_REG // index = 0 // len(mask) = 1 // mask[0] = 'x' VS10Reg reg; $$.type = TYPE_CONSTANT_A0_REG; if ( $3.type != TYPE_ADDRESS_REG ) { LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); } else if ( $3.index != 0 ) { LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); } else { int len = 0; while ( len < 2 ) { if ( $5[len] == 0 ) break; len++; } if ( len != 1 || $5[0] != 'x' ) { LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); } reg.type = TYPE_CONSTANT_A0_REG; $$ = reg; } } | 'c' '[' REGISTER '.' XYZW_MODIFIER '+' INTVAL ']' { // Register is valid only if // type = TYPE_ADDRESS_REG // index = 0 // len(mask) = 1 // mask[0] = 'x' VS10Reg reg; $$.type = TYPE_CONSTANT_A0_OFFSET_REG; if ( $3.type != TYPE_ADDRESS_REG ) { LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); } else if ( $3.index != 0 ) { LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); } else { int len = 0; while ( len < 2 ) { if ( $5[len] == 0 ) break; len++; } if ( len != 1 || $5[0] != 'x' ) { LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); } reg.type = TYPE_CONSTANT_A0_OFFSET_REG; reg.index = $7; $$ = reg; } } | 'c' '[' REGISTER ']' { $$.type = TYPE_CONSTANT_A0_REG; LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); } | 'c' '[' REGISTER '+' INTVAL ']' { $$.type = TYPE_CONSTANT_A0_REG; LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); } | 'c' '[' '-' REGISTER ']' { $$.type = TYPE_CONSTANT_A0_REG; LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); } | 'c' '[' '-' REGISTER '+' INTVAL ']' { $$.type = TYPE_CONSTANT_A0_REG; LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); } | 'c' '[' '-' REGISTER '.' XYZW_MODIFIER ']' { $$.type = TYPE_CONSTANT_A0_REG; LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); } | 'c' '[' '-' REGISTER '.' XYZW_MODIFIER '+' INTVAL ']' { $$.type = TYPE_CONSTANT_A0_REG; LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); } ; SCALARopinstruction: SCALARop genericReg ',' genericReg { $$ = new VS10Inst( get_linenum(), $1, $2, $4 ); } ; UNARYopinstruction: UNARYop genericReg ',' genericReg { $$ = new VS10Inst( get_linenum(), $1, $2, $4 ); } ; BINopinstruction: BINop genericReg ',' genericReg ',' genericReg { $$ = new VS10Inst( get_linenum(), $1, $2, $4, $6 ); } ; TRIopinstruction: TRIop genericReg ',' genericReg ',' genericReg ',' genericReg { $$ = new VS10Inst( get_linenum(), $1, $2, $4, $6, $8 ); } ; VECTORop: MOV_INSTR { $$ = VS10_MOV; } | LIT_INSTR { $$ = VS10_LIT; } ; SCALARop: RCP_INSTR { $$ = VS10_RCP; } | RSQ_INSTR { $$ = VS10_RSQ; } | EXP_INSTR { $$ = VS10_EXP; } | EXPP_INSTR { $$ = VS10_EXPP; } | LOG_INSTR { $$ = VS10_LOG; } | LOGP_INSTR { $$ = VS10_LOGP; } ; UNARYop: FRC_INSTR { $$ = VS10_FRC; } ; BINop: MUL_INSTR { $$ = VS10_MUL; } | ADD_INSTR { $$ = VS10_ADD; } | DP3_INSTR { $$ = VS10_DP3; } | DP4_INSTR { $$ = VS10_DP4; } | DST_INSTR { $$ = VS10_DST; } | MIN_INSTR { $$ = VS10_MIN; } | MAX_INSTR { $$ = VS10_MAX; } | SLT_INSTR { $$ = VS10_SLT; } | SGE_INSTR { $$ = VS10_SGE; } | M3X2_INSTR { $$ = VS10_M3X2; } | M3X3_INSTR { $$ = VS10_M3X3; } | M3X4_INSTR { $$ = VS10_M3X4; } | M4X3_INSTR { $$ = VS10_M4X3; } | M4X4_INSTR { $$ = VS10_M4X4; } | SUB_INSTR { $$ = VS10_SUB; } ; TRIop: MAD_INSTR { $$ = VS10_MAD; } ; %% void yyerror(char* s) { LexError( "Syntax Error.\n" ); //errors.set(s); //errors.set("unrecognized token"); }