Vous êtes sur la page 1sur 37

02/02/2011

SEMANTICA STATICA E DINAMICA

Controlli semantici

Congruenza fra le dichiarazioni delle entit e il loro impiego nelle istruzioni Rispetto delle regole che governano i tipi degli operandi nelle espressioni e negli assegnamenti Correttezza delle strutture di controllo del linguaggio Rispetto delle regole di visibilit e unicit degli identificatori Rispetto delle regole di importazione ed esportazione degli oggetti

02/02/2011

Type Checking

Un compilatore esegue le verifiche semantiche oltre che le verifiche sintattiche. Semantica


Statica le verifiche semantiche vanno eseguite durante la compilazione Dinamica le verifiche sono eseguite a run-time non possiamo fare tutti I type checking a compile-time. Alcuni sistemi usano anche dynamic type checking.

Type checking uno delle operazioni di checking statico.


Type Checking

Un type system una collezione di regole per assegnare una espressione di tipo ad una parte di programmi Un type checker implementa un type system. Un sound type system elimina gli errori di tipo. Un linguaggio di programmazione e detto strongly-typed, se ogni programma compilato solo se privo di errori di tipo.

In pratica, alcune operazioni di type checking sono fatti a runtime (la maggioranza dei programmi non strongly-typed). Esempi int x[100]; x[i] la maggioranza dei compilatori non garantiscono che i [0 .. 99]

02/02/2011

Type Expression

Il tipo si un costrutto di un linguaggio denotato dal type expression. Una type expression pu essere:

basic type Un tipo primitivo, int, float, type-error per segnalare un errore di tipo void type name Un nome che denota il tipo di una espressione

Type Expression

Un costruttore applicato ad altri type expressions


arrays: se T un type expression, allora array(I,T) un type expression dove I rappresenta il range degli indici: esempio array(0..99,int) products: se T1 e T2 sono type expressions, allora il prodotto cartesiano T1 x T2 un type expression. esempio: int x int pointers: se T una type expression, allora pointer(T) una type expression. esempio: pointer(int) functions: possiamo trattare funzioni in un linguaggio di programmazione come il mapping da un domain type D ad un range type R. Cosi, il tipo di una funzione puop essere raappresentato dal type expression DR dovee D e R sono type expressions. Esempio: intint reppresenta un tipo di uns funzione che prende come parametro un calore int e tiporrna un valore int.

02/02/2011

Lattributo type

un attributo sintetizzato

associato alle dichiarazioni di tipo, espressioni e descrive il tipo dellentit considerata Azioni semantiche o condizioni

Un semplice Type Checking System


P D;E D D;D D T id T char T int T float T *T1 T T1 [intnum]

{ addtype(id.entry,T.type) } { T.type=char } { T.type=int } { T.type=float } { T.type=pointer(T1.type) } {T.type=array(0..intnum-1.val,T1.type)}

02/02/2011

Type Checking di espressione


E id E charliteral E intliteral E realliteral { E.type=lookup(id.entry) } { E.type=char } { E.type=int } { E.type=real }

E E1 + E2

{ if (E1.type=int and E2.type=int) E.type=int


else if (E1.type=int and E2.type=real) E.type=real else if (E1.type=real and E2.type=int) E.type=real else if (E1.type=real and E2.type=real) E.type=real else E.type=type-error }

E E1 [E2]

{ if (E2.type=int and E1.type=array(s,t)) E.type=t else E.type=type-error }

Type Checking di istruzioni


