Náznak ukázky syntaxe a sémantiky pro projekt. 1 Syntaktické prvky. Poslední aktualizace: 8.

Podobné dokumenty
Implementace LL(1) překladů

Syntaktická analýza. Implementace LL(1) překladů. Šárka Vavrečková. Ústav informatiky, FPF SU Opava

Překladač a jeho struktura

Poslední aktualizace: 14. října 2011

Binární vyhledávací strom pomocí směrníků Miroslav Hostaša L06620

Implementace seznamů do prostředí DELPHI pomocí lineárního seznamu

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

Programovací jazyk Pascal

Maturitní otázky z předmětu PROGRAMOVÁNÍ

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Úvod do programovacích jazyků (Java)

6. Příkazy a řídící struktury v Javě

Algoritmizace a programování

1. D Y N A M I C K É DAT O V É STRUKTUR Y

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Reprezentace aritmetického výrazu - binární strom reprezentující aritmetický výraz

6 Příkazy řízení toku

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

Vyučovací hodina. 1vyučovací hodina: 2vyučovací hodiny: Opakování z minulé hodiny. Procvičení nové látky

Abstraktní datové typy FRONTA

Sémantika Tabulka symbolů Intermediální kód Typová kontrola, přetypování Statická a dynamická sémantika. Sémantická analýza.

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

O datových typech a jejich kontrole

Časová a prostorová složitost algoritmů

type Obdelnik = array [1..3, 1..4] of integer; var M: Obdelnik;

Úvod do programování

Syntaxí řízený překlad

Činnost: 1) Vyhodnotí se výraz E. 2) Jeho hodnota se uloží do proměnné V.

Binární vyhledávací stromy

dovolují dělení velkých úloh na menší = dekompozice

Program a životní cyklus programu

Základní způsoby: -Statické (přidělění paměti v čase překladu) -Dynamické (přiděleno v run time) v zásobníku na haldě

Řídicí struktury. alg3 1

Základní způsoby: -Statické (přidělění paměti v čase překladu) -Dynamické (přiděleno v run time) v zásobníku na haldě

Programovací jazyk. - norma PASCAL (1974) - implementace Turbo Pascal, Borland Pascal FreePascal Object Pascal (Delphi)

Interpret jazyka IFJ2011

NPRG030 Programování I, 2015/16 1 / :25:32

Uplatnění metod na zvolený jazyk

Obsah přednášky. programovacího jazyka. Motivace. Princip denotační sémantiky Sémantické funkce Výrazy Příkazy Vstup a výstup Kontinuace Program

Anotace. Soubory a práce s nimi, rekurze podruhé, struktury (datový typ record), Martin Pergel,

1. Implementace funkce počet vrcholů. Předmět: Algoritmizace praktické aplikace (3ALGA)

1 PRVOCISLA: KRATKY UKAZKOVY PRIKLAD NA DEMONSTRACI BALIKU WEB 1

Aplikovaná informatika. Podklady předmětu Aplikovaná informatika pro akademický rok 2006/2007 Radim Farana. Obsah. Obsah předmětu

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

NPRG030 Programování I, 2016/17 1 / :58:13

Anotace. Dámy na šachovnici dominance a nezávislost. Aritmetické výrazy, notace a převody mezi nimi, nejdelší rostoucí podposloupnost.

Atributovaný překlad

Tematický celek Proměnné. Proměnné slouží k dočasnému uchovávání hodnot během provádění aplikace Deklarace proměnných

GENEROVÁNÍ KÓDU 9. SHRNUTÍ - PŘÍKLAD POSTUPU PŘEKLADU VSTUPNÍHO PROGRAMU (ZA POUŽITÍ DOSUD ZNÁMÝCH TECHNIK)

Standardní algoritmy vyhledávací.

NPRG030 Programování I, 2010/11

Implementace binárního stromu směrníky

Obecná informatika. Matematicko-fyzikální fakulta Univerzity Karlovy v Praze. Podzim 2012

Sada 1 - Základy programování

Identifikátory označují objekty v programu používané (proměnné, typy, podprogramy).

Algoritmizace. 1. Úvod. Algoritmus

NPRG030 Programování I, 2017/18 1 / :22:16

