Principles of Programming Languagesandrea/Didattica/PLP-16/SLIDES/PLP-2016-10.pdf · Principles of...

38
Principles of Programming Languages h"p://www.di.unipi.it/~andrea/Dida2ca/PLP-16/ Prof. Andrea Corradini Department of Computer Science, Pisa Syntax-Directed Transla>on Lesson 10

Transcript of Principles of Programming Languagesandrea/Didattica/PLP-16/SLIDES/PLP-2016-10.pdf · Principles of...

PrinciplesofProgrammingLanguagesh"p://www.di.unipi.it/~andrea/Dida2ca/PLP-16/

Prof.AndreaCorradiniDepartmentofComputerScience,Pisa

•  Syntax-DirectedTransla>on

Lesson 10!

2

TheStructureoftheFront-End

Lexicalanalyzer

SourceProgram�

(Character�stream)

Token�stream

Intermediaterepresentation

Syntaxdefini>on(BNFgrammar)

Develop�parser and code�

generator for translator

IRspecifica>on

ParserSyntax-directed

translator

3

Syntax-DirectedTransla>on•  Brieflyintroducedinthefirstlectures•  Generaltechniqueto“manipulate”programs,basedoncontext-freegrammars

•  Tightlyboundwithparsing•  Willbeusedforsta>canalysis(typechecking)and(intermediate)codegenera>on

•  Severalotheruses:–  Genera>onofabstractsyntaxtrees–  Evalua>onofexpressions–  Implementa>onofDomainSpecificLanguages(seeexampleontypeseUngmathformulasinthebook)

–  …•  PartlysupportedbyparsergeneratorslikeYacc

