Programming Assignment 4
Due Date: 11:59PM
on April 14, 2009
For PA3 you have developed the compiler for a Bronco# programming language. In this programming assignment, there is no error in any input file and your program is to translate the input file into some intermediate representation which is output to an external file.
Your intermediate representation as the output should consider the following issues:
INPUT GRAMMAR FOR PA2
Module
module → unit { unit } //{…} represents 0 or many
repetitions
unit → declaration ‘;’ //global variables
→ function //functions
→ type_decl ‘;’ //types
→ λ // NULL
Type Declarations
type_decl → type ident ‘=’ type_def
type_def → array ‘[‘ int_const “..” int_const ‘]’ of type_id
→ record field_list end
→ enum ‘{‘ ident_list ‘}’
→ pointer of type_id
field_list → field {‘;’ field}
field → type_id ident_list
type_id → ident | base_type //’ident’ is a defined type
base_type →
int | float | short // short takes 2 bytes and
others take 4 bytes
Variable Declarations
declaration_list→declaration { ‘;’ declaration }
declaration → type_id ident_list
ident_list →
ident { ‘,’ ident }
Function Declarations
function → function return_type ident ‘(‘ parameter_list ‘)’
compound_stmt
return_type → type_id | void //Function returns nothing
parameter_list → parameter {‘,’ parameter } | λ
parameter →
mode type_id ident
mode → ref | λ
Statements
stmt_list → statement { ‘;’ statement}
statement → assign_stmt
→ while_stmt
→ if_stmt
→ function_call //Must return VOID
→ compound_stmt
→ return_stmt
→ print_stmt
→ new_stmt
→ λ //NULL statement
assign_stmt → variable “=” expr
while_stmt → while ‘(‘ expr ‘)’ statement
if_stmt → if ‘(‘ expr ‘)’ statement
→ if ‘(‘ expr ‘)’ statement else statement
function_call → ident ‘(‘ expr_list ‘)’
compound_stmt →’{‘ declaration_list ‘;’ stmt_list ‘}’
→ ‘{‘ stmt_list ‘}’
return_stmt →
return ‘(‘ expr ‘)’ | return
print_stmt → print ‘(‘ output_list ‘)’
→
println
‘(‘ output_list ‘)’ | println
new_stmt → new variable
Output List
output_list → output_element { ‘,’ output_element }
output_element →
expr | string
Expression List
expr_list → expr { ‘,’ expr } | λ
Variables
variable → ident variable_tail
variable_tail → ‘[‘ expr ‘]’ variable_tail
→ ‘.’ ident variable_tail //Ident is defined field
→ ‘->’ ident variable_tail
→ λ
Expressions
expr → expr bin_op expr
→ unary_op expr
→ ‘(‘ expr ‘)’
→ variable
→ function_call
→
int_const
→
real_const
bin_op → ‘+’ | ‘-‘ | ‘*’ | ‘/’ | ‘%’
→ ‘<’ | ‘>’ | ‘<=’ | ‘>=’ | ‘!=’ | ‘==’
→ ‘&&’ | ‘||’
unary_op → ‘-‘ | ‘!’
Standard mathematical rules of precedence and associativity apply (‘%’ has the same associativity as ‘+’). Binary operators are LEFT associative.
Output Grammar for P4
Module
Module → function_list
function_list → function_list function | function
function → ident compound_stmt
Statements
stmt_list → stmt_list stmt | stmt
statement → assign_stmt
→ while_stmt
→ if_stmt
→ function_call
→ compound_stmt
→ print_stmt
→ return_stmt
→ new_stmt
assign_stmt → assign expr variable
→ assign variable variable //Big assignment
while_stmt → while expr statement
if_stmt → if expr statement
→ if expr statement else statement
//Parameters are on the stack
//Constant is new Top-of-stack offset
//(aka “high_water_mark”)
function_call → ({first_letter_result_type}_call | expr)__ident {({first_letter_type_name}_param| ref ) expr } end // _param normal parameters; ref is a pointer
compound_stmt→’{‘ –integer_const stmt_list ‘}’
return_stmt →
return_{ first_letter_result_type} expr
print_stmt → print print_list | println print_list
print_list → expr | string | print_list { expr} | print_list {string}
new_stmt
→ new variable integer_const
Expressions
expr → bin_op_{first_letter_type_name} expr expr
→ unary_op_{first_letter_type_name} expr
→ variable
→ function_call
bin_op → ‘+’ | ‘-‘ | ‘*’ | ‘/’ | ‘%’
→ ‘<’ | ‘>’ | ‘<=’ | ‘>=’ | ‘!=’ | ‘==’
→ ‘&&’ | ‘||’
unary_op → ‘uminus’ | ‘!’
variable → datatype object_area offset
datatype → integer |
float | composite length_of_size // size of the data
object_area → local | global | ref_parameter | parameter
offset → expr
An important note
about Storage Allocation:
The stack in the output file grows in a negative location (do minus operation for each allocation). The parameter list to a function is located at a positive offset above the frame pointer; the local area is allocated from a negative offset from the frame pointer. The return value should be located at a positive offset above 0 and below the parameter list.
Locations 0 and -4 of the activation record (i.e. in the local object area) are used by the code generator to save the dynamic link and return address of the program. Therefore, you must begin storage allocation at location -8 of your activation record. So the configuration of a stack is shown as follows:
![]()
![]()
![]()
![]()

Example Transformations
Consider the recursive implementation of the factorial function:
function int factorial( int n )
{
if (n <= 1)
return( 1 )
else
if (1)
return( n * factorial( n - 1 ))
else
{
int temp;
temp = factorial( n - 1 );
println(" Return value from factorial is ", temp );
return( n * temp );
}
}
We can see by inspection that there are no undefined variables or parse errors. The following is a transformation into prefix form:
__factorial
{ -8
if <=_i integer parameter 8 1 return_i 1
else if 1 return_i *_i integer parameter 8 i_call __factorial i_param -_i integer parameter 8 1 end
else { -12
assign i_call __factorial i_param -_i integer parameter 8 1 end integer local -8
println " Return value from factorial is " integer local -8
return_i *_i integer parameter 8 integer local -8
}
}
Consider the DOT-product:
type vector = array[ 1 .. 10 ] of float;
function float dot_product( vector x, vector y )
{
int i;
float result;
i = 1;
result = 0.0;
while (i <= 10)
{
result = result + x[ i ] * y[ i ];
i = i + 1;
}
return( result );
}
This would translate into:
__dot_product
{ -16
assign 1 integer local -8
assign 0.0 float local -12
while <=_i integer local -8 10 { -16
assign +_f float local -12 *_f float parameter -_i 44 *_i 4 -_i integer local -8 1 float parameter -_i 84 *_i 4 -_i integer local -8 1 float local -12
assign +_i integer local -8 1 integer local -8
}
return_f float local -12
}