introducere in teoria compilatoarelor

Upload: bogdana-corcoz

Post on 04-Mar-2016

17 views

Category:

Documents


1 download

DESCRIPTION

Introducere in teoria compilatoarelor

TRANSCRIPT

Compilatoare

INTRODUCERE

Teoria CompilatoarelorBogdana Corcoz

Informatica, An. III

CUPRINS:1. Introducere i istorie

1.1 Tipuri de compilatoare

1.2 Design-ul compilatorului

1.3 Principalele componente ale unui compilator2. Derularea procesului de compilare3. Descrierea BNF (Backus-Naur Form) a gramaticii unui limbaj4. Descrierea EBNF (Extended BNF)

5. Procesul de Generare cod intermediar

6. Analiza Sintactica

6.1 Parser6.2 Tipuri de Parser

7. Arborele sintactic

7.1 Proiectarea unui arbore sintactic

Concluzii

1.Introducere i istorie

Un compilator este un program (sau un set de programe) care transform codul surs scris ntr-un limbaj de programare (limbaj surs) ntr-un alt limbaj (limbaj int, care au adesea un format binar cunoscut sub numele de codul obiect).

Mesaje de eroare

Limbajul surs este ntotdeauna un limbaj de nivel superior, n comparaie cu codul main, limbajul de asamblare fiind cel mai puin compatibil limbaj(asamblorul fiind un caz special de compilator care traduce limbajul de asamblare n codul main). Limbajele de nivel superior sunt cele mai complexe, nu numai pentru c acestea cresc nivelul de abstractizare ntre codul surs i codul main rezultat, ci pentru c creterea complexitii este necesar pentru a formaliza aceste structure abstracte.

Limbajul int este n mod normal un limbaj de nivel sczut (cum ar fi limbajul de asamblare), scris cu abrevieri oarecum criptice pentru instruciunile main, n acest caz rulnd, de asemenea, un limbaj de asamblare pentru a genera codul main final. Dar unele compilatoare pot genera direct codul main pentru un computer real sau virtual, de exemplu, byte-code pentru Java Virtual Machine.

Cele mai multe compilatoare traduc codul surs ntr-un limbaj de nivel nalt fa de codul obiect sau limbajul main, care pot fi executate direct de ctre un calculator sau o main virtual. Cu toate acestea, traducerea de la un limbaj de nivel sczut la un nivel nalt este, de asemenea, posibil; acest lucru este, n mod normal, cunoscut c un decompilator n cazul n care se reconstruiete un program de limbaj de nivel nalt, care ar fi generat programul de limbaj de nivel sczut. Exist, de asemenea, compilatoare care traduc de la un limbaj de nivel nalt la altul (compilatoare cross), sau, uneori, la un limbaj intermediary care are nc nevoie de o prelucrare ulterioar; acestea sunt cunsocute sub numele de cascaders.

Compilatoarele de ieire, aa numitele obiecte care conin practice codul main cu informaii despre numele i amplasarea de pucte de intrare i apeluri externe (pentru funcii care nu sunt cuprinse n obiect). Un set de fiiere obiect, care nu a fost nevoie s aparin aceluiai compilator, cu condiia c compilatoarele folosite s aib un format de ieire comun, poi fi legate mpreun pentru a cre executabilul final, care poate fi rulat direct de ctre un utilizator.

Mai multe compilatoare experimentale au fost dezvoltate n anii 1950, dar echipa FORTRAN condus de John Backus de la IBM a fost cunoscut c fiind cea care a introdus primul compilator complet n 1957. COBOL a fost un limbaj care a fost compilat pe mai multe arhitecturi, n 1960.

Ideea de compilare a prins repede, iar cele mai multe dintre principiile de design de compilare au fost dezvoltate n anii 1960.

Un compilator este el nsui un program scris ntr-un limbaj de implemetare. Vechile compilatoare au fost scrise n limbaje de asamblare. n timpul anilor 1990, un numr mare de compilatoare i instrumente de dezvoltare ale compilatoarelor au fost dezvoltate pentru toate tipurile de limbaje, fcnd parte att din proiectul GNU, ct i din alte iniiative open-source.

1.1 Tipuri de compilatoare

