This is an old revision of the document!


Schelet si checker pentru fiecare limbaj:

Deadline etapa 3: … ora 23:59

Proiect

Etapa 3 a proiectul consta in implementarea unui lexer in python sau scala.

Este recomandat sa va folositi de functionalitatile implementate la etapele precedente pentru rezolvarea etapei

Un lexer este un program care imparte un sir de caractere in subsiruri numite lexeme, fiecare dintre acestea fiind clasificat ca un token, pe baza unei specificatii.

Care este input-ul unui lexer?

Lexer-ul primeste initial o specificatie de forma:

TOKEN1 : REGEX1;

TOKEN2 : REGEX2;

TOKEN3 : REGEX3;

...

unde fiecare TOKENi este un nume dat unui token, iar REGEXi este un regex ce descrie lexemele ce pot fi clasificate ca acel token. Puteti imagina aceasta specificatie ca un fisier de configurare, care descrie modul in care va functiona lexerul pe diverse fisiere de text.

Inputul efectiv al unui lexer este un text care va fi impartit in lexeme folosind expresii regulate. In cursurile viitoare veti afla mai multe detalii despre cum functioneaza si cum sunt implementate lexerele.

Care este output-ul unui lexer?

Lexer-ul are ca output o lista de forma : [(lexema1, TOKEN_LEXEMA_1), (lexema2, TOKEN_LEXEMA_2), …], unde TOKEN_LEXEMA_N este numele token-ului asociat lexemei n, pe baza specificatiei.

Python

Pentru aceasta etapa va fi nevoie sa implementati clasa Lexer cu 2 metode obligatorii:

  • constructorul care primeste ca parametru configuratia lexerului
  • metodalex care va primi un cuvand ca str si va intoarce rezultatul lexarii lui sub forma List[Tuple[str, str]] | str. Metoda lex va intoarce o lista de tupluri (token, lexem_cuvant) in cazul in care lexarea reuseste si un string cu un mesaj de eroare in caz contrar. (Mai multe despre cazurile in care un lexer poate esua mai jos)

Specificatia va fi incarcata in teste sub forma unui dictionar TOKEN → REGEX

Scala

Erorile de lexare sunt in general cauzate o configuratie gresita / incompleta sau de un cuvant invalid. Informatiile care trebuie transmise in acest caz trebuie sa ajute programatorul sa isi dea seama unde un cod s-a intamplat eroare si care este tipul erorii. Din acest motiv vom afisa linia si coloana unde lexarea a esuat si tipul erorii.

  • Unordered List ItemEroare cauza de un caracter invalid in cuvant

Aceasta eroare va aparea daca lexarea s-a oprit fara a accepta nici-un cuvant in prealabil. Aceasta este echivalenta cu ajungerea in starea SINK_STATE a lexerului fara a trece in prealabil printr-o stare finala. In acest caz vom afisa un mesaj de eroare in formatul

No viable alternative at character ..., line ...

In primul loc liber vom pune indexul caracterului unde s-a oprit lexarea (am ajuns in SINK_STATE) indexat de la 0, iar in an doilea spatiu liber vom pune linia unde s-a intamplat asta (indexata de la 0).

  • Unordered List ItemEroare cauza de un cuvant incomplet

Aceasta eroare va aparea daca lexarea a ajuns la finalul cuvantului fara a accepta in prealabil un lexem. In aceasta stare lexerul nu a ajuns in sink state, insa nici intr-o stare finala. In acest caz vom afisa un mesaj de eroare in formatul:

No viable alternative at character EOF, line ...

Ca un mic rezumat: prima eroare apare atunci cand caracterul la care am ajuns este invalid si nu avem cum sa acceptam, iar a doua apare atunci cand lexerul ar mai accepta, insa cuvantul este incomplet si nu mai are ce.

Python

In python eroare va fi intoarsa sub forma unui string de functa lex

Scala

In scala eroare va fi intoarsa sub forma unui Either[String] in formatul Left(message)

In radacina proiectului trebuie pus un fisier intitulat ID.txt ce va avea pe prima linie a sa ID-ul vostru anonim (ar trebui sa il fi primit pe mail, dar daca din vreun motiv nu il aveti, luati legatura cu asistentul vostru) si pe a doua linie limbajul in care rezolvati tema (python sau scala)

Exemplu de continut pentru ID.txt:

9921225
scala

sau

9246163
python

Structura arhivei (Python)

.
├── ID.txt
└── src
    ├── DFA.py
    ├── __init__.py
    ├── NFA.py
    ├── Regex.py
    ├── Parser.py
    ├── Lex.py
    ... (alte surse pe care le folositi)

Structura arhivei (Scala)

.
├── build.sbt
├── ID.txt
└── src
    └── main
        └── scala
            ├── Dfa.scala
            ├── Nfa.scala
            ├── Regex.scala
            ├── Lexer.scala
            
            ... (alte surse pe care le folositi)
Pentru niciunul din limbaje nu este necesar sa includeti folder-ul cu teste, dar includerea sa nu va cauza erori.