Implementace aritmetického stromu pomocí směrníků

Dynamické datové typy a struktury

Sada 1 - Základy programování

NPRG030 Programování I, 2018/19 1 / :03:07

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

ŘÍDÍCÍ STRUKTURY - PODMÍNKY

Anotace. Spojové seznamy, haldy. AVL-stromy, A-B stromy. Martin Pergel,

Virtuální počítač. Uživatelský program Překladač programovacího jazyka Operační systém Interpret makroinstrukcí Procesor. PGS K.

Lexikální analýza Teorie programovacích jazyků

PODPROGRAMY PROCEDURY A FUNKCE

PROGRAMOVACÍ JAZYKY A PŘEKLADAČE LL SYNTAKTICKÁ ANALÝZA DOKONČENÍ, IMPLEMENTACE.

Západočeská univerzita v Plzni Dokumentace překladače PL/0 v PHP Předmět KIV/FJP

Struktura programu v době běhu

2.1 Podmínka typu case Cykly Cyklus s podmínkou na začátku Cyklus s podmínkou na konci... 5

Binární vyhledávací strom. Proč binární? Vyhledávání

Programování 2 (NMIN102) Soubory. RNDr. Michal Žemlička, Ph.D.

Anotace. zpět k rekurzi: teorie her. Martin Pergel,

X36UNX 16. Numerické výpočty v sh příkazy expr, bc, dc. Zdeněk Sojka

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

Příklady: (y + (sin(2*x) + 1)*2)/ /2 * 5 = 8.5 (1+3)/2 * 5 = /(2 * 5) = 1.3. Pavel Töpfer, 2017 Programování 1-3 1

GENEROVÁNI KÓDU jazyk Mila

Inovace bakalářského studijního oboru Aplikovaná chemie

PROGRAMOVÁNÍ V SHELLU

1.1 Struktura programu v Pascalu Vstup a výstup Operátory a některé matematické funkce 5

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

Anotace. Jednotky (tvorba a využití), struktury (typ record),

EVROPSKÝ SOCIÁLNÍ FOND. Úvod do PHP PRAHA & EU INVESTUJEME DO VAŠÍ BUDOUCNOSTI

Přednáška 8. Proměnné. Psaní a ladění skriptů. Parametry skriptu. Vstup a výstup. Konfigurační soubory shellu. Úvod do Operačních Systémů Přednáška 8

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Algoritmy a datové struktury

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Je n O(n 2 )? Je n 2 O(n)? Je 3n 5 +2n Θ(n 5 )? Je n 1000 O(2 n )? Je 2 n O(n 2000 )? Cvičení s kartami aneb jak rychle roste exponenciála.

Programovací jazyky. imperativní (procedurální) neimperativní (neprocedurální) assembler (jazyk symbolických instrukcí)

TÉMATICKÝ OKRUH TZD, DIS a TIS

Binární vyhledávací stromy pokročilé partie

Algoritmizace a programování

Rekurze. Pavel Töpfer, 2017 Programování 1-8 1

Generování vnitřní reprezentace programu

Anotace. Pointery. Martin Pergel,

Cvičení 7: Delphi objekty CheckedBox, Radio- Button, EditBox

ALGORITMIZACE A PROGRAMOVÁNÍ

5 Přehled operátorů, příkazy, přetypování

Transkript:

Jednoduchý interpretační překladač Náznak ukázky syntaxe a sémantiky pro projekt Šárka Vavrečková Ústav informatiky, FPF SU Opava sarka.vavreckova@fpf.slu.cz Poslední aktualizace: 8. ledna 2008 1 Syntaktické prvky matematické výrazy, proměnné (celočíselné), celá čísla, begin, end, var, obdelnik, jestli, pak, cti, pis, možné příkazy: var prom1, prom2,...; deklarace proměnných příkaz var je vždy na začátku programu, ukončení středníkem je povinné, proměnné nemusí být žádné, obdelnik(x,y,s,v) vykreslení obdélníka na souřadnice [x, y] o šířce s a výšce v, parametry jsou výrazy, cti(prom), pis(vyraz), begin... end složený příkaz, blok, jestli podminka pak prikaz rozhodování, podmínka je vyraz < vyraz nebo vyraz = vyraz, prom := vyraz přiřazovací příkaz, dvojsymbol := se načte lexikálním analyzátorem jako symbol r, příkazy jsou ukončeny středníkem. 1