Un compilator poate produce un cod destinat s ruleze pe acelai tip de calculator i cu un acelasi sistem de operare. Acesta este denumit ca fiind un compilator native-cod. Alternativ, poate produce un cod destinat s ruleze pe o platforma diferit i poart denumirea de compilator cross. Compilatoarele cross sunt foarte utile atunci cnd platforma hardware este nou.

Compilatorul sursa la sursa este un tip de compilator care are un limbaj de nivel nalt. De exemplu, un compilator paralel va lua un program de limbaj nalt ca i intrare i apoi va transfroma codul i l va adnota cu nsemnri de cod paralel (exemplu OpenMP).

Compilatorul cross poate fi considerat un program de cutare de baze de date. Acesta doar nlocuiete irurile de caractere din surs cu codul binar dat. Nivelul acestui cod binar poate varia; de fapt, unele compilatoare FORTH pot compila programe care nici mcar nu au nevoie de un sistem de operare.

CompilatorulIncremental - funciile individuale pot fi compilate ntr-un mediu run-time, care include, de asemenea, funcii de interpretat.

Compilatorul Just-n-time - cererile sunt livrate n bytecode, ce sunt compilate n codul main nativ chiar nainte de execuie. CompilatorulRetargetable - un compilator care poate fi relativ uor de modificat pentru a genera codul pentru diferite arhitecturi de CPU. Codul obiect produs de acesta este adesea de calitate mai mic dect cel produs de un compilator dezvoltat special pentru un procesor. Aceste tipuri de compilatoare sunt de asemenea i compilatoare cross. GCC este un exemplu.

1.2Design-ul compilatorului

n trecut, compilatoarele au fost mprite n mai multe moduri (passes) pentru a economisi spaiu. Un pass n acest context, este o rulare a compilatorului prin codul surs al programului care trebuie s fie compilat, avnd ca rezultat obinerea complet a datelor interne ale compilatorului. La final, compilatorul poate elibera spaiul de date intern rezultat. Metoda de compilaremultipass a fost o metod de compilare utilizat n acel moment i din cauza memoriilor mici ale calculatoarelor gazd n raport cu codul surs i cu datele.

Multe compilatoare moderne au un design comunin dou etape. Front end-ul translateaz limbajul surs ntr-o reprezentare intermediar. A doua etap este back end-ul, care funcioneaz ca o reprezentare pe plan intern pentru a produce un cod n limbajul de ieire. Front end-ul i back end-ul pot funciona ca passes diferite, sau front end-ul poate apela back end-ul ca o subrutin. Aceast abordare accentueaza complexitatea, separnd preocuprile front end-ului, care graviteaz de obicei n jurul semanticii limbajului, verificrii erorilor, de preocuprile back end-ului care se concentreaz pe ieire, ceea ce este att eficient ct i corect. De asemenea, are avantajul de a permite utilizarea unui singur back end pentru mai multe limbaje surs i permite n mod similar utilizarea de diferite back end-uri pentru obiective diferite.

Anumite limbaje, datorit design-ului limbajului i a anumitor reguli, introduc n declararea variabilelor i alte obiecte utilizate, precum i declararea de proceduri executabile anterior referinei, ce sunt capabile de a fi compilate ntr-un singur pass. Limbajul de programare Pascal este bine cunoscut pentru aceast capacitate i, de fapt, multe compilatoare Pascal sunt scrise n limbajul Pascal din cauza specificaiilor rigide ale limbajului i capacitii de a folosi un singur pass pentru a compila programe care au folosit limbajul Pascal. 1.3 Principalele componente ale unui compilatorDefinitii Un translator este un program care primeste la intrare un text scris intr-un limbaj de programare - limbaj sursa- si produce la iesire un text echivalent scris in alt limbaj de programare - limbaj obiect. Daca limbajul sursa este un limbaj de nivel inalt, iar limbajul obiect este un limbaj de nivel inferior (limbaj de asamblare sau cod masina ), atunci translatorul respectiv se numeste compilator. Structura unui compilator Procesul de compilare a unui program are loc in mai multe faze. O faza este o operatie unitara in cadrul careia are loc transformarea programului sursa dintr-o reprezentare in alta. Principalele faze ale unei compilari sunt cele din figura de mai jos: Analiza lexicala: textul sursa este preluat sub forma unei secvente de caractere care sunt grupate apoi in entitati numite atomi; atomilor li se atribuie coduri lexicale, astfel ca , la iesirea acestei faze, programul sursa apare ca o secventa de asemenea coduri. Exemple de atomi: cuvinte cheie, identificatori, constante numerice, semne de punctuatie etc. Analiza sintactica: are ca scop gruparea atomilor rezultati in urma analizei lexicale in structuri sintactice. O structura sintactica poate fi vazuta ca un arbore ale carui noduri terminale reprezinta atomi, n timp ce nodurile interioare reprezinta siruri de atomi care formeaza o entitate logica . Exemple de structuri sintactice: expresii, instructiuni, declaratii etc. Pe durata analizei sintactice, de obicei are loc si oanaliza semantica, ceea ce inseamna efectuarea unor verificari legate de: compatibilitatea tipurilor datelor cu operatiile in care ele sunt implicate sirespectarea regulilor de vizibilitate impuse de limbajul sursa. Erorile intr-un program pot fi:

