Tabela de simboluri Masina virtuala
Analiza tipurilor




Obtinerea informatiilor de tip

Informatiile de tip se extrag in decursul analizei declaratiilor si a expresiilor si pot fi considerate ca atribute atasate simbolurilor gramaticale implicate in declaratii si expresii. Obtinerea propriu-zisa a acestor informatii are loc fie prin preluarea lor din TS, fie prin receptarea lor de la analizorul lexical, in momentul detectarii terminalelor identificator sau constanta.

Transmiterea informatiilor de tip spre punctele din analizorul sintactic unde urmeaza sa se execute rutine de analiza semantica se poate realiza prin intermediul:

Realizarea analizei semantice pentru limbajul descris in Anexa B impune atasarea la anumite neterminale (cum ar fi: Expresie, Termen, Factor, Variabila etc) a urmatoarelor atribute:
a. Atrib_tip - indica tipul (simplu) pe care il are o constanta, o variabila sau o expresie. Valoarea acestui atribut poate fi: 'intreg', 'real' sau 'caracter'.
b. Atrib_lvalue - poate lua una din valorile: 'adresa ' sau 'valoare', indicand daca o anumita expresie are atasata o adresa stabila de memorie (expresia este formata dintr-o variabila declarata in sectiunea var, sau dintr-un parametru formal declarat cu var), respectiv daca expresia reprezinta un rezultat intermediar, aflat temporar in memorie. Acest atribut este necesar pentru verificari ale parametrilor, in cazul apelurilor de subprograme. El permite detectarea situatiilor in care unui parametru formal declarat cu var (transmis prin adresa) ii corespunde un parametru real care nu are o adresa stabila (nu este o expresie l-value, daca ar fi sa folosim terminologia din limbajul C). Exemplu:
var A : integer;
procedure P (var X : integer);
begin
X := . . .
end; { P }
begin {program principal}
P(12); {1}
P( A + 2 ); {2}
P(A); {3}
end.
In secventa de mai sus apelurile din liniile notate cu {1} si {2} sunt incorecte din punct de vedere al modului de transmitere a parametrilor, in timp ce apelul din linia {3} este corect.
Dupa cum se vede, am convenit ca valorile atributului Atrib_lvalue sa fie aceleasi cu cele ale campului 'tip_transmisie' din nodurile listei LISTA_PAR din TS, pentru a usura rutina de verificare a parametrilor (v. Apeluri de subprograme si Factori).

c. Atrib_val - se foloseste in cazul declaratiilor de constante (sectiunea const) si indica valoarea atribuita unei constante. O asemenea valoare este calculabila la compilare si se obtine prin evaluarea unei expresii statice (v. Evaluarea expresiilor statice).

Reguli semantice referitoare la concordanta tipurilor

In cele ce urmeaza vom adopta urmatoarele conventii legate de tipuri:
 

Expresii relationale
 
E1 oprel E2

Regula este:

{ Atrib_tip(E1), Atrib_tip(E2) }{ 'intreg', 'real' } sau
Atrib_tip(E1) = Atrib_tip(E2) = 'caracter'

Tipul rezultatului unei expresii relationale va fi:

Atrib_tip(E1oprel E2) = 'intreg'

(convenim ca rezultatul unei expresii relationale este 1 sau 0, dupa cum relatia definita de oprel este sau nu satisfacuta ).
 
Expresii aditive
 

E1 opad E2

Regula este:

{ Atrib_tip(E1), Atrib_tip(E2)} { 'intreg', 'real' }

Tipul rezultatului este:

      if Atrib_tip(E1) = Atrib_tip(E2) then
        Atrib_tip(E1 opad E2) = Atrib_tip(E1)
      else
        Atrib_tip(E1 opad E2) = 'real'
      endif

 
Expresii multiplicative
E1 opmul E2

Regula este:

    if opmul in {div, mod} then
      *trebuie ca Atrib_tip(E1) = Atrib_tip(E2) = 'intreg'
    else
      *trebuie ca {Atrib_tip(E1), Atrib_tip(E2)}{'intreg', 'real'}
    endif
Tipul rezultatului este:
    if opmul in {div, mod} then
      Atrib_tip(E1 opmul E2) = 'intreg'
    else
      if opmul = '/' then
        Atrib_tip(E1 opmul E2) = 'real'
      else
      endif
    endif
Facem conventia ca , in cazul utilizarii operatorului '/' (impartire reala) pentru operanzi intregi, acestia sa fie convertiti la tipul real.
 
Operatii de atribuire
 

V := E

Regula este:

( Atrib_tip(V) = Atrib_tip(E) sau
( Atrib_tip(V) = 'real' si Atrib_tip(E) = 'intreg' ) ) si
( Atrib_lvalue(V) = 'adresa' )

Se face conventia ca daca tipul membrului stang este 'real' si tipul membrului drept este 'intreg', acesta din urma se converteste la tipul 'real'.
 

Instructiunea for
for V := E1 to/downto E2 step E3 do I

Regula este ca

(Atrib_tip(V) = Atrib_tip(E1) = Atrib_tip(E2) = Atrib_tip(E3) = 'intreg') si
Atrib_lvalue(V) = 'adresa'

Variabile indexate
id[E]

Daca notam cu loc_id locul in TS ocupat de simbolul id, regula este:

TS[loc_id].CLASA = 'nume de tablou' si Atrib_tip(E) = 'intreg'.