2 Popis jazyka Sémantické prvky: proměnné musí být deklarovány na začátku programu, při deklaraci je proměnná zařazena do tabulky symbolů, protože je umožněno používat příkaz typu IF, příkazy mají dědičný atribut prov (proved ), který je při nesplnění podmínky nastaven na false a tato hodnota je také děděna (například u příkazu bloku), příkaz je proveden (interpretován) pouze tehdy, když má atribut proved nastaven na true, jinak je pouze syntakticky rekurzívně rozvinut (pro kontrolu syntaktických chyb). 2.1 Syntaxe S DbT e. D vi deklarace I ij I ; J, I T P R posloupnost příkazů T ε R ; T P o(v, V, V, V ) obdelnik P c(i) cti P p(v ) pis P bt e blok příkazů P jmtp jestli... P irv i := V 2.2 Kontrola, zda je LL(1) V AB B +AB B AB B ε A CE E CE E /CE E ε C n C i C (V ) M V N N = V N < V výraz podmínka Množiny Follow: F L(S) = {$} F L(D) = {b} F L(I) = {b} F L(J) = {b} F L(T ) = {e} F L(R) = {e} F L(P ) = {; } F L(V ) = {,, ), ;, =, <, t} F L(A) = {+,,,, ), ;, =, <, t} F L(B) = {,, ),;, =, <, t} F L(C) = {, /, +,,,, ), ;, =, <, t} F L(E) = {+,,,, ), ;, =, <, t} F L(M) = {t} F L(N) = {t} Dá se snadno ověřit, že se jedná o LL(1) gramatiku. 2

3 Sémantika S Db {T.prov = true} T e. D vi I i {Pridej(i.nazev)} J I ; J, I T {P.prov = T.prov} P {R.prov = T.prov} R T ε R ; {T.prov = R.prov} T P {V 0.prov = V 1.prov = V 2.prov = V 3.prov = P.prov} o(v 0, V 1, V 2, V 3 ) {if P.prov then KresliObd(V 0.val, V 1.val, V 2.val, V 3.val)} P c(i {if P.prov then Zmen(i.N azev, NactiZeVstupu)} ) P p( {V.prov = P.prov} V {if P.prov then Vypis(V.val)} ) P b {T.prov = P.prov} T e P 0 j {M.prov = P 0.prov} Mt {if P 0.prov and M.bool then P 1.prov = true else P 1.prov = false} P 1 P ir {V.prov = P.prov} V {if P.prov then Zmen(i.nazev, V.val)} V {A.prov = B.prov = V.prov} A {if V.prov then B.m = A.val} B {if V.prov then V.val = B.val} B 0 {A.prov = B.prov = V.prov} + A {if B 0.prov then B 1.m = B 0.m + A.val} B 1 {if B 0.prov then B 0.val = B 1.val} B 0 {A.prov = B.prov = V.prov} A {if B 0.prov then B 1.m = B 0.m A.val} B 1 {if B 0.prov then B 0.val = B 1.val} B ε {if B.prov then B.val = B.m} A {C.prov = E.prov = A.prov} C {if A.prov then E.m = C.val} E {if A.prov then A.val = E.val} E 0 {C.prov = E 1.prov = E 0.prov} C {if E 0.prov then E 1.m = E 0.m C.val} E {if E 0.prov then E 0.val = E 1.val} E 0 {C.prov = E 1.prov = E 0.prov} / C {if E 0.prov then E 1.m = E 0.m/C.val} E 1 {if E 0.prov then E 0.val = E 1.val} E ε {if E.prov then E.val = E.m} C n {if C.prov then C.val = n.lex} C i {if C.prov then C.val = DejHodn(i.lex)} C ( {V.prov = C.prov} V ) {if C.prov then C.val = V.val} M {V.prov = N.prov = M.prov} V {if M.prov then N.m = V.val} N {if M.prov then M.bool = N.bool} N = {V.prov = N.prov} V {if N.prov then N.bool = (N.m == V.val)} N < {V.prov = N.prov} V {if N.prov then N.bool = (N.m < V.val)} 3