-lexicale (scrierea eronata a unui identificator, a unui cuvant cheie, etc)

-sintactice (omiterea unor paranteze intr-o expresie artimetica, etc)

-semantice (aplicarea unui operator aritmetic unor operanzi logici, nepotrivirea tipului la atribuiri, etc)

-logice (un apel recursive infinit)

Generarea de cod intermediar: in aceasta faza are loc transformarea arborelui sintactic intr-o secventa de instructiuni simple, similare macroinstructiunilor unui limbaj de asamblare. Diferenta dintre codul intermediar si un limbaj de asamblare este in principal aceea ca, in codul intermediar nu se specifica registrele utilizate in operatii. Exemple de reprezentari pentru codul intermediar: notatia postfix, instructiunile cu trei adrese etc. Codul intermediar prezinta avantajul de a fi mai usor de optimizat decat codul masina .Optimizarea de cod: este o faza optionala , al carei rol este modificarea unor portiuni din codul intermediar generat, astfel incat programul rezultat sa satisfaca anumite criterii de performanta vizand timpul de executie si/sau spatiul de memorie ocupat.Generarea codului final: presupune transformarea instructiunilor codului intermediar (eventual optimizat) n instructiuni masina (sau de asamblare) pentru calculatorul tinta (cel pe care se va executa programul compilat).In afara de actiunile enumerate mai sus, procesul de compilare mai include urmatoarele: Gestionarea tabelei de simboluri: tabela de simboluri (TS) este o structura de date destinata pastrarii de informatii despre simbolurile (numele) care apar in programul sursa; compilatorul face referire la aceasta tabela aproape in toate fazele compilarii. Tratarea erorilor: un compilator trebuie sa fie capabil sa recunoasca anumite categorii de erori care pot sa apara in programul sursa; tratarea unei erori presupune detectarea ei, emiterea unui mesaj corespunzator si revenirea din eroare, adica, pe cat posibil, continuarea procesului de compilare pana la epuizarea textului sursa, astfel incat numarul de compilari necesare eliminarii tuturor erorilor dintr-un program sa fie cat mai mic. Practic, exista erori specifice fiecarei faze de compilare.

2. Derularea procesului de compilare Fazele unui proces de compilare se pot nlantui, n principiu, n doua moduri: La iesirea fiecarei faze se va genera un fisier intermediar continand forma de reprezentare a programului sursa rezultata in faza respectiva, fisier care va constitui intrare pentru faza urmatoare. In acest caz, in fiecare faza va avea loc cel putin o parcurgere a programului sursa, de la inceput la sfarsit. O asemenea parcurgere se numeste trecere. Doua sau mai multe faze de compilare se interclaseaza astfel incat ele sa se execute printr-o singura trecere.Aplicarea uneia sau alteia dintre cele doua modalitati depinde de natura limbajului compilat, precum si de mediul n care urmeaza sa ruleze compilatorul. La nivelul cel mai nalt, compilarea este mprit n mai multe pri:

Analiza lexicala (tokenizing)

Token: o secventa de caractere tratata ca o singura unitate.Exemple:

Cuvinte rezervate (ex begin, end, struct, if etc.)

