Uplatnění metod na zvolený jazyk

Podobné dokumenty
Poslední aktualizace: 14. října 2011

Programovací jazyk Pascal

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

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

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

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

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

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

Implementace LL(1) překladů

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

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

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

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

ALGORITMIZACE A PROGRAMOVÁNÍ

NPRG030 Programování I, 2018/19 1 / :25:37

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

VISUAL BASIC. Práce se soubory

Algoritmizace a programování

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

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

Sada 1 - Základy programování

Úvod do programování

Paměť počítače. alg2 1

NPRG030 Programování I, 2010/11

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

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

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

Překladač a jeho struktura

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

DUM 07 téma: Proměnné, konstanty a pohyb po buňkách ve VBA

Odvozené a strukturované typy dat

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

O datových typech a jejich kontrole

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

Lexikální analýza. Rozhraní lexikálního analyzátoru. Miroslav Beneš Dušan Kolář. M. Beneš, D. Kolář: Lexikální analýza 1. Lexikální analýza 2

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

Algoritmizace prostorových úloh

Úvod do programovacích jazyků (Java)

Lexikální analýza. Miroslav Beneš Dušan Kolář

Data v počítači. Informační data. Logické hodnoty. Znakové hodnoty

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

- speciální symboly + - * / =., < > <> <= >= a další. Klíčová slova jsou chráněnými útvary, které nelze použít ve významu identifikátorů.

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

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

Konečný automat. Jan Kybic.

Elementární datové typy

Objektově orientované programování

PROGRAMOVÁNÍ V SHELLU

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

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

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

Algoritmizace prostorových úloh

Zápis programu v jazyce C#

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

PROGRAMOVÁNÍ V JAZYCE C V PŘÍKLADECH 11 Dynamické datové struktury 11.1 Spojové struktury Příklad PROG_

Algoritmus. Přesné znění definice algoritmu zní: Algoritmus je procedura proveditelná Turingovým strojem.

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

LEKCE 6. Operátory. V této lekci najdete:

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

Třídění čísel v poli = vnitřní třídění (řazení)

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

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

Pseudonáhodná čísla = algoritmicky generovaná náhrada za náhodná čísla

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

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

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

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.

Algoritmizace a programování

Předmluva k aktuálnímu vydání Úvod k prvnímu vydání z roku Typografické a syntaktické konvence... 20

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

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

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

Algoritmizace a programování

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

Souhrn Apendixu A doporučení VHDL

Číselné soustavy. Binární číselná soustava

1 PRVOCISLA: KRATKY UKAZKOVY PRIKLAD NA DEMONSTRACI BALIKU WEB 1

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

Prezentace a vysvětlení programového prostředí NXC

Časová a prostorová složitost algoritmů

Pracovní listy - programování (algoritmy v jazyce Visual Basic) Algoritmus

Proměnná. Datový typ. IAJCE Cvičení č. 3. Pojmenované místo v paměti sloužící pro uložení hodnoty.

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Program převod z desítkové na dvojkovou soustavu: /* Prevod desitkove na binarni */ #include <stdio.h>

Implementace překladače imperativního jazyka IFJ05

Konstruktory překladačů

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

for (int i = 0; i < sizeof(hodnoty) / sizeof(int); i++) { cout<<hodonoty[i]<< endl; } cin.get(); return 0; }

Operátory, výrazy. Tomáš Pitner, upravil Marek Šabo

Třídy a struktury v C++

C2115 Praktický úvod do superpočítání

Struktura programu v době běhu

Algoritmizace prostorových úloh

2 Datové typy v jazyce C

8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek

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

Datové struktury 2: Rozptylovací tabulky

BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky

Sada 1 - Základy programování

Jazyk C# a platforma.net

Transkript:

