Production rule | Semantic action |
S → call id(Elist) | for each item p on QUEUE do GEN (param p) GEN (call id.PLACE) |
Elist → Elist, E | append E.PLACE to the end of QUEUE |
Elist → E | initialize QUEUE to contain only E.PLACE |
● The symbol table of the output object file appears.
● Global be declared.
● In an equivalent sentence, be described.
Two types of assignment statements exist:● Symbol assignment statements, Defining or redefining a symbol in the namespace of a symbol.
● Register assignment statements, Defining or redefining the name of the register in the symbol name space.
2. Register assignment statements
The following syntax is available for a register assignment statement:identifier = register name // commentsWhere, Identifier = Represents the name of a register in the name space of the symbol.Register name = Specifies the name of the alternative register. If the name of the register is a stack or a revolving register name, the current name of the register continues to refer to the previously specified name of the register, even if the name is no longer valid. An example of an assignment statement that specifies a name for a register is as follows:B = p1 Q. 3) Describe a case statement ?Ans : Case Statement In a number of languages, the "switch" or "case" statement is available. The syntax for switch-statement is as shown below: Switch-statement syntax s with expressionbegin case value : statementcase value : statement.. case value : statementdefault : statementendThere is a selector expression to be evaluated, followed by n constant values that may be taken by the expression, including a default value that, if no other value does, always matches the expression. Code to: is the intended translation of a turn. 1. Assess an expression. 2. Find which value is equivalent to the value of the expression in the list of cases.3. Conduct the assertion that is correlated with the found meaning. Find the following paragraph about the switch: switch Ebegin case V1 : S1 case V2 : S2 case Vn-1 : Sn-1default : Sn endThis case statement is translated into an intermediate code in the following form: Translation of a case statement. code to analyze E into t goto testgoto TEST L1: code for S1 goto NEXT L2: code for S2 goto NEXT . . . Ln-1: code for Sn-1 goto NEXT Ln: code for Sn goto NEXT TEST: if T = V1 goto L1 if T = V2 goto L2 . . . if T = Vn-1 goto Ln-1 goto NEXT: A new temporary T and two new label tests are created when the switch keyword is seen, and next. When the case keyword happens, a new label Li is generated and inserted into the symbol table for each case keyword. A stack is put with the Vi value of each case constant and a pointer to this table-symbol entry. Q. 4) Write something about declaration ?Ans : Declaration We need to lay out storage for the declared variables when we encounter declarations. You can manage declaration with a list of names as follows :D T id ; D | εT B C | record ‘{‘D’}’B int | floatC ε | [ num ] C ● A declaration sequence is generated by Nonterminal D. ● A fundamental, array or record form is generated by nonterminal T. ● One of the basic int or float types is generated by nonterminal B. ● Nonterminal C produces a string of zero or more integers, each surrounded by brackets for "component". We create a ST(Symbol Table) entry for every local name in a procedure, containing: ● The type of the name● How much storage the name requiresProduction :D → integer, id D → real, id D → D1, id For declarations, an appropriate transformation scheme would be:Production rule | Semantic action |
D → integer, id | ENTER (id.PLACE, integer) D.ATTR = integer |
D → real, id | ENTER (id.PLACE, real) D.ATTR = real |
D → D1, id | ENTER (id.PLACE, D1.ATTR) D.ATTR = D1.ATTR |
Production rule | Semantic action |
E → E1 OR E2 | {E.place = newtemp(); Emit (E.place ':=' E1.place 'OR' E2.place) } |
E → E1 + E2 | {E.place = newtemp(); Emit (E.place ':=' E1.place 'AND' E2.place) } |
E → NOT E1 | {E.place = newtemp(); Emit (E.place ':=' 'NOT' E1.place) } |
E → (E1) | {E.place = E1.place} |
E → id relop id2 | {E.place = newtemp(); Emit ('if' id1.place relop.op id2.place 'goto' nextstar + 3); EMIT (E.place ':=' '0') EMIT ('goto' nextstat + 2) EMIT (E.place ':=' '1') } |
E → TRUE | {E.place := newtemp(); Emit (E.place ':=' '1') } |
E → FALSE | {E.place := newtemp(); Emit (E.place ':=' '0') } |
Ans : Back PatchingAll labels can not be recognised in a single pass in the code generation process (primarily, 3 Address Code), so we use a technique called Backpatching. Backpatching is the task of filling in unspecified label information during the code generation process using acceptable semantic behaviour. Three functions are used to implement the backpatching technique. The three functions performed in two passes to create code using backpatching are Makelist(), merge() and backpatch(). Three kinds of operations are carried out by Backpatching Algorithms
Parse Tree | Syntax Tree |
A graphical representation of the substitution form in a derivation is the Parse tree. | The compact form of a parse tree is the syntax tree. |
Any characteristic information from the real syntax is given by Parse trees. | Syntax trees do not have any of the actual syntax characteristics. |
A terminal is defined by any leaf node. | An operand represents each leaf node. |
Parse trees are relatively less dense than trees with syntax. | There are comparatively denser syntax trees than parse trees. |
A grammar rule is defined by each interior node. | An operator is defined by any interior node. |