Cuvinte cheie (integer, true etc.)

Operatori (+, &&, ++ etc)

Identificatori (nume de variabile, nume de procedura, parametri)

Constante (numerice,sir de caractere)

Semne de punctuatie (:, , etc.)

Analiza sintactica (parsing)

Tip de verificare

Generare de cod

Orice compilator are unele cerinte esentiale, care sunt, probabil, mai stricte decat la alte programe:

Orice program valid trebuie sa fie tradus in mod corect (nicio traducere incorecta nu este permisa);

Orice program invalid trebuie sa fie respins si sa nu fie tradus;

Figure 3O compilare tipica poate consta din urmatoarele etape dupa cum arata Figure3:

In primul rand, front end-ul executa si creeaza un model de BIP-EMF;

Apoi filtrele din middle end sunt executate la randul lor. Rezultatul este un model de BIP-CEM, eventual modificat;

In cele din urma, toate back end-urile sunt executate la randul lor. Rezultatele lor sunt rezultatele de compilare.

The front end

Aceast parte este responsabil pentru citirea datelor introduse de utilizator (de ex codul surs BIP i argumentul n linia de comand) i transformarea acestora ntr-o reprezentare intermediar, care va fi utilizat pentru alte pri ale compilatorului. Actualul front-end conine un parser pentru limbajul BIP i un meta-model al BIP-ului care descrie reprezentarea intermediar. Un exemplu de model BIP reprezentat de meta-modelul BIP este numit BIP-EMF (deoarece aceste este un model BIP exprimat folosind tehnologia Eclipse Modeling Framework (EMF)).

The middle end

Middle end-ul gzduiete toate transformrile BIP la BIP. Acest lucru acioneaz pe modelul BIP-CEM prin intermediul unor operaii:

Modificari ale arhitecturii (de ex aplatizare);

Simplificari petri net ( reea Petri=graf orientat bipartit, ale crui noduri sunt locuri sau tranziii);

Colectii de date;

In prezent, compilatorul nu are nicio astfel de operatie: middle end-ul este gol.

The back end

Back end-ul preia modelul BIP-EMF i i este permis doar s citeasc cel mai probabil un cod surs ntr-un alt limbaj (de ex, C, C++, etc), sau chiar n BIP. n prezent, principalul back end utilizat este back end-ul C++, care produce cod C++ potrivit pentru motorul standar (standar engine). Program Sursa Forma intermediara Program Obiect ANALIZA SINTAXA INTRARE ERORI analiza lexicala

Sir de arbori lexicali

analiza sintactica A

Arbore sintactic

analiza semanticaGESTIUNEA TABELELOR

Generare cod intermediar

Arbore atribuit

Optimizare cod

Cod intermediar optimizat

1)Analiza Generare cod obiect

2)Sinteza3.Descrierea BNF (Backus-Naur Form) a gramaticii unui limbaj

In informatica, BNF (Backus Normal Form sau Backus-Naur Form) este una dintre cele dou tehnici de notare principale n gramatic, de multe ori folosita pentru a descrie sintaxa limbajului utilizat n calcul, cum ar fi limbaje de programare independente, formate de documente, seturi de instruciuni i protocoale de comunicare ; cealalt tehnic de scriere a gramaticii independente este tehnic van Wijngaarden. Ele sunt aplicate ori de cte ori este nevoie de descrieri exacte ale limbajului

BNF folosete un mic set de simboluri pentru a descrie o secvena gramaticala. Autorii de orice limbaj de programare (de exemplu C++, Visual Basic) trebuie s noteze secvenele gramaticale ale limbajului respectiv. Acetia folosesc adesea notaia BNF pentru a descrie aceste secvene. Autorul compilatorului citete apoi acest document i face n aa fel nct programul compilatorului s se conformeze cu el.

Fiecare secventa in BNF are urmatoarea structura:

Name(simbol non-terminal) ::= expansion(expresie care contine simboluri terminale si non-terminale unite prin secventiere si alegere)

Un simbol terminal poate fi simbolul + , function, sau integer.

Unele dintre notatiile BNF includ:

folosit pentru a cuprinde un element sintactic; fiecare nume din BNF este inconjurat de aceste paranteze, oriunde s-ar afla el;

