Lukáš Turek

Indent – formátování zdrojového kódu v jazyce Pascal

Dokumentace

Zadání

Napište program, který naformátuje zadaný zdrojový kód v jazyce Pascal.

Princip funkce programu

Základem programu je vyhledávací stroj (konečný automat) sloužící k hledání klíčových slov a operátorů. Je implementován stromem: v každém uzlu je pole 256 pointerů (1 pointer odpovídá jednomu znaku), tzv. přechodová funkce. Přechodová funkce je buď definována (ukazuje na další uzel stromu) nebo je nedefinována (pointer je nil). Tento strom se po spuštění programu vytvoří ze souboru keywords.txt, obsahujícího klíčová slova a jejich formát. Formát je hodnota typu longint, jejíž jednotlivé bity určují formátovací příznaky. Jejich popis a vztahy mezi nimi jsou v komentářích ke zdrojovému kódu.

Hledání ve stromě: začneme v kořeni, pokud je přechodová funkce pro znak slova definována, přejdeme na další uzel stromu a postup opakujeme pro další písmeno. Je-li nedefinována, vrátíme formát uložený v posledním navštíveném uzlu.

Konstrukce stromu: dokud je přechodová funkce definována, postupujeme jako u vyhledávání. Potom začneme vytvářet nové uzly pro zbývající písmena slova. Do posledního vytvořeného uzlu uložíme formát slova.

Formátování lze rozdělit do tří částí:

  1. Vkládání mezer

    Nejjednodušší, poměrně jednoduchá pravidla. Problém způsobuje snad jen operátor ^ (někdy je před identifikátorem a někdy za ním).

  2. Odsazování

    Nejsložitější (tělo cyklu může být 1 příkaz nebo blok, přiřazení else správnému if). Použil jsem zásobník, do kterého se odsazení ukládá. Při zvýšení odsazení se do zásobníku vloží značka. Značka označuje skutečné odsazení a má dva typy: normální (IND_ONELINE) a speciální (IND_2PARTS). Ta se používá u příkazu if, ke kterému může příslušet else. Na konci řádku se ze zásobníku vyhodí všechny hodnoty do poslední zarážky.

    Zarážkou je:

    Spolu s přidáváním a odstraňováním ze zásobníku se upravuje i proměnná indent určující aktuální odsazení.

    Vedle toho existuje zvláštní odsazení (special_indent) pro var, type, const apod., aby byly identifikátory deklarovaných proměnnných, typů a konstant pěkně pod sebou.

  3. Vkládání prázdných řádků

    Prázdné řádky pro zlepšení čitelnosti textu se vkládají podle souboru pravidel: před a za blok, mezi procedury apod.

Detailní popis je v komentářích ke zdrojovému kódu.

Poznámka: program zcela ignoruje původní formát, vytváří jej znovu. Jedinou vyjímkou jsou komentáře: rozlišuje, zda je komentář umístěn na konci řádky nebo na samostatné řádce.

Vstup

Vstup je načítán ze souboru, jehož jméno je zadáno jako 1. parametr na příkazové řádce. Program kontroluje, zda soubor existuje a lze jej číst. Vstupem programu je libovolný syntakticky správný zdroják v jazyce Pascal. Pokud nebude vstup syntakticky správně, program se nezhroutí, pouze bude výsledné naformátování nedefinované (a pravděpodobně horší, než původní).

Výstup

Výstup se zapíše do souboru, jehož jméno je zadáno jako 2. parametr na příkazové řádce. Program kontroluje, zda lze do souboru zapisovat. Pokud nedojde k žádné chybě, nevypisuje program na konzoli nic. V případě chyby (nelze číst vstupní soubor, nelze zapisovat výstupní soubor, chybí parametr) vypíše odpovídající hlášení. Je-li program zavolán bez parametrů, vypíše požadovanou syntaxi.

Testovací data

K programu přikládám testovací soubor Test.pas, který jsem používal k ladění programu. Druhým testovacím souborem je samotný zdrojový kód programu :-)

Nedostatky (aneb co by se dalo zlepšit)

Závěr

Předpokládal jsem, že bude program výrazně jednodušší. Ale Pascal mě nepříjemně překvapil, neustále jsem musel přidávat další pravidla, vyjímky z nich, vyjímky z vyjímek: dvojznačná klíčová slova (of, var), operátor "^", operátor ":", …