S id = E { if (id.type=E.type) then S.type_error=false else S. type-error = true } S if (E ) S1 { if (E.type=int ) then S.type_error=S1.type_error else S.type_error=true} S while (E ) S1 S id (A) { if (E.type=int) then S.type_error =S1.type_error else S..type-error =true } S.type_error(confronta (A,get(id))

02/02/2011

Type Checking di funzioni


E E1 ( E2 ) { if (E2.type=s and E1.type=st) then E.type=t else E.type=type-error } Ex: int f(double x, char y) { ... } f: double x char int return type

argument types

Equivalenza strutturale di Type Expressions

Come verificare che due type expression sono uguali? type expressions sono costruiti dai tipi base e (no type names), possiamo utilizzare equivalenza strutturale per due type expressions

02/02/2011

Equivalenza strutturale di Type Expressions


if (s and t sono dello stesso tipo base) return true else if (s=array(s1,s2) and t=array(t1,t2)) return (sequiv(s1,t1) and sequiv(s2,t2)) else if (s = s1 x s2 and t = t1 x t2) return (sequiv(s1,t1) and sequiv(s2,t2)) else if (s=pointer(s1) and t=pointer(t1)) return (sequiv(s1,t1)) else if (s = s1 s2 and t = t1 t2) return (sequiv(s1,t1) and sequiv(s2,t2)) else return false

Names per Type Expressions

In alcuni linguaggi di programmazione noi diamo un nome ad type expression, e utilizziamo il type expression.

typedef link = *cell; p,q,r,s sono dello stesso tipo? link p,q; *cell r,s;

02/02/2011

Definizione ricorsive di Type Expressions


typedef *cell link; typedef struct S{ int x; link next; }cell Non possibile utilizzare equivalenza strutturale se ci sono cicli Il nome del tipo deve essere utilizzato come un tipo base

Conversioni di tipi
double x; int y; x+y quale il tipo di questa espressione (int o double)? Quale codice produce? inttofloat float+ y,,t1 t1,x,t2

02/02/2011

Azioni di controllo

Lattributo scope rappresenta linsieme di tutte le coppie che definiscono gli identificatori visibili in quel contesto

Sintassi
S while (E) S1 Condizioni if (E.type=int then S.type=S1.type else S.type=type-error Azioni di controllo E.scope = S.scope S1.,scope = S.scope

S id = E
Condizioni if (id.type=E.type then S.type=void else S.type=type-error Azioni di controllo E.scope = S.scope id. scope = S.scope S if (E) S1 Condizioni if (E.type=int then S.type=S1.type else S.type=type-error Azioni di controllo E.scope = S.scope S1.,scope = S.scope

02/02/2011

Visibilit e unicit degli identificatori


P { Blocco } Blocco LD LI Blocco.scope = P.scope P.oldscope = Blocco.oldscope LI.scope = Blocco.oldscope I.LD Blocco.corr= if (I.LD in Blocco.oldscope) false else Blocco.corr = LI.corr LD.scope = LD1.scope I.LD = I.D LD.scope = {} I.D = id

LD LD1 D LD D T id LI LI Is LI Is id = E

GENERAZIONE DI CODICE INTERMEDIO

10

02/02/2011

Intermediate Code Generation


Il codice intermedio sono indipendenti dal linguaggio macchina ma sono legati alle istruzioni macchina Il programma viene tradotto dal linguaggio sorgente in un programma equivalente in un linguaggio intermedio dal generarore di codice intermedio. Come linguaggio intermedio possono essere utilizzati diversi linguaggi:

Lalbero sintattico Una notazione postfissa postfix notation can be used as an intermediate language. three-address code (4-uple) Noi utilizzaremo un linguaggio costituito da 4-uple Il linguaggio delle 4-uple e simile al linguaggio macchina Talvolta I linguaggi di programmazione utilizzano linguaggi intermedi pi evoluti: java java virtual machine C# -clr prolog warren abstract machine

GENERAZIONE DI UN AST

11

02/02/2011

Intro

Vediamo adesso una tecnica che permette di effettuare analisi semantiche e traduzione usando la struttura sintattica data dalla grammatica di un linguaggio Lidea chiave quella di associare, ad ogni costrutto del linguaggio, alcune informazioni utili per il nostro scopo (attributi) Il valore di ogni attributo calcolato tramite regole semantiche associate con le produzioni della grammatica

Due notazioni a diversi livelli

Ci sono due diversi tipi di notazione per scrivere le regole semantiche:


1.

2.

Definizioni guidate dalla sintassi: sono specifiche di alto livello: nascondono i dettagli implementativi e non richiedono di specificare lordine di valutazione che la traduzione deve seguire Schemi di traduzione, invece, indicano lordine in cui le regole semantiche devono essere valutate e quindi permettono la specifica di alcuni dettagli di implementazione

12

02/02/2011

Il flusso concettuale

Dalla stringa di input viene costruito il parse tree e poi lalbero viene attraversato nella maniera adatta (data dal grafo delle dipendenze) per valutare le regole semantiche che si trovano sui nodi Come al solito, comunque, una reale implementazione non segue questo flusso concettuale, ma esegue tutto durante il parsing senza costruire il parse tree esplicitamente, n il grafo delle dipendenze

Definizioni guidate dalla sintassi

Possiamo pensare ad ogni nodo del parse tree come ad un record i cui campi sono i nomi degli attributi Ogni attributo pu rappresentare qualunque cosa vogliamo: stringhe, numeri, tipi, locazioni di memoria, etc. Il valore di ogni attributo ad ogni nodo determinato da una regola semantica associata alla produzione che si usa nel nodo

13

02/02/2011

Regole semantiche

La valutazione, nellordine giusto, delle regole semantiche determina il valore per tutti gli attributi dei nodi del parse tree di una stringa data La valutazione pu avere anche side-effects (effetti collaterali) come la stampa di valori o laggiornamento di una veriabile globale

Decorazioni

Un parse tree che mostri i valori degli attributi ad ogni nodo chiamato parse tree annotato Il processo di calcolo di questi valori si dice annotazione o decorazione del parse tree

14

02/02/2011

Assunzioni e convenzioni

In una definizione guidata dalla sintassi si assume che i simboli terminali abbiano solo attributi sintetizzati I valori per questi attributi sono in genere forniti dallanalizzatore lessicale Il simbolo iniziale, se non diversamente specificato, non ha attributi ereditati

Costruzione di AST

Vediamo come utilizzare le definizioni guidate dalla sintassi per specificare la costruzione degli alberi sintattici Luso degli alberi sintattici come rappresentazione intermedia divide il problema del parsing da quello della traduzione Infatti le routine di traduzione che vengono invocate durante il parsing hanno delle limitazioni

15

02/02/2011

Limitazioni
1.

2.

Una grammatica che sia adatta per il parsing potrebbe non riflettere la naturale struttura gerarchica dei costrutti del linguaggio Il metodo di parsing vincola lordine in cui i nodi del parse tree sono considerati e questo ordine pu non corrispondere con quello in cui linformazione sui costrutti diventa disponibile

Abstract Syntax Trees (AST)

Un albero sintattico (astratto) una forma condensata di un parse tree che utile per rappresentare i costrutti dei linguaggi Ad esempio, la produzione S if B then S1 else S2 potrebbe apparire in un albero sintattico come:
if-then-else B S1 S2

16

02/02/2011

Syntax trees

Negli alberi sintattici gli operatori e le parole chiave non appaiono come foglie, ma sono associati ad un nodo interno Inoltre unaltra semplificazione che le catene di applicazione di una singola produzione vengono collassate:
+ * 3 5 4

Syntax trees

La traduzione guidata dalla sintassi pu benissimo essere basata su alberi sintattici piuttosto che su parse tree Lapproccio sempre lo stesso: associamo degli attributi ai nodi dellalbero

17

02/02/2011

Costruzione di syntax tree (syntree)


Vediamo come costruire gli alberi sintattici per le espressioni aritmetiche: Costruiamo sottoalberi per le sottoespressioni creando un nodo per ogni operatore ed operando I figli di un nodo operatore sono le radici dei sottoalberi che rappresentano le sottoespressioni con le quali costruita lespressione principale Ogni nodo di un syntree pu essere implementato come un record con diversi campi

Costruzione di un syntree

In un nodo operatore un campo identifica loperatore stesso e i campi rimanenti son i puntatori ai nodi operandi Loperatore spesso chiamato letichetta del nodo Quando vengono usati per la traduzione, i nodi in un syntree possono avere campi addizionali per gli attributi che sono stati definiti

18

02/02/2011

Costruzione di un syntree

1.

2.

3.

In questo esempio usiamo le seguenti funzioni per costruire i nodi degli alberi sintattici per espressioni con operatori binari: mknode(op, left, right) crea un nodo operatore con etichetta op e due campi puntatore alloperando destro e sinistro mkleaf(id, entry) crea un nodo identificatore con etichetta id e puntatore entry alla tabella dei simboli mkleaf(num,val) crea un nodo numero con etichetta num e un campo val contentente il valore

Costruzione di un syntree

1) 2) 3) 4) 5)