::= inseamnaeste definit de sau consta din;

| cand este plasat intre doua elemente inseamna o alegere SAU intre ele;

{} acoladele inseamna valoarea zero sau mai multe repetari ale continutului;

4. Descrierea EBNF (Extended BNF)

EBNF este folosit pentru a realiza o descriere formal a unui limbaj formal care ar putea fi un limbaj de programare. EBNF este o extensie a descrierii BNF. Descrierea EBNF a fost dezvoltat de Niklaus Wirth. EBNF este un cod care exprim gramatica unui limbaj formal. Un EBNF este format din simboluri terminale i reguli de producie non-terminale, care sunt restriciile ce reglementeaz modul n care simbolurile terminale pot fi combinate ntr-o secvena. Exemplele de simboluri terminale includ caractere alfanumerice, semne de punctuaie i caractere white space.

EBNF defineste regulile de productie in cazul in care secventele de simboluri sunt atribuite la un non-terminal.5. Procesul de Generare cod intermediar

n informatic, analiza lexical reprezinta procesul de conversie al unei secvene de caractere ntr-o secven de token-uri (iruri de caractere semnificative). Un program sau o funcie care efectueaz analiza lexical este numit un analizor lexical, lexer, tokenizer sau scanner, dei "scanner" este, de asemenea, folosit pentru prima etap a unui lexer. Un lexer este, n general, combinat cu un parser, care s analizeze mpreun sintaxa de limbaje de programare, cum ar fi n compilatoare pentru limbaje de programare, dar i parsere HTML n browsere web, printre alte exemple.

Strict vorbind, un lexer este el nsui un fel de parser ,sintaxa limbii fiind mprita n dou buci: sintaxa lexical (structura de cuvnt), care este procesat de lexer; i structura de fraz, care este procesat de (la nivel de fraz) parser.

Un lexer n sine poate fi mprit n dou etape: scanerul, care segmenteaz secvena de intrare n grupuri i le clasific n clase simbolice; i evaluatorul, care transform caracterele de intrare n valoari procesate.

5.1 Token

Un token este un ir de una sau mai multe caractere care este semnificativ ca grup. Procesul de formare a token-urilor de la un flux de intrare de caractere se numete tokenizare.

Token-urile sunt identificate pe baza regulilor specifice ale unui lexer. Unele metode folosite pentru a identifica token-uri includ: expresii regulate, secvene specifice de caractere cunoscute ca un flag, caractere specifice de separare numite delimitatoare, precum i definirea explicit de un dicionar. Caracterele speciale, inclusiv semnele de punctuaie, sunt utilizate n mod obinuit de ctre lexer pentru a identifica token-uri, din cauza utilizrii lor n mod natural n scris i n programare.

Token-urile sunt adesea clasificate n funcie de coninutul de caracter sau de context n fluxul de date. Categoriile sunt definite de normele de lexer. Acestea de multe ori implica elemente gramaticale ale limbii utilizate n fluxul de date. Limbajele de programare clasific de multe ori token-urile ca identificatori, operatori grupati dup simboluri sau dupa tipul de date. Limbile scrise clasific de obicei token-urile ca substantive, verbe, adjective sau semne de punctuaie. Categoriile sunt utilizate pentru post-procesare a token-urilor, fie prin analizor sau fie prin alte funcii n cadrul programului.

Un analizor lexical, n general, nu face nimic cu combinatiile de simboluri, sarcina este lsat pentru un parser. De exemplu, un analizor lexical tipic recunoate parantezele token-urilor, dar nu face nimic pentru a se asigura c fiecare "(" corespunde cu ")".

Token-urile sunt adesea definite prin expresii regulate, care sunt nelese de ctre un generator de analizor lexical, cum ar fi lex. Analizorul lexical (fie generate automat de un instrument ca lex, sau artizanale), citete ntr-un flux de caractere, identific lexemele din flux i le clasific n token-uri. Aceasta se numete "tokenizing". n cazul n care lexer-ul gsete un simbol invalid, se va raporta o eroare. Dupa tokenizing urmeaz parsarea. De acolo, datele pot fi ncrcate n structurile de date de uz general, interpretate sau compilate.5.2 Gramatica lexical

