Cykly, vetvenie a sémantická analýza

Ciele
  1. Doplniť kód generátora o funkcie pre generovanie inštrukcií skokov.
  2. Doplniť prekladač o jednoduchú sémantickú analýzu.
  3. Doplniť do kódu prekladača funkcie generátora.
Úvod
    Na dnešnom cvičení si ukážeme, ako implementovať generovanie skokov. To nám umožní prekladať inštrukcie pre cyklus a vetvenie. Taktiež bude vašou úlohou vytvoriť jednoduchú sémantickú analýzu, ktorá odhalí či sme nedeklarovali dva krát tú istú premennú a či každá používaná premenná je deklarovaná.
Postup
  1. Na to, aby ste správne implementovali cyklus a vetvenie do prekladača najprv musíte pochopiť, odkiaľ a kam chcete skákať. Na zistenie aktuálnej adresy použite funkciu get_address().

    Poznámka: K premennej address pristupujeme cez funkciu get_address() preto, aby ste ju nemohli náhodou modifikovať v kóde prekladača. Hodnota sa inkrementuje automaticky pri vkladaní inštrukcie či atribútu do výstupného kódu.

    Na obrázku nižšie vidíte ilustráciu kódu pre cyklus. V oblasti Expr sa počíta výraz, ktorý rozhoduje o skoku. Teda ak výsledok výrazu je nula, cyklus sa nekoná. Zapamätajte si počiatočnú adresu, na ktorej začína oblasť Expr. Atribút pre inštrukciu BZE (teda adresu kam chceme skočiť) však budeme poznať až po vygenerovaní kódu pre telo. Zatiaľ na túto adresu vložte nulu a zapamätajte si index poľa code_list, ktorý dostanete funkciou get_address() po vložení inštrukcie BZE a jej atribútu.

    Nasleduje zápis inštrukcií pre telo cyklu. Po ukončení tohto zápisu vložte do kódu inštrukciu JMP, ktorej atribútom je počiatočná adresa oblasti Expr. Takto sa vykonávanie vráti späť na vyhodnocovanie výrazu. V tomto bode už poznáte adresu, na ktorú má cyklus skočiť ak je výsledok výrazu 0. Zapíšte túto hodnotu na pozíciu za inštrukciou BZE, ktorú ste si zapamätali vyššie.

    Obr.: : Kód pre cyklus

    Kód pre vetvenie je mierne odlišný (viď obrázok nižšie). Neskáčeme už späť ale na konci prvej vetvy musíme preskočiť celú druhu vetvu. Do druhej vetvy sa dostaneme ak výraz na začiatku je rovný nule. Vtedy teda preskočíme celý kód pre prvú vetvu. V tomto prípade si musíme v programe zapamätať pozície pre atribúty (teda indexy v code_list) oboch skokov, keďže v oboch prípadoch skáčeme vpred. Teda atribút pre inštrukciu BZE vieme zapísať až potom, čo zapíšme inštrukciu JMP do kódu. Atribút tejto inštrukcie zasa vieme doplniť až zapíšeme kód pre celé vetvenie.

    Dôležitý fakt je ten, že negatívna vetva je nepovinná. Nie je to však nutné nijak špeciálne ošetrovať, keďže v takomto prípade nám JMP skočí na nasledujúcu (PC+2) inštrukciu. Na to isté miesto skočí aj inštrukcia BZE.

    Obr.: : Kód pre vetvenie
    Úloha: Doplňte do kódu prekladača inštrukcie pre vykonanie cyklu a vetvenia.
  2. Možno ste postrehli, že váš prekladač nijak nekontroluje to, či sú všetky premenné deklarované, alebo či nemáte premennú deklarovanú viackrát. Lexikálny analyzátor obsahuje tabuľku identifikátorov, no ten slúži primárne samotnej lexikálnej analýze. Vytvorte si (najlepšie v samostatnom zdrojovom súbore) nové pole rovnakej veľkosti ako tabuľka identifikátorov, v ktorom budú príznaky (teda buď 0 alebo 1) toho, či je daná premenná deklarovaná. Index premennej je totožný s indexom tabuľky identifikátorov.

    Nastavte si váš prekladač aby takéto sémantické chyby oznamoval ako chybu, no nezastavujte samotný preklad, pretože chcete odhaliť čo najviac chýb. Na túto filozofiu nadviažeme nasledujúce cvičenie, kde sa budeme zaoberať zotavením po syntaktických chybách.

    Úloha: Vytvorte si tabuľku príznakov pre deklaráciu premenných a aj funkcie ktoré to overujú.
     
  3. V tomto bode už máte všetky informácie na zostrojenie funkčného prekladača bez zotavenia. Ak teda nemáte implementované nejaké funkcie gramatiky, teraz si ich môžete dopracovať.

    Úloha: Doplňte si do funkcií gramatiky všetky správne funkcie generátora.
    Poznámka: Ak máte všetko správne implementované, tak si môžete vyskúšať váš prekladač. Vygenerujte si binárny strojový kód a spustite ho v Computrone.
Doplňujúce úlohy
    Úloha: Rozšírte sémantickú analýzu aj o kotnrolu, či daná premenná bola inicializovaná na hodnotu. Na to môžete použiť jedno pole, v ktorom budú štruktúry pre dvojice, teda jeden príznak pre deklarácie a jeden pre inicializácie.
comments powered by Disqus