Ex LFTC Final

You might also like

Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 29

 

1. Sa se scrie analizorul sintactic pentru urmatoarea gramatica:


 
propozitii: propozitii propozitie
propozitie: ( subiectSimplu ARE | subiectCompus AU ) numar .
subiectSimplu: ID
subiectCompus: ID (, subiectCompus | epsilon)
numar: INT LEI ( SI INT BANI | epsilon ) | INT BANI
 
 

2. Sa se scrie analizorul lexical care valideaza persoane cu nume corespunzatoare urmatorului format:

PERSOANA: NUME SPATIU PRENUME


NUME: LITERA_MARE LITERA_MICA+
PRENUME: LITERA_MARE LITERA_MICA+ ( ( MINUS LITERA_MARE LITERA_MICA+ ) | epsilon )
 

3. Sa se scrie analizorul sintactic pentru urmatoarea gramatica:


 
clasa: CLASS ID {   listaDecl   }
decl: declVar | declFunc
listaDecl: listaDecl decl | epsilon
declVar: ID ID
declFunc: ID ID ( argumente )
argumente: declVar ( , argumente | epsilon ) | epsilon

4. Sa se realizeze analizorul lexical pentru gramatica de mai jos:

LITERA ::= a..z | A..Z


DIGIT ::= 0..9
ID ::= LITERA ( LITERA | DIGIT )*
REAL ::= DIGIT+ [ . DIGIT+ ]

5. Sa se realizeze analizorul sintactic pentru gramatica de mai jos. Analizorul lexical se considera
cunoscut. Componentele scrise ingrosat sunct considerati atomi lexicali.

tesut: celule fibre| tesut


celule: (celula)+
celula: ADN ARN
6. Realizati un analizor sintactic pentru urmatoarea gramatica
(Asignment 7)

<lista_ramuri> -> <ramura>|<lista_ramuri> <ramura>


<ramura> -> <lista_val> : <instr> ;
<lista_val> -> <constanta> , <lista_val>|<constanta>
<constanta> -> <constanta_num>|<constanta_car>
<constanta_car> -> litera
<const_num> -> <nr_intreg>|<nr_real>
<nr_intreg> -> <nrBaza10>|<baza>@ cifra

Raspuns:
Deoarece in cazul: <lista_ramuri> = <ramura>|<lista_ramuri> <ramura>, exista recursivitate la stanga,
aceasta trebuie eliminata prin introducerea unui neterminal nou:
<lista_ramuri> = <ramura> <lista_ramuri_prim>
<lista_ramuri_prim> = epsilon| ; <ramura> <lista_ramuri_prim>
void error(int error_code); /* raporteaza eroare */
void lista_ramuri(void);
void lista_ramuri_prim(void);
void ramura(void);
void lista_val(void);
void constanta(void);
void constanta_car(void);
void const_num(void);
void nr_intreg(void);
void get_next_lex(void); /* citeste urmatorul element lexical */
COD_LEXICAL codLex; /* elementul lexical citit */
int main()
{
get_next_lex();
lista_ramuri();
return 0;
}

void lista_ramuri()
{
ramura();
lista_ramuri_prim();
}
void ramura()
{
lista_val();

get_next_lex();
if( codLex != ':' )
{
error(1);/* se astepta " : " */
return;
}

get_next_lex();
instr(); /* verifica daca e instructiune */

get_next_lex();
if( codLex != ';')
{
error(2);/* se astepta " ; " */
return;
}
}
void lista_ramuri_prim()
{
get_next_lex();

ramura();
lista_ramuri_prim();
}
void lista_val()
{
get_next_lex();
constanta();

get_next_lex();
if(codLex != ',')
{
error(3);/* se astepta " , " */
return;
}

lista_val();
}
void constanta()
{
const_num();
constanta_car();
}
void const_num()
{
nr_intreg();
nr_real();
}
void constanta_car
{
get_next_lex();

if(((codLex <= 'a') || (codLex >= 'z') ) && ((codLex <= 'A') || (codLex >= 'Z')))
{
error(4);/* se astepta un caracter */
return;
}
}
void nr_intreg()
{
get_next_lex();

if((codLex < 0)||(codLex > 9))


{
error(5);/* se astepta un numar */
return;
}
}
7. Se cere analizorul sintactic pentru urmatoarea gramatica:
(Assignment 1)