Specificatiile limbajului de programare adesea include un set de reguli , printer care si gramatica lexicala, ce definete sintaxa lexical. Sintaxa lexicala este, de obicei, un limbaj obinuit , cu regulile gramaticale formate din expresii regulate ; ele definesc setul de secvene posibile de caractere care sunt folosite pentru a forma simboluri individuale. Un lexer recunoate iruri de caractere , i pentru fiecare tip de ir gsit in programul lexical ia o aciune, cele mai multe pur i simplu produc un token .

Dou categorii importante lexicale comune sunt spaiul alb i comentariile . Acestea sunt , de asemenea, definite n gramatica i prelucrate de ctre lexer , dar sunt n general eliminate (nu produc niciun token) i considerate nesemnificative , cel mult separ dou token-uri ( ca n cazul n care if x n loc de ifx ) . Acestea sunt cele mai importante. n primul rnd , regulile limbajelor care delimiteaz blocurile cu indentare , spaiu iniial este semnificativ , deoarece determin structura de bloc , i este n general tratat la nivelul de lexer . n al doilea rnd , n unele utilizri non- compilator de lexer , comentariile trebuie s fie pstrate. n anii 1960 , n special pentru ALGOL , spaiul i comentariile au fost eliminate , ca parte din faza de reconstrucie a liniei ( faza iniial a interfaei unui compilator ) , dar aceast faz separat a fost eliminat, iar acestea sunt n prezent gestionate de lexer .

Tokenizarea este procesul de a delimita i, eventual, clasifica seciuni dintr-un ir de caractere de intrare. Token-urile rezultate sunt apoi trecute la o alt form de prelucrare. Procesul poate fi considerat o sub-sarcina de parsare la intrare.

5.3 Scanner-ul

n prima etap, scannerul, se bazeaz de obicei pe o main (FSM). Ea codeaza in acesta, informaii cu privire la posibilele secvene de caractere care pot fi coninute n oricare dintre semen (cazuri individuale ale acestor secvene de caractere sunt cunoscute ca lexeme). De exemplu, un simbol ntreg poate conine orice secven de caractere numerice cifre. n multe cazuri, primul caracter non-spaiu pot fi utilizate pentru a deduce tipul de simbol pe care urmeaz i caracterele de intrare ulterioare sunt apoi procesate una la un moment dat pn cnd ajunge la un caracter care nu este acceptat de setul de caractere pentru acel token. n unele limbi, regulile de create de lexem sunt mult mai complicate i pot implica backtracking peste caractere citite anterior. De exemplu, n C, un singur caracter "L" nu este suficient pentru a distinge ntre un identificator care incepe cu "L" i un ir de caractere la nivel literal.5.4 Evaluator-ul

Un lexem este doar un ir de caractere cunoscut, de un anumit tip ( de exemplu , un ir literal , o secven de litere ) . Cu scopul de a construi un token , analizorul lexical are nevoie de o a doua etap , evaluatorul , care trece peste caracterele lexem pentru a produce o valoare . Tipul de lexem combinat cu valoarea sa este ceea ce constituie n mod corespunztor un semn , care poate fi dat la parser . Unele token-uri , cum ar fi parantezele nu au ntradevr valori , i astfel funcia de evaluator pentru acestea poate ntoarce nimic : este nevoie doar de tip . n mod similar , uneori, evaluatorii pot suprima un lexem n ntregime , ascunzndu- se de parser , care este util pentru spaiu i comentarii . Evaluatorii de identificatori sunt de obicei simpli. Evaluatorii pentru literele intregi pot face parte dintr-un sir sau singure.

.

Instrumentul de programare Lex i compilatorul sunt concepute pentru a genera cod pentru analizorul lexical rapid, bazat pe o descriere formal a sintaxei lexicale. Nu este, n general, considerat suficient pentru aplicaii cu un set complex de reguli lexicale i cerine severe de performan; de exemplu, compilatorul GNU Collection (GCC) utilizeaz litere scrise de mn.

5.5 Generatorul de lexer

Lexer-urile sunt de multe ori generate de un generator de lexer, analog generatoarelor de parser, i astfel de instrumente de multe ori vin mpreun. Cel mai stabilit este lex, asociat cu generatorul yacc parser.