4 Implementace Použijeme rekurzivní sestup, vytvoříme tyto funkce (procedury): S, D, I, J, T(prov: boolean), R(prov: boolean), P(prov: boolean), V(prov: boolean; var val: integer), A(prov: boolean; var val: integer), B(prov: boolean; m: integer; var val: integer), E(prov: boolean; m: integer; var val: integer), C(prov: boolean; var val: integer), M(prov: boolean; var bool: integer), N(prov: boolean; m: integer; var bool: integer), Pridej, Zmen, DejHodn pro práci s tabulkou, KresliObd pro vykreslení obdélníka, NactiZeVstupu, Vypis pro práci se vstupem a výstupem. Atribut prov a jeho testování lze vynechat, pokud nepoužijeme rozhodovací příkaz. 4.1 Tabulka Symbolů pro uložení proměnných Možnosti implementace jsou různé, jedna z nejjednodušších je třeba spojový seznam. type TNazev = string[15]; // omezeni delky nazvu promenne PPolozkaTab = ˆTPolozkaTab; TPolozkaTab = record nazev: TNazev; hodnota: integer; dalsi: PPolozkaTab; var Tabulka: PPolozkaTab; // ukazatel na prvni prvek tabulky procedure InicializujTabulku(var tab: PPolozkaTab); procedure ZnicTabulku(var tab: PPolozkaTab); procedure Najdi(var ukaz_tab: PPolozkaTab; nazev: TNazev); // v ukazateli ukaz_tab vrati ukazatel na tu polozku tabulky, ve ktere // je promenna s danym nazvem, kdyz v seznamu neni, vrati nil procedure Pridej(var tab: PPolozkaTab; nazev: TNazev; hodnota: integer); // jestlize je tabulka prazdna, vytvori prvni polozku s temito udaji, 4

// jestlize ne, najde dane misto v tabulce a prida zaznam // kdyby uz polozka existovala, hlasi semantickou chybu procedure Zmen(var tab: PPolozkaTab; nazev: TNazev; hodnota: integer); // overi, zda polozka s timto nazvem existuje, kdyz ne, hlasi // semantickou chybu, kdyz ano, provede zmenu hodnoty function DejHodn(tab: PPolozkaTab; nazev: TNazev): integer; // kdyz polozka s timto nazvem neexistuje, hlasi semantickou chybu První parametr těchto funkcí můžeme vynechat, pokud budeme mít jen jedinou (globální) tabulku. Jestliže chceme použít blokovou strukturu a odlišovat různé úrovně lokálních proměnných, navíc přidáme dynamický zásobník, do kterého budeme řadit tabulky bloků, a vyhledávací proceduru upravíme tak, aby začala vyhledávat na vrcholu zásobníku a pokračovala v něm dále. Jinou podobnou implementací by byl binární strom, ve kterém by se navíc zjednodušilo a zrychlilo vyhledávání. Rozdíl je jenom v uspořádání položek místo v seznamu by byly v binárním stromu, do datového typu TPolozkaTab dáme místo odkazu na následující položku dva odkazy (levý a pravý potomek). 4.2 Implementace procedury P Nejdřív uvedeme základní tvar procedury, dále vnitřek pro jednotlivá pravidla: procedure P(prov: boolean); var v1, v2, v3, v4: integer; b: boolean; s: NazevProm; begin case vstupni_sym.typ of... // jednotlive hodnoty typu symbolu else chyba(...); // case P {V 0.prov = V 1.prov = V 2.prov = V 3.prov = P.prov} o(v 0, V 1, V 2, V 3 ) {if P.prov then KresliObd(V 0.val, V 1.val, V 2.val, V 3.val)} SYM_OBD: begin expect(sym_obd); expect(sym_lzav); V(prov,v1); expect(sym_carka); V(prov,v2); expect(sym_carka); V(prov,v3); expect(sym_carka); V(prov,v4); expect(sym_rzav); if prov then KresliObd(v1,v2,v3,v4); 5