•  Wewillconsider:– Syntax-DirectedDefini>ons(A"ributeGrammars)– Syntax-DirectedTransla>onSchemes– Transla>onevaluatedontheparsetree– Transla>onevaluatedduringparsing

4

Syntax-DirectedTransla>on

5

Syntax-DirectedDefini>ons

•  Asyntax-directeddefini6on(ora"ributegrammar)isacontextfreegrammarwhere:–  Terminalsandnonterminalshavea"ributesholdingvalues–  Produc>onshaveassociatedseman6crules,whichsetthevaluesofaYributes

•  EachgrammarsymbolcanhaveanynumberofaYributes

•  AYributevalofsymbolXisdenotedX.val•  Aseman>cruleofaproduc>onA→αhastheform

b:=f(c1,c2,…,ck)whereb,c1,c2,…,ckareaYributesofAorofthesymbolsinα

6

AYributes•  AnannotatedparsetreeisaparsetreewhereallaYributesofnodeshavethecorrespondingvalue

•  AYributevaluesmayrepresent–  Numbers(literalconstants)–  Strings(literalconstants)–  Intermediateprogramrepresenta>ons

•  (pointersto)nodesofabstractsyntaxtree•  (pointersto)stringsrepresen>ngtheintermediatecode

– Memoryloca>ons,suchasaframeindexofalocalvariableorfunc>onargument

–  Adatatypefortypecheckingofexpressions–  Scopinginforma>onforlocaldeclara>ons

7

Synthesizedvs.InheritedAYributes

•  Givenaproduc>onA→αandaseman>crule b:=f(c1,c2,…,ck)–  ifbisanaYributeofAthenitisasynthesizedaYributeofA–  ifbisanaYributeofasymbolBinαthenitisaninheritedaYributeB

•  Note:terminalsymbolshaveonlysynthesizedaYributes

D → T L �T → int �… �L → id

L.in := T.type�T.type := ‘integer’�… �… := L.in

Production Semantic Rule inherited

synthesized

8

S-AYributedDefini>ons•  Asyntax-directeddefini>onthatusessynthesizedaYributesexclusivelyiscalledanS-a"ributeddefini6on(orS-a"ributedgrammar)

•  AparsetreeofanS-aYributeddefini>oncanbeannotatedwithasingleboYom-uptraversal

•  Givenaparsetree,anypostorderdepth-firsttraversalalgorithmcanbeusedtoexecutetheseman>crulesandassignaYributevalues

•  InsomecasesaYributescanbeevaluatedduringparsing,withoutbuildingtheparsetreeexplicitly

•  [Yacc/BisononlysupportS-aYributeddefini>ons]

9

Example:evalua>ngexpressionswithsynthesizedaYributes

L → E n �E → E1 + T �E → T �T → T1 * F�T → F�F → ( E )F → digit

L.val := E.val�E.val := E1.val + T.val�E.val := T.val�T.val := T1.val * F.val�T.val := F.val�F.val := E.val�F.val := digit.lexval

Productions Semantic Rules

ASyntax-DirectedDefini6on(SDD)orA"ributeGrammar

10

Example:AnAnnotatedParseTree

E.val = 16

T.val = 2

9 + 5 + 2

E.val = 14

E.val = 9 T.val = 5

F.val = 9

L.val = 16

n

T.val = 9 F.val = 5

F.val = 5

L → E n �E → E1 + T �E → T �T → T1 * F�T → F�F → ( E )F → digit

ProductionsL.val := E.val�E.val := E1.val + T.val�E.val := T.val�T.val := T1.val * F.val�T.val := F.val�F.val := E.val�F.val := digit.lexval

Semantic Rule

11

Annota>ngaParseTreewithDepth-FirstPost-OrderTraversals

procedure visit(n : node);�begin � for each child m of n, from left to right do� visit(m);� evaluate semantic rules at node n�end

12

Depth-FirstTraversals(Example)

E.val = 16

T.val = 2

9 + 5 + 2

E.val = 14

E.val = 9 T.val = 5

F.val = 9

L.val = 16

n

T.val = 9 F.val = 5

F.val = 5 L.val := E.val�E.val := E1.val + T.val�E.val := T.val�T.val := T1.val * F.val�T.val := F.val�F.val := E.val�F.val := digit.lexval

Semantic Rules

Note:right-to-lebtraversalworksaswell

13

Example:genera>onofAbstractSyntaxTrees

•  Aparsetreeiscalledaconcretesyntaxtree•  Anabstractsyntaxtree(AST)isdefinedbythecompilerwriterasamoreconvenientintermediaterepresenta>on

E

+E T

id

id

id

*

Concrete syntax tree

+

*id

id id

Abstract syntax tree

T T

14

S-AYributedDefini>onsforGenera>ngAbstractSyntaxTrees

ProductionE → E1 + T �E → E1 - T �E → T �T → T1 * id �T → T1 / id�T → id

Semantic Rule�E.nptr := mknode(‘+’, E1.nptr, T.nptr)E.nptr := mknode(‘-’, E1.nptr, T.nptr)E.nptr := T.nptrT.nptr := mknode(‘*’, T1.nptr, mkleaf(id, id.entry))T.nptr := mknode(‘/’, T1.nptr, mkleaf(id, id.entry))T.nptr := mkleaf(id, id.entry)

15

Genera>ngAbstractSyntaxTrees

E.nptr

+E.nptr T.nptr

id

id

id

*T.nptr T.nptr

+

id *

id id

Synthesize�AST

16

ExampleAYributeGrammarwithSynthesized+InheritedAYributes

D → T L �T → int �T → real�L → L1 , id �L → id

L.in := T.type�T.type := ‘integer’ �T.type := ‘real’ �L1.in := L.in; addtype(id.entry, L.in)�addtype(id.entry, L.in)

Production Semantic RuleSynthesized:T.type, id.entry �Inherited: L.in

•  Grammargenera>ngdeclara>onoftypedvariables•  Limitedside-effect:TheaYributesaddtypinginforma>onto

thesymboltableviasideeffects•  InheritedaYributesallowtohandleinforma>onthatdoesnot

respectthetreestructure

Evalua>onorderofaYributes

•  InpresenceofinheritedaYributes,itisnotobviousinwhatordertheaYributesshouldbeevaluated

•  AYributesofanonterminalinaproduc>onmaydependinanarbitrarywayonaYributesofothersymbols

•  Theevalua>onordermustbeconsistentwithsuchdependencies

•  Ifthedependenciesarecircular,thereisnowaytoevaluatetheaYributes

•  Side-effectrulesareinterpretedasdefini>onofdummysynthesizedaYributesoftheheadsymbol

17

18

DependencyGraphsforAYributedParseTrees

A→XYA.a := f(X.x, Y.y) synthesized

A.a

X.x Y.y

X.x := f(A.a, Y.y) inherited

A.a

X.x Y.y

Y.y := f(A.a, X.x) inherited

A.a

X.x Y.y

Direction of��

value dependence

•  Givenaparsetree,considerasnodesallitsaYributes•  Representgraphicallythedependenciesinducedbyseman>c

rules

19

DependencyGraphswithCycles?

•  Edgesinthedependencygraphdeterminetheevalua>onorderforaYributevalues

•  Dependencygraphscannotbecyclic:noevalua>onorderispossible

A.a := f(X.x) �X.x := f(Y.y)�Y.y := f(A.a)

A.a

X.x Y.y

Error: cyclic dependence

20

ExampleAnnotatedParseTreeL.in := T.type�T.type := ‘integer’ �T.type := ‘real’ �L1.in := L.in; addtype(id.entry, L.in)�addtype(id.entry, L.in)

D → T L �T → int �T → real�L → L1 , id �L → id

realid,id,id

D

T1.type = ‘real’ L1.in = ‘real’

L2.in = ‘real’

L3.in = ‘real’ id2.entry

id1.entry

id3.entryreal

,

,

DummysynthesizedaYributeofLinducedbyside-effectac>ons

21

ExampleAnnotatedParseTreewithDependencyGraph

L.in := T.type�T.type := ‘integer’ �T.type := ‘real’ �L1.in := L.in; addtype(id.entry, L.in)�addtype(id.entry, L.in)

D → T L �T → int �T → real�L → L1 , id �L → id

realid,id,id

Dependenciesinducedbyside-effectac>ons

D

T1.type = ‘real’ L1.in = ‘real’

L2.in = ‘real’

L3.in = ‘real’ id2.entry

id1.entry

id3.entryreal

,

,

22

Evalua>onOrder

•  Atopologicalsortofadirectedacyclicgraph(DAG)isanyorderingm1,m2,…,mnofthenodesofthegraph,suchthatifmi→mjisanedge,thenmiappearsbeforemj

•  Anytopologicalsortofadependencygraphgivesavalidevalua>onorderoftheseman>crules

23

Example Parse Tree with �Topologically Sorted Actions

D

T1.type = ‘real’ L1.in = ‘real’

L2.in = ‘real’

L3.in = ‘real’ id2.entry

id1.entry

id3.entryreal

,

,

1

2

3

4 5 6

7 8

9 10

Topological sort:�1. Get id1.entry�2. Get id2.entry�3. Get id3.entry4. T1.type=‘real’�5. L1.in=T1.type�6. addtype(id3.entry, L1.in)�7. L2.in=L1.in�8. addtype(id2.entry, L2.in)�9. L3.in=L2.in�10. addtype(id1.entry, L3.in)

24

Evalua>onMethods

•  Parse-treemethods:foreachinput,buildtheparsetreeandthedependencygraph,anddetermineanevalua>onorderfromatopologicalsort

•  Rule-basemethodstheevalua>onorderispre-determinedfromtheseman>crules

•  Obliviousmethodstheevalua>onorderisfixedandseman>crulesmustbe(re)wriYentosupporttheevalua>onorder(forexampleS-aYributeddefini>ons)

25

L-AYributedDefini>ons

•  Asyntax-directeddefini>onisL-a"ributedifeachinheritedaYributeofXjontherightsideofA→X1X2…Xndependsonlyon1.  theaYributesofthesymbolsX1,X2,…,Xj-12.  theinheritedaYributesofA3.  theaYributesofXj,inanon-circularway

A.a

X1.x X2.xPossibledependencesofinheritedaYributes

26

L-AYributedDefini>ons(cont’d)

•  L-aYributeddefini>onsallowforanaturalorderofevalua>ngaYributes:depth-firstandlebtoright

•  Note:everyS-aYributedsyntax-directeddefini>onisalsoL-aYributed(sinceitdoesn’thaveanyinheritedaYribute)

A→XY X.i := A.i�Y.i := X.s �A.s := Y.s

A

X YY.i:=X.s

X.i:=A.i A.s:=Y.s

Syntax-DirectedTransla>onSchemes

•  Translation Schemes provide an alternative notation for Syntax-Directed Definitions and are more expressive in general

•  The semantic rules include arbitrary side-effects and can be suitably embedded into productions

•  SDD’s can be evaluated in any order compatible with the dependencies, SDT’s should be evaluated left-to-right

•  SDT’s can always be implemented by building the parse tree first, and then performing the actions in left-to-right depth-first order

•  In several cases they can be implemented during parsing, without building the whole parse tree first

27

28

Syntax-DirectedTransla>onSchemes

•  A production of a translation scheme and corresponding node in a parse tree:

•  Possible implementation:– Build the parse tree ignoring semantic actions– Add semantic actions in the right place below non-

terminals– Visit the tree in depth-first, pre-order left-to-right

traversal executing all actions

rest → + term { print(“+”) } rest

Embedded�semantic action

rest

term rest+ { print(“+”) }

PosnixTransla>onSchemes

•  IfthegrammarisLR(thuscanbeparsedboYom-up)andtheSDDisS-aYributed(synthesizedaYributesonly),seman>cac>onscanbeplacedattheendoftheproduc>ons

•  Theyareexecutedwhenthebodyisreducedtothehead

•  SDTswhereallac>onsareattheendofproduc>onsarecalledposNixSDTs

29

30

ExampleTransla>onSchemeforPosnixNota>on

expr → expr + term�expr → expr - term�expr → term �term → 0�term → 1�…�term → 9

{ print(“+”) }�{ print(“-”) }��{ print(“0”) }�{ print(“1”) }�…�{ print(“9”) }

31

ExampleTransla>onScheme(cont’d)

expr

term

9

-

5

+

2

expr

expr term

term

{ print(“-”) }

{ print(“+”) }

{ print(“9”) }

{ print(“5”) }

{ print(“2”) }

Translates 9-5+2 into postfix 95-2+

Implementa>onofPosnixSDTs

•  PosnixSDTscanbeimplementedduringLRparsing

•  Theac>onsareexecutedwhenreduc>onsoccur•  TheaYributesofgrammarsymbolscanbeputonthestack,togetherwiththesymbolorthestatecorrespondingtoit

•  SinceallaYributesaresynthesized,theaYributefortheheadcanbecomputedwhenthereduc>onoccurs,becauseallaYributesofsymbolsinthebodyarealreadycomputed

32

UsingTransla>onSchemesforL-AYributedDefini>ons

•  AnL-aYributedSDDforagrammarthatcanbeparsedtop-down(LL)canbeimplementedusingTransla>onSchemes

1.  Embedac>onsthatcomputeinheriteda"ributesfornonterminalAimmediatelybeforeA–  Notethatinleb-to-rightparsing,allaYributesonwhichthe

inheritedaYributemaydependareevaluatedalready2.  Placeac>onsthatcomputeasynthesizeda"ributefor

theheadofaproduc>onattheendofthebodyofthatproduc>on

•  Weconsidersomewaysofimplemen>ngtheresul>ngSDTsduringparsing,bothtop-downandboYom-up

33

34

UsingTransla>onSchemesforL-AYributedDefini>ons

D → T L �T → int �T → real�L → L1 , id �L → id

L.in := T.type�T.type := ‘integer’ �T.type := ‘real’ �L1.in := L.in; addtype(id.entry, L.in)�addtype(id.entry, L.in)

Production Semantic Rule

D → T { L.in := T.type } L �T → int { T.type := ‘integer’ } �T → real { T.type := ‘real’ } �L → { L1.in := L.in } L1 , id { addtype(id.entry, L.in) }�L → id { addtype(id.entry, L.in) }

Translation Scheme

35

Implemen>ngL-AYributedDefini>onsinRecursive-DescentParsers

expr → term rest� rest → + term rest� | - term rest� | ε�term → id

procedure rest();�begin � if lookahead in FIRST(+ term rest) then � match(‘+’); term(); rest()� else if lookahead in FIRST(- term rest) then � match(‘-’); term(); rest()� else if lookahead in FOLLOW(rest) then � return � else error()�end;

RecapofRecursiveDescentParsing•  GrammarmustbeLL(1)•  Everynonterminalhasone(recursive)procedure•  Whenanonterminalhasmul>pleproduc>ons,theinputlook-

aheadisusedtochooseone•  Note:theprocedureshavenoparametersandnoresult

36

Implemen>ngL-AYributedDefini>onsinRecursive-DescentParsers

D→T{L.in:=T.type}LT→int{T.type:=‘integer’}T→real{T.type:=‘real’}

void D() { Type Ttype = T(); Type Lin = Ttype; L(Lin); } Type T() { Type Ttype; if (lookahead == INT) { Ttype = TYPE_INT; match(INT); } else if (lookahead == REAL) { Ttype = TYPE_REAL; match(REAL); } else error(); return Ttype; } void L(Type Lin) { … }

•  Attributes are passed as arguments to procedures (inherited) or returned (synthesized)

•  Procedures store computed attributes in local variables

Input:�inherited�attribute

Output:synthesized�

attribute

37

Implemen>ngL-AYributedDefini>onsinTop-DownTable-DrivenParsers

•  Thestackwillcontain,besidesgrammarsymbols,ac6on-recordsandsynthesize-records

•  InheritedaYributesofAareplacedinA’srecord–  Thecodecompu>ngthemisinarecordaboveA

Predic>veparsingprogram(driver)

ParsingtableM

a + b $

XYZ$

stack

input

output

•  SynthesizedaYributesofAareplacedinarecordjustbelowA

•  ItmaybenecessarytomakecopiesofaYributestoavoidthattheyarepoppedwhens>llneeded

38

Implemen>ngL-AYributedDefini>onsforLLgrammarsinBoYom-UpParsers•  Removeanyembeddedac>onwithmarkingnonterminal: A→α{act}β becomes A→αNβ N→ε{act’}whereact’: –  CopiesasinheritedaYributesofNanyaYributeofA,αneededbyact

–  ComputesaYributeslikeact,makingthemsynthesizedforN•  Fact:ifthestartgrammarwasLL,thenewoneisLR•  Note:act’accessesaYributesoutofitsproduc>on!Thisworks,astheyare(deeper)intheLRstack