Aceste instrumente au randament de dezvoltare foarte rapid, ceea ce este deosebit de important n dezvoltarea timpurie, pentru a obine un lexer de lucru. n plus, acestea ofer de multe ori caracteristici avansate, cum ar fi pre i post condiii care sunt greu de programat manual. Cu toate acestea, lexer-erele generate automat pot fi lipsite de flexibilitate, i, astfel, ar putea necesita unele modificri manuale sau un lexer scris complet manual.

Lista de generatoare Lexer:

- ANTLR - Poate genera analizoare lexicale i interpretoare.

- DFASTAR - Genereaz DFA n C + +.

- Flex - variant alternativ a clasic "lex" (C / C + +).

- JFlex - O rescriere a JLex.

- Ragel - O main i lexer generator n C, C + +, C #, Objective-C, D, Java, Go i Ruby.

Generaoare unicod:

JavaCC - JavaCC genereaza analizoare lexicale scrise n Java.

JLex - Un generator de analizor lexical pentru Java.

Quex - Un generator rapid universal analizor lexical pentru C i C + +.

6. Analiza sintactica

Parsarea sau analiz sintactic este procesul de a analiza o serie de simboluri, fie n limbaj natural sau n limbaje de programare, n conformitate cu regulile unei gramatici formale.

6.1 Parser

Un parser este o component software care preia datele de intrare (frecvent text) i construiete o structur de date - de multe ori un fel de arbore parser parser tree, copac sintatic abstract sau alt structur ierarhic - oferind o reprezentare structural de intrare, de verificare pentru sintaxa corect n proces. Parsarea poate fi precedata sau urmata de alte msuri, acestea pot fi combinate ntr-un singur pas. Parser este adesea precedat de un analizor lexical separat, care creeaz token-uri din secvena de caractere de intrare; n mod alternativ, acestea pot fi combinate n parsare scannerless . Interpretoarele poate fi programate manual sau pot fi generate automat sau semi-automat, de ctre un generator de parser. Parsarea este complementar templating-ului, care produce formatul de ieire. Acestea pot fi aplicate n diferite domenii, dar de multe ori apar mpreun, cum ar fi perechea scanf / printf, sau stagiile compilatorului de intrare (parsing front-end) i de ieire (generarea codului de final).

Intrarea la un parser este de multe ori de tip text ntr-un limbaj de calculator, dar poate fi, de asemenea, de text ntr-o limb natural sau de date textuale mai puin structurate, n cazul n care, n general, numai anumite pri ale textului sunt extrase. Interpretoarele variaz de la funcii foarte simple, cum ar fi scanf, la programe complexe, cum ar fi interfaa a unui compilator C + + sau analizorul HTML a unui browser web

6.2 Tipuri de parser

Sarcina parser-ului este, n esen, de a determina dac i cum intrarile pot fi derivate din simbolul de start al gramaticii.Aceasta se poate face n esen, dou moduri:

Parsarea de sus n jos (top-down) - analiz poate fi privit ca o ncercare de a gsi in stnga cele mai multe derivatii de la o intrare-flux de cutare pentru arborii.Token-uri sunt consumate de la stnga la dreapta.

Parsarea de jos in sus (bottom-up) - un parser poate ncepe cu intrarea i s ncerce s-o rescrie la simbolul de pornire.Intuitiv, parser-ul ncearc s gseasc elementele cele mai de baz, apoi elementele care conin acestea, i aa mai departe.

Exemple de parsere:Parser de sus n jos

Unele dintre analizatorilor care folosesc parsing de sus-jos includ:

Parser recursive-descendent

LL parser (Left-to-right,Leftmost derivation)

Earley parser

Parser de jos n sus

Parser cu prioritate

BC (bounded context) parser

LR parser(Left-to-right,Rightmost derivation)

Parsere pentru dezvoltare de software

ANTLR Bison Coco/R GOLD JavaCC JParsec Lemon Lex Parboiled Parsec ParseIT Ragel SHProto(FSM parser language)[7] Spirit Parser Framework Syntax Definition Formalism SYNTAX XPL Yacc7.Arborele sintactic