Fisier= fisier (linie | epsilon)


Linie=(ID (lista_param | epsilon) | epsilon) NL
Lista_param = param (, lista_param | epsilon)
Param=( ID | F) (param | epsilon)

Struct atom {
string nume;
int categorie; // categorie lexicala
int cod;
}a;
atom *a;
// fisier=fisier (linie | epsilon)
//
// apare recursivitatea de stanga => introducem un neterminal nou si rescriem
gramatica
// fisier=fisier (linie | epsilon) devine
//
// fisier = (linie | epsilon) fisierprim
// fisierprim = fisierprim | epsilon
int fisier(){
if(linie()){
a=a->next;
if(fisierprim()){
a=a->next;
return 1;
}else{
printf("Fisierprim invalid");
exit(0);
}
elseif(!linie()){
printf("Linie incorecta");
exit(0);
}
else{
if(fisierprim()){
a=a->next;
return 1;
}
} //pentru linie | epsilon
}
2
int fisier(){
if(linie()){
a=a->next;
if(fisierprim()){
a=a->next;
return 1;
}elseif(!linie()){
printf("Fisierprim invalid");
exit(0);
}
a=a->next;
return 1; //pentru epsilon
}
int fisierprim(){
if(fisierprim()){
a=a->next;
return 1;
}
elseif(!fisierprim())
printf("Fisierprim invalid");
exit(0);
else{
a=a->next;
return 1; //pentru epsilon
}
}
// linie=(ID (lista_param | epsilon) | epsilon) NL
int linie(){
if(strcmp(a->categorie, "ID") == 0){
a=a->next;
if(lista_param()){
a=a->next;
if(strcmp((a->nume), "NL")==0){
a=a->next;
return 1;
}
}elseif(!lista_param()){
printf("Lista de parametri incorecta");
exit(0);
}elseif(strcmp((a->nume), "NL")==0){
a=a->next;
return 1;
} //pentru lista_param | epsilon
}elseif(strcmp(a->categorie, "ID") != 0){
printf("ID incorect");
exit(0);
}elseif(strcmp((a->nume), "NL")==0){
a=a->next;
return 1;
} //pentru lista_param | epsilon //pentru ID | epsilon
}
3
// lista_param=param (, lista_param | epsilon)
int lista_param(){
if(param()){
a=a->next;
if(strcmp(a->nume, ",") == 0){
a=a->next;
return 1;
}
elseif(strcmp(a->nume, ",") != 0)
printf("Lipseste ,");
exit(0);
else{
a=a->next;
return 1; //pentru , lista_param | epsilon
}
}else{
printf("Eroare la parametru!");
exit(0);
}
}
// param=(ID | F) (param | epsilon)
int param(){
if((strcmp(a->categorie, "ID") == 0) || (strcmp(a->categorie, "F") == 0)){
a=a->next;
if(param()){
a=a->next;
return 1;
}
elseif(param()!=1){
printf("Parametru incorect\n");
exit(0);
}
else{
a=a->next;
return 1; //pentru (param | epsilon)
}else{
printf("ID sau F lipsa\n");
exit(0);
}
}

8. Să se scrie un analizor sintactic corespunzător gramaticii de mai jos:


(Assignment 3)

<declaratii>::=<declaratie>|<declaratii> ; <declaratie>
<declaratie>::= ID (<stars>|epsilon) ID ([INT] | ( <args>|epsilon) )
<stars>::=STAR|STAR <stars>
<args>::=<arg>|<arg> , <args>
<arg>::= ID (<stars>|epsilon) ID

Observații: ID, INT si STAR sunt atomi lexicali. Toate celelalte caractere care sunt îngroșate reprezintă de
asemenea atomi lexicali. Analizorul lexical pentru această gramatică se consideră deja implementat.
 

Struct Atom {
string nume;
int categorie_lexicala;
int cod;
} a;

Atom *a;

//a. recursivitate de stanga:


// <declaratii>::= <declaratie> <declaratiip>
//<declaratiip>::= ; <declaratie> <declaratiip> | epsilon

// <declaratii>::= <declaratie> <declaratiip>


int declaratii()
{
if (declaratie(a))
{
a = getNextAtom();
if (declaratiip(a)) {
a = getNextAtom();
return 1;
}
else {
printf ("Eroare la declaratiip!");
exit (0);
}
}
else {
printf("Eroare la declaratie!");
exit(0);
}
}

//<declaratiip>::= ; <declaratie> <declaratiip> | epsilon


int declaratiip ()
{
if (strcmp(a->nume, ";") == 0)
{
if (declaratie(a))
{
a = getNextAtom();
if (declaratiip(a))
{
a=getNextAtom();
return 1;
}
else
{
printf("Eroare la declaratiip!");
exit(0);
}
}
else {
printf("Eroare la declaratie!");
exit(0);
}
}
else {
printf("Lipsa ; !");
exit(0);
}
return 1;
}

//b.<declaratie>::= ID (<stars>|epsilon) ID ([INT] | ( <args>|epsilon) )


int declaratie (){
if (strcmp(a->nume, "ID") == 0)
{
a = getNextAtom();
if (stars())
{
a = getNextAtom();
if (strcmp(a->nume, "ID") == 0)
{
a = getNextAtom();
if (strcmp(a.nume, "INT") == 0)
{
a = getNextAtom();
return 1;
}
else {
if (args())
{
a = getNextAtom();
return 1;
}
else {
printf("Eroare <args>");
exit(0);
}
return 1; //pt epsilon
}
}
else {
printf ("Eroare ID");
exit (0);
}
}
else {
if (strcmp(a->nume, "ID") == 0)
{
a = getNextAtom();
if (strcmp(a.nume, "INT") == 0)
{
a = getNextAtom();
return 1;
}
else {
if (args())
{
a = getNextAtom();
return 1;
}
else {
printf("Eroare <args>");
exit(0);
}
return 1; //pt epsilon
}
}
else {
printf ("Eroare ID");
exit (0);
}
}
else {
printf ("Eroare la primul ID");
exit (0);
}
}

//c.<stars>::=STAR|STAR <stars>
// ambiguitate: <stars> ::= STAR <starsp>
// <starsp>::= <stars> | epsilon
//<stars> ::= STAR <starsp>
int stars()
{
if (stracmp(a->nume, "STAR") == 0)
{
if (starsp(a))
{
a = getNextAtom();
return 1;
}
else {
printf("Eroare <starsp>");
exit (0);
}
}
else {
printf("Eroare STAR");
exit (0);
}
}
//<starsp>::= <stars> | epsilon
int starsp()
{
if (stars(a))
{
a = getNextAtom();
return 1;
}
else {
printf ("Eroare <stars>");
exit(0);
}
return 1; //epsilon
}

//d.<args>::=<arg> | <arg> , <args>


//ambiguitate: <args> ::= <arg> <argsp>
// <argsp>::= , <args> | epsilon
//<args> ::= <arg> <argsp>
int args()
{
if (arg(a))
{
a = getNextAtom();
if (argsp(a))
{
a = getNextAtom();
return 1;
}
else {
printf("Eroare la <argsp>");
exit(0);
}
}
else {
printf ("Eroare la <arg>");
exit(0);
}
}
// <argsp>::= , <args> | epsilon
int argsp()
{
if(strcmp(a->nume, ",") == 0)
{
a = getNextAtom();
if (args(a))
{
a = getNextAtom();
return 1;
}
else {
printf ("Eroare la <args>");
exit (0);
}
}
else {
printf("Lipseste ,");
exit(0);
}
return 1; //epsilon
}

//e.<arg>::= ID (<stars>|epsilon) ID
int arg()
{
if (strcmp(a->nume, "ID") == 0)
{
a = getNextAtom();
if (stars(a))
{
a = getNextAtom();
if (strcmp(a.nume, "ID") == 0)
{
a = getNextAtom();
return 1;
}
else {
printf("Lipseste ID dupa <stars>");
exit(0);
}
}
else if (strcmp(a->nume, "ID") == 0)
{
a = getNextAtom();
return 1;
}
else {
printf("Lipseste al doilea ID");
exit(0);
}
}
else {
printf("Lipseste primul ID");
exit(0);
}
}
9. Se cere să se scrie un analizor sintactic pentru gramatica de mai jos.
(Assignment 4)

<source_file> ::= <declarations> <code>


<declarations> ::= vars <list_of_variables> ;
<list_of_variables> ::= <variable> | <list_of_variables> , <variable>
<code> ::= <statements> .
<statements> ::= <assignment> | <statements> ; <assignment>
<assignment> ::= <variable> := <expression>
<expression> ::= <expression> + <term> | <expression> - <term> | <term>
<term> ::= <term> * <factor> | <term> / <factor> | <factor>
<factor> ::= <number> | <variable>

Analizorul lexical pentru aceasta gramatica se presupene deja implementat.

Remarca: In enunt au fost marcate cu rosu terminalele considerând situația că


gramatica e complet definită. În cazul în care gramatica din enunț nu e complet definită,
ținând cont de convenția că între <> se trec neterminalele, <number> și <variable> nu sunt
terminale.

Atom a;
int source_file()
{
if(declarations())
{
a = getNextAtom();
if(code())
{
return 1;
}
else error "Missing code";
}
else error "Missing declarations";
}
int declarations()
{
if(strcmp(a->name, "vars"))
{
a = getNextAtom();
if(list_of_varibles())
{
a = getNextAtom();
if(strcmp(a->name, ";"))
2
{
return 1;
}
else error "Missing token ;";
}
else error "Missing list of variables";
}
else error "Missing keyword/terminal vars";
}
int list_of_variables()
{
if(strcmp(a->category, “variable”))
{
return 1; // s-a considerat interpretarea (<variable>) | (<list_of_variables> , <variable>)
}
else if (list_of_variables())
{
a = getNextAtom();
if (strcmp(a->name, ","))
{
a = getNextAtom();
if (a->category, “variable”)
{
return 1 ;
}
else error "Missing variable";
}
else error "Missing token ,";
}
else error "Missing variable or list_of_variables";
}
}

int code ()
{
if(statements ())
{
a=getNextAtom();
if(strcmp(a->name, "."))
{
return 1;
}
else error "Missing token .";
}
else error "Missing code/empty code";
}
int statements()
{
if((assignment())
{
3
return 1; // s-a considerat interpretarea (<assignment>) | (<statements> ;
<assignment>)
}
else if (statements())
{
a = getNextAtom();
if (strcmp(a->name, ";"))
{
a = getNextAtom();
if(assignment())
{
return 1;
}
else error "Missing assignment";
}
else error "Missing token ;";
}
else error "Missing assignment or statements";
}
int assignement()
{
if (strcmp(a->category, “variable”))
{
a = getNextAtom();
if (strcmp(a->name, ":"))
{
a = getNextAtom();
if (strcmp(a->name, "="))
{
a = getNextAtom();
if (expression())
{
return 1;
}
else error "Missing expression";
}
else error "Missing token =";
}
else error "Missing token :";
}
else error "Missing variable";
}
int expression()
{
if (expression())
{
a = getNextAtom();
if ((strcmp(a->name, "+")) || (strcmp(a->name, "-")))
{
a = getNextAtom();
if (term())
4
{
return 1;
}
else error " Missing term";
}
else error "Missing token + or -";
}
else
{
if(term())
{
return 1 ;
}
else error "Missing term or expression";
}
}
int term()
{
if (term())
{
a = getNextAtom();
if ((strcmp(a->name, "*")) || (strcmp(a->name, "/")))
{
a = getNextAtom();
if (factor())
{
return 1;
}
else error " Missing factor";
}
else error "Missing token * or /";
}
else
{
if(factor())
{
return 1 ;
}
else error "Missing factor or term";
}
}

int factor()
{
if(strcmp(a->category, “number"))
{
return 1;
}
else
{
if (strcmp(a->category, “variable”))
5
{
return 1 ;
}
else error "Missing number or variable";
}

10. Se cere analizorul sintactic pentru a citi un fisier de balante de plati

(Assignment 6)

Se cere analizorul sintactic pentru a citi un fisier de balante de plati in care pe fiecare linie se afla
optional oricare dintre cele trei elemente, in ordinea data:
 
a)      cod (atom lexical ID, sir de caractere si cifre care incep cu un caracter) urmat optional de oricate
subcoduri, despartite prin “->”
b)      incasare (atom lexical F, un numar real)
c)       plata (atom lexical F, un numar real), obligatoriu precedat de “#” daca e doar un numar pe linie,
altfel “#” este optional
 
Pot exista si linii complet vide, iar separatorul de linii este atomul lexical NL. Intre elemente se pune
“,”. Fisierul poate fi complet gol. Toate partile subliniate sunt considerate atomi lexicali.
 
Gramatica:
fisier=linie (fisier | epsilon) | epsilon
linie= ( cod (, (F (, op | epsilon) | # F) | epsilon) | F (, op | epsilon) | # F | epsilon ) NL
cod=cod -> ID | ID
op=(# | epsilon) F

Rezolvare:

cod=cod -> ID | ID
Se observa o recursivitate la stânga imediată, care trebuie eliminată, dupa metoda: A→Aα⏐β ⇒ A→βA’
A’→αA’⏐ε
Vom introduce un neterminal nou, mărind numărul producțiilor:
cod = ID cod_prim
cod_prim= ->ID cod_prim | epsilon

Vom obține următorul analizator sintactic:

Linie – desfașurat după definitie


Linie – simplificat

PROGRAMUL:
//......................
enum ATOMI_LEXICALI {ID, NL, DIEZ, VIRGULA, SAGEATA, ALTUL};
void eroare(int error_code); // pentru raportarea erorilor
void fisier(void); //prelucreaza un fisier
void linie(void); // prelucreaza o linie
void cod(void); //prelucreaza un cod
void cod_prim(void); //v. mai sus – eliminarea recursivitatii la stanga
void op(void); // prelucreaza o plata
void citeste_atom(void); // citeste un atom lexical (joaca rol de ALEX)
ATOMI_LEXICALI atom_lexical; //tipul de atom lexical citit
int avem_erori=0; //aici tinem evidenta daca avem erori sau nu

int main()
{
citeste_atom(); //citeste un nou atom lexical
fisier(); //prelucrează fișierul
if (avem_erori==0)
printf ("Programul este corect dpdv. sintactic");
return 0;
}
void fisier()
{
if (atom_lexical) //daca fisierul nu este gol
{
linie(); // prelucram linia
citeste_atom();
fisier();
}
} //end fisier

void linie()
{
if (atom_lexical ==NL) //daca e linie vida
return;
if (atom_lexical == ID) //daca avem cod (atom lexical ID)
{
cod(); //prelucreaza codul
citeste_atom(); //cautam o virgula sau un NL dupa cod
if (atom_lexical) //daca se citeste ceva
{
if (atom_lexical ==NL) //daca linia se termina dupa cod
return;
if (atom_lexical !=VIRGULA) //daca se citeste ceva care nu e virgula
{
eroare(4); // ar trebui sa urmeze o virgula
return;
}
citeste_atom(); // Daca am ajuns aici, s-a citit o virgula. Citim atomul de
dupa virgula.
if ((atom_lexical !=F) && (atom_lexical != DIEZ))
{
eroare(5); // dupa virgula trebuie sa urmeze F sau DIEZ
return;
}
}
}

if (atom_lexical == F) //daca avem o incasare (fie după virgulă, fie prima pe linie daca nu
există cod)
{
citeste_atom();
if (atom_lexical) //daca se citeste ceva
{
if (atom_lexical==NL) //daca linia se termina dupa incasare
return;
if (atom_lexical !=VIRGULA) //daca se citeste ceva care nu e virgula
{
eroare(4); // ar trebui sa urmeze o virgula
return;
}
op(); // dacă am ajuns aici fără erori, atunci după virgulă ar trebui să urmeze
o plată, pe care o prelucrăm cu funcția op()
citeste_atom();
if ((atom_lexical) && (atom_lexical !=NL))
// daca mai există ceva in fisier după plată, ar trebui să urmeze pe o linie
nouă
{
eroare(2); // se asteapta NL sau end of file după plată( deoarece e
finalul liniei)
return;
}
}

else if (atom_lexical == DIEZ) // F si #F nu pot coexista pe aceeași linie, deci #F e


pe ramura de else if si se ajunge la el doar daca nu am avut direct F dupa virgula
{
citeste_atom(); //aici ar trebui sa se citeasca un nr real
if(atom_lexical != F)
{
eroare(3); //se așteaptă nr. real după diez
return;
}
citeste_atom();
if ((atom_lexical) && (atom_lexical !=NL))
//daca mai exista ceva in fisier, ar trebui să urmeze pe o linie nouă
{
eroare(2); // ar trebui sa fie NL sau end of file la finalul unei
linii
return;
}
}
} //end linie

void cod()
{
if (atom_lexical != ID)
{
eroare(1); // trebuia sa urmeze un ID
return;
}
citeste_atom(); //dacă nu există erori, trecem mai departe la atomul următor
cod_prim();
}

void cod_prim()
{
if (atom_lexical==SAGEATA)
{
citeste_atom();
if (atom_lexical != ID)
{
eroare(1); // Ar trebui sa urmeze un ID
return;
}
cod_prim(); //pot urma mai multe sub-coduri introduse prin săgeată, deci
continuăm să le căutăm după fiecare săgeată
}
}

void op()
{
citeste_atom();
if (atom_lexical == DIEZ) // daca incepe cu un diez, trecem la atomul urmator
citeste_atom();
if(atom_lexical != F) //ar trebui să urmeze un nr. real. Aici ajungem indiferent daca
există diez sau nu.
eroare(6); //plata ar trebui sa fie un nr real – dacă nu este, semnalăm
eroarea
}

void eroare(int error_code); // pentru raportarea erorilor


{
avem_erori=1; //daca s-a ajuns aici, avem erori si punem variabila globala pe 1
switch (error_code) { //acestea sunt tipurile de erori pe care le-am putea intalni
case 1:
printf ("Ar trebui sa urmeze un ID: sir de caractere si cifre care incep cu un
caracter.");
break;
case 2:
printf ("Ar trebui sa urmeze un NL la finalul liniei sau sa fie end of file.");
break;
case 3:
printf ("Ar trebui sa urmeze un nr real dupa DIEZ.");
break;
case 4:
printf ("Ar trebui sa urmeze o virgula.");
break;
case 5:
printf ("Dupa virgula ar trebui sa urmeze F sau DIEZ.");
break;
case 6:
printf ("Plata ar trebui sa fie un nr real.");
break;
}
}

11. Assignment 2
Se cere automatul cu stari finite si analizorul lexical care recunoaste un numar intreg, scris in oricare
dintre cele 3 baze de numeratie: binar, zecimal, hexazecimal. Partile subliniate reprezinta atomi
lexicali

BD=0 | 1
DD=0 .. 9
HD=0 .. 9 | a .. f | A .. F
INT= 0 (x HD+ | b BD+) | DD+
AD

2 AD 3
Altc
X eva

4
Start 0 0 1 BD
a
B cev
Alt
5 BD 6

DD va
ltce
A
7

#include <iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
struct atom
{
char nume;
int codLexical;//2=identificator,1=constanta,0=eroare, nu avem cuvinte cheie
};
//pt. simplitate, stochez atomul ca vector, deci atributul va fi indexul.
int stare=0;
atom BD(char c)
{
atom b;
if ((c=='0')||(c=='1'))
{
b.codLexical=1;
b.nume=c;
}
else
{
b.codLexical=0;
b.nume=c;
stare=-1;
};
return (b);
};
atom DD(char c)
{
1/9
atom b;
if (isdigit(c))
{
b.codLexical=1;
b.nume=c;
}
else
{
b.codLexical=0;
b.nume=c;
stare=-1;
};
return (b);
};
atom HD(char c) {
atom b;
if (isdigit(c))
{
b.codLexical=1;
b.nume=c;
}
else
{
if ((isupper(c))&&(c<='F'))
{
b.codLexical=1;
b.nume=c;
}
else
{
if ((islower(c))&&(c<='f'))
{
b.codLexical=1;
b.nume=c;
}
else
{
b.codLexical=0;
b.nume=c;
stare=-1;
}
}
}; 2/9
return (b);
};
atom INT(char c)
{
atom b;
if (stare==0)
{
if (isdigit(c))
{
if(c=='0') //starea 2, 0
{
b.codLexical=1;
b.nume=c;
stare=2;
}
else //starea 1, numar>0
{
b.codLexical=1;
b.nume=c;
stare=1;
}
}
else //eroare, asteptam un numar
{
b.codLexical=0;
b.nume=c;
stare=-1;
}
return b;
}
else
{
//cel putin primul caracter ce defineste starea a fost ales.
if (stare==1)
{
return (DD(c));
}
else
{
if(stare==2)
{
if (c=='x')
3/9
{
//starea 3
b.codLexical=1;
b.nume=c;
stare=3;
}
else
{
if (c=='b')
{
//starea 5
b.codLexical=1;
b.nume=c;
stare=5;
}
else stare=-1; //avem o eroare...
}
return b;
}
if (stare==3)
{
return(HD(c));
}
if (stare==5)
{
return(BD(c));
}
}
}
};
void afisare(atom Atom[],int lungime)
{
int i;
cout<< "Afisarea atomilor:\n";
cout<<"Sirul de nume :";
for(i=0; i<lungime; i++)
{
cout<< Atom[i].nume<<"| ";
};
cout<<"\nCodurile lexicale:";
for(i=0; i<lungime; i++)
{
4/9

cout<< Atom[i].codLexical<<"| ";


};
cout<<"\n";
};
int main()
{
atom atomul[9999];
int i,nr;
string intrarea;
intrarea="xxxxxxxx";
nr=0;
stare=0;
cout<<"Sirul "<<intrarea;
for (int i = 0; i < intrarea.size(); i++)
{
atomul[nr]=INT((char)intrarea[i]);
if (((int)atomul[nr].codLexical==0)||(stare==-1))
{
i=intrarea.size();
cout<<"Contine erori:";
};
nr++;
};
cout<<"\n";
afisare(atomul, nr);
intrarea="0b10101";
nr=0;
stare=0;
cout<<"Sirul "<<intrarea;
for (int i = 0; i < intrarea.size(); i++)
{
atomul[nr]=INT((char)intrarea[i]);
if (((int)atomul[nr].codLexical==0)||(stare==-1))
{
i=intrarea.size();
cout<<"Contine erori:";
};
nr++;
};
cout<<"\n";
afisare(atomul, nr);
5/9

intrarea="0xfFaA510101";
nr=0;
stare=0;
cout<<"Sirul "<<intrarea;
for (int i = 0; i < intrarea.size(); i++)
{
atomul[nr]=INT((char)intrarea[i]);
if (((int)atomul[nr].codLexical==0)||(stare==-1))
{
i=intrarea.size();
cout<<"Contine erori:";
};
nr++;
};
cout<<"\n";
afisare(atomul, nr);
intrarea="353450431";
nr=0;
stare=0;
cout<<"Sirul "<<intrarea;
for (int i = 0; i < intrarea.size(); i++)
{
atomul[nr]=INT((char)intrarea[i]);
if (((int)atomul[nr].codLexical==0)||(stare==-1))
{
i=intrarea.size();
cout<<"Contine erori:";
};
nr++;
};
cout<<"\n";
afisare(atomul, nr);
return 0;
}

3. Automatul cu stări finite corespunzător seriei de atomi cerute:

Ce este un compilator?
Un compilator este un translator care citeşte un program scris într-un limbaj de nivel înalt (limbajul
sursă) şi îl traduce într-un limbaj echivalent în alt limbaj, de nivel mai scăzut (limbajul obiect sau
destinaţie).

Care sunt fazele unui compilator?


12. Assignment 5
Sa se scrie un analizor lexical corespunzator setului de atomi din definitia de mai jos. Se va realiza si
automatul cu stari finite aferent acestei definitii.

 escape -> \ (0|n|t|”|’|r)
 string -> “(char | escape)* ”
 char -> a..z|A..Z|0..9|_|spatiu

Rezolvare:

Automatul cu stări finite aferent definiției din enunț:

Codul Analizorului lexical:

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
typedef struct _Token{
char *buf;
struct _Token *next;

} Token;
int printError(const char *format, ...)

va_list va;
va_start(va,format);
fprintf(stderr,"parse error: ");
vfprintf(stderr,format,va);
fputc('\n',stderr);
va_end(va);
exit(1);

}
Token* tokenize(char *buf)

Token *root = NULL;

Token *tok = NULL;

Token *tmp = NULL;

int state = 0;
int sp = 0;
int ep = 0;
int dif = 0;

while (1){

if (buf[ep] == '\0'){

break;

switch (state) {
case 0:

if (buf[sp] != '"'){

sp++;

ep++;

} else { ep++;

state = 1;

break;

case 1:

if ( buf[ep] == '\\' ){

ep++;

state = 2;

}else if (('a' <= buf[ep] && buf[ep] <= 'z') || ('A' <= buf[ep]
&& buf[ep] <= 'Z') || ('0' <= buf[ep] && buf[ep]
<= '9') || buf[ep] == '_' ||

buf[ep] == ' ') {

ep++;

}else if ( buf[ep] == '"' ){

ep++;

state = 4;
}else {

state = 3;

break;

case 2:

if (buf[ep] == '0' ||

buf[ep] == 'r' ||
buf[ep] == 'n' ||
buf[ep] == 't' ||
buf[ep] == '\'' ||
buf[ep] == '"'){
ep++;
state = 1;

} else { state = 3;

break;

case 3:

printError("sir: %s \n positie %d", buf, ep); break;

case 4:

tmp = (Token *) malloc(sizeof(Token)); dif = ep -


sp;

tmp->buf = (char*)malloc(dif + 1 );
memcpy(tmp->buf, buf+sp, dif); tmp->buf[dif]
= '\0'; tmp->next = NULL;

if (!root

root = tmp;

}else

tok->next = tmp;

tok = tmp;

sp = ep;

state = 0;

break;

default:

break;
}
}
return root;
}
void printTokens(Token *root)
{
printf("Tokeni lexicali: \n");

while (root){

printf("%s\n", root->buf);

root = root->next;

}
}
int main(int argc, const char * argv[])
{
char unparsedBuff[50] = "\"primul token\"
ajkd \"doi\"\"al_trei\\nlea\"\"\"";
Token *parsedTokens;

parsedTokens = tokenize(unparsedBuff);
printTokens(parsedTokens);
return 0;

You might also like