Compiler Construction Chapter 6

download Compiler Construction Chapter 6

of 111

Transcript of Compiler Construction Chapter 6

  • 8/10/2019 Compiler Construction Chapter 6

    1/111

    Chapter 6: Semantic Analysis

    1

  • 8/10/2019 Compiler Construction Chapter 6

    2/111

    (Static) Semantic Analyzer

    ==> Semantic Structure

    - What is the program supposed to do?

    - Semantics analysis can be done during syntax analysis

    phase or the final code generation phase.

    - typical static semantic features include declarations and

    type checking.

    - information (attributes) gathered can be either added tothe tree as annotations or entered into the symbol table.

    2

  • 8/10/2019 Compiler Construction Chapter 6

    3/111

  • 8/10/2019 Compiler Construction Chapter 6

    4/111

    Output of the semantic analyzer annotated AST

    with subscripts from a range

    4

  • 8/10/2019 Compiler Construction Chapter 6

    5/111

    Two Categories of Semantic Analysis

    1. The analysis of a program to meet the

    definition of the programming language.

    2. The analysis of a program to enhance the

    efficiency of execution of the translatedprogram.

    5

  • 8/10/2019 Compiler Construction Chapter 6

    6/111

    Semantic Analysis Process

    includes formally:

    - description of the analyses to perform- implementation of the analysis (translation of

    the description) that may use appropriatealgorithms.

    6

  • 8/10/2019 Compiler Construction Chapter 6

    7/111

    Description of Semantic Analysis

    1. Identify attributes (properties) of language(syntactic) entities.

    2. Write attribute equations (or semantic rules) thatexpress how the computation of such attributesis related to the grammar rules of the language.

    Such a set of attributes and equations is called anattribute grammar.

    7

  • 8/10/2019 Compiler Construction Chapter 6

    8/111

    Syntax-directed semantics

    -

    The semantic content of a program is closelyrelated to its syntax.

    - All modern languages have this property.

    8

  • 8/10/2019 Compiler Construction Chapter 6

    9/111

    Attributes

    - An attribute is any property of a programming

    language construct.- Typical examples of attributes are:

    the data type of a variable, the value of anexpression, the location of a variable in memory,

    the object code of a procedure, the number ofsignificant digits in a number.

    - Attribute corresponds to the name of a field of astructure.

    9

  • 8/10/2019 Compiler Construction Chapter 6

    10/111

    Attribute Grammars

    In syntax-directed semantics, attributes areassociated with grammar symbols of thelanguage. That is, if X is a grammar symbol anda is an attribute associated to X, then we writeX.a for the value of a associated to X.

    For each grammar rule X0-> X1 X2 Xn thevalues of the attributes Xi.aj of each grammarsymbol Xi are related to the values of theattributes of other grammar symbols in the rule.

    10

  • 8/10/2019 Compiler Construction Chapter 6

    11/111

    That is, each relationship is specified by an

    attribute equation or semantic rule of the form:

    Xi.aj = fij (X0.a1 ,.., X0.ak ,.., X1.a1 ,.., X1.ak , .., Xn.a1

    ,.., Xn.a

    k )

    An attribute grammar for the attributes a1,,ak isthe collection of all such attribute equations

    (semantic rules), for all the grammar rules of thelanguage.

    11

  • 8/10/2019 Compiler Construction Chapter 6

    12/111

    number.val must be

    computed prior to

    factor.val

    12

  • 8/10/2019 Compiler Construction Chapter 6

    13/111

    Attribute grammars may involve severalinterdependent attributes.

    13

  • 8/10/2019 Compiler Construction Chapter 6

    14/111

    e.g. 345o

    128d

    128o (x)

    based-num -> num basecharbasechar -> o | dnum -> num digit | digitdigit -> o | 1 | 2 | 3 | 4 | 5 | 6 | 7 8 | 9

  • 8/10/2019 Compiler Construction Chapter 6

    15/111

  • 8/10/2019 Compiler Construction Chapter 6

    16/111

    Attribute grammars may be defined fordifferent purposes.

    16

  • 8/10/2019 Compiler Construction Chapter 6

    17/111

    17

  • 8/10/2019 Compiler Construction Chapter 6

    18/111

    *

    - 42

    334

    (34 3) * 42

    term1.tree = mkOpNode(*,term2.tree,factor.tree)

    factor.tree =

    mkNumNode(number.lexval)

  • 8/10/2019 Compiler Construction Chapter 6

    19/111

    Algorithms for attribute computation

    Dependency graph and evaluation order

    19

  • 8/10/2019 Compiler Construction Chapter 6

    20/111

    Attribute grammar for simple C-like variable declarations

    Grammar Rules Semantic Rules

    decl type var-list var-list.dtype = type.dtype

    type int type.dtype = integer

    type float type.dtype = real

    var-list1 id , var-list2 id.dtype = var-list1.dtypevar-list2.dtype = var-list1.dtype

    var-list id id.dtype = var-list.dtype

  • 8/10/2019 Compiler Construction Chapter 6

    21/111

    decl

    type

    (dtype = real)

    float

    var-list(dtype = real)

    id , var-list(x)

    (dtype = real)(dtype = real)

    id(y)

    (dtype = real)Parse tree for the stringfloat x , y

  • 8/10/2019 Compiler Construction Chapter 6

    22/111

  • 8/10/2019 Compiler Construction Chapter 6

    23/111

  • 8/10/2019 Compiler Construction Chapter 6

    24/111

    decl

    type

    (dtype = real)

    float

    var-list(dtype = real)

    id , var-list(x)

    (dtype = real)(dtype = real)

    id(y)

    (dtype = real)Parse tree for the stringfloat x , y

    trivialdependency

  • 8/10/2019 Compiler Construction Chapter 6

    25/111

  • 8/10/2019 Compiler Construction Chapter 6

    26/111

    26

  • 8/10/2019 Compiler Construction Chapter 6

    27/111

    27

  • 8/10/2019 Compiler Construction Chapter 6

    28/111

  • 8/10/2019 Compiler Construction Chapter 6

    29/111

    29

  • 8/10/2019 Compiler Construction Chapter 6

    30/111

    30

  • 8/10/2019 Compiler Construction Chapter 6

    31/111

    base is computed inpreorder and val inpostorder

  • 8/10/2019 Compiler Construction Chapter 6

    32/111

    Synthesized Attributes

    An attribute a is synthesized if, given a grammar ruleA -> X1 X2 Xn, the only associated attribute equation

    with an a on the left-hand side is of the form:A.a = f (X1.a1 ,.., X1.ak ,.., Xn.a1 ,.., Xn.ak)

    e.g., E1 -> E2 + E3 {E1.val = E2.val + E3.val; }where E.val represents the attribute (numerical value

    obtained) for EAn attribute grammar in which all the attributes aresynthesized is called S-attributed grammar.

    32

  • 8/10/2019 Compiler Construction Chapter 6

    33/111

    S-attributedgrammar

    33

  • 8/10/2019 Compiler Construction Chapter 6

    34/111

    *

    - 42

    334

    (34 3) * 42

    term1.tree = mkOpNode(*,term2.tree,factor.tree)

    factor.tree =

    mkNumNode(number.lexval)

    *

    -

    34 3

    42

  • 8/10/2019 Compiler Construction Chapter 6

    35/111

  • 8/10/2019 Compiler Construction Chapter 6

    36/111

    Inherited Attributes

    An attribute that is not synthesized is calledan inherited attribute.

    36

  • 8/10/2019 Compiler Construction Chapter 6

    37/111

    Preorder /Preorder & Inordertraversal

  • 8/10/2019 Compiler Construction Chapter 6

    38/111

    Computation of Attributes During

    Parsing

    L-attributed grammars

    38

  • 8/10/2019 Compiler Construction Chapter 6

    39/111

    -- LALR(1) parser are primarily suited to

    handling synthesized attributes.

    -- Two stacks are required.

    value stack and parsing stack

    Computing Synthesized Attributes During

    LR Parsing

    39

    E : E + E { $$ = $1 + $3} // Yacc specification

  • 8/10/2019 Compiler Construction Chapter 6

    40/111

    E : E E { $$ $1 $3} // Yacc specification

    Parsingstack

    Valuestack

    40

  • 8/10/2019 Compiler Construction Chapter 6

    41/111

    41

  • 8/10/2019 Compiler Construction Chapter 6

    42/111

    Translation (Attribute Computation)

    A translation scheme is merely a context-free

    grammar in which a program fragment calledsemantic action is associated with eachproduction.

    42

  • 8/10/2019 Compiler Construction Chapter 6

    43/111

    e.g. A -> XYZ { }

    In a bottom up parser the semantic actions is taken when XYZ is reduced to A. In a top-down parser the action is taken when A, X,Y, or Z is expanded, whichever is appropriate.

    43

  • 8/10/2019 Compiler Construction Chapter 6

    44/111

    Semantic Action

    In addition to those stated before, the semantic

    action may also involve:1. the computation of values for variables

    belonging to the compiler.

    2. the generation of intermediate code.3. the printing of an error diagnostic.

    4. the placement of some values in the symboltable.

    44

  • 8/10/2019 Compiler Construction Chapter 6

    45/111

    Bottom-up Translation of S-attributedGrammars

    - A bottom-up parser uses a stack to hold information aboutsubtrees that have been parsed. We can use extra fields inthe parser stack to hold the values of synthesized attributes.

    e.g. A -> XYZ {A.a = f (X.x, Y.y, Z.z)}

    - Before reduction: the value of the attribute Z.z is in val [top],Y.y is in val [top-1], and Z.z is in val [top-2].

    After reduction: top is decremented by 2, A.a is put in val[top]

  • 8/10/2019 Compiler Construction Chapter 6

    46/111

    46

    For Special Conditions : Hook

    stmt -> IF cond THEN { action to emit appropriate cond.

    jump } stmt ELSE { action to emit appropriate uncond.jump } stmt

    Or

    hook1-> { action to emit appropriate conditional jump }

    hook2-> { action to emit appropriate unconditional jump }

    stmt -> IF cond THEN hook1 stmt ELSE hook2 stmt

    stmt -> IF cond THEN stmt ELSE stmt==>

  • 8/10/2019 Compiler Construction Chapter 6

    47/111

    47

    Symbol Table

    consists of the records that associateattributes with various programmer declaredobjects. The main one is its name (a stringof characters, e.g. identifier).

    semantic action will put information into

    symbol table or take out attribute fromsymbol table.

  • 8/10/2019 Compiler Construction Chapter 6

    48/111

    48

    What kind of objects?

    1. variables

    2. components of a composition structure (i.e.,field names of structure)

    3. labels

    4. procedure and function name

    5. parameters for procedure and function

    6. files

  • 8/10/2019 Compiler Construction Chapter 6

    49/111

    49

    What attr ibutes (attributes of objects)?

    1. name

    2. type (e.g. int, float, array, struct, a pointer tostruct, etc.)

    3. location for variables and entry point

    4. value for named constant

    5. initial value for variable

    6. flag showing if it has been accessed.

  • 8/10/2019 Compiler Construction Chapter 6

    50/111

    50

    How does an attribute be represented?

    1. Name strategy:

    (a) use a field of n char in the symbol table

    record to store the first (up to) n characters ofthe identifier.

    (b) use an auxiliary string table and store apointer (e.g. 5) to the 1st char. of the identifier

    and the length ( e.g. 4) of the identifier in the"name" field of symbol table record.

  • 8/10/2019 Compiler Construction Chapter 6

    51/111

    51

    Scheme(B) allows arbitrary large name, savesspace and requires more programming. Often

    this table is kept for string literals and can be

    used with little extra programming.

    Scheme(A) is simpler, faster and requireless programming.

  • 8/10/2019 Compiler Construction Chapter 6

    52/111

    52

    Def. The static scope of an occurrence of anidentifier is that portion of the (source) program

    in which other occurrence of the sameidentifier represents the same object.

    2. type Since type can be arbitrarily complex,

    they are best represented by a pointerto alinked data structure that reflects the structureof the type. (type is mainly used to determineif semantics is correct and offset computation.)

  • 8/10/2019 Compiler Construction Chapter 6

    53/111

    53

    e.g. in Pascal, it is the procedure or function inwhich it was declared minus all sub-procedures

    and sub-functions in which it is represented.

    program P;procedure Q; -----------------------------

    var x: real; |

    procedure R; ----- |var x: integer; | | scope of x

    | minus this |x := ... | |

    end; ----- |

    |x := x + 1 |

    end; ----------------------------end.

  • 8/10/2019 Compiler Construction Chapter 6

    54/111

    54

    Symbol table mechanism ?

    1. What should be done when translating adeclaration?

    2. What should be done when reference to anidentifier?

    3. What should be done when at scope entry?

    4. What should be done when at scope exit?

  • 8/10/2019 Compiler Construction Chapter 6

    55/111

    55

    Multiscope symbol table

    - descriptor is a record that describing an object.

    - its fields are called attributes- its key contains an identifier together with a

    context (a context is a block or a declaration,represented by a lexical number).

  • 8/10/2019 Compiler Construction Chapter 6

    56/111

    56

    e.g. float x; -------

    struct y{ ----- |int x; | |

    int z; | inner context | another context

    . | |

    } ----- --------

  • 8/10/2019 Compiler Construction Chapter 6

    57/111

    Each context associated with a #, x will pair with the# to look up at symbol table.

    - when we enter a context (compiling time - not runtime) we give it a new # on to the context stack (it isthe current context).

    - when we exit a context we pop that # from the stack.

    - when resolving a reference to a simple identifier, say

    x9, we pair it with the current context and look it up inthe symbol table, if not there try with next context, etc.until found, or we run out the context.

    - when declaring an object we allocate a descriptor forit. Put the current context into its context field and the

    identifier into its identifier-field. Then fill in other attribute as appropriate. In the case of a recorddeclaration

  • 8/10/2019 Compiler Construction Chapter 6

    58/111

    58

    y has #2 in its context field and x has # 3 in its internalcontext field. Lookup y using context # 2. Look up itsfield x with context # 3.

    - when resolving a reference to a qualified identifier (e.g.student.grad) we look up the struct as before uponfinding, we get an attribute that called (that will be a #)internal-context and lookup the field with the context tofind the descriptor for that object.

    e.g. float x; ------struct y { ---- |

    int x; | |int z; | context #3 | context #2. | |} ---- -------

  • 8/10/2019 Compiler Construction Chapter 6

    59/111

    Consider the following basic programming-language

    constructs for generating intermediate codes:

    1. Declarations ()

    2. arithmetic assignment operations ()

    3. Boolean expressions ()4. flow-of-control statements` if-statement() while ()

    5. array references ()

    6. procedure calls ()

    7. switch statements ()8. structure-type references ()

    59

  • 8/10/2019 Compiler Construction Chapter 6

    60/111

    Semantic Actions for different

    language constructs

    1. Declarations

    e.g. int x,y,z;float w, z, s;

    60

  • 8/10/2019 Compiler Construction Chapter 6

    61/111

    Suggested grammar:(Note: This is a very simple grammar mainly

    used for explanation.)

    P -> MD;

    M ->

    /* empty string */D -> D, id

    | int id

    | float id

    P

    M D

    D , id

    int id

    ;

    int x , y ;

    1

    2

    3

    4

    61

    (Syntax directed) Translation

  • 8/10/2019 Compiler Construction Chapter 6

    62/111

    (Syntax-directed) Translation

    P -> MD; {/* do nothing */}

    M -> { if offset was not initialized then offset = 0;}

    D -> int id { enter (id.name, int, offset);

    /* a function entering type int and

    particular offset to the entry id.nameof the symbol table */

    D.type = int;

    offset = offset + 4; /*bytes, width of int*/

    D.offset = offset; }

    1

    2

    4

    62

  • 8/10/2019 Compiler Construction Chapter 6

    63/111

    D -> float id { enter (id.name, float, offset);

    D.type = float;

    offset = offset + 8;/*bytes, width of float*/

    D.offset = offset ; }

    D - > D(1), id { enter (id.name, D(1).type, D(1).offset);

    D.type = D

    (1)

    .type;If D(1).type == int D.offset = D(1).offset + 4;

    else if

    D(1).type == float D.offset = D(1).offset+8;

    offset = D.offset;}

    Note: We can construct a data structure to store the information

    (attributes) of D. (i.e., D.type and D.offset)

    2

    3

    A id d

  • 8/10/2019 Compiler Construction Chapter 6

    64/111

    Avoided grammar:

    D -> int namelist ; | float namelist ;

    namelist -> id, namelist | id

    Why?

    When the 'id' is reduced into namelist, we cannotknow the type of 'id' (int or float?) immediately.Therefore, it is troublesome to enter such typeinformation into the corresponding field of the 'id' in

    the symbol table. Hence, we must use special codingtechnique (e.g. linked list keeping the ids name(pointers to symbol table) to achieve such a purpose.(* In other words, we need backpatch to chain the

    data type.)

    D

    int namelist ;

    id

    int x ;

    1

    2

    64

    A bl

  • 8/10/2019 Compiler Construction Chapter 6

    65/111

    Acceptable grammar:

    D -> int intlist ; | float floatlist ;

    intlist -> id, intlist | id

    Advantage: The above-mentioned problem will nothappen. That is, when 'id' is reduced, we canidentify the type of id. (If id is reduced to intlist, thenid is of int type)

    Defect: too much production will occur. => too manystates => bad performance

    floatlist -> id, floatlist | id

    65

  • 8/10/2019 Compiler Construction Chapter 6

    66/111

    How to handle the following declaration?

    x,y,z : float

    Two approaches:

    (I) decl -> id_list ':' type

    id_list -> id_list ',' id | id

    type -> int | float

    (II) decl -> id ':' type | id , decltype -> int | float

    Which one is better for LR parsing? Why?

    1

    2

    3

    1

    2

    66

  • 8/10/2019 Compiler Construction Chapter 6

    67/111

    Suggested Grammar for the following Declaration:

    var x,y,z : real; u,v,t : integer;

    declarations : VAR decl_list

    | /* empty (no declaration is permitted) */

    ;decl_list : declaration ';'

    | declaration ';' decl_list

    ;

    declaration : ID ':' type| ID ',' declaration

    ;

    type : REAL

    | INTEGER

    ;67

    Try to construct a parse tree for the following declaration

  • 8/10/2019 Compiler Construction Chapter 6

    68/111

    Try to construct a parse tree for the following declaration

    and see how to parse it: var x: real; y: integer;

    declarations

    VAR decl_list

    var declaration ; decl_list

    ID : type declaration ;

    x real ID : type

    y integer

  • 8/10/2019 Compiler Construction Chapter 6

    69/111

    The following grammar for declaration is

    difficult for attribute gathering.

    declaration : id_list ':' type ;

    id_list : ID| id_list ',' ID

    type : REAL

    | INTEGER

    69

  • 8/10/2019 Compiler Construction Chapter 6

    70/111

    e.g., declaration

    id_list : type

    id_list , ID REAL

    id_list , ID

    ID

    1

    2

    34

    5

    Intermediate Code Generation

  • 8/10/2019 Compiler Construction Chapter 6

    71/111

    Intermediate Code Generation

    Three Address Code (Two Address code => Triples)

    Quadruples (a collective data structure, each unit is with 4 fields)Operator Arg1 Arg2 Result=+

    =-

    =*

    =/=%

    []=

    =[]

    .

    Note: The entries of operator column are integers that represent

    individual operators. The entries of Arg1 (operand1) Arg2

    (operand2) and Result are index (pointer) to the symbol table.

    A unit

  • 8/10/2019 Compiler Construction Chapter 6

    72/111

    Kinds of three-address codes:

    1.A = B op(1) C (op is a binary arithmetic or logical operation)

    2.A = op(2) B (op is a unary operation, e.g. minus, negation, shiftoperators, conversion operator, identity operator)

    3. goto L (unconditional jump, execute the Lth three-

    address code)

    4. if A relop B goto L (relop denotes relational operators, e.g., , >=, !=, etc.)

    5. param A and call P,n (used to implement a procedure call)

    6. A = B [i]

    7. A[i] = B

    8. A = &B9. A = *B

    10. *A = B

  • 8/10/2019 Compiler Construction Chapter 6

    73/111

    In Quadruples:

    Operator Arg1 Arg2 Result

    1. ==> op(1) B C A

    2. ==> op(2) B A

    3. ==> goto L4. ==> relopgoto A B L

    5. ==> param A

    5. ==> call P n

    6. ==> =[] B i A7. ==> []= B i A

    8. ==> =& B A

    9. ==> =* B A

    10. ==> *= B A73

    E l D A*B C D A B * C

  • 8/10/2019 Compiler Construction Chapter 6

    74/111

    Example: D = A*B+C

    The generated three address code is:

    T1 = A * B T1 = B * C

    T2 = T1 + C T2 = A + T1

    D = T2 D = T2

    Operator Arg1 Arg2 Result

    =* A B T1

    =+ T1 C T2

    = T2 D

    * T1 and T2 are compiler-generated temporary variables and they

    are also saved in the symbol table.

    D = A + B * C

    Interpretthis

    Actually, in implementation the

  • 8/10/2019 Compiler Construction Chapter 6

    75/111

    Actually, in implementation the

    quadruples look as:

    Operator Arg1 Arg2 Result

    8 6 7 9

    15 9 8 11

    3 11 10

    in symbol table: index identifier attributes0 twa

    1 K

    .. ..

    .. ..

    6 A7 B

    8 C

    9 T1 /* compiler generated temporary variable */

    10 D

    11 T2 /* compiler generated temporary variable */

    Interpretthis

    75

  • 8/10/2019 Compiler Construction Chapter 6

    76/111

    2. Arithmetic Statements

    A -> id = E

    E -> E(1) + E(2)

    E -> E(1) - E(2)

    E -> E(1) * E(2)

    E -> E(1) / E(2)

    E -> - E(1)

    E -> (E(1))

    E -> id

    A

    id = E

    E + E

    id id

    x = a + b T1 = a + b

    x = T1

    1 2

    3

    4

    76

    A id E { GEN (id l E l ) }

  • 8/10/2019 Compiler Construction Chapter 6

    77/111

    A -> id = E { GEN (id.place = E.place); }/* GEN (argument) - a function used to save its argument into the

    quadruple. The implementation of E is a data structure with one field

    E.place which holds the name that will hold the index value of thesymbol table. */

    E -> E(1) + E(2) { T = NEWTEMP();/* NEWTEMP() - a function used to generate a

    temporary variable T and save T into symboltable and return the index value of the symbol

    table. */

    E.place = T;

    /* Ts index value in symbol table is assigned to

    E.place */GEN(E.place = E(1).place + E(2).place); }

    T = a + b

    2

    3

  • 8/10/2019 Compiler Construction Chapter 6

    78/111

    E -> E(1) * E(2) { T = NEWTEMP();

    E.place = T;

    GEN(E.place = E(1).place * E(2).place); }

    E -> - E(1) { T = NEWTEMP();

    E.place = T;

    GEN(E.place = -E(1).place); }

    E -> (E(1)) { E.place = E(1).place; }

    E -> id { E.place = id.place; }

    /*idindexEfield 'place' ; Inimplementation id.place refers to the index value

    of id in the symbol table. */

    2

    2

    2

    1

    Enhanced version for E > E(1) op E(2)

  • 8/10/2019 Compiler Construction Chapter 6

    79/111

    Enhanced version for E -> E(1) op E(2)

    **in this version E (array ofstruct of EEattributes, array indexEvalue stack)

    { T = NEWTEMP();

    if E(1).type == int and E(2).type == int then{ GEN (T = E(1).place intop E(2).place);

    E.type = int;

    }

    else if E(1)

    .type == float and E(2)

    .type == float then{ GEN (T = E(1).place floatop E(2).place);

    E.type = float;

  • 8/10/2019 Compiler Construction Chapter 6

    80/111

    yp ;}

    else if E(1).type == int and E(2). type == float then

    { U = NEWTEMP();GEN (U = inttofloat E(1).place);GEN (T = U floatop E(2).place);E. type = float;

    }

    else /* E(1). type == float and E(2). type == int then{ U = NEWTEMP();GEN (U = inttofloat E(2).place);GEN (T = E(1).place floatop U);

    E. type = float;}

    }

  • 8/10/2019 Compiler Construction Chapter 6

    81/111

    3. Boolean Expression

    M ->

    E - > E o r M E| E and M E

    | not E

    | ( E )

    | id

    | id relop id

    81

  • 8/10/2019 Compiler Construction Chapter 6

    82/111

    An example

    if p < q || r < s && t < u

    x = y + z;k = m n;

    For the above boolean expression thecorresponding contents in the quadruplesare:

    82

    quadruples if p < q || r < s && t < u+

  • 8/10/2019 Compiler Construction Chapter 6

    83/111

    Location Three-Address Code

    .

    100 if p < q goto 106

    101 goto 102

    102 if r < s goto 104

    103 goto 108

    104 if t < u goto 106

    105 goto 108 /*s.next = 105

    106 t1 = y + z

    107 x = t1

    108 t2 = m - n

    109 k = t2

    ... .........

    x = y + z;k = m n;

    E

    E or M E

    E and M E

    id < id

    id < id

    id < id

    counter = 100

    1 2

    34

    5

    7

    6

  • 8/10/2019 Compiler Construction Chapter 6

    84/111

    NEXTQUAD an integer variable used for saving the index (location)value of the next available entry of the quadruples.

    E.true an attribute of E that holds a set of indexes (locations) of thequadruples, each indexed quadruple saves the three-address codewith true boolean expression.

    E.false an attribute of E that holds a set of indexes of the

    quadruples, each indexed quadruple saves the three-address codewith false boolean expression.

    GEN(x) a function that translates x (a kind of three-address-code) intoquadruple representation.

    So, we need to construct a data structure for E which includes twofields, each field can save an unlimited number of integer.Meanwhile, we need to construct an array of this Es structure tostore several Es attributes to be used in the same period of time .

    1. M -> { M.quad = NEXTQUAD; }

    /* M d i d t t t i t d ith M */

    2

  • 8/10/2019 Compiler Construction Chapter 6

    85/111

    /* M.quad is a data structure associated with M */

    2. E -> E(1) or M E(2)

    {

    BACKPATCH (E(1).false, M.quad);

    E.true = MERGE (E(1).true, E(2).true);

    E.false = E(2).false;

    }

    /* BACKPATCH (p, i) a function that makes each of thequadruple index values on the list pointed to by p take

    quadruple i as a target (i.e., goto i).*/

    /* MERGE (a, b) a function that takes the lists pointed toby a and b, concatenates them into one list, andreturns a pointer to the concatenated list. */

    4

    (1) (2)

  • 8/10/2019 Compiler Construction Chapter 6

    86/111

    3. E -> E(1) and M E(2)

    {

    BACKPATCH (E(1).true, M.quad);E.true = E(2).true;

    E.false = MERGE (E(1).false, E(2).false);

    }

    4. E -> not E(1)

    { E.true = E(1).false; E.false = E(1).true;}

    5. E -> ( E(1) )

    { E.true = E(1).true; E.false = E(1).false;}

    3

    3

    4

    6 E -> id1

  • 8/10/2019 Compiler Construction Chapter 6

    87/111

    6. E -> id

    {

    E.true = MAKELIST (NEXTQUAD);

    E.false = MAKELIST(NEXTQUAD + 1);GEN (if id.place goto _ );

    GEN (goto _);

    }

    /* MAKELIST ( i ) a function that creates a list containing i, anindex into the array of quadruples, and returns a pointer to thelist it has made. */

    /* GEN(x) a function that translates x (a kind of three-address-

    code) into quadruple representation. */

    1

  • 8/10/2019 Compiler Construction Chapter 6

    88/111

    7. E -> id(1) relop id(2)

    {E.true = MAKELIST (NEXTQUAD);E.false = MAKELIST(NEXTQUAD + 1);GEN (if id(1).place relop id(2).place goto _ );

    GEN (goto _);}

    falseE true

    20

    if id(1).place relopid(2).place goto _20

    21 goto _

    .

    NEXTQUAD

    21

    22

    1

    88

  • 8/10/2019 Compiler Construction Chapter 6

    89/111

    4. Flow-of-Control statements

    A. Conditional Statements

    S -> if E then S else S

    | if E then S

    | A| begin L end

    L - > S

    | L ; S

    /* A denotes a general assignment statement

    L denotes statement list

    S denotes statement */

    89

  • 8/10/2019 Compiler Construction Chapter 6

    90/111

    1. S -> if E then M(1) S(1) N else M(2) S(2)

    {BACKPATCH (E.true, M(1).quad);BACKPATCH (E.false, M(2).quad);S.next = MERGE (S(1).next, N.next, S(2).next);

    }

    /* S.next is a pointer to a list of all conditional andunconditional jump (goto) to the quadruple following thestatement S in execution order. */

    7

    90

  • 8/10/2019 Compiler Construction Chapter 6

    91/111

    2. S -> if E then M S(1)

    { BACKPATCH (E.true, M.quad);S.next = MERGE (E.false, S(1).next)

    }

    3. M -> { M.quad = NEXTQUAD; }

    4. N -> {

    N.next = MAKELIST (NEXTQUAD);GEN (goto _);

    }

    nextN

    20NEXTQUAD = 2020 Goto ___

    NEXTQUAD

    1

    2

    7

    91

  • 8/10/2019 Compiler Construction Chapter 6

    92/111

    5. S -> A{ S.next = MAKELIST ( ); }

    /* initialize S.next to an empty list */

    6. L -> S { L.next = S.next; }

    7. L -> L(1) ; M S

    {BACKPATCH (L(1).next, M.quad); // To resolve all

    quadruples with conditional & unconditional unresolvedgoto _

    L.next = S.next;}

    8. S -> begin L end { S.next = L.next; }

    3

    4

    5

    6

    92

  • 8/10/2019 Compiler Construction Chapter 6

    93/111

    B. Iterative Statement

    S -> while E do S

    9. S -> while M(1) E do M(2) S(1)

    {

    BACKPATCH (E.true, M(2)

    .quad);BACKPATCH (S(1).next, M(1).quad);S.next = E.false;GEN (goto M(1).quad);

    }

    93

    An example:hil (A B) d if (C D) th X Y Z

  • 8/10/2019 Compiler Construction Chapter 6

    94/111

    while (A

  • 8/10/2019 Compiler Construction Chapter 6

    95/111

    5. Array References

    Addressing Array Elements

    one-dimension: A[low..high]

    two-dimension: A[low1..high1, low2..high2]

    n-dimension: A[low1..high1, low2..high2, ... , lown..highn]

    Let: base = address of beginning of A, and

    w = width of an array element

    ni = the number of array elements in i-th dimension (row)

    /* row major */

    ( e.g. n1 = high1 - low1 + 1; n2 = high2 - low2 + 1;n3 = high3 - low3 + 1; ...)

    A[i] has address: base (of A) + (i - low) * w = i * w + (base

  • 8/10/2019 Compiler Construction Chapter 6

    96/111

    A[i] has address: base (of A) (i low) w i w (base

    low * w), where base - low * w is compile-time invariant.

    A[i1, i2] has address (row-major): base + ((i1 - low1) * n2 +i2 - low2) * w = (i1 * n2 + i2) * w + base - (low1 * n2 +

    low2) * w, where base - (low1 * n2 + low2) * w is compile-

    time invariant

    A[i1, i2, i3] has address: base + ((i1 - low1) * n2 * n3 + (i2

    low2) * n3 + (i3 - low3)) * w = base + (((i1 - low1) * n2 + (i2

    - low2)) * n3 + (i3 - low3)) * w = ((i1* n2 + i2) * n3 + i3) * w

    + base - ((low1* n2 + low2) * n3 + low3) * w, where base

    ((low1* n2 + low2) * n3 + low3) * w is compile-time invariant.

    In general, A[i1, i2, ... ,ik] has address: ((..(((i1* n2 + i2) * n3 + i3)

  • 8/10/2019 Compiler Construction Chapter 6

    97/111

    *n4 + ... ) * nk + ik) * w + base - ((..((low1* n2 + low2) * n3 +

    low3)... ) * nk + lowk) * w, where base - ((..((low1* n2 + low2) *

    n3 + low3) ... ) * nk + lowk) * w is compile-time invariant.

    Therefore, we can compute as follows:

    e1 = i1

    e2 = e1* n2 + i2

    e3 = e2* n3 + i3

    .

    em = em-1* nm + im

    .ek = ek-1* nk + ik

  • 8/10/2019 Compiler Construction Chapter 6

    98/111

    The address of A[i1, i2, ... ,ik] is: ek * w + compile-

    time invariant.

    98

    Translation Scheme for Addressing Arra Elements

  • 8/10/2019 Compiler Construction Chapter 6

    99/111

    Translation Scheme for Addressing Array Elements

    Assume: (1) for each id there exists id.place which holds

    its name,

    (2) there is a function limit( ) where

    limit(array_name, m) = nm i.e., the # of

    elements of array array_name at dimensionm-th,

    (3) we can find the width of an array element

    from the name of array (i.e. from symbol

    table)

    // Please read Section 8.3.2 (Array References) of thetextbook.

    ( ) S

  • 8/10/2019 Compiler Construction Chapter 6

    100/111

    (1) S -> L = E

    { if L.offset = null then

    GEN (L.place = E.place)else

    GEN (L.place[L.offset] = E.place); //

    }

    (2) E - > E 1 + E 2

    { E.place = newtemp(); //generate a temporary variable and

    save its symbol table index

    GEN (E.place = E1.place+ E2.place);

    }

    6

    7

    (3) E > (E (1)) { E l E (1) l }6

  • 8/10/2019 Compiler Construction Chapter 6

    101/111

    (3) E -> (E (1)) { E.place = E (1).place }

    (4) E - > L { if L.offset = null thenE.place = L.place

    else

    E.place = newtemp();

    GEN (E.place = L.place[L.offset]);}

    (5) L -> Elist ]

    { L.place = Elist.array_name;

    L.offset = newtemp();GEN (L.offset = w * Elist.place); }

    /* w is known from declaration of array */

    3

    5

    6

    (6) L - > i d { L.place = id.place; L.offset = null }4

  • 8/10/2019 Compiler Construction Chapter 6

    102/111

    (7) Elist -> Elist (1), E

    { T = newtemp(); m = Elist (1).ndimen + 1;

    GEN ( T = Elist (1).place * limit(Elist (1). array_name, m));GEN ( T = T + E.place );

    Elist.array_name = Elist (1).array_name;

    Elist.place = tj; // tj T

    Elist.ndimen = mj; } // mj m

    /* note em = em-1* nm + im , where Elist.place = em, Elist (1).place = em-1,limit(Elist (1).array, m) = nm, and E.place = im */

    (8) Elist -> id [ E { Elist.place = E.place; Elist.ndimen = 1;

    Elist.array_name := id.place; }

    // : compile-time invariant id.place

    1

    2

    6 Procedure calls

  • 8/10/2019 Compiler Construction Chapter 6

    103/111

    6. Procedure calls

    1. call -> id (args)

    2. args -> args , E3. args -> E

    1. call -> id (args)

    { for each item p on QUEUE do

    GEN (param p);GEN (call id.place, length of QUEUE); }

    /* QUEUE is a data structure for saving the indexes of the symboltable containing the names of the arguments. The length of

    QUEUE is the number of elements in QUEUE */

    3

    2 args > args E2

  • 8/10/2019 Compiler Construction Chapter 6

    104/111

    2. args -> args , E

    { append E.place to the end of QUEUE; }

    3. args -> E

    { initialize QUEUE to contain only

    E.place; }

    /* Originally, QUEUE is empty and, after the reductionof E to args, QUEUE contains a single pointer to thesymbol table location for the name that denotes thevalue of E. */

    1

    2

    7. Structure Declarations (Read Sec. 8.3.3)

  • 8/10/2019 Compiler Construction Chapter 6

    105/111

    ( )

    type -> struct { fieldlist} /*Note: symbols with bold face are

    terminals */| ptr

    | char

    | int

    | float

    | double

    fieldlist -> fieldlist field;

    | field;

    field -> type id| field [integer/*a token denoting any string of digits*/]

    int x

    int x [10] [20] [30]field

    int x [10] or

    struct { int x; //offset 0float y; //offset 2char k[10];//offset 6

    } m;

    m.width = 16 bytes

  • 8/10/2019 Compiler Construction Chapter 6

    106/111

    field -> type id

    { field.width = type.width;

    field.name = id.name;

    W_enter(id.name, type.width);}

    | field(1)

    [integer]{ field.width = field(1).width * integer.val;

    field.name = field(1).name;

    D_enter(field(1).name, integer.val);}

    2

    3

    fieldlist -> field; {O_enter (field.name, 0); fieldlist.width = field.width;}

    | fieldlist(1) field; { fieldlist width = fieldlist(1) width

    3

  • 8/10/2019 Compiler Construction Chapter 6

    107/111

    | fieldlist(1) field; { fieldlist.width = fieldlist(1).width

    + field.width;

    O_enter (field.name, fieldlist(1)

    .width);}type -> struct '{' fieldlist '} ' { type.width = fieldlist.width; }

    type -> char { type.width = 1; } /* Assume characters take one byte.*/

    type -> ptr {type.width = 4; } /*Assume pointers take four bytes.*/

    type -> int { type.width = 2; } /* Assume integers take two bytes.*/

    .......

    5

    1

    1

    1

    4

    Definitions of functions used

  • 8/10/2019 Compiler Construction Chapter 6

    108/111

    D_enter(name,size) increases the number of dimensions for

    name by one and enters the last dimension as size in thesymbol table entry for name.

    W_enter(name,width) enters widthas the width of each

    element of name. If name is not an array, then its width isthe number of locations taken by data of names type.

    O_enter(name,offset) makes offset the number for which

    field name name stands. This information, also, is recordedin the symbol table entry for name.

  • 8/10/2019 Compiler Construction Chapter 6

    109/111

    8. Switch Statement

    Syntax:

    switch E

    {case V1: S1;

    case V2: S2;

    .............

    .............case Vn-1: Sn-1;

    default: Sn;

    }10

    9

    When translated into three-address code:

  • 8/10/2019 Compiler Construction Chapter 6

    110/111

    100 Code to evaluate E into T

    101 If T V1 goto 104

    102 Code for S1103 Goto 113

    104 If T V2 goto 107

    105 Code for S2

    106 Goto 113

    107 ...108 ...

    109 If T Vn-1 goto 112

    110 Code for Sn-1

    111 Goto 113

    112 code for Sn113 .

    Temporary variable

  • 8/10/2019 Compiler Construction Chapter 6

    111/111

    Based on the given translation example, you

    can infer how to generate the three-address

    codes for switch statement easily !!!