Translation of Array References
Introduction: The chief problem in generating code for array references is to relate the address calculation formulas in Section 6.4.3 to a grammar for array references. Let nonterminal L generate an array name followed by a sequence of index expressions:
L - L [ E ] | id [ E ]
As in C and Java, assume that the lowest-numbered array element is 0. Let us calculate addresses based on widths, using the formula (6.4), rather than on numbers of elements, as in (6.6). The translation scheme in Fig. 6.22 generates three-address code for expressions with array references. It consists of the productions and semantic actions from Fig. 6.20, together with productions involving nonterminal L.
Nonterminal L has three synthesized attributes:
1. L.addr denotes a temporary that is used while computing the offset for the array reference by summing the terms ij x Wj in (6.4).
2. L.array is a pointer to the symbol-table entry for the array name. The base address of the array, say, L.array.base is used to determine the actual /-value of an array reference after all the index expressions are analyzed.
3. L.type is the type of the subarray generated by L. For any type t, we assume that its width is given by t.width. We use types as attributes, rather than widths, since types are needed anyway for type checking. For any array type t, suppose that t.elem gives the element type.
The production S -» id = E; represents an assignment to a nonarray variable, which is handled as usual. The semantic action for S —?> L = E; generates an indexed copy instruction to assign the value denoted by expression E to the location denoted by the array reference L. Recall that attribute L.array gives the symbol-table entry for the array. The array's base address — the address of its Oth element — is given by L.array.base. Attribute L.addr denotes the temporary that holds the offset for the array reference generated by L. The location for the array reference is therefore L.array.base[L.addr]. The generated instruction copies the r-value from address E.addr into the location for L.
Productions E Ei E2 and E —> id are the same as before. The semantic action for the new production E —»• L generates code to copy the value from the location denoted by L into a new temporary. This location is L.array.base[L.addr], as discussed above for the production S -¥ L = E;. Again, attribute L.array gives the array name, and L.array.base gives its base address. Attribute L.addr denotes the temporary that holds the offset. The code for the array reference places the r-value at the location designated by the base and offset into a new temporary denoted by E. addr.