ΕΠΛ323 - Θεωρία και Πρακτική Μεταγλωττιστών Lecture 8a Syntax-directed Transla1on Elias Athanasopoulos eliasathan@cs.ucy.ac.cy
Syntax-directed TranslaPon (SDT) Μετάφραση Κατευθυνόμενη από τη Σύνταξη We associate informapon with a programming language construct by azaching azributes to the grammar symbols represenpng the construct. Values of azributes are computed based on semanpc rules. We define Syntax-directed DefiniPons and Syntax-director TranslaPons. We parse the input token stream, build the parse tree, and then traverse the tree as needed to evaluate the semanpc rules at the parse-tree nodes. input string parse tree dependency graph evaluapon order for semanpc rules
Syntax-directed DefiniPons (SDTs) Ορισμοί κατευθυνόμενοι από τη σύνταξη A syntax-directed definipon is a generalizapon of a context-free grammar in which each grammar symbol has an associated set of azributes Synthesized azributes (παραγόμενα), Inherited azributes (κληρονομούμενα). AZributes can represent anything Strings, numbers, types, memory locapons, etc. A parse tree showing the values of azributes at each node is called an annotated parse tree.
AZributes In a syntax-directed definipon, each grammar producpon Aàa has associated with it a set of semanpc rules of the form b := f(c 1, c 1,..., c k ) where a f is a funcpon. Synthesized b is a synthesized azribute of A, Example: AàBC, A.val = f(b.val, C.val), i.e., the azribute val of A is computed by azributes of its children (B and C). Inherited b is an inherited azribute of one of the grammar symbols on the right side of the producpon. Terminals have only inherited azributes. Example: AàBCD, C.val = f(a.val, B.val, C.val), i.e., the azribute val of C (on the right side of the producpon) is computed by azributes of its parent (A) and its siblings (B and D). In either case, we say that azribute b depends on azributes c 1, c 1,..., c k.
Example Synthesized A[ributes PRODUCTION L à E n E à E 1 + T E à T T à T 1 * T T à F F à ( E ) F à digit SEMANTIC RULES print(e.val) E.val:=E 1.val+T.val E.val:=T.val T.val:=T 1.val*T.val T.val:=F.val F.val:=E.val F.val:=digit.lexval Syntax-directed definipon (called also S-a[ributed definiaon), which contains only synthesized azributes. All semanpc rules are wrizen at the right end of the producpons. AZribute val of E is a funcpon of the azributes of its children, namely E 1 and T.
S-aZributed DefiniPon Input: 3*5+4 L E.val=19 n E.val=15 + T.val=4 T.val=15 F.val=4 T.val=3 * F.val=5 digit.lexval=5 F.val=3 digit.lexval=5 digit.lexval=3
Example Inherited A[ributes D à T L T à int PRODUCTION T à real L à L 1, id L à id SEMANTIC RULES L.in := T.type T.type := integer T.type := real L 1.in := L.in addtype(id.entry, L.in) addtype(id.entry, L.in) Syntax-directed definipon with inherited azributed L.in. AZribute in of L is a funcpon of the azribute of its sibling T.
Parse tree with inherited azribute L.in Input: real id 1,id 2,id 3 D T.type=real L.in=real real L.in=real, id 3, L.in=real id 2 id 1
SemanPc Analysis Syntax-directed Defini1on (SDD) A context-free grammar with seman1c rules for calculapng the azributes PRODUCTION E à E 1 + T SEMANTIC RULES E.val:=E 1.val+T.val Syntax-directed Transla1ons (SDTs) A context-free grammar with seman1c ac1ons and their exact order (acpons can appear anywhere in the right side of a producpon) T à num { print(num.val) }
Dependency graph EvaluaPng azributes is easier when we know the dependency graph, i.e., the relapon between various azributes Construcaon 1. For each node of the parse tree and for each azribute we create a new node. 2. For each semanpc rule, b = f(c 1, c 2,..., c n ) we construct an edge from c i to node b. 3. In case the semanpc rule is a procedure call, we create a dummy azribute for this rule.
Example PRODUCTION EàE 1 +E 2 SEMANTIC RULE E.val:=E 1.val+E 2.val E.val E 1.val E + 2.val
Syntax Trees An (abstract) syntax tree (AST) is a condensed form of a parse tree, useful for represenpng language constructs. An AST is much more simplified compared to the parse tree Much more easier to be handled from following phases of the compiler
Example L E.val=19 n AST + E.val=15 + T.val=4 * 4 T.val=15 F.val=4 3 5 T.val=3 * F.val=5 digit.lexval=4 F.val=3 digit.lexval=5 digit.lexval=3
AST ConstrucPon We use the following funcpons to create an AST. mknode(op, left, right) creates an operator node with label op and two fields containing pointers to lee and right. mkleaf(id, entry)creates an idenpfier node with label id and a field containing entry, a pointer to the symbol-table entry for the idenpfier. mkleaf(num, val)creates a number node with label num and a field containing val, the value of the number.
Syntax-directed DefiniPon for AST construcpon PRODUCTION E à E 1 + T E à E 1 - T E à T T à ( E ) T à id T à num SEMANTIC RULES E.nptr:=mknode( +, E 1.nptr, T.nptr) E.nptr:=mknode( -, E 1.nptr, T.nptr) E.nptr:=T.nptr T.nptr:=E.nptr T.nptr:=mkleaf(id, id.entry) T.nptr:=mkleaf(num, num.val)
a-4+c + 0-0 id 0 id 0 ptr for a num 4 ptr for c (1) p1 := mkleaf(id, entrya) (2) p2 := mkleaf(num, 4) (3) p3 := mknode( -, p1, p2) (4) p4 := mkleaf(id, entryc) (5) p5 := mknode( +, p3, p4)
Directed Acyclic Graph (DAG) Each Pme we create a new node, we can check if the node has been already constructed. If the node has been already constructed then we use the already constructed pointer. Like a syntax tree, the interior node represents the operator and its children represent the operands. A node in a DAG may have several parents.
a+a*(b-c)+(b-c)*d + + * a No1ce p1 = p2 p8 = p3 p9 = p4 * b - d c (1) p1 := mkleaf(id, a) (2) p2 := mkleaf(id, a) (3) p3 := mkleaf(id, b) (4) p4 := mkleaf(id, c) (5) p5 := mknode( -, p3, p4) (6) p6 := mknode( *, p2, p5) (7) p7 := mknode( +, p1, p6) (8) p8 := mkleaf(id, b) (9) p9 := mkleaf(id, c) (10) p10 := mknode( -, p8, p9) (11) p11 := mkleaf(id, d) (12) p12 := mknode( *, p10, p11) (13) p13 := mknode( +, p7, p12)