Chapter 8 Intermediate Code Generation Intermediate languages Syntax


![x : = y [i] x[i] : = y x : = &y Set x : = y [i] x[i] : = y x : = &y Set](https://slidetodoc.com/presentation_image_h2/e808d35ce7765aac4f0a0b42dc7d17de/image-3.jpg)



![stmt_part assignop expr | [expr] assignop expr | (expr_list) |ε • The stmt procedure stmt_part assignop expr | [expr] assignop expr | (expr_list) |ε • The stmt procedure](https://slidetodoc.com/presentation_image_h2/e808d35ce7765aac4f0a0b42dc7d17de/image-7.jpg)





![match(‘num’); match(‘]’); match(‘of’); if lookahead = ‘integer’ then begin match(‘integer’); typ. Typeexpr : = match(‘num’); match(‘]’); match(‘of’); if lookahead = ‘integer’ then begin match(‘integer’); typ. Typeexpr : =](https://slidetodoc.com/presentation_image_h2/e808d35ce7765aac4f0a0b42dc7d17de/image-13.jpg)
- Slides: 13

Chapter 8 Intermediate Code Generation

• Intermediate languages: Syntax trees, three-address code, quadruples. • Types of Three – Address Statements: x : = y op z where op is a binary operator x : = op y where op is a unary operator. x : = y goto L where L is the label of a 3 – address statement if x relop y goto L where relop is a relational operator. param x call p, n Used to call procedures annd functions. return y Return the value y from a function. return from a procedure.
![x y i xi y x y Set x : = y [i] x[i] : = y x : = &y Set](https://slidetodoc.com/presentation_image_h2/e808d35ce7765aac4f0a0b42dc7d17de/image-3.jpg)
x : = y [i] x[i] : = y x : = &y Set x to the location of y. x : = *y Set x to the contents of the location pointed to by y. *x : = y Copy the contents of y to the location pointed to by x. • Generating three-address code in atop-down parser. An expression, E, has two attributes: E. place is the name holding the value of E. E. code is the code to generate E.

Typical Semantic Rules • The concatenation operator is shown as ||, X || Y means the concatenation of X and Y. A function, newtwmp, returns a new name whenever it is called. The gen function generates a three-address statement. S id : = E S. code : = E. code || gen (id. place ‘: =‘ E. place) E E 1 + E 2 E. place : = newtemp; E. code : = E 1. code || E 2. code ||gen (E. place ‘: =‘ ‘+’ E 2. place) E -E 1 E. place : = newtemp; E. code : = E 1. code || gen (E. place ‘: = uminus’ E 1. place) E (E 1) E. place : = E 1. place; E. code : = E 1. code; E id E. place : = id. place; E. code : = ‘’

• While – do statement : S while E do S 1 S. begin : = newlabel; S. after : = newlabel; S. code : = gen (S. begin ‘: ’) || E. code || gen (‘if’ E. place ‘= false goto’ S. after) || S 1. code || gen (‘goto’ S. begin) || gen (S. after ‘: ’) • If – then – else statement: S if E then S 1 else S 2 S. false : = newlabel; S. after : = newlabel; S. code : = E. code || gen (‘if’ E. place ‘= false goto’ S. false) || S 1. code || gen (‘goto’ S. after) || gen (S. false ‘: ’) || S 2. code || gen (S. after ‘: ’)

• Example : Consider the nontermional statement in the grammar. After substituting for variable, procedure_statement and compound_statement we have the productions: stmt id assignop expr | id [expr] assignop expr | id (expr_list) | begin opt_stmts end | if expr then stmt else stmt | while expr do stmt • We left-factor id out of the first four productions to get: stmt id stmt_part | begin opt_stmts end | if expr then stmt else stmt | while expr do stmt
![stmtpart assignop expr expr assignop expr exprlist ε The stmt procedure stmt_part assignop expr | [expr] assignop expr | (expr_list) |ε • The stmt procedure](https://slidetodoc.com/presentation_image_h2/e808d35ce7765aac4f0a0b42dc7d17de/image-7.jpg)
stmt_part assignop expr | [expr] assignop expr | (expr_list) |ε • The stmt procedure in a recursive – descent parser handles statements. • Assume that expr is a function that produces code for an expression and returns the location where the expression value will be stored. • To produce 3 – address code the stmt procedure looks like :

procedure stmt; var L 1, L 2 : label; Eplace : location_of_expression_value; begin if lookahead = ‘id’ then stmtpart else if lookahead = ‘begin’ then compoundstmt else if lookahead = ‘if’ then begin match(‘if’); L 1 : = newlabel; L 2 = newlabel; Eplace : = expr; match(‘then’); gen (‘if’ Eplace = ‘false goto’ L 1); stmt; match(‘else’); gen(‘goto’ L 2); gen(L 1 ‘: ’); stmt; gen(L 2 ‘: ’) end else if lookahead = ‘while’ then begin L 1 : = newlabel; L 2 : = newlabel; match (‘while’); gen (L 1 ‘: ’); Eplace : = expr; match (‘do’); gen (‘if’ Eplace ‘= false goto’ L 2); stmt; gen (‘goto’ L 1); gen (L 2 ‘: ’) end Else error End;

procedure stmtpart; var nptr : pointer_to_symbol_table_entry; E 1, E 2 : location_of_expression_value; n : integer; begin nptr : = lookup (id. entry); match(‘id’); if lookahead = ‘assignop’ then begin match (‘assignop’); E 1 : = expr; gen (nptr. name ‘: =’ E 1) end else if lookahead = ‘[’ then begin match(‘[’); E 1 : = expr; match(‘]’); match (‘assignop’); E 2 : = expr; gen (nptr. name ‘[’ E 1 ‘] : =’ E 2) end else if lookahead = ‘(’ then begin match(‘(’); n : = 1; E 1 : = expr; gen(‘param’ E 1) end; match(‘(’); gen(‘call’ nptr. name ‘, ’ n) end else gen(‘call’ nptr. name ‘, 0’) end;

• Declarations: In Pascal a set of declarations begins with a single var token. • The syntax of declarations can be changed to normal Pascal. • The productions for declarations are: declarations var identifier_list : type; | ε • The productions must be modified to eliminate the leftrecursion: declarations var identifier_list : type; declarations | ε • An identifier_list contains one or more id tokens separated by commas. The type of the id tokens is not known until type is reached. We need to know what the type is before processing the id tokens.

declarations var id decl_ext ; declarations | ε decl_ext , id decl_ext | : type integer | real | array [num. . num] of integer | array [num. . num] of real • Assume integers are 4 bytes wide and reals are 8 bytes wide. • A recursive – descent parser calls function typ to process the type nonterminal. • Function typ returns a type_record with two fields: Width to show the number of bytes in the type and Type. Expr to show the type (either integer, real, integer array, or real array). The typ function looks like:

function typ : type_record; var N 1, N 2 : integer; begin if lookahead = ‘integer’ then begin match(‘integer’); typ. Width : = 4; typ. Type. Expr : = ‘integer’ end else if lookahead = ‘real’ then begin match(‘real’); typ. Width : = 8; typ. Type. Expr : = ‘real’end else if lookahead = ‘array’ then begin match(‘array’); match(‘[’); if lookahead = ‘num’ then N 1 : = num. value else error; match(‘num’); match(‘. . ’); if lookahead = ‘num’; then N 2 : = num. value else error;
![matchnum match matchof if lookahead integer then begin matchinteger typ Typeexpr match(‘num’); match(‘]’); match(‘of’); if lookahead = ‘integer’ then begin match(‘integer’); typ. Typeexpr : =](https://slidetodoc.com/presentation_image_h2/e808d35ce7765aac4f0a0b42dc7d17de/image-13.jpg)
match(‘num’); match(‘]’); match(‘of’); if lookahead = ‘integer’ then begin match(‘integer’); typ. Typeexpr : = ‘integer array’; typ. Width : = 4 * (N 2 – N 1 + 1) end else if lookahead = ‘real’ then begin match(‘real’); typ. Typeexpr : = ‘real array’; typ. Width : = 8 * (N 2 – N 1 +1) end {if lookahead = ‘real’} end {if lookahead = ‘array’} else error end;