Ad esempio il seguente frammento di programma crea (bottom-up) un syntax tree per lespresione a4+c p1 := mkleaf(id, entrya); p2 := mkleaf(num, 4); p3 := mknode(-, p1, p2); p4 := mkleaf(id, entryc); p5 := mknode(+, p3, p4);

19

02/02/2011

Syntree per a 4 + c

id Entrata per c

id Entrata per a

num

Usiamo una definizione

Diamo una definizione guidata dalla sintassi Sattributed per la costruzione dellalbero sintattico di una espressione contenente gli operatori + e Definiamo un attributo nptr per ogni simbolo non terminale. Esso deve tenere traccia dei puntatori ritornati dalle funzioni di creazione dei nodi

20

02/02/2011

Syntree
PRODUZIONI REGOLE SEMANTICHE E.nptr := mknode(+, E1.nptr, T.nptr) E.nptr := mknode(-, E1.nptr, T.nptr)

E E1 + T E E1 - T ET T (E) T id T num

E.nptr := T.nptr T.nptr := E.nptr T.nptr := mkleaf(id, id.entry) T.nptr := mkleaf(num, num.val)

Lalbero annotato
E.nptr E.nptr E.nptr T.nptr id id Entrata per a num 4 id Entrata per c + + T.nptr num T.nptr id

