Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




Expresii aritmetice. Evaluare si generarea codului

Informatica


Expresii aritmetice. Evaluare si generarea codului

Ne vom ocupa de expresiile aritmetice în care intervin operatorii binari , , , si cuprinderea între paranteze. Vom considera ca expresiile cu care lucram sunt corecte.



Pentru simplificare, vom presupune ca variabilele care apar în expresii sunt litere.

Scopul propus consta în evaluarea expresiilor (presupunând ca variabilele au valori stabilite 737b13h oarecare) si în generarea codului corespunzator expresiei, într-un limbaj de asamblare ad-hoc.

stim ca:

o expresie este o "suma" de termeni (între care intervin numai operatorii de adunare si scadere);

un termen este un "produs" de factori (între care intervin numai operatorii de înmultire si împartire);

un factor este fie o variabila, fie o expresie între paranteze.

Gramatica independenta de context corespunzatoare, cu simbolul initial E, este:

E T+E | T-E | T

X l

T T*F | T/F | F

F litera | (E)

Primul pas în rezolvarea problemelor enuntate consta în constructia arborelui binar atasat expresiei.

Exemplu. Expresiei aritmetice ((a-b)*(a+c))/(d-(e+f)) îi corespunde arborele:

unde etichetele vârfurilor sunt et=(/,*,-,-,+,d,+,a,b,a,c,e,f)

Vom prezenta un program Java care construieste direct acest arbore; la intrare poate sa apara orice exprsie aritmetica (cu conditia sa fie corecta) urmata de un caracter ce nu apartine gramaticii.

Generarea codului pentru expresii aritmetice

Presupunem ca nu avem restrictii de memorie (deci putem introduce oricâte variabile suplimentare) si ca dispunem de un registru r pentru efectuarea operatiilor. Instructiunile disponibile si semnificatiile lor sunt urmatoarele:

LOAD x   r ← x

STORE x r → x

x  r ← r x, unde

Observam ca toate instructiunile au doua câmpuri.

Se considera ca toate aceste instructiuni necesita acelasi timp de executare.

Nu vom lua în considerare nici una dintre proprietatile algebrice ale operatiilor (comutativitate, asociativitate, distributivitate), nici posibilitatea reducerilor unor termeni si nici eventuala aparitie a unor subexpresii care se repeta.

Dorim sa construi un un cod (o succesiune de instructiuni de tipurile de mai sus), a carui executare sa aduca în registrul r valoarea expresiei aritmetice. Dorim de asemenea ca acest cod sa fie optim adica sa fie format dintr-un numar minim de instructiuni.

Observatie În orice cod neredundant:

numarul de instructiuni de tipul 3) este egal cu numarul vârfurilor interne, deci cu numarul operatorilor ce apar în expresie; prin urmare acest numar este fix;

orice instructiune LOAD, afara de prima, este precedata imediat de o instructiune STORE. Codul începe cu o instructiune LOAD.

Cu alte cuvinte, numarul instructiunilor LOAD este mai mare cu o unitate decât cel al instructiunilor STORE: LOAD)=#(STORE)+1. De aceea un cod optim este un cod cu un numar minim de instructiuni STORE .

Este evident ca pentru construirea codului, arborele trebuie parcurs în postordine.

Atasam fiecarui vârf x codul Cx în care în prima instructiune lipseste câmpul LOAD

Vârfurilor terminale (frunzelor) x le atasam codul: _ et(x)

Pentru vârfurile neterminale x vom folosi codurile atasate subarborelui stâng st si subarborelui drept dr. Deosebim urmatoarele cazuri:

daca descendentul drept al lui x este o frunza, codul Cx va fi:

Cst

et(x) Cdr

daca descendentul drept al lui x nu este o frunza, se observa ca este mai convenabil (din punctul de vedere al numarului de instructiuni) sa începem cu evaluarea subarborelui drept:

Cdr

STORE T

LOAD Cst

et(x) T

unde T este o variabila suplimentara.

Variabilele suplimentare vor fi notate cu Tk, unde k este initial si creste cu o unitate la fiecare constructie a unui nou cod pentru un vârf al carui descendent drept nu este o frunza.

Pentru exemplul considerat mai sus obtinem succesiv:

C a

C b

C a

- b

C a

C c

C a

+ c

C a

+ c

STORE T1

LOAD a

- b

* T1

C d

C e

C f

C e

+ f

C e

+ f

STORE T2

LOAD d

- T2

C e

+ f

STORE T2

LOAD d

- T2

STORE T3

LOAD a

STORE T1

LOAD a

- b

* T1

/ T3

Programul în Java

Constructia arborelui urmeaza întocmai definitia expresiilor aritmetice: va fi scrisa câte o metoda pentru expresie, termen si factor.

Fiecare vârf (obiect de tipul clasei varf) are câmpurile st dr si et desemnând respectiv descendentul stâng, cel drept si eticheta sa.

Se presupune ca variabilele sunt litere mici de la începutul alfabetului.

Mai este folosita o variabila ch care joaca rolul unui "spion" catre caracterul urmator din expresie.

Vom folosi asociativitatea la stânga a operatorilor. De exemplu daca un termen începe cu un "produs" de factori pentru care am construit arborele de radacina x si urmeaza un factor pentru care am construit obiectul y x va deveni descendent stâng al lui y, care va fi radacina noului arbore corespunzator termenului:

import java.util.*;

class Expresie

class varf

varf(char e)

varf factor()

else

return x;

}

varf termen()

return x;

}

varf expresie()

return x;

}

String cod(varf x)

Mai ramâne de demonstrat optimalitatea codului obtinut în modul descris mai sus.

Propozitie În orice cod atasat unui arbore binar, #(STORE) este cel putin egal cu numarul vârfurilor al caror descendent drept nu este frunza.

Vom face demonstratia prin inductie dupa numarul n al vârfurilor din arbore.

Pentru n=1, afirmatia este evident adevarata.

Presupunem afirmatia din enuntul propozitiei adevarata pentru orice arbore cu cel mult n vârfuri si consideran un arbore cu n+1 vârfuri.

Daca descendentul drept al radacinii este o frunza, atunci numarul vârfurilor al caror descendent drept nu este frunza coincide cu numarul vârfurilor din subarborele stâng al caror descendent drept nu este frunza; cum acest subarbore are cel mult n vârfuri, putem aplica ipoteza de inductie.

Daca descendentul drept al radacinii nu este o frunza, atunci fie:

n= numarul vârfurilor din arbore al caror descendent drept nu este frunza;

s= numarul de instructiuni STORE din codul atasat arborelui;

n1= numarul vârfurilor din subarborele stâng al caror descendent drept nu este frunza;

s1= numarul de instructiuni STORE din codul atasat subarborelui stâng;

n2= numarul vârfurilor din subarborele drept al caror descendent drept nu este frunza;

s2= numarul de instructiuni STORE din codul atasat subarborelui drept.

Conform ipotezei de inductie avem: s1 n1 si s2 n2. Evident, n=n1+n2+1. Pe de alta parte în codul atasat arborelui mai trebuie introdusa cel putin o instructiune STORE, deci s s1+s2+1. Rezulta s n1+n2+1=n

Optimalitatea algoritmului prezentat rezulta acum din faptul ca el introduce o noua instructiune STORE numai pentru vârfurile al caror descendent drept nu este o frunza.


Document Info


Accesari: 1406
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2024 )