Implementace LL(1) překladů



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

Syntaxí řízený překlad

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

Poslední aktualizace: 14. října 2011

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

Výpočetní modely pro rozpoznávání bezkontextových jazyků zásobníkové automaty LL(k) a LR(k) analyzátory

Zadání: TÉMA: Zápis algoritmu, čtení textového souboru, porovnání řetězců.

Vlastnosti Derivační strom Metody Metoda shora dolů Metoda zdola nahoru Pomocné množiny. Syntaktická analýza. Metody a nástroje syntaktické analýzy

Programovací jazyk Pascal

Binární soubory (datové, typované)

Algoritmy a datové struktury

Čísla značí použité pravidlo, šipka směr postupu Analýza shora. Analýza zdola A 2 B 3 B * C 2 C ( A ) 1 a A + B. A Derivace zleva:

5 Rekurze a zásobník. Rekurzivní volání metody

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

Jednoznačné a nejednoznačné gramatiky

Řešení: PŘENESVĚŽ (N, A, B, C) = přenes N disků z A na B pomocí C

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

Překladač a jeho struktura

Automaty a gramatiky

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

6 Příkazy řízení toku

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

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

PROGRAMOVACÍ JAZYKY A PŘEKLADAČE LEXIKÁLNÍ ANALÝZA

NPRG030 Programování I, 2010/11

O datových typech a jejich kontrole

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

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

Uplatnění metod na zvolený jazyk

Bezkontextové gramatiky. Z. Sawa (VŠB-TUO) Úvod do teoretické informatiky 6. května / 49

8) Jaké jsou důvody pro použití víceprůchodového překladače Dříve hlavně kvůli úspoře paměti, dnes spíše z důvodu optimalizace

Algoritmizace a programování

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

Úvod do programovacích jazyků (Java)

Konstruktory a destruktory

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

Anotace. Dijkstrův algoritmus,

Datový typ prioritní fronta Semestrální práce z předmětu 36PT

PROGRAMOVACÍ JAZYKY A PŘEKLADAČE REALIZACE PŘEKLADAČE I

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

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

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

Kapitola 6. LL gramatiky. 6.1 Definice LL(k) gramatik. Definice 6.3. Necht G = (N, Σ, P, S) je CFG, k 1 je celé číslo.

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

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

Basic256 - úvod do programování Příklady. ing. petr polách

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

Překladač sestrojující k regulárnímu výrazu ekvivalentní konečný automat Připomeňme si jednoznačnou gramatiku G pro jazyk RV({a, b})

Konstruktory překladačů

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

ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK)

Přednáška 3. Rekurze 1

1 PRVOCISLA: KRATKY UKAZKOVY PRIKLAD NA DEMONSTRACI BALIKU WEB 1

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

Rozklad problému na podproblémy

Algoritmizace Dynamické programování. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK)

Interpret jazyka IFJ2011

Prohledávání do šířky = algoritmus vlny

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

Úvod do programování

Rekurzivní algoritmy

2 Strukturované datové typy Pole Záznam Množina... 4

- znakové konstanty v apostrofech, např. a, +, (znak mezera) - proměnná zabírá 1 byte, obsahuje kód příslušného znaku

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

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

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

1. Definujte překladač. Jaký je rozdíl mezi interpretačním a kompilačním překladačem? Co je to konverzační překladač?

Stromy. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta a kol.

Semestrální práce z předmětu Teorie programovacích jazyků

Přednáška 7. Celočíselná aritmetika. Návratový kód. Příkazy pro větvení výpočtu. Cykly. Předčasné ukončení cyklu.

DUM 06 téma: Tvorba makra pomocí VBA

Lineární spojový seznam (úvod do dynamických datových struktur)

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

Obsah přednášky. Příkaz for neúplný. Příkaz for příklady. Cyklus for each (enhanced for loop) Příkaz for příklady

Úvod do informatiky. Miroslav Kolařík