Uplatnění metod na zvolený jazyk Při výběru mezi metodami výše popsanými se řídíme především podle typu symbolů, které jazyk obsahuje. Výhodná bývá často kombinace těchto metod nejdřív použijeme metodu přímého stavového programování (A) a pokud je načtený symbol identifikátor, použijeme některou z metod pro konečné jazyky pro zjištění, zda se jedná o klíčové slovo. U metod ukázaných na příkladech?? a?? musíme ještě přidat test znaku následujícího za symbolem, který nás zavedl do některého koncového stavu. Budeme dále pokračovat v příkladu z kapitoly??. Sestavíme proceduru Lex, jejímž úkolem bude načíst řetězec symbolu a určit jeho typ (identifikovat). V každém koncovém stavu symbolu bud přímo stanovíme hodnotu proměnné symbol.atrib deklarované v kapitole??, nebo v případě identifikátoru budeme volat proceduru ZpracujID, která načtený atribut dále zpracuje a určí, zda nejde o klíčové slovo. Na konci každého symbolu se procedura zastaví a pokračuje ve vyhodnocení vstupu, když je znovu volána. znak: TZnak; // znak načtený ze souboru symbol: TSymbol; // zde ukládáme načtený symbol... procedure Lex; // načte jeden symbol do globální proměnné symbol // Procedura Dejznak byla už volána, načtený znak je v záznamu znak while (znak.rad[znak.pozice] = ) do case znak.rad[znak.pozice] of A.. Z : // identifikátor nebo klíčové slovo symbol.atrib := znak.rad[znak.pozice]; while (znak.rad[znak.pozice] in [ A.. Z, 0.. 9 ]) do symbol.atrib := symbol.atrib + znak.rad[znak.pozice]; ZpracujID(symbol.atrib); 0.. 9 : // číslo symbol.atrib := znak.rad[znak.pozice]; while (znak.rad[znak.pozice] in [ 0.. 9 ]) do symbol.atrib := symbol.atrib + znak.rad[znak.pozice]; symbol.typ := S_NUM; < : // symbol < nebo <= nebo <> case znak.rad[znak.pozice] of > : symbol.typ := S_NEQ; // <>

= : symbol.typ := S_LQ; // <= else symbol.typ := S_LESS; // <... // Podobně všechny ostatní symboly else... // Ošetření chyby Dále musíme odlišit klíčová slova od ostatních identifikátorů a výsledky uložit do výstupního souboru. Proceduru můžeme sestavit více způsoby. První způsob je vhodný nejvýše pro velmi jednoduchý programovací jazyk s několika klíčovými slovy, my tento způsob nebudeme používat: procedure ZpracujID(s: string); if s = BEGIN then symbol.typ := S_BEGIN else if s = END then symbol.typ := S_END else if s = CONST then symbol.typ := S_CONST else if s = VAR then symbol.typ := S_VAR... // atd. pro všechna klíčová slova else symbol.typ := S_ID; // Není to klíčové slovo symbol.atrib := s; // Tento řádek v našem případě není nutný Z hlediska překladu a výsledného kódu překladače (časové složitosti překladu) je optimálnější, u jazyků s rozsáhlejší slovní zásobou velmi výrazně, jiná metoda. Napíšeme proceduru jako konečný automat podle druhé nebo třetí metody z kapitoly??. Příklad 0.1 Sestavíme gramatiku, podle ní tabulku přechodů a program, který bude rozpoznávat tento jazyk: L = {, end, const,, if, then, else, print} S ba 1 S ea 5 S ca 7 S va 11 A 1 ea 2 A 5 na 6 A 7 oa 8 A 11 aa 12 A 2 ga 3 A 6 d A 8 na 9 A 12 r A 3 ia 4 A 9 sa 10 A 4 n A 10 t S ia 13 S ta 14 A 5 la 17 S pa 19 A 13 f A 14 ha 15 A 17 sa 18 A 19 ra 20 A 15 ea 16 A 18 e A 20 ia 21 A 16 n A 21 na 22 A 22 t

Automat bude mít stavy 0... 22 přejaté z gramatiky, dále přidáme tyto stavy: const k_chyba = 23; k_const = 26; k_then = 29; k_ = 24; k_ = 27; k_else = 30; k_end = 25; k_if = 28; k_print = 31; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 B E G I N D C O S T V A R F H L P 0 1 5 13 7 14 11 19 1 2 2 3 3 4 4 24 5 6 17 6 25 7 8 8 9 9 10 10 26 11 12 12 27 13 28 14 15 15 16 16 29 17 18 18 30 19 20 20 21 21 22 22 31 Tabulka 1: Tabulka přechodů pro klíčová slova zvoleného jazyka Navrhneme deterministickou tabulku přechodů (je v tabulce 1, bez řádků pro chybový a koncové stavy) a přepíšeme do datové struktury. Pokračujeme: const PocetZnaku = 17; // Počet znaků, ze kterých se skládají klíčová slova tab: array [0..22, 1..PocetZnaku] of byte; procedure NactiTabulku; i, j: byte; for i := 0 to 22 do for j := 1 to PocetZnaku do tab[i,j] := k_chybovy; tab[ 0, 1] := 1; tab[ 0, 2] := 5; tab[ 0, 4] := 13;