P c(i {if P.prov then Zmen(i.N azev, NactiZeVstupu)} ) SYM_CTI: begin expect(sym_cti); expect(sym_lzav); if vstupni_sym.typ = SYM_ID then s := sym.atribstr; expect(sym_id); if prov then begin NactiZeVstupu(v1); Zmen(s,v1); expect(sym_rzav); P p( {V.prov = P.prov} V {if P.prov then Vypis(V.val)} ) SYM_PIS: begin expect(sym_pis); expect(sym_lzav); V(prov,v1); if prov then Vypis(v1); expect(sym_rzav); P b {T.prov = P.prov} T e SYM_BEGIN: begin expect(sym_begin); T(prov); expect(sym_end); P 0 j {M.prov = P 0.prov} Mt {if P 1.prov and M.bool then P 1.prov = true else P 1.prov = false} P 1 SYM_JESTLI: begin expect(sym_jestli); M(prov,b); expect(sym_pak); P(prov and b); P ir {V.prov = P.prov} V {if P.prov then Zmen(i.nazev, V.val)} SYM_ID: begin s := sym.atribstr; expect(sym_id); expect(sym_prirad); V(prov,v1); if prov then Zmen(s,v1); 6

5 Příkazy cyklů U příkazů cyklů je třeba vyřešit jeden důležitý problém zpravidla je nutné se vracet v kódu. To lze řešit dvěma způsoby v závislosti na tom, jak je naprogramován lexikální analyzátor: 1. Jestliže je lexikální analyzátor v samostatném průchodu a tedy syntaktický analyzátor má k dispozici výstup lexikální analýzy vcelku (třeba jako dynamický seznam), provádí návrat samotný syntaktický analyzátor a blok kódu uvnitř cyklu včetně podmínky je vyhodnocován lexikální analýzou pouze jednou. 2. Pokud je lexikální a syntaktický analyzátor ve společném průchodu a tedy syntaktický analyzátor nemá přístup k celému svému zdroji najednou, musí provést navracení lexikální analyzátor, a to přímo ve zdrojovém souboru. Můžeme postupovat například takto: kdykoliv narazí na klíčové slovo určující cyklus, třeba while, uloží svou pozici vytvoří zarážku, když syntaktický analyzátor narazí na konec cyklu, vyhodnotí, zda se má tento cyklus znovu provést, pokud ano, požádá lexikální analyzátor o návrat k nejbližší zarážce (tj. od nejvnitřnějšího cyklu), pokud ne, požádá lexikální analyzátor o zrušení nejbližší zarážky, je třeba ošetřit i takové cykly, které se ve skutečnosti neprovedou ani jednou (to se může stát u cyklů typu while). Nevýhodou je nutnost provádět lexikální analýzu obsahu cyklu a podmínky opakovaně pro všechny průchody. To se sice dá řešit vytvořením dočasného mezikódu vnitřku cyklu, ale toto řešení není zrovna transparentní, už proto, že cyklus může být třeba v rozsahu celého programu a také cykly mohou být navzájem vnořené, čímž se dostáváme k prvnímu bodu tohoto seznamu a ztrácíme výhodu zařazení obou fází překladu do společného průchodu. První případ se řeší zachycením ukazatele do seznamu výstupu lexikální analýzy, druhý vytvořením funkcí pro komunikaci s lexikálním analyzátorem s tím, že je nutné vyřešit samotné navracení ve vstupu (soubor by mohl být načten jako stream, ve kterém se lze snadněji pohybovat). Ukážeme si náznak řešení pro příkaz while v případě použití prvního postupu (lexikální analyzátor je v samostatném průchodu), implementace druhého postupu by byla podobná (práce se zarážkami). Pravidlo včetně sémantiky bude vypadat takto: P 0 w {M.prov = P 0.prov, UlozUmisteni, repeat, NactiUmisteni} Md {P 1.prov = P 0.prov and M.bool} P 1 {until not(p 1.prov and M.bool} 7

Programový kód (úsek v proceduře P) vypadá takto: SYM_WHILE: begin expect(sym_while); pom_sym := zpracovavany_symbol; // zachytime momentalni pozici v kodu repeat zpracovavany_symbol := pom_sym; // vratime se na zachycenou pozici M(prov,b); expect(sym_do); P(prov and b); until not (prov and b); 8