EMPLOYING A STRUCTURE
FOR THE ELEMENTS OF SYMBOL STACK
In both Lex and Yacc employ the following #defines:
typedefstruct {
int kind_of_location;
int location; } yystype;
#define YYSTYPE yystype
#define SYMREF 0 /* short for symbol table reference */
#define REGISTER 1
IN LEX
Let the code associated with the r.e. for an identifier set:
yylval.kind_of_location = SYMREF;
yylval.location = (the index into symbol list for the identifier) ;
The code associated with other r.e.'s do not need to set the values of these yylval components.
IN YACC
#define SYMREF_SYMREF 0
#define SYMREF_REGISTER 1
#define REGISTER_SYMREF2
#define REGISTER_REGISTER3
int registerstack[ ] = {9, 11, 14, 15} /* the codes defined for CX, BX, SI, DI */
int registerstack_i = 4;
int reg;
The code for e.g.: expression → expression + term
switch($1.kind_of_location*2 + $3.kind_of_location) {
case SYMREF_SYMREF:
reg = getreg(); /* see below for sample code */
move(reg, DIRECT, symbol_table[$1.location].offset); /* move & add */
add(reg, DIRECT, symbol_table[$3.location].offset);
$$.kind_of_location = REGISTER;
$$.location = reg;
break;
case SYMREF_REGISTER:
add($3.location, DIRECT, symbol_table[$1.location].offset);
$$ = $3;
break;
case REGISTER_SYMREF:
add($1.location, DIRECT, symbol_table[$3.location].offset);
break;
case REGISTER_REGISTER:
reg = $3.location;
add($1.location, reg, 0);
free(reg); /* see below for sample code */
break;
} /* end of switch for + */
The code for e.g.: expression → expression - term
The code is exactly the sames as that described above for
expression → expression + term,
except that all the occurrences of add should be replaced by sub, and the instruction neg($3) should be inserted before the call to add in the SYMREF_REGISTER case.
The code for: term → ( expression )
$$ = $2;
Note: No code is required in Yacc for: term → identifier
Sample code for getreg() and free(register)
int getreg() {
--registerstack_i;
return (registerstack[registerstack_i]);
}
void free(int Register) {
registerstack[registerstack_i] = Register;
++registerstack_i;
}
Machine code for multiplication
The general Assembler form of one of the imul instructions is:
imul reg, other-argument
The “reg” refers to a 16-bit register (coded as defined in the handout in machine instructions) and “other-argument” is an argument of any type except immediate. The calculation involved is of the form:
reg = reg * other-argument
The machine code is:
0Fh AFh mod reg r/m displ. low displ. high
where mod, r/m, and the optional fields displ, low and displ. high are as defined in the handout on machine instructions