21

02/02/2011

GENERAZIONE DI CODICE A TRE INDIRIZZI

Three-Address Code (4.uple)

Una 4-uple : x := y op z

x, y e z sono nomi, costanti, elementi temporanei generati dal compilatore stesso op un operatore.

Nel seguito utilizzata la seguente notazione (4-uple) op y,z,x con il significato applica loperatore op a y e z, e restitutisci il risultato in x.

22

02/02/2011

Codice a tre indirizzi


una rappresentazione lineare di AST Un indirizzo pu assumere una delle seguenti forme
Nome

cio un nome di un identificatore (in un implementazione reale il puntatore alla tabella dei simboli) Una costante Un nome temporaneo generato dal compilatore

Istruzioni di un codice a tre indirizzi

Assegnamento
z

= x op y z = op y

(binario) (unario)

Copia
x

=y

23

02/02/2011

Three-Address: istruzioni
Operatori binari: op y,z,result Dove op un operatore binario o logico. Ex: add a,b,c gt a,b,c addr a,b,c addi a,b,c Unary Operator: op y,,result Dove op un operatore binario o logico. Ex: uminus a,,c not a,,c inttoreal a,,c

Three-Address:istruzioni
Move Operator: mov y,,result
il contenuto di y e copiato in result. Ex: mov a,,c movi a,,c movr a,,c

Unconditional Jumps: jmp ,,L


salto allistruzione di etichetta L Ex: jmp ,,L1 // salto a L1 jmp ,,7 // salto allistruzione 7

24

02/02/2011

Three-Address Statements (cont.)


Conditional Jumps: jmprelop y,z,L
salta allistruzione con etichetta L se il risultato di y relop z vero.Se il risultato false continua con listruzione seguente

Ex:

jmpgt jmpgte jmpe jmpne

y,z,L1 y,z,L1 y,z,L1 y,z,L1

