Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cpl:labs:01 [2015/12/06 19:15]
laura.vasilescu [Prezentare teoretică]
cpl:labs:01 [2016/10/03 21:56] (current)
bogdan.nitulescu [Introducere]
Line 1: Line 1:
 ====== 01. Introduction to Flex ====== ====== 01. Introduction to Flex ======
  
 +===== Introducere =====
 +De-a lungul acestui semestru, veți studia în cadrul cursului modul de implementare al unui compilator. La nivel conceptual, compilatorul este un program ce face translatarea dintr-un limbaj în altul. Cel mai adesea, compilatorul face translatarea dintr-un limbaj de nivel înalt (C, C++, Java), ce este scris și înteles de un programator,​ într-un limbaj low level (bytecode, limbaj asamblare, cod mașina) ce poate fi mai apoi executat de procesor (eventual după aplicarea unei noi translatări).
 +
 +Operația de compilare a unui limbaj se face în general în mai mulți pași. Fiecare pas produce ca output o translatare a datelor de intrare primite, output ce servește ca input pentru pasul următor. Principalii pași ce se disting, în mod conceptual, pentru majoritatea compilatoarelor se pot vedea în figura urmatoare, împreuna cu inputul si outputul aferent, precum și tool-urile pe care le vom folosi în cadrul laboratorului și temelor pentru implementare.
 +
 +{{ :​cpl:​labs:​lab1better.png?​600 |}}
 ===== Nice to read ===== ===== Nice to read =====
  
Line 11: Line 17:
 ''​flex''​ este un generator de analizoare lexicale. Acesta primește la intrare un fișier ce conține o specificație a atomilor pe care urmează să-i recunoască analizorul generat, precum și o serie de acțiuni semantice de executat. Specificațiile vor fi scrise într-un fișier text ce poate avea orice denumire/​extensie. De regulă se folosește extensia ''​.lex''​. ''​flex''​ este un generator de analizoare lexicale. Acesta primește la intrare un fișier ce conține o specificație a atomilor pe care urmează să-i recunoască analizorul generat, precum și o serie de acțiuni semantice de executat. Specificațiile vor fi scrise într-un fișier text ce poate avea orice denumire/​extensie. De regulă se folosește extensia ''​.lex''​.
  
-Pe baza spcificațiilor,​ ''​flex''​ generează un program C ce conține tabele de analiză și o funcție de analiză numită ''​yylex''​. Numele implicit al fișierului astfel generat este ''​lex.yy.c''​. Acesta urmează să fie compilat (''​gcc''​ sau altceva) pentru a se obține fișierul executabil. ​+Pe baza spcificațiilor,​ ''​flex''​ generează un program C ce conține tabele de analiză și o funcție de analiză numită ''​yylex''​. Numele implicit al fișierului astfel generat este ''​lex.yy.c''​. Acesta urmează să fie compilat (''​gcc''​ sau un alt compilator) pentru a se obține fișierul executabil. ​
  
 {{ :​cpl:​labs:​flex.png?​300 |}} {{ :​cpl:​labs:​flex.png?​300 |}}
Line 17: Line 23:
 ===== Instalare flex ===== ===== Instalare flex =====
  
-În cadrul acestui laborator vom folosi pachetul ''​flex''​ standard ​suportat ​de către ​distribuție. Pentru mașina virtuală CPL pusă la dispoziție versiunea pachetului ''​flex''​ este ''​2.5.35''​.+În cadrul acestui laborator vom folosi pachetul ''​flex''​ standard ​oferit ​de distribuție. Pentru mașina virtuală CPL pusă la dispoziție versiunea pachetului ''​flex''​ este ''​2.5.35''​.
  
 <​code>​sudo apt-get install flex</​code>​ <​code>​sudo apt-get install flex</​code>​
Line 27: Line 33:
 </​code>​ </​code>​
  