tab[ 0, 7] := 7; tab[ 0,10] := 14; tab[ 0,11] := 11; tab[ 0,17] := 19; tab[ 1, 2] := 2; tab[ 2, 3] := 3; tab[ 3, 4] := 4; tab[ 4, 5] := 24; tab[ 5, 5] := 6; tab[ 5,16] := 17; tab[ 6, 6] := 25; tab[ 7, 8] := 8; tab[ 8, 5] := 9; tab[ 9, 9] := 10; tab[10,10] := 26; tab[11,12] := 12; tab[12,13] := 27; tab[13,14] := 28; tab[14,15] := 15; tab[15, 2] := 16; tab[16, 5] := 29; tab[17, 9] := 18; tab[18, 2] := 30; tab[19,13] := 20; tab[20, 4] := 21; tab[21, 5] := 22; tab[22,10] := 31; function DejCisloZnaku(zn: char): byte; // Pokud zn nepatří do abecedy, nad kterou jsou vytvořena klíčová slova, // funkce vrátí hodnotu 0. Jinak vrací index znaku. const Index: string [PocetZnaku] = BEGINDCOSTVARFHLP ; i, v: byte; v := 0; // číslo 0 náleží nedefinovanému znaku i := 1; while (i <= PocetZnaku) do if (zn = Index [i]) then v := i; // nalezen index (číslo) znaku v seznamu break; inc(i); DejCisloZnaku := v; procedure ZpracujID(s: string); stav: byte; // aktuální stav automatu pozice: byte; // pozice v testovaném řetězci s delka: byte; // délka řetězce s znak: byte; // číslo znaku podle seznamu znaků klíčových slov stav := 0; pozice := 1; delka := length(s); while (pozice <= delka) and (stav < k_chyba) do znak := DejCisloZnaku(s[i]); if (znak = 0) then stav := chybovy else stav := tab[stav,znak]; case stav of k_: symbol.typ := S_BEGIN; k_end: symbol.typ := S_END; k_const: symbol.typ := S_CONST; k_: symbol.typ := S_VAR; k_if: symbol.typ := S_IF; k_then: symbol.typ := S_THEN; k_else: symbol.typ := S_ELSE; k_print: symbol.typ := S_PRINT;

else symbol.typ := S_ID; symbol.atrib := s; procedure InitLex; // Tato procedura je volána pouze jednou za celý překlad... // Otevření vstupního souboru pro čtení, zpřístupnění // přes proměnnou zdroj (textový soubor). NactiTabulku; DejZnak; // Načteme tabulku přechodů do proměnné tab. // Načteme do proměnné znak první znak souboru, // v proceduře NactiSymbol se s tím počítá První způsob implementace používající prosté porovnávání řetězců je určitě velmi jednoduchý, rychlý a intuitivní. Časová složitost výpočtu 1 je však (zejména pro jazyky s větším množstvím klíčových slov) podstatně vyšší, než je únosné. Důvodem je vícenásobné procházení testovaného řetězce v nejhorším případě, tedy když nejde o klíčové slovo, je alespoň začátek řetězce procházen při každém uvedeném porovnávání. Proto má smysl takto postupovat pouze u jazyků, které mají jen velmi málo klíčových slov a jsou postaveny především na jiných typech symbolů. U druhého způsobu je časová složitost obecně mnohem nižší (každý znak slova je zpracováván nejvýše jednou), narůstá však prostorová složitost 2, protože v paměti je uložena celá tabulka přechodů automatu. V dnešní době však vyšší prostorová složitost již tolik nevadí, a i kdyby, dá se řešit například použitím technik pro zachycení řídké matice (většina prvků tabulky má tutéž hodnotu, chybový stav). Můžeme samozřejmě postupovat také metodou pro konečné jazyky s nižší prostorovou složitostí, která je ukázaná na příkladu?? na straně??. Datové typy konstantních hodnot Do této chvíle jsme pracovali pouze s programovacími jazyky, které měly jediný datový typ celé nezáporné číslo. V praxi se však používají jazyky přijímající obvykle celá čísla (bez znaménka nebo se znaménkem), reálná čísla, znaky, řetězce, pole, záznamy, pointery, výčtové typy atd. Lexikální analyzátor se obvykle takovými rozlišeními nemusí zabývat, pokud ovšem nejde o konstanty. Čísla můžeme nechat v znakové podobě tak, jak byla ve zdrojovém textu, nebo je předat dál v binárním tu ve vhodné reprezentaci (pak pro atribut nepoužijeme řetězec, ale iantní záznam, příp. v C union, kde jednotlivé možnosti budou odpovídat zvolenému datovému typu konstanty). Tuto reprezentaci volíme podle toho, co nám nabízí programovací jazyk, ve kterém překladač píšeme, obvykle například u celých čísel máme na výběr mezi těmito možnostmi: 1 Časová složitost znamená náročnost výpočtu algoritmu z hlediska doby jeho trvání v závislosti na délce vstupu. Vyšší časovou složitost má ten algoritmus, jehož provedení v běžném případě trvá déle. 2 Jestliže máme dva algoritmy A 1 a A 2 a řekneme, že A 1 má vyšší prostorovou složitost, znamená to, že při výpočtu algoritmu A 1 je pro běžné vstupy použito více pamět ového prostoru než při výpočtu algoritmu A 2.