n informatic, un arbore sintactic abstract (AST), sau pur i simplu arborele sintactic, este o reprezentare a structurii sintactice abstracte, de cod surs, scris ntr-un limbaj de programare.Fiecare nod al arborelui denot un constructor care apare n codul surs.Sintaxa este "abstracta", nu reprezint fiecare detaliu care apare n sintaxa real.De exemplu, gruparea parantezelor sunt implicite n structura arborescent, i o construcie sintactic ca o expresie dac-condiie atunci pot fi notate cu ajutorul unui singur nod cu dou ramuri.

Arborii sintactici sunt adesea construiti de ctre un parser in timpul traducerii codului surs i a procesului de compilare.Odat construit, informaii suplimentare se adaug la acesta prin prelucrare ulterioar.

7.1 Proiectarea unui arbore sintactic

Cnd proiectam un AST trebuie s fim contieni de funcionalitatea pe care compilatorul o va atepta.Aa cum am menionat mai nainte, nu putem stoca declaraiile de program n forma surs.n acelai timp, declaraiile trebuie s pstreze tipurile i locaia lor.Ordinea de declaraii executabile trebuie s fie reprezentate n mod explicit i bine definit.Asignare are nevoie pentru a stoca identificatorul care va pstra valoarea atribuit.Aceste cerine pot fi folosite pentru a proiecta structura de date de folosit.Este cunoscut faptul c unele operaiii vor fi ntotdeauna constituite din dou elemente, cum ar fi adunarea a 2 numere.Ca rezultat, un AST trebuie s fie, de asemenea, suficient de flexibil i rapid pentru a permite adaos rapid de cantiti arbitrare ale copiilor.O alt cerin majore de proiectare pentru un AST este c ar trebui s fie posibila s se unparseze un AST n surs form de cod, care este suficient de asemntor cu originalul i a crei executare este suficient de similara cu executarea programului reprezentat de AST.

Datorit complexitii cerinelor pentru un AST i complexitatea de ansamblu a unui compilator, este benefic s se aplice principiile de dezvoltare de software de sunet.Una dintre acestea este de a utiliza modele de design dovedite a mbunti modularitatea i uurina de dezvoltare.Datorit faptului c diferitele operaii nu au neaprat diferite tipuri, este important de a avea o ierarhie de clase nod sunet.Acest lucru este crucial n crearea i modificarea AST ca compilatorul sa progreseze.Deoarece compilatorul face cteva traversri ale arborelui pentru a determina corectitudinea sintactica, este important s se fac traversarea arborelui intr-o operaie simpl.De cnd ajunge la fiecare nod, compilatorul execut un set specific de operaiuni, n funcie de tipul de nod, are sens s utilizeze modelul vizitatorilor.

AST este folosit intensiv n timpul de analiz semantic, n cazul n care se fac controalele de compilare pentru utilizarea corect a elementelor de program i limba.De asemenea, n timpul analizei semantice compilatorul genereaz tabelele de simboluri pe baza AST.O traversare complet a arborelui permite s se verifice corectitudinea programului.Dup verificarea corectitudinii, AST servete ca baz pentru etapa de generare de cod.Acesta este adesea cazul n care AST este utilizat pentru a genera "reprezentarea intermediara" "(IR)" pentru generarea de cod numit uneori un limbaj intermediar.Concluzii:Pentru a putea fi interpretate de procesor, programul scris de om ("codul surs", scris de exemplu n limbaj de asamblare) trebuie nti redus prin compilare (sau asamblare sau interpretare) la "codul obiect" (n cod main), n acest scop fiind folosite "compilatoarele", "asambloarele" sau "interpretorii".

Programarea n limbaj de asamblare presupune o bun cunoatere a structurii procesorului i a componentelor sale adiacente. Ea face ca utilizatorul s aib acces la toate facilitile unui calculator; dar programul rezultat va putea funciona numai pe acest tip de calculator. Dac programul trebuie portat (transpus) i pe alte tipuri de calculatoare, atunci se prefer limbajele de programare de nivel mai nalt.

Bibliografie:

Gh. Grigoras- Proiectarea Compilatoarelor, 2006-2007, Univ. Al. I Cuza

https://ro.wikipedia.org/wiki/Limbaj_de_asamblareObiectivul programului

Programul surs

Compilator

2