-Implicit, ​dacă comanda este rulată ​fără nicio opțiune va aștepta introducerea de specificații de la intrarea standard (stdin).+Implicit, ​rulând programul ​fără nicio opțiuneva aștepta introducerea de specificații de la intrarea standard (stdin).
  
 Comanda dispune de o varietate de parametri și opțiuni ([[http://​www.manpagez.com/​man/​1/​flex/​|man flex]]) dintre care amintim: Comanda dispune de o varietate de parametri și opțiuni ([[http://​www.manpagez.com/​man/​1/​flex/​|man flex]]) dintre care amintim:
Line 45: Line 51:
 </​code>​ </​code>​
  
-Se pot adăuga ** %%/%%* comentarii ca în C */ **.+Se pot adăuga ** %%/%%* comentarii ca în C */ ** cât timp sunt precedate de cel puțin un spațiu.
  
 ==== Secțiunea de definiții ==== ==== Secțiunea de definiții ====
Line 69: Line 75:
   * //%option main// - generează o funcție ''​main''​ care doar apelează funcția de analiză ''​yylex'';​   * //%option main// - generează o funcție ''​main''​ care doar apelează funcția de analiză ''​yylex'';​
   * //%option debug// - activează modul debugging;   * //%option debug// - activează modul debugging;
-  * //​%option ​caseless// - analizatorul va fi case insensitive;​+  * //​%option ​case-insensitive// - analizatorul va fi case insensitive;​
   * //%option yylineno// - activează variabila globală ''​yylineno''​ ce va conține numărul liniei corespunzătoare din codul sursă;   * //%option yylineno// - activează variabila globală ''​yylineno''​ ce va conține numărul liniei corespunzătoare din codul sursă;
  
 === Stări de start === === Stări de start ===
    
-''​flex''​ este capabil să lucreze simultan cu mai multe seturi de reguli diferite. Acest lucru poate fi util spre exemplu dacă se dorește ​analizarea ​unui fișier sursă în care apar secvențe de cod scrise în limbaje diferite, cărora le corespund seturi de expresii regulate diferite. Astfel, există un mecanism ce permite activarea dinamică a unui anumit set de reguli în funcție de startea de start.+''​flex''​ este capabil să lucreze simultan cu mai multe seturi de reguli diferite. Acest lucru poate fi util spre exemplu dacă se dorește ​analiza ​unui fișier sursă în care apar secvențe de cod scrise în limbaje diferite, cărora le corespund seturi de expresii regulate diferite. Astfel, există un mecanism ce permite activarea dinamică a unui anumit set de reguli în funcție de startea de start.
  
 Stările de start trebuie declarate în secțiunea de definiții, folosind una dintre următoarele două metode: Stările de start trebuie declarate în secțiunea de definiții, folosind una dintre următoarele două metode:
Line 89: Line 95:
 <​state1,​state2,​...,​stateN>​rule <​state1,​state2,​...,​stateN>​rule
 </​code>​ </​code>​
 +
 +Un exemplu [[http://​pastebin.com/​uaCe7CxS|aici]].
  
 === Secvențe de cod C în secțiunea de definiții === === Secvențe de cod C în secțiunea de definiții ===
Line 112: Line 120:
 === Expresii regulate === === Expresii regulate ===
  
-^  ​Pattern ​ ​^ ​ Descriere ​ ^+^  ​Șablon ​ ​^ ​ Descriere ​ ^
 |  a  | caracterul //a// | |  a  | caracterul //a// |
 |  .  | orice caracter mai puțin sfârșitul de linie | |  .  | orice caracter mai puțin sfârșitul de linie |
Line 123: Line 131:
 |  <​nowiki>​[^a]</​nowiki> ​ | orice în afară de caracterul //a// | |  <​nowiki>​[^a]</​nowiki> ​ | orice în afară de caracterul //a// |
 |  <​nowiki>​[^a-z]</​nowiki> ​ | orice în afară de litere mici | |  <​nowiki>​[^a-z]</​nowiki> ​ | orice în afară de litere mici |
-|  r*  | zero sau mai multe apariții succesive ale expresiei ​regulare ​//r// | +|  r*  | zero sau mai multe apariții succesive ale expresiei ​regulate ​//r// | 
-|  r+  | una sau mai multe apariții succesive ale expresiei ​regulare ​//r// |+|  r+  | una sau mai multe apariții succesive ale expresiei ​regulate ​//r// |
 |  r?  | maxim o apariție a expresiei regulate //r// | |  r?  | maxim o apariție a expresiei regulate //r// |
 |  r{2,​5} ​ | 2, 3, 4 sau 5 apariții succesive ale expresiei regulate //r// | |  r{2,​5} ​ | 2, 3, 4 sau 5 apariții succesive ale expresiei regulate //r// |
Line 137: Line 145:
 |  r$  | expresia regulată //r//, cu condiția ca această să apară la sfârșit de linie | |  r$  | expresia regulată //r//, cu condiția ca această să apară la sfârșit de linie |
 |  <​nowiki><<​EOF>></​nowiki> ​ | marcaj de sfârșit de fișier | |  <​nowiki><<​EOF>></​nowiki> ​ | marcaj de sfârșit de fișier |
-|  <​s>​r ​ | expresia regulată //r//, dar numai în condiția de start //s// |+|  <​s>​r ​ | expresia regulată //r//, dar numai în condiția de start //s// și în condițiile inclusive|
  
 === Secvențe de cod C în secțiunea de reguli === === Secvențe de cod C în secțiunea de reguli ===
Line 153: Line 161:
 === Variabile și macro-uri utile === === Variabile și macro-uri utile ===
  
-În această secțiune vom defini un set de variabile și macro-uri utile suportate ​de ''​flex''​. Acestea pot fi folosite în cadrul secțiunii de cod, dar și în momentul inserării de cod în cadrul secțiunii de definiții sau de reguli.+În această secțiune vom defini un set de variabile și macro-uri utile oferite ​de ''​flex''​. Acestea pot fi folosite în cadrul secțiunii de cod, dar și în momentul inserării de cod în cadrul secțiunii de definiții sau de reguli.
  
   * //char *yytext// - adresa zonei în care sunt reținute caracterele ce compun atomul curent;   * //char *yytext// - adresa zonei în care sunt reținute caracterele ce compun atomul curent;
Line 160: Line 168:
   * //FILE *yyout// - pointer către fișierul deschis în care se poate scrie cu ajutorul macro-ului ''​ECHO'';​   * //FILE *yyout// - pointer către fișierul deschis în care se poate scrie cu ajutorul macro-ului ''​ECHO'';​
   * //ECHO// - realizează scrierea conținutului ''​yytext''​ în ''​yyout'';​   * //ECHO// - realizează scrierea conținutului ''​yytext''​ în ''​yyout'';​
-  * //BEGIN start_state//​ - comută analizorul în ''​start_state'';​+  * //BEGIN(start_state)// - comută analizorul în ''​start_state'';​
   * //REJECT// - caută următoarea regulă al cărei șablon se potrivește cu atomul în curs de prelucrare (sau cu un prefix) și execută acțiunea asociată regulii găsite;   * //REJECT// - caută următoarea regulă al cărei șablon se potrivește cu atomul în curs de prelucrare (sau cu un prefix) și execută acțiunea asociată regulii găsite;
   * //​YY_START//​ - starea curentă (un număr);   * //​YY_START//​ - starea curentă (un număr);
-  * //yyerminate()// - termină procesul de analiză și returnează ​valoarea 0 către apelantul funcției ''​yylex'';​+  * //yyterminate()// - termină procesul de analiză și întoarce ​valoarea 0 către apelantul funcției ''​yylex'';​
   * //​yymore()//​ - concatenează următorul atom la atomul existent în ''​yytext'';​   * //​yymore()//​ - concatenează următorul atom la atomul existent în ''​yytext'';​
   * //​yyless(int n)// - lasă în ''​yytext''​ primele //n caractere// ale atomului curent, restituind în șirul de intrare caracterele de pe pozițiile n+1 până la sfârșit; actualizează ''​yyleng''​ la n;   * //​yyless(int n)// - lasă în ''​yytext''​ primele //n caractere// ale atomului curent, restituind în șirul de intrare caracterele de pe pozițiile n+1 până la sfârșit; actualizează ''​yyleng''​ la n;
Line 172: Line 180:
 ===== Funcția yylex ===== ===== Funcția yylex =====
  
-  * se aplică acțiunile corespunzătoare din specificație (secțiunea de reguli) care pot genera text specific în fișierul ''​yyout''​ sau pot returna ​coduri lexicale;+  * se aplică acțiunile corespunzătoare din specificație (secțiunea de reguli) care pot genera text specific în fișierul ''​yyout''​ sau pot întoarce ​coduri lexicale;
   * textul din fișierul sursă care nu se potrivește cu niciun șablon este copiat automat în ''​yyout'';​   * textul din fișierul sursă care nu se potrivește cu niciun șablon este copiat automat în ''​yyout'';​
   * dacă pentru un text se potrivesc mai multe șabloane, se alege potrivirea **cea mai lungă**;   * dacă pentru un text se potrivesc mai multe șabloane, se alege potrivirea **cea mai lungă**;
   * dacă pentru un text se potrivesc mai multe șabloane de aceeași lungime, se alege **prima potrivire în ordine textuală** din specificație;​   * dacă pentru un text se potrivesc mai multe șabloane de aceeași lungime, se alege **prima potrivire în ordine textuală** din specificație;​
   * textul corespunzător potrivirii este copiat în ''​yytext'',​ iar lungimea acestuia este reținută în ''​yyleng'';​   * textul corespunzător potrivirii este copiat în ''​yytext'',​ iar lungimea acestuia este reținută în ''​yyleng'';​
-  * când analizorul întâlnește marcajul ''​EOF'',​ verifică rezultatul funcției ''​yywrap'';​ dacă rezultatul este fals (zero), înseamnă că analiza trebuie să continue cu noul fișier desemnat de ''​yyin'';​ dacă rezultatul este nenul, analiza se termină și se returnează ​valoarea zero spre apelantul funcției ''​yylex'';​+  * când analizorul întâlnește marcajul ''​EOF'',​ verifică rezultatul funcției ''​yywrap'';​ dacă rezultatul este fals (zero), înseamnă că analiza trebuie să continue cu noul fișier desemnat de ''​yyin'';​ dacă rezultatul este nenul, analiza se termină și se întoarce ​valoarea zero spre apelantul funcției ''​yylex'';​
  
 Absența funcției ''​yywrap''​ poate fi suplinită de opțiunea ''​%option noyywrap''​ sau prin opțiunea ''​-lfl''​ la linkare. ​ Absența funcției ''​yywrap''​ poate fi suplinită de opțiunea ''​%option noyywrap''​ sau prin opțiunea ''​-lfl''​ la linkare. ​
Line 183: Line 191:
  
 În rezolvarea laboratorului folosiți arhiva de sarcini {{ :​cpl:​labs:​lab01_num_lines.zip | lab01_num_lines.zip }} În rezolvarea laboratorului folosiți arhiva de sarcini {{ :​cpl:​labs:​lab01_num_lines.zip | lab01_num_lines.zip }}
 +
 +====== Exercițiul 0 ======
 +
 +Înscrieți-vă pe [[cpl:​info:​lista-discutii | Lista de discuții de CPL]].
  
 ===== Exercițiul 1 - num lines (3p) ===== ===== Exercițiul 1 - num lines (3p) =====
Line 199: Line 211:
 ===== Exercițiul 3 - names (2p) ===== ===== Exercițiul 3 - names (2p) =====
  
-Scrieți un fișier de specificație ''​.lex''​ care identifică toate cuvintele ​dintr-un text care încep cu majusculă.+Scrieți un fișier de specificație ''​.lex''​ care identifică toate cuvintele care încep cu majusculă.
  
 ===== Exercițiul 4 - appearances (2p) ===== ===== Exercițiul 4 - appearances (2p) =====
cpl/labs/01.1449422122.txt.gz · Last modified: 2015/12/06 19:15 by laura.vasilescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0