// jump to L1 if // jump to L1 if // jump to L1 if // jump to L1 if

y>z y>=z y==z y!=z

oppure jmpnz jmpz jmpt jmpf y,,L1 y,,L1 y,,L1 y,,L1 // jump to L1 se y == 0 // jump to L1 if y != 0 // jump to L1 if y == true // jump to L1 if y == false

Altre istruzione
Parametri di Procedure : Chiamata di Procedure : param x,, call p,n,
dove x un parametre attuale Ex: param x1,, param x2,, p(x1,...,xn) param xn,, call p,n, f(x+1,y) add param param call x,1,t1 t1,, y,, f,2,

25

02/02/2011

Indexed Assignments: move y[i],,x con il significato x = y[i] move x,,y[i] con il significato y[i] = x Address and Pointer Assignments: moveaddr y,,x con il significato x = &y movecont y,,x con il significato x = *y

Esempio di traduzione

Do i = i + 1 While (a[i]<v)

1. 2. 3.

4. 5.

Add i ,1 , t1 move t1, ,i Mult i, 8, t2 //dimenz move a[t2],,t3 Jump t3<v goto 1

26

02/02/2011

Implementazione di un codice a tre indirizzi

Quadrule
Quattro
Gli

campi op arg1 arg2 result

operatori unari e di copia non utilizzano arg Le istruzioni come param non usano ne arg2 ne result Le istruzioni di salto salvano letichetta in result

Per generare il codice nella forma a tre indirizzi dal codice sorgente noi utilizzaremo un approccio basato sulle grammatiche ad attributi. Esempio: le espressioni: Attributi: S ha un attributo "code contiene il frammento di codice E ha due attributi: code - contiene il frammento di codice

place e il nome che daremo al valore corrispondente a E

La notazione <fragment> || expr rappresenta la concatenazione dellespressione nel frammento di codice

27

02/02/2011

Esempi di traduzione
S id := E E E1 + E2
S.code = E.code || gen(mov E.place ,, id.place) E.place = newtemp(); E.code = E1.code || E2.code || gen(add E1.place , E2.place , E.place)

E E1 * E2

E.place = newtemp();
E.code = E1.code || E2.code || gen(mult E1.place , E2.place , E.place)

E - E1 E ( E1 ) E id

E.place = newtemp(); E.code = E1.code || gen(uminus E1.place ,, E.place) E.place = E1.place; E.code = E1.code E.place = id.place; E.code = null

a := b * c + b * -c
S a := E3n E1n * E2n E8n + E7n E4n * E6n

E5n
c

28

02/02/2011

Costruzione degli attributi


place E1n E2n E3n E4n E5n E6n E7n b c t1 E1n.code || E2n.code || t1 := b * c code

b
c t2 t3 E5n.code || t2 := uminus c E4n.code || E6n.code || t3 := b * t2

Traduzione Syntax-Directed
S while (E) do S1
S.begin = newlabel(); S.after = newlabel(); S.code = gen(S.begin :) || E.code || gen(jmpf E.place ,, S.after) || S1.code || gen(jmp ,, S.begin) || gen(S.after :)

S if (E) S1 else S2 S.else = newlabel();


S.after = newlabel(); S.code = E.code || gen(jmpf E.place ,, S.else) || S1.code || gen(jmp ,, S.after) || gen(S.else :) || S2.code || gen(S.after :)

29

02/02/2011

Looking up the Symbol Table


S id = E { p= lookup(id.name); if (p is not nil) then emit(mov E.place ,, p) else error(undefined-variable) } E E1 + E2 { E.place = newtemp(); emit(add E1.place , E2.place , E.place) } E E1 * E2 { E.place = newtemp(); emit(mult E1.place , E2.place , E.place) } E - E1 { E.place = newtemp(); emit(uminus E1.place ,, E.place) } E ( E1 ) { E.place = E1.place; } E id { p= lookup(id.name); if (p is not nil) then E.place = id.place else error(undefined-variable) }