Tipul unei variabile indexate este :

Atrib_tip( id[E] ) = TS[loc_id].TIP.

Declaratii de tablouri
array [E1 .. E2] of T

Regula este:

Atrib_tip(E1) = Atrib_tip(E2) = 'intreg' si
Atrib_val(E1) <= Atrib_val(E2)
Referinte ale campurilor de structuri
id1. id2

Daca notam cu loc1, respectiv cu loc2 pozitiile din TS ocupate de id1 si id2, atunci regula este:

TS[loc1].CLASA = 'nume de structura ' si
TS[loc2].CLASA = 'nume de camp' si
exista un nod in TS[loc2].LISTA_REC care face trimitere spre loc1

Tipul unei asemenea variabile va fi:

Atrib_tip( id1. id2 ) = TS[loc2].TIP.

 
 
Apeluri de subprograme
id ( E1, E2, . . . , En )

Notand cu loc_id locul din TS ocupat de id, se vor impune urmatoarele conditii:

  • TS[loc_id].CLASA = 'nume functie' sau 'nume procedura ', dupa cum apelul apare intr-o expresie, respectiv intr-o instructiune apel de procedura;
  • TS[loc_id].NR_PAR = n;
  • Atrib_tip(Ei) = TS[loc_id].LISTA_PARi.tip_param sau
    (Atrib_tip(Ei) = 'intreg' si TS[loc_id].LISTA_PARi.tip_param ='real' si TS[loc_id].LISTA_PARi.tip_transmisie = 'valoare' ), pentru i = 1 . . n.
    Se precizeaza ca LISTA_PARi reprezinta nodul de pe pozitia i, din lista LISTA_PAR.
  • Atrib_lvalue(Ei) = TS[loc_id].LISTA_PARi.tip_transmisie, pentru i = 1 . . n.
Convenim ca, in cazul in care un parametru formal este de tip 'real', iar parametrul de apel corespunzator este de tip 'intreg', valoarea acestuia din urma sa fie convertita la tipul 'real'.

In cazul apelurilor de functii tipul rezultatului va fi:

Atrib_tip( id( E1, E2, . . . , En )) = TS[loc_id].TIP

Instructiunea case
Verificarea semantica are loc practic pe durata analizei expresiilor si presupune completarea si testarea atributelor mentionate in acest paragraf. In plus, in cazul expresiilor statice se efectueaza si evaluarea.

In cele ce urmeaza , partea de analiza a expresiilor va fi prezentata utilizand inserarea de marcaje in productiile gramaticale si indicand actiunile semantice corespunzatoare.
 

Evaluarea expresiilor statice

Se realizeaza prin intermediul atributului Atrib_val. Productiile implicate sunt cele care decurg din simbolul Sectiune_const.
 

Expresii aditive
E1 opad E2

Atrib_val( E1 opad E2 ) = Atrib_val(E1) opad Atrib_val(E2)

Expresii multiplicative
E1 opmul E2

Determinarea lui Atrib_val se face ca la Expresii aditive, inlocuind opad cu opmul. In cazul impartirilor se vor face verificari pentru a evita impartirea cu 0.

Factori statici
FS -> id | const | ( E )

Daca factorul este o constanta , atunci Atrib_val ia valoarea constantei respective (memorata in TAB_CONST).

Daca factorul este un identificator, atunci se verifica daca TS[loc_id].CLASA = 'nume constanta ' (unde loc_id este locul din TS ocupat de identificator) si daca da, atunci Atrib_val(F) = TAB_CONST[TS[loc_id].VAL ].

Daca factorul este o expresie intre paranteze, atunci Atrib_val(F) = Atrib_val(E).
 

Pozitionarea marcajelor si tratarea acestora pentru evaluarea expresiilor statice sunt explicate pe larg in Anexa D.
 

Analiza expresiilor
 

Atribuiri
Instr_atrib -> Variabila := Expresie1
Variabila -> identificator1 |
                    identificator2 [Expresie2 ] |
                    identificator3 . identificator4


Notand cu tipv si tipe_i valorile lui Atrib_tip determinate pentru Variabila, respectiv pentru Expresiei (i=1..2), avem:


 
 


 
 

Expresii multiplicative

Se trateaza in mod similar cu cele aditive, aplicand insa regulile enuntate pentru operatiile multiplicative
 

Factori

Notam cu :


 

Stabilirea marcajelor si a rutinelor aferente pentru analiza tipurilor la instructiunile for si case este propusa studentilor ca exercitiu
 
 

Desfasurarea lucrarii

Dupa modelul procedurilor prezentate in capitolul Analiza expresiilor si in Anexa D, se va completa compilatorul realizat pana acum cu rutinele de analiza a tipurilor. In vederea testarii se vor alege texte sursa care sa contina in principal definitii si referiri de constante, atribuiri, apeluri de subprograme, expresii de diverse grade de complexitate, instructiuni for. Pentru aceste categorii sintactice se vor tipari informatii legate de atributele Atrib_tip, Atrib_lvalue si Atrib_val, precum si mesaje privind eventualele erori semantice semnalate la analiza de tip.
Pentru a realiza integrarea rutinelor semantice cu analizoarele sintactice realizate in lucrarile anterioare se vor utiliza modelele prezentate in Anexa D.

Tabela de simboluri Masina virtuala