celé číslo se znaménkem na 2 B (integer) 3, rozmezí 32 768... 32 767, celé číslo bez znaménka na 2 B (word), rozmezí 0... 65 535, celé číslo se znaménkem na 1 B (short), rozmezí 128... 127, celé číslo bez znaménka na 1 B (byte, char), rozmezí 0... 255. Vzhledem k tomu, že znaménko můžeme chápat jako zvláštní symbol, volíme spíše datové typy, které znaménko nepoužívají, ale díky tomu na stejně velkém pamět ovém místě nabízejí větší rozsah pro kladné číslo. Pro racionální čísla s plovoucí desetinnou čárkou můžeme volit vždy tentýž datový typ nebo rozhodovat obdobně jako u celých čísel. V takovém jazyce byl napsán úsek programu: CONST a = 224; b = - 224; c = - 5; d = 10000;... prom := 25 * b + 8224; Vyskytuje se zde celkem šest celočíselných konstant, u kterých je nutné určit datový typ. Toto rozlišení může provádět sémantický analyzátor nebo je lze přenechat lexikálnímu. V lexikálním analyzátoru postupujeme takto: 1. načteme řetězec s číslicemi (nebo průběžně načítáme), 2. převedeme řetězec na číslo (vytvoříme meziprodukt představující nejuniverzálnější reprezentaci použijeme datový typ zabírající nejvíce místa v paměti), 3. porovnáváme načtené číslo s mezními hodnotami a podle toho určujeme přesný datový typ, 4. pokud má lexikální analyzátor přístup k informaci, zda jde o kladné nebo záporné číslo, můžeme tento fakt zohlednit při výběru datového typu, ovšem to se týká spíše definice pojmenované konstanty než výskytu konstanty ve výrazu. V našem případě tedy bude výsledek takový (jsou uvedeny pouze číselné symboly, nikoliv ostatní včetně symbolu pro znaménko ): S_NUM_BYTE 224 S_NUM_BYTE 224 S_NUM_BYTE 5 S_NUM_WORD 10000 S_NUM_BYTE 25 S_NUM_WORD 8224 3 Skutečné množství paměti pro integer závisí na operačním systému 2 B platí pro 16-bitový OS, 32-bitové operační systémy (momentálně nejpoužívanější) používají 4 B, v 64-bitových systémech zabírá integer 8 B, a od toho se odvíjí také rozmezí hodnot.