Automaty a gramatiky(bi-aag) Motivace. 1. Základní pojmy. 2 domácí úkoly po 6 bodech 3 testy za bodů celkem 40 bodů

Problém, jehož různé instance je třeba často řešit Tyto instance lze vyjádřit větami v jednoduchém jazyce

Algoritmus pro hledání nejkratší cesty orientovaným grafem

Funkce pokročilé možnosti. Úvod do programování 2 Tomáš Kühr

Algoritmizace. 1. Úvod. Algoritmus

Rekurze a zásobník. Jak se vypočítá rekurzivní program? volání metody. vyšší adresy. main(){... fa(); //push ret1... } ret1

Dynamické datové typy a struktury

Dynamicky vázané metody. Pozdní vazba, virtuální metody

Časová a prostorová složitost algoritmů

V každém kroku se a + b zmenší o min(a, b), tedy vždy alespoň o 1. Jestliže jsme na začátku dostali 2

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Datové struktury. alg12 1

VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ BRNO UNIVERSITY OF TECHNOLOGY

Dynamické datové struktury III.

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

53. ročník Matematické olympiády 2003/2004

Stromy. Strom: souvislý graf bez kružnic využití: počítačová grafika seznam objektů efektivní vyhledávání výpočetní stromy rozhodovací stromy

Motivace. Vstup a výstup. Minimální komunikace. Motivace. ÚDPJ - Vstup a výstup. Ing. Lumír Návrat katedra informatiky, A

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Dynamické datové struktury IV.

ŘÍDÍCÍ STRUKTURY - PODMÍNKY

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Bezkontextové jazyky. Bezkontextové jazyky 1 p.1/39

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

Transkript:

Překladače, přednáška č. 6 Ústav informatiky, FPF SU Opava sarka.vavreckova@fpf.slu.cz Poslední aktualizace: 30. října 2007

Postup Programujeme syntaktickou analýzu: 1 Navrhneme vhodnou LL(1) gramatiku popisující strukturu jazyka. 2 Vytvoříme podle ní překladový automat (rozkladovou tabulku). 3 Naprogramujeme: metodou přepisu rozkladové tabulky, metodou rekurzivního sestupu.

Postup Programujeme syntaktickou analýzu: 1 Navrhneme vhodnou LL(1) gramatiku popisující strukturu jazyka. 2 Vytvoříme podle ní překladový automat (rozkladovou tabulku). 3 Naprogramujeme: metodou přepisu rozkladové tabulky, metodou rekurzivního sestupu.

Postup Programujeme syntaktickou analýzu: 1 Navrhneme vhodnou LL(1) gramatiku popisující strukturu jazyka. 2 Vytvoříme podle ní překladový automat (rozkladovou tabulku). 3 Naprogramujeme: metodou přepisu rozkladové tabulky, metodou rekurzivního sestupu.

Postup Programujeme syntaktickou analýzu: 1 Navrhneme vhodnou LL(1) gramatiku popisující strukturu jazyka. 2 Vytvoříme podle ní překladový automat (rozkladovou tabulku). 3 Naprogramujeme: metodou přepisu rozkladové tabulky, metodou rekurzivního sestupu.

Postup Programujeme syntaktickou analýzu: 1 Navrhneme vhodnou LL(1) gramatiku popisující strukturu jazyka. 2 Vytvoříme podle ní překladový automat (rozkladovou tabulku). 3 Naprogramujeme: metodou přepisu rozkladové tabulky, metodou rekurzivního sestupu.

Přepis rozkladové tabulky Potřebujeme rozkladovou tabulku, zásobník na ukládání symbolů, proměnnou, ve které je uložen právě zpracovávaný symbol, funkci lex(), která nám vrátí další symbol, který extrahovala ze vstupního souboru (uloží do proměnné z předchozího bodu), proměnnou pro výstup (soubor, dynamická struktura apod.).

Popis metody Analýza probíhá takto: 1 zavoláme funkci Lex(), 2 zjistíme, o jaký symbol jde, přiřadíme terminál, 3 provedeme analýzu symbolu, zařadíme do derivačního stromu, při chybě nebo akceptování celého vstupu končíme výpočet, 4 pokud je hodnota symbolu potřebná (například identifikátor nebo číslo), uložíme ji, 5 návrat k prvnímu bodu.

Popis metody Analýza probíhá takto: 1 zavoláme funkci Lex(), 2 zjistíme, o jaký symbol jde, přiřadíme terminál, 3 provedeme analýzu symbolu, zařadíme do derivačního stromu, při chybě nebo akceptování celého vstupu končíme výpočet, 4 pokud je hodnota symbolu potřebná (například identifikátor nebo číslo), uložíme ji, 5 návrat k prvnímu bodu.

Popis metody Analýza probíhá takto: 1 zavoláme funkci Lex(), 2 zjistíme, o jaký symbol jde, přiřadíme terminál, 3 provedeme analýzu symbolu, zařadíme do derivačního stromu, při chybě nebo akceptování celého vstupu končíme výpočet, 4 pokud je hodnota symbolu potřebná (například identifikátor nebo číslo), uložíme ji, 5 návrat k prvnímu bodu.

Popis metody Analýza probíhá takto: 1 zavoláme funkci Lex(), 2 zjistíme, o jaký symbol jde, přiřadíme terminál, 3 provedeme analýzu symbolu, zařadíme do derivačního stromu, při chybě nebo akceptování celého vstupu končíme výpočet, 4 pokud je hodnota symbolu potřebná (například identifikátor nebo číslo), uložíme ji, 5 návrat k prvnímu bodu.

Popis metody Analýza probíhá takto: 1 zavoláme funkci Lex(), 2 zjistíme, o jaký symbol jde, přiřadíme terminál, 3 provedeme analýzu symbolu, zařadíme do derivačního stromu, při chybě nebo akceptování celého vstupu končíme výpočet, 4 pokud je hodnota symbolu potřebná (například identifikátor nebo číslo), uložíme ji, 5 návrat k prvnímu bodu.

Popis metody Budeme potřebovat tyto funkce: expand(číslo pravidla) uloží pravou stranu pravidla s daným číslem do zásobníku a na výstup přidá číslo pravidla, pop ověří shodnost symbolu na vstupu se symbolem vyjmutým ze zásobníku a načte další symbol ze vstupu, accept při konci vstupu a konci zásobníku ukončí výpočet programu, error ošetří chybu, která se vyskytla při překladu, Akce je hlavní řídicí funkce, v cyklu volá předchozí, zajišťuje pohyb v tabulce, Init je inicializační funkce (inicializuje zásobník, zajistí přednačtení prvního symbolu apod.), úklidová funkce je Done.

Ukážeme na příkladu: S AB A CD B +AB AB ε C (S) i n D CD /CD ε 1 2 3, 4, 5 6, 7, 8 9, 10, 11 Rozkladová tabulka i n + / ( ) $ S e1 e1 e1 A e2 e2 e2 B e3 e4 e5 e5 C e7 e8 e6 D e11 e11 e9 e10 e11 e11

Ukážeme na příkladu: S AB A CD B +AB AB ε C (S) i n D CD /CD ε 1 2 3, 4, 5 6, 7, 8 9, 10, 11 Rozkladová tabulka i n + / ( ) $ S e1 e1 e1 A e2 e2 e2 B e3 e4 e5 e5 C e7 e8 e6 D e11 e11 e9 e10 e11 e11

Proměnné vystup soub: string; (* název výstupního souboru *) vystup: text: (* soubor pro výstup programu *) konec: boolean; (* indikátor konce výpočtu, proveden accept*) vstupni sym: char; (* aktuální symbol načtený z prom. vstup *) vstupni atr: TAtribut; (* atribut právě načteného vstup. symbolu *) vrchol zasob:char; (* symbol na vrcholu zásobníku *) Dále předpokládáme funkce a datové struktury pro načtení znaku a práci se zásobníkem.

Proměnné vystup soub: string; (* název výstupního souboru *) vystup: text: (* soubor pro výstup programu *) konec: boolean; (* indikátor konce výpočtu, proveden accept*) vstupni sym: char; (* aktuální symbol načtený z prom. vstup *) vstupni atr: TAtribut; (* atribut právě načteného vstup. symbolu *) vrchol zasob:char; (* symbol na vrcholu zásobníku *) Dále předpokládáme funkce a datové struktury pro načtení znaku a práci se zásobníkem.

Hlavní funkce syntaktické analýzy Úkol: inicializovat výpočet, v cyklu volat funkci Akce pracující s tabulkou, ukončit výpočet. procedure S analyza; Init; while (not Konec) do Akce; Done;

Hlavní funkce syntaktické analýzy Úkol: inicializovat výpočet, v cyklu volat funkci Akce pracující s tabulkou, ukončit výpočet. procedure S analyza; Init; while (not Konec) do Akce; Done;

Init, Done procedure Init;... otevře vstupní soubor Vytvor zasobnik; Pridej do zasobniku( # ); Pridej do zasobniku( S ); pop; (* načte symbol ze vstupu do vstupni sym *) Konec := false; procedure Done; Zlikviduj zasobnik; (* uvolní paměť zásobníku *)... zavře soubory, atd.

Init, Done procedure Init;... otevře vstupní soubor Vytvor zasobnik; Pridej do zasobniku( # ); Pridej do zasobniku( S ); pop; (* načte symbol ze vstupu do vstupni sym *) Konec := false; procedure Done; Zlikviduj zasobnik; (* uvolní paměť zásobníku *)... zavře soubory, atd.

accept procedure accept; (* Jsme na konci vstupního souboru, syntaktická analýza správně ukončena. *) Konec := true;

pop porovná terminál ze zásobníku se vstupem (musí být stejné), posune se na vstupu (funkce Lex vrací další symbol ze vstupního souboru). procedure pop; if vstupni sym = vrchol zasob then Lex(vstupni sym, vstupni atr) else error;

pop porovná terminál ze zásobníku se vstupem (musí být stejné), posune se na vstupu (funkce Lex vrací další symbol ze vstupního souboru). procedure pop; if vstupni sym = vrchol zasob then Lex(vstupni sym, vstupni atr) else error;

expand procedure expand(cislo prav); case cislo prav of 1: (* S -> AB *) Pridej do zasobniku( B ); Pridej do zasobniku( A ); 2: (* A -> CD *) Pridej do zasobniku( D ); Pridej do zasobniku( C ); 3: (* B -> +AB *) Pridej do zasobniku( B ); Pridej do zasobniku( A ); Pridej do zasobniku( + ); 4: (* B -> -AB *) Pridej do zasobniku( B ); Pridej do zasobniku( A ); Pridej do zasobniku( - );... writeln(vystup, cislo prav);

error procedure error; Konec := true; writeln( Chyba při syntaktické analýze,... );... ošetření chyby

Akce Funkce Akce Pracuje takto: vyndá ze zásobníku jeden symbol, tím určí řádek tabulky a podle symbolu na vstupu určí sloupec tabulky, podle obsahu buňky na daném řádku a sloupci zavolá funkci expand, pop, accept nebo error (prázdná buňka znamená error), je volána v cyklu tak dlouho, dokud není konec zpracovávaného programu.

Akce procedure Akce; vrchol zasob := Vyjmi ze zasobniku; case vrchol zasob of... pro S, A B : case vstupni sym of (* řádek B *) + : expand(3); (* sloupec + *) - : expand(4); (* sloupec - *) ), $ : expand(5); (* sloupce ),$ *) else error; (* ostatní sloupce *)... pro B, C, D # : if (vstupni sym = $ ) then accept else error; else if (vrchol zasob in terminaly) then pop else error;

metody Výhody: nepoužíváme přímo rekurzi (netřeba řešit problém hloubky rekurze s prostorovou složitostí), lze využít rozkladovou tabulku. Nevýhody: hůře se implementuje sémantika.

metody Výhody: nepoužíváme přímo rekurzi (netřeba řešit problém hloubky rekurze s prostorovou složitostí), lze využít rozkladovou tabulku. Nevýhody: hůře se implementuje sémantika.

Rekurzívní sestup Potřebujeme LL(1) gramatiku (nemusíme dělat rozkladovou tabulku), množiny F IRST a F OLLOW, pro každé pravidlo A α vytvoříme množinu signatur F S(A, α) = F IRST (α F OLLOW (A)) proměnnou, ve které je uložen právě zpracovávaný symbol, funkci lex(), která nám vrátí další symbol, který extrahovala ze vstupního souboru (uloží do proměnné z předchozího bodu), proměnnou pro výstup (soubor, dynamická struktura apod.).

Popis metody Analýza probíhá takto: 1 zavoláme funkci Lex(), pak opět voláme pro každý symbol, 2 postupujeme přesně tak, jakobychom konstruovali derivační strom ručně : když jsme v uzlu ohodnoceném neterminálem, vytvoříme poduzly podle zvoleného pravidla, tentýž postup rekurzívně uplatníme na všechny poduzly (zleva doprava), které jsou ohodnoceny neterminály, u terminálních poduzlů pouze spustíme kontrolní porovnání podobně, jako bylo u předchozí metody pop. 3 rekurzívní volání probíhá zleva doprava a shora dolů, tedy i vstup je čten zleva doprava, 4 když skončí všechny rekurzivní výpočty pro jednotlivé větve a vstup je celý přečtený ($), akceptujeme vstup.

Popis metody Analýza probíhá takto: 1 zavoláme funkci Lex(), pak opět voláme pro každý symbol, 2 postupujeme přesně tak, jakobychom konstruovali derivační strom ručně : když jsme v uzlu ohodnoceném neterminálem, vytvoříme poduzly podle zvoleného pravidla, tentýž postup rekurzívně uplatníme na všechny poduzly (zleva doprava), které jsou ohodnoceny neterminály, u terminálních poduzlů pouze spustíme kontrolní porovnání podobně, jako bylo u předchozí metody pop. 3 rekurzívní volání probíhá zleva doprava a shora dolů, tedy i vstup je čten zleva doprava, 4 když skončí všechny rekurzivní výpočty pro jednotlivé větve a vstup je celý přečtený ($), akceptujeme vstup.

Popis metody Analýza probíhá takto: 1 zavoláme funkci Lex(), pak opět voláme pro každý symbol, 2 postupujeme přesně tak, jakobychom konstruovali derivační strom ručně : když jsme v uzlu ohodnoceném neterminálem, vytvoříme poduzly podle zvoleného pravidla, tentýž postup rekurzívně uplatníme na všechny poduzly (zleva doprava), které jsou ohodnoceny neterminály, u terminálních poduzlů pouze spustíme kontrolní porovnání podobně, jako bylo u předchozí metody pop. 3 rekurzívní volání probíhá zleva doprava a shora dolů, tedy i vstup je čten zleva doprava, 4 když skončí všechny rekurzivní výpočty pro jednotlivé větve a vstup je celý přečtený ($), akceptujeme vstup.

Popis metody Analýza probíhá takto: 1 zavoláme funkci Lex(), pak opět voláme pro každý symbol, 2 postupujeme přesně tak, jakobychom konstruovali derivační strom ručně : když jsme v uzlu ohodnoceném neterminálem, vytvoříme poduzly podle zvoleného pravidla, tentýž postup rekurzívně uplatníme na všechny poduzly (zleva doprava), které jsou ohodnoceny neterminály, u terminálních poduzlů pouze spustíme kontrolní porovnání podobně, jako bylo u předchozí metody pop. 3 rekurzívní volání probíhá zleva doprava a shora dolů, tedy i vstup je čten zleva doprava, 4 když skončí všechny rekurzivní výpočty pro jednotlivé větve a vstup je celý přečtený ($), akceptujeme vstup.

Popis metody Analýza probíhá takto: 1 zavoláme funkci Lex(), pak opět voláme pro každý symbol, 2 postupujeme přesně tak, jakobychom konstruovali derivační strom ručně : když jsme v uzlu ohodnoceném neterminálem, vytvoříme poduzly podle zvoleného pravidla, tentýž postup rekurzívně uplatníme na všechny poduzly (zleva doprava), které jsou ohodnoceny neterminály, u terminálních poduzlů pouze spustíme kontrolní porovnání podobně, jako bylo u předchozí metody pop. 3 rekurzívní volání probíhá zleva doprava a shora dolů, tedy i vstup je čten zleva doprava, 4 když skončí všechny rekurzivní výpočty pro jednotlivé větve a vstup je celý přečtený ($), akceptujeme vstup.

Popis metody Analýza probíhá takto: 1 zavoláme funkci Lex(), pak opět voláme pro každý symbol, 2 postupujeme přesně tak, jakobychom konstruovali derivační strom ručně : když jsme v uzlu ohodnoceném neterminálem, vytvoříme poduzly podle zvoleného pravidla, tentýž postup rekurzívně uplatníme na všechny poduzly (zleva doprava), které jsou ohodnoceny neterminály, u terminálních poduzlů pouze spustíme kontrolní porovnání podobně, jako bylo u předchozí metody pop. 3 rekurzívní volání probíhá zleva doprava a shora dolů, tedy i vstup je čten zleva doprava, 4 když skončí všechny rekurzivní výpočty pro jednotlivé větve a vstup je celý přečtený ($), akceptujeme vstup.

Popis metody Analýza probíhá takto: 1 zavoláme funkci Lex(), pak opět voláme pro každý symbol, 2 postupujeme přesně tak, jakobychom konstruovali derivační strom ručně : když jsme v uzlu ohodnoceném neterminálem, vytvoříme poduzly podle zvoleného pravidla, tentýž postup rekurzívně uplatníme na všechny poduzly (zleva doprava), které jsou ohodnoceny neterminály, u terminálních poduzlů pouze spustíme kontrolní porovnání podobně, jako bylo u předchozí metody pop. 3 rekurzívní volání probíhá zleva doprava a shora dolů, tedy i vstup je čten zleva doprava, 4 když skončí všechny rekurzivní výpočty pro jednotlivé větve a vstup je celý přečtený ($), akceptujeme vstup.

Popis metody Budeme potřebovat tyto funkce: Init, Done, expect ověří shodnost symbolu na vstupu se symbolem, který je parametrem této funkce, a načte další symbol ze vstupu, S, A, B,... pro každý neterminál vytvoříme stejně nazvanou funkci, tyto funkce se budou navzájem rekurzívně volat, error ošetří chybu, která se vyskytla při překladu.

Ukážeme na příkladu: S AB A CD B +AB AB ε C (S) i n D CD /CD ε 1 2 3, 4, 5 6, 7, 8 9, 10, 11

Proměnné vystup soub: string; (* název výstupního souboru *) vystup: text: (* soubor pro výstup programu *) vstupni sym: char; (* aktuální symbol načtený z prom. vstup *) vstupni atr: TAtribut; (* atribut právě načteného vstup. symbolu *) Dále předpokládáme funkce pro načtení znaku ze vstupu.

Proměnné vystup soub: string; (* název výstupního souboru *) vystup: text: (* soubor pro výstup programu *) vstupni sym: char; (* aktuální symbol načtený z prom. vstup *) vstupni atr: TAtribut; (* atribut právě načteného vstup. symbolu *) Dále předpokládáme funkce pro načtení znaku ze vstupu.

Hlavní funkce syntaktické analýzy Úkol: inicializovat výpočet, zavolat funkci S, dále je vše voláno rekurzí, ukončit výpočet. procedure S analyza; Init; S; Done;

Hlavní funkce syntaktické analýzy Úkol: inicializovat výpočet, zavolat funkci S, dále je vše voláno rekurzí, ukončit výpočet. procedure S analyza; Init; S; Done;

Init, Done procedure Init;... otevře vstupní soubor Lex(vstupni sym, vstupni atr); procedure Done;... zavře soubory, atd.

Init, Done procedure Init;... otevře vstupní soubor Lex(vstupni sym, vstupni atr); procedure Done;... zavře soubory, atd.

expect porovná zpracovávaný symbol (terminál z pravidla) se znakem na vstupu (musí souhlasit), načte další znak ze vstupu. procedure expect(term: char); if term = vstupni sym then Lex(vstupni sym, vstupni atr) else chyba;

expect porovná zpracovávaný symbol (terminál z pravidla) se znakem na vstupu (musí souhlasit), načte další znak ze vstupu. procedure expect(term: char); if term = vstupni sym then Lex(vstupni sym, vstupni atr) else chyba;

Funkce neterminálů Pro každou množinu pravidel se stejnou levou stranou: A α 1 α 2 α n procedure A; if vstupni sym in FS(A,α 1 ) then... postupně jsou ošetřeny symboly z řetězce α 1 else if vstupni sym in FS(A,α 2 ) then... postupně jsou ošetřeny symboly z řetězce α 2 else... ostatní pravidla else error;

Funkce neterminálů Pro každou množinu pravidel se stejnou levou stranou: A α 1 α 2 α n procedure A; if vstupni sym in FS(A,α 1 ) then... postupně jsou ošetřeny symboly z řetězce α 1 else if vstupni sym in FS(A,α 2 ) then... postupně jsou ošetřeny symboly z řetězce α 2 else... ostatní pravidla else error;

Funkce neterminálů S AB procedure S; if vstupni sym in ( i, n, ( ) then A; B; end else error;

Funkce neterminálů S AB procedure S; if vstupni sym in ( i, n, ( ) then A; B; end else error;

Funkce neterminálů A CD procedure A; if vstupni sym in ( i, n, ( ) then C; D; end else error;

Funkce neterminálů A CD procedure A; if vstupni sym in ( i, n, ( ) then C; D; end else error;

Funkce neterminálů B +AB AB ε procedure B; if vstupni sym = + then expect( + ); A; B; end else if vstupni sym = - then expect( - ); A; B; end else if vstupni sym in ( ),$) then ; else error;

Funkce neterminálů B +AB AB ε procedure B; if vstupni sym = + then expect( + ); A; B; end else if vstupni sym = - then expect( - ); A; B; end else if vstupni sym in ( ),$) then ; else error;

Funkce neterminálů C (S) i n procedure C; if vstupni sym = ( then expect( ( ); S; expect( ) ); end else if vstupni sym = i then expect( i ) else if vstupni sym = n then expect( n ) else error;

Funkce neterminálů C (S) i n procedure C; if vstupni sym = ( then expect( ( ); S; expect( ) ); end else if vstupni sym = i then expect( i ) else if vstupni sym = n then expect( n ) else error;

Funkce neterminálů D CD /CD ε procedure D; if vstupni sym = * then expect( * ); C; D; end else if vstupni sym = / then expect( - ); C; D; end else if vstupni sym in ( +, -, ),$) then ; else error;

Funkce neterminálů D CD /CD ε procedure D; if vstupni sym = * then expect( * ); C; D; end else if vstupni sym = / then expect( - ); C; D; end else if vstupni sym in ( +, -, ),$) then ; else error;

metody Výhody: není nutné vytvářet rozkladovou tabulku, třebaže množiny signatur vytvořit musíme, není problém s navázáním sémantické analýzy. Nevýhody: hloubka rekurze může za určitých okolností působit problémy s prostorovou složitostí.

metody Výhody: není nutné vytvářet rozkladovou tabulku, třebaže množiny signatur vytvořit musíme, není problém s navázáním sémantické analýzy. Nevýhody: hloubka rekurze může za určitých okolností působit problémy s prostorovou složitostí.