Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
lfa:2025:proiect:etapa2 [2025/11/25 18:58] pdmatei |
lfa:2025:proiect:etapa2 [2025/11/25 20:48] (current) ldaniel |
||
|---|---|---|---|
| Line 74: | Line 74: | ||
| Un parser foloseste output-ul produs de lexer pentru etapa de analiza sintactica a textului. | Un parser foloseste output-ul produs de lexer pentru etapa de analiza sintactica a textului. | ||
| - | Construim un parser pe baza unei gramatici care contine reguli ce descriu sintaxa valida a inputului. O astfel de gramatica va folosi lexemele generate de analiza lexicala in rolul de terminali. | + | Construim un parser pe baza unei gramatici care contine reguli ce descriu sintaxa valida a inputului. O astfel de gramatica va folosi categoriile lexicale generate de analiza lexicala in rolul de terminali. |
| === Sintaxa pentru gramatici === | === Sintaxa pentru gramatici === | ||
| Line 105: | Line 105: | ||
| In plus fata de algoritmul CYK implementat la curs, care ne spune daca un text este acceptat de gramatica, ne dorim sa avem si secventa de derivari care a produs cuvantul, sau echivalent: arborele de parsare pentru textul nostru. In scheletul temei aveti implementata o clasa numita ParseTree, care reprezinta arborele de parsare. | In plus fata de algoritmul CYK implementat la curs, care ne spune daca un text este acceptat de gramatica, ne dorim sa avem si secventa de derivari care a produs cuvantul, sau echivalent: arborele de parsare pentru textul nostru. In scheletul temei aveti implementata o clasa numita ParseTree, care reprezinta arborele de parsare. | ||
| - | Arborele de parsare va fi afisat ca un arbore in care copiii au o indentare cu 2 spatii mai la dreapta decat parintele. Pentru regulile intermediare generate de normalizarea gramaticii (care trebuie sa inceapa cu **int_**) nu se va afisa numele regulii, ci direct copiii. Pentru regulile simple, de tipul neterminal produce un terminal (a: TOKEN) se va afisa doar categoria lexicala si lexemul corespunzator, fara numele regulii. Aceste lucruri sunt deja implementate in metoda str() a lui ParseTree. | + | Arborele de parsare va fi afisat ca un arbore in care copiii au o indentare cu 2 spatii mai la dreapta decat parintele. |
| - | Pentru a obtine un arbore de parsare ca rezultat, in implementarea algoritmului CYK va recomandam sa folositi o matrice de dictionare in care pentru fiecare neterminal sa aveti ca valoare un nod de ParseTree cu informatiile despre derivarile bottom-up care au dus la obtinerea acelui neterminal. La final, in caz de acceptare, arborele de parsare afisat va fi nodul de arbore aferent simbolului de start. | + | Atunci cand doreste sa foloseasca o gramatica independenta de context arbitrara pentru parsare, programatorul trebuie intai sa o converteasca (manual) in FNC. Pentru a usura vizualizarea arborilor de parsare, convenim sa denumim toti non-terminalii creati in procesul de conversie cu **int_**. Vom folosi aceasta conventie pentru a nu afisa regulile ce au in stanga un non-terminal de forma **int_**, ci direct copii. Astfel, arborii de parsare sunt mai usor de citit. Pentru regulile simple, de tipul neterminal produce un terminal (a: TOKEN) se va afisa doar categoria lexicala si lexemul corespunzator, fara numele regulii. Aceste lucruri sunt deja implementate in metoda str() a lui ParseTree. |
| + | |||
| + | Pentru a obtine un arbore de parsare ca rezultat, in implementarea algoritmului CYK va recomandam sa folositi o matrice de dictionare in care pentru fiecare neterminal sa aveti ca valoare un ParseTree cu informatiile despre derivarile bottom-up care au dus la obtinerea acelui neterminal. La final, in caz de acceptare, arborele de parsare afisat va fi arborele avand ca radacina simbolul de start. | ||
| === Cerinta: === | === Cerinta: === | ||
| Line 119: | Line 121: | ||
| 3. Completati specificatia pentru Lexerul de expresii lambda in fisierul "**lexer_spec.json**", adaugand regex-ul potrivit pentru fiecare Token. | 3. Completati specificatia pentru Lexerul de expresii lambda in fisierul "**lexer_spec.json**", adaugand regex-ul potrivit pentru fiecare Token. | ||
| - | 4. In clasa Parser completati metoda "parse", pentru a scrie un parser general care citeste o gramatica in FNC din fisierul primit ca parametru la initializare si returneaza arborele de parsare. | + | 4. In clasa Parser completati metoda "parse", care primeste un text de intrare si returneaza arborele de parsare. Folositi-va de campurile lexer si grammar ale parserului pentru analiza lexicala si apoi analiza sintactica a textului. Dupa analiza lexicala va trebui sa ignoratii tokenii SPACE inainte de a trece la analiza sintactica. |
| === Exemplu de parsare === | === Exemplu de parsare === | ||
| - | Pentru textul "int x = 1 + 2" analiza lexicala a produs tokenii [(TYPE, "int"), (ID, "x"), (EQUAL, "="), (NUMBER, "3"), (PLUS, "+"), (NUMBER, "2")] (tokenii de SPACE au fost ignorati). | + | Pentru textul "int x = 1 + 2" analiza lexicala a produs tokenii [(TYPE, "int"), (ID, "x"), (EQUAL, "="), (NUMBER, "3"), (PLUS, "+"), (NUMBER, "2")] (tokenii SPACE au fost ignorati). |
| - | Parserul e configurat cu urmatoarea gramatica (care in exemplu nu e in FNC, dar inainte de a fi interpretata de Parser a fost normalizata): | + | Parserul e configurat cu urmatoarea gramatica (care in exemplu nu e in FNC, dar inainte de a fi interpretata de Parser a fost convertita la FNC): |
| <code> | <code> | ||
| assign: TYPE ID EQUAL sum | assign: TYPE ID EQUAL sum | ||
| Line 172: | Line 174: | ||
| │ ├── __init__.py | │ ├── __init__.py | ||
| │ ├── DFA.py | │ ├── DFA.py | ||
| - | │ ├── Grammar.py | ||
| - | │ ├── Lexer.py | ||
| │ ├── NFA.py | │ ├── NFA.py | ||
| + | │ ├── Regex.py | ||
| + | │ ├── Lexer.py | ||
| │ ├── Parser.py | │ ├── Parser.py | ||
| + | │ ├── Grammar.py | ||
| │ ├── ParseTree.py | │ ├── ParseTree.py | ||
| | ... (alte surse pe care le folositi) | | ... (alte surse pe care le folositi) | ||