Reprezentace konstantního řetězce není problém, pouze vzhledem k optimalizaci prostorové složitosti volíme vhodnou délku řetězce. Řetězec je obvykle ohraničen speciálními znaky (jednoduché nebo dvojité uvozovky), takže lexikální analyzátor po nalezení prvního takového znaku pokračuje v načítání, dokud nenajde druhý, uzavírací znak řetězce. Uvozovací znaky nejsou symboly, z hlediska překladače jde pouze o pomocné znaky, které mu říkají, kde řetězec začíná a kde končí. Dále můžeme ošetřit případ, kdy uživatel velmi dlouhý řetězec rozdělí na více menších řetězců a každý umístí na nový řádek (to umožňuje například programovací jazyk C). Pokud konstantní řetězce ukládáme do dostatečně rozsáhlých hodnot symbolů (jestliže je výstupem dynamická struktura nebo soubor, lze délku hodnot typu řetězec určovat též dynamicky), můžeme všechny tyto konstantní řetězce spojit do jediného. Pokud programovací jazyk umožňuje sčítání řetězců, lze jednotlivé řetězce načíst zvlášt a spojit je explicitně operátorem sčítání (není to obvyklý postup) nebo se lexikální analyzátor nemusí vůbec namáhat řešením těchto situací a výsledkem je prostě posloupnost řetězců, kterou zpracuje syntaktický analyzátor. U konstantních polí a záznamů záleží na zvolené vnitřní reprezentaci jazyka a předepsaném tu definice těchto konstant. Obvyklé je zadávat pole jako výčet prvků oddělených čárkou a záznam jako posloupnost vnitřních proměnných a jejich hodnot, takže lexikální analyzátor tyto konstanty jako celek nemusí zpracovávat a předává je dál v rozloženém tu. Úkoly ke kapitole 2 1. Vytvořte regulární gramatiku jazyka celých nezáporných čísel. 2. Podle gramatiky, kterou jste sestrojili v úkolu 1, vytvořte diagram deterministického konečného automatu. 3. Vytvořte regulární gramatiku jazyka reálných nezáporných čísel, celá a reálná část čísla jsou odděleny desetinnou tečkou, která je nepovinná (pak jde o celé číslo), před tečkou nemusí být žádná číslice, za tečkou musí být alespoň jedna číslice. Podle této regulární gramatiky vytvořte diagram deterministického konečného automatu. 4. Sestrojte regulární gramatiku a podle ní deterministický konečný automat reprezentovaný tabulkou přechodů pro jazyk L 1 = {is, then, this}. Automat má rozpoznávat jednotlivá slova jazyka, bude mít pro každé slovo jiný koncový stav. Gramatiku vytvořte tak, aby bylo možné konstruovat automat přímo jako deterministický, bez nutnosti další transformace. 5. Naprogramujte konečný automat z úkolu 4 některou z metod z této kapitoly nebo jejich kombinací (metody jsou popsány v podkapitole?? od strany??, možnost kombinace metod v podkapitole od strany 1). 6. Sestrojte regulární gramatiku a podle ní deterministický konečný automat pro tyto jazyky: L 2 = {if, then, else, elif, end} (automat reprezentovaný tabulkou symbolů)

L 3 = {jdi, stop, doprava, doleva} (automat reprezentovaný tabulkou symbolů) L 4 = {read, write, } {a,..., z} + (tři klíčová slova a názvy proměnných obsahující pouze malá písmena, alespoň jedno) L 5 = {if, write, <, >, <=, >=, <>} {0,..., 9} + (dvě klíčová slova, relační operátory, celá čísla) L 6 = {line, oval, rect,,, [, ]} {0,..., 9} + (tři klíčová slova, čárka, hranaté závorky, celá čísla) L 7 = {+,,, /, :=, (, )} {0,..., 9} + ({a,..., z} {a,..., z, 0,..., 9} ) (matematické výrazy s běžnými aritmetickými operátory a operátorem přiřazení, závorkami, celými čísly a proměnnými název proměnné začíná písmenem, pak mohou následovat písmena nebo číslice) L 8 = L 6 L 7 (v parametrech příkazů z jazyka L 6 mohou být běžné matematické výrazy včetně použití proměnných, hodnotu proměnných lze určit přiřazovacím příkazem) 7. Vyberte si kterýkoliv z jazyků L 2 L 7 z předchozího úkolu a naprogramujte jeho lexikální analýzu některou z metod uvedených v této kapitole (nebo jejich kombinací). 8. Naprogramujte lexikální analýzu jazyka L 8 z předchozího úkolu kombinací metod podle podkapitoly (strana 1).