res := a * (alpha + -b)


Assumiamo che res, a, alpha e b siano stata gia dicharate e poste Nella tabella rei simboli lexptr : ->res ->a ->alpha ->b token : ID_T ID_T ID_T ID_T attributes : index : 5 6 7 8

30

02/02/2011

processed string res := a res :=E res :=E res :=E res :=E res :=E res :=E
1 1 1 1 1 1

attributes

output

E .place = <6>
1

* (alpha * (E * (E + -b * (E + -E * (E + E
2 2 2 2 4 5

E .place = <7>
2

E .place = <8>
3

res :=E * (E
1 1

E .place = <9>
4

<9> := uminus<8> <10> := <7>+<9>

res :=E * (E )
5

E .place = <10>
5

res :=E * E
1

Three Address Codes - Example


x:=1; y:=x+10; while (x<y) { x:=x+1; if (x%2==1) then y:=y+1; else y:=y-2; } 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: mov add mov lt jmpf add mov mod eq jmpf add mov jmp sub mov jmp 1,,x x,10,t1 t1,,y x,y,t2 t2,,17 x,1,t3 t3,,x x,2,t4 t4,1,t5 t5,,14 y,1,t6 t6,,y ,,16 y,2,t7 t7,,y ,,4

31

02/02/2011

Arrays

GLi elementi di arrays possono essere recuperati rapidamente se gli elementi sono memorizzati in blocchi consecutivi.

Array monodimenzionali A

baseA lindirizzo della prima locazione dellarray A, width la dimenzione di un elemento dellarray. low lindice del primo elemento dellarray La locazione del generico elemento A[i] baseA+(i-low)*width

Arrays (cont.)
baseA+(i-low)*width Pu essere riscritto come i*width + (baseA-low*width)
Dovrebbe essere calcolato a run-time. e si vuole accedere ad A[i] la formula i*width+c sara calcolata a run time ma c = (baseA-low*width) pu essere calcolato a compile-time. Il generatore di codice intermedio deve comunque produrre il codice per valutare la formula i*width+c.

32

02/02/2011

Array bidimenzionali

Un array a due dimenzioni pu essere memorizzato


per righe (row-major) per colonne (column-major)

La maggior parte dei linguaggi di programmazione utilizzano il metodo row-major.

Address_of _A[i1,i2] =

baseA+ ((i1-low1)*n2+i2-low2)*width

baseA lindirizzo della prima locazione dellarray A, width la dimenzione di un elemento dellarray low1 lindice della prima riga low2 lindice della prima colonna n2 il numero di elementi in una riga

La formula pu essere riscritta


((i1*n2)+i2)*width + (baseA-((low1*n1)+low2)*width)

Schema di traduzione per un Array


Grammatica per gli array G1 (richiede attributi ereditati). L id L id [ Elist ] Elist Elist , E Elist E

G2 (solo attributi sintetizzati) L id L Elist ] Elist Elist , E Elist id [ E

33

02/02/2011

Schema di traduzione per un Array


L id { L.place = id.place; L.offset = null; } L Elist ] { L.place = newtemp(); L.offset = newtemp(); emit(mov c(Elist.array) ,, L.place); emit(mult Elist.place , width(Elist.array) , L.offset) } Elist Elist1 , E { Elist.array = Elist1.array ; Elist.place = newtemp(); Elist.ndim = Elist1.ndim + 1; emit(mult Elist1.place , limit(Elist.array,Elist.ndim) , Elist.place); emit(add Elist.place , E.place , Elist.place); } Elist id [ E {Elist.array = id.place ; Elist.place = E.place; Elist.ndim = 1; }

Schema di traduzione per un Array Esempio1

A : array [5..100 ] of double n1=95 width=8 (double) low1=5

Codice intermedio per mov mult mov c,,t1 y,8,t2 t1[t2],,t3

x := A[y] // dove c=baseA-(5)*8

mov

t3,,x

34

02/02/2011

Schema di traduzione per un Array Esempio2

A : array [1..10,1..20] of integer n1=10 n2=20 width=4 (integers) low1=1 low2=1

Codice intermedio per x := A[y,z] mult add mov mult mov mov y,20,t1 t1,z,t1 c,,t2 t1,4,t3 t2[t3],,t4 t4,,x // where c=baseA-(1*20+1)*4

Dichiarazioni
PMD M DD;D D id : T { enter(id.name,T.type,offset); offset=offset+T.width } T int { T.type=int; T.width=4 } T real{ T.type=real; T.width=8 } T array[num] of T1 { T.type=array(num.val,T1.type); T.width=num.val*T1.width } T T1 { T.type=pointer(T1.type); T.width=4 } Dove enter crea una tabella dei simboli per un dato valore { offset=0 }

35

02/02/2011

Nested Procedure Declarations

Per ogni sottoprogrmma deve esserecreata una tabella dei simboli.

mktable(previous) crea una nuova tabella dei simboli dove previous la tabella dei simboili che ha generaro la nuova tabella. enter(symtable,name,type,offset) crea un nuovo elemento per una variabile in una data tabella dei simboli. enterproc(symtable,name,newsymbtable) crea un nuovo elemento per un sottoprogramma nella tabella dei simboli dei suoi genitoti. addwidth(symtable,width) pone la dimenzione di tutte gli elementi nella tabella dei simboli nell header della tabella.

Utilizzaremo due pile:


tblptr memorizza I puntatori dalla tabella dei simboli offset memorizza loffsets corrente nella tabella dei simbili nella pila tblptr

Nested Procedure Declarations


PMD M DD;D D proc id N D ; S { t=top(tblptr); addwidth(t,top(offset)); pop(tblptr); pop(offset); enterproc(top(tblptr),id.name,t) } D id : T { enter(top(tblptr),id.name,T.type,top(offset)); top(offset)=top(offset)+T.width } N { t=mktable(top(tblptr)); push(t,tblptr); push(0,offset) } { addwidth(top(tblptr),top(offset)); pop(tblptr); pop(offset) } { t=mktable(nil); push(t,tblptr); push(0,offset) }

36

02/02/2011

Chiamata di sottoprogrammi

Valuta gli argomenti e li memorizza in una posizione conosciuta Genera I valori dei puntatori per accedere ai dati Salva lo stato della procedura chiamante Salva lindirizzo di ritorno e salta al codice della procedura chiamata Alla fine (return) richiama e salva qualsiasi valore di ritorno

Schema di traduzione
1) S call id (Elist) {for each item p on queue do emit (param p); emit (call id.place)} 2) Elist Elist .E {append E.place to the end of queue} 3) Elist E {inizilie queue to contein only E.place}

37

Vous aimerez peut-être aussi

  • L15
    L15
    Document36 pages
    L15
    Marco Deezy Di Sano
    Pas encore d'évaluation
  • L14
    L14
    Document28 pages
    L14
    Marco Deezy Di Sano
    Pas encore d'évaluation
  • L10
    L10
    Document29 pages
    L10
    Marco Deezy Di Sano
    Pas encore d'évaluation
  • L09
    L09
    Document48 pages
    L09
    Marco Deezy Di Sano
    Pas encore d'évaluation
  • L12
    L12
    Document39 pages
    L12
    Marco Deezy Di Sano
    Pas encore d'évaluation
  • L06
    L06
    Document55 pages
    L06
    Marco Deezy Di Sano
    Pas encore d'évaluation
  • L08
    L08
    Document10 pages
    L08
    Marco Deezy Di Sano
    Pas encore d'évaluation
  • L07
    L07
    Document16 pages
    L07
    Marco Deezy Di Sano
    Pas encore d'évaluation
  • L05
    L05
    Document23 pages
    L05
    Marco Deezy Di Sano
    Pas encore d'évaluation
  • L02
    L02
    Document38 pages
    L02
    Marco Deezy Di Sano
    Pas encore d'évaluation