The grammar below generates sequences of declarations
of the form
T.
P
D
D
DD
D
T
T
T
T
T1
T
T1
As usual id is the token for identifiers, integer denotes
a type of integers, float denotes a type of floating point numbers
and num is the token for integer values.
Note that array,
, ; , :, [, ] and of are
terminals too. Moreover,
T
denotes the type of arrays of length
.val with elements of type T.type.
T denotes the type of pointers to elements of type T.type.
You are asked to write a translation scheme which
computes the memory address of every declared name and stores this information
in the symbol table.
To reach that goal you may associate the nonterminal T
with a synthesized attribute T.width that indicates
the number of memory units taken by objects of type T.
For
T and
T
it is usual to have
T.width = 4 and
T.width = 8 respectively.
For
TT the formula
for T.width is easy to guess.
For
TT1 remember that a pointer is an integer.
As usual, the nonterminal T has
a synthesized attribute T.type.
You are not asked to give the semantic rules
computing T.type (although this is easy).
You may need a global variable offset which gives the current available memory address:
Before the first declaration is made, offset should be initialized to 0.
As each name
.name is seen, that name is entered in the symbol
table with offset equal to the current value and offset is incremented
by the width of the type of
.name.
The procedure call enter(
.name, T.type, offset) creates a symbol-table
entry for
.name, with type T.type and memory address offset.