Konečný automat. Jan Kybic.

Podobné dokumenty
SPJA, cvičení 1. ipython, python, skripty. základy syntaxe: základní datové typy, řetězce. podmínky: if-elif-else, vyhodnocení logických výrazů

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

Programovací jazyk Pascal

doplněk, zřetězení, Kleeneho operaci a reverzi. Ukážeme ještě další operace s jazyky, na které je

Algoritmizace a programování

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

IB111 Úvod do programování skrze Python Přednáška 7

Úvod do programovacích jazyků (Java)

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

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

Naproti tomu gramatika je vlastně soupis pravidel, jak

Syntaxí řízený překlad

AUTOMATY A GRAMATIKY. Pavel Surynek. Kontextové uzávěrové vlastnosti Turingův stroj Rekurzivně spočetné jazyky Kódování, enumerace

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

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

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

Funkce, podmíněný příkaz if-else, příkaz cyklu for

VISUAL BASIC. Práce se soubory

Množinu všech slov nad abecedou Σ značíme Σ * Množinu všech neprázdných slov Σ + Jazyk nad abecedou Σ je libovolná množina slov nad Σ

Konstruktory překladačů

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

Poslední aktualizace: 14. října 2011

Úvod do programování. Lekce 1

Automaty a gramatiky(bi-aag) Formální překlady. 5. Překladové konečné automaty. h(ε) = ε, h(xa) = h(x)h(a), x, x T, a T.

NPRG030 Programování I, 2010/11

Standardní algoritmy vyhledávací.

Regulární výrazy. Definice Množina regulárních výrazů nad abecedou Σ, označovaná RE(Σ), je definována induktivně takto:

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

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

Regulární výrazy. M. Kot, Z. Sawa (VŠB-TU Ostrava) Úvod do teoretické informatiky 14. března / 20

Programování v jazyce JavaScript

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

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

Vlastnosti regulárních jazyků

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

Konstrukce relace. Postupně konstruujeme na množině všech stavů Q relace i,

Textové soubory. alg9 1

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.

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

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

WSH Windows Script Hosting. OSY 2 Přednáška číslo 2 opravená verze z

Třídění a vyhledávání Searching and sorting

Překladač a jeho struktura

Regulární výrazy. Vzory

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

3. Třídy P a NP. Model výpočtu: Turingův stroj Rozhodovací problémy: třídy P a NP Optimalizační problémy: třídy PO a NPO MI-PAA

OSTRAVSKÁ UNIVERZITA V OSTRAVĚ PŘÍRODOVĚDECKÁ FAKULTA

Úvod do programování - Java. Cvičení č.4

VY_32_INOVACE_08_2_04_PR

Turingovy stroje. Teoretická informatika Tomáš Foltýnek

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

Formální jazyky a automaty Petr Šimeček

A7B38UOS Úvod do operačních systémů. 6. Cvičení. Příkazy sed a awk

Uplatnění metod na zvolený jazyk

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

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

Regulární výrazy. Filtry grep, sed a awk.

ŘÍDÍCÍ STRUKTURY - PODMÍNKY

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

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

Zápis programu v jazyce C#

Prioritní fronta, halda

Vztah jazyků Chomskeho hierarchie a jazyků TS

Algoritmizace prostorových úloh

2 Formální jazyky a gramatiky

Poslední nenulová číslice faktoriálu

Konstruktory a destruktory

Programování v Pythonu

Programování. Bc. Veronika Tomsová

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

Přednáška 4. Regulární výrazy. Filtry grep, sed a awk. Úvod do Operačních Systémů Přednáška 4

Programování v Pythonu

AUTOMATY A GRAMATIKY

Základy algoritmizace

2. lekce Algoritmus, cyklus Miroslav Jílek

Knihovna XmlLib TXV druhé vydání říjen 2012 změny vyhrazeny

ALGORITMIZACE A PROGRAMOVÁNÍ

Složitost Filip Hlásek

Algoritmy I. Cvičení č. 2, 3 ALGI 2018/19

DSL manuál. Ing. Jan Hranáč. 27. října V této kapitole je stručný průvodce k tvorbě v systému DrdSim a (v

PHP - úvod. Kapitola seznamuje se základy jazyka PHP a jeho začleněním do HTML stránky.

Sada 1 - PHP. 03. Proměnné, konstanty

Úvod do UNIXu. Okruh č. 4 - vi, regulární výrazy, grep a sed. Jakub Galgonek. verze r2. inspirováno materiály Davida Hokszy

Definice 9.4. Nedeterministický algoritmus se v některých krocích může libovolně rozhodnout pro některé z několika možných různých pokračování.

Formální jazyky a gramatiky Teorie programovacích jazyků

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

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

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

Algoritmizace a programování

Tvorba výrazu: speciální znaky shellu se uvádějí do apostrofů jednotlivé části výrazu se oddělují mezerou

Implementace LL(1) překladů

63. ročník Matematické olympiády 2013/2014

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

Lekce 01 Úvod do algoritmizace

Preprocesor. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze. Karel Richta, Martin Hořeňovský, Aleš Hrabalík, 2016

Programování: základní konstrukce, příklady, aplikace. IB111 Programování a algoritmizace

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

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

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

Chyby a výjimky. Chyba. Odkud se chyby berou? Kdo chyby opravuje? Co můžete dělat jako programátor? Dvě hlavní metody práce s chybami.

Transkript:

Konečný automat Jan Kybic http://cmp.felk.cvut.cz/~kybic kybic@fel.cvut.cz 2016 2017 1 / 33

Konečný automat finite state machine Konečný automat = výpočetní model, primitivní počítač Řídící jednotka s konečným počtem stavů Vstupní posloupnost textový řetězec, fyzické vstupy Výstupní posloupnost, fyzické výstupy 2 / 33

Konečný automat finite state machine Konečný automat = výpočetní model, primitivní počítač Řídící jednotka s konečným počtem stavů Vstupní posloupnost textový řetězec, fyzické vstupy Výstupní posloupnost, fyzické výstupy Definice: konečná množina stavů Q počáteční stav q 0 Q konečná množina vstupních symbolů A přechodová funkce f : Q A Q q t+1 = f (q t, a t ) t je čas nebo index do vstupní posloupnosti (někdy) množina koncových stavů F Q (někdy) množina akcí G a výstupní funkce g : Y G nebo g : Y A G 2 / 33

Příklad: řízení výtahu Stavový diagram jede nahoru motor nahoru tlačítko nahoru kontakt 1.patro přízemí 1. patro kontakt přízemí tlačítko dolu jede dolů motor dolů 3 / 33

Příklad: řízení výtahu Přechodová a výstupní tabulka vstupy stavy výstupy Tl.d. Tl.n. Příz. 1.p. q t q t+1? 0?? přízemí přízemí 0 0? 1?? přízemí jede nahoru 1 0??? 0 jede nahoru jede nahoru 1 0??? 1 jede nahoru 1. patro 0 0 0??? 1. patro 1. patro 0 0 1??? 1. patro jede dolů 0 1?? 0? jede dolů jede dolů 0 1?? 1? jede dolů přízemí 0 0 4 / 33

Automat přijímající jazyk Jazyk = (i nekonečná) množina řetězců Rozhodovací konečný automat Vstupem je řetězec. Dává odpověď ano/ne, zda vstup patří do jazyka. V každém kroku čte automat jeden znak z řetězce. Vstupní abeceda A jsou všechny přípustné znaky. Automat přijímá řetězec na konci řetězce je automat v přijímajícím (koncovém) stavu. 5 / 33

Příklad: jméno proměnné Totální automat Automat přijímá platná jména proměnných v Pythonu. start písmeno,_ ano písmeno, číslice, _ jinak jinak ne cokoliv 6 / 33

Příklad: jméno proměnné Totální automat Automat přijímá platná jména proměnných v Pythonu. start písmeno,_ ano písmeno, číslice, _ jinak jinak ne cokoliv Automat je totální přechodová funkce f je definována pro všechna Q A. 6 / 33

Příklad: jméno proměnné (2) Částečný automat start písmeno,_ ano písmeno, číslice, _ Částečný automat nedefinovaný přechod znamená nepřijetí. 7 / 33

Jméno proměnné implementace def is_variable_name(s): """ je s platné jméno proměnné v Pythonu? """ state="start" for c in s: if state=="start": if c=="_" or is_letter(c): state="ano" return False # stav "ano" if not (c=="_" or is_letter(c) or c.isdigit()): return False return state=="ano" def is_letter(c): return c.isupper() or c.islower() Soubor automaton_examples.py. 8 / 33

Jméno proměnné příklady print(is_variable_name("moje_promenna12")) True print(is_variable_name("moje{}_promenna")) False print(is_variable_name("12moje{}_promenna")) False 9 / 33

Transformace textu Transformační konečný automat Vstupem je řetězec. Výstupem je řetězec. V každém kroku čte automat jeden znak z řetězce. Vstupní abeceda A jsou všechny přípustné znaky. Součásti každého přechodu (nebo stavu) může být výstup jednoho či více znaků. 10 / 33

Příklad: přeskakování komentářů Úkol: Vstupem je textový soubor Komentář je vše od znaku # (včetně) do konce řádky Vypište obsah souboru bez komentářů. Soubor preskoc_komentare.py 11 / 33

Přeskakování komentářů znak c # vypiš c start 0 1 # konec řádky jinak 12 / 33

# Tento program voláme s argumentem jméno souboru # Vypíše obsah souboru bez Pythonovských komentářů import sys def preskoc_komentare(f): # vytiskne obsah souboru f s vynechanymi komentari stav=0 # počáteční stav automatu while True: c=f.read(1) # přečti jeden znak if c=="": # konec souboru return if stav==0: # počáteční stav if c=="#": # začátek komentáře stav=1 print(c,end="") # vytiskni znak # stav 1="komentar" if c=="\n": # konec řádky stav=0 # konec komentáře print(c,end="") # vše ostatní ignorujeme pass if name ==" main ": with open(sys.argv[1], rt ) as f: # otevři textový soubor preskoc_komentare(f) # pokud se povedlo, přeskakuj 13 / 33

Terminal> python3 preskoc_komentare.py preskoc_komentare.py import sys def preskoc_komentare(f): stav=0 while True: c=f.read(1) if c=="": return if stav==0: if c==" stav=1 print(c,end="") if c=="\n": stav=0 print(c,end="") pass if name ==" main ": with open(sys.argv[1],'rt') as f: preskoc_komentare(f) 14 / 33

Přeskakování komentářů (2) Verze, kterou nezmate # v řetězci. znak c # vypiš c start 0 1 # " vypiš " 2 konec řádky " vypiš " c " vypiš c jinak 15 / 33

# Verze kterou nezmate # mezi " " import sys def preskoc_komentare(f): # vytiskne obsah souboru f s vynechanymi komentari stav=0 # počáteční stav automatu while True: c=f.read(1) # přečti jeden znak if c=="": # konec souboru return if stav==0: # počáteční stav if c=="#": # začátek komentáře stav=1 if c== " : stav=2 # začátek řetězce print(c,end="") # vytiskni znak elif stav==1: # 1="komentar" if c=="\n": # konec řádky stav=0 # konec komentáře print(c,end="") # vše ostatní ignorujeme pass # stav = řetězec if c== " : stav=0 print(c,end="") # vytiskni znak 16 / 33

Terminal> python3 preskoc_komentare2.py preskoc_komentare.py import sys def preskoc_komentare(f): stav=0 while True: c=f.read(1) if c=="": return if stav==0: if c=="#": stav=1 print(c,end="") if c=="\n": stav=0 print(c,end="") pass if name ==" main ": with open(sys.argv[1],'rt') as f: preskoc_komentare(f) 17 / 33

Terminal> python3 preskoc_komentare2.py preskoc_komentare.py import sys def preskoc_komentare(f): stav=0 while True: c=f.read(1) if c=="": return if stav==0: if c=="#": stav=1 print(c,end="") if c=="\n": stav=0 print(c,end="") pass if name ==" main ": with open(sys.argv[1],'rt') as f: preskoc_komentare(f) Cvičení: doplňte řetězce oddělené. 17 / 33

Lexikální analýza (parsing) Vstupem je řetězec (posloupnost znaků) Výstupem je posloupnost symbolů (tokens) číslo, operátor, identifikátor, klíčové slovo,... Symboly mohou mít atributy řetězec, hodnota,... Reprezentujeme jako dvojice typ symbolu + atribut Další operace Vynechání komentářů Odstranění mezer Chybová hlášení 18 / 33

Příklad: Lexikální analýza textu Rozdělte řetězec na posloupnost symbolů: Interpunkce., ; :?! ( ) (jeden znak) Slovo řetězec znaků, neobsahující interpunkci, mezery ani konce řádků. Konce řádků, mezery a tabulátory (whitespace) ignorujte. Soubor analyza_textu.py 19 / 33

Analýza textu mezera interpunkce vypiš znak slova akumuluj 0 1 mezera vypiš slovo znak slova akumuluj interpunkce vypiš slovo vypiš interpunkci Počáteční stav q 0 = 0. 20 / 33

def analyzuj(f): interpunkce=""".,;:?!" ()""" mezery=" \t\n" stav=0 # počáteční stav - mimo slovo while True: c=f.read(1) # přečti jeden znak if c=="": # konec souboru return if stav==0: if c in interpunkce: print("interpunkce: ",c) elif c not in mezery: # je to znak slova slovo=c # akumulátor slova stav=1 # stav==1 - uvnitř slova if c not in interpunkce and c not in mezery: slovo+=c # pořád uvnitř slova # slovo končí print("slovo: ",slovo) stav=0 if c in interpunkce: print("interpunkce: ",c) if name ==" main ": analyzuj(sys.stdin) 21 / 33

Terminal> python3 analyza_textu.py Kam jdeš? Stůj! Slovo: Kam Slovo: jdeš Interpunkce:? Slovo: Stůj Interpunkce:! 22 / 33

Nedeterministický automat (Non deterministic finite automaton NFA) Přechodová funkce vrací množinu stavů, f : Q A 2 Q, automat si jeden nedeterministicky vybere. Slovo je přijímáno automatem, pokud existuje posloupnost výběrů vedoucí do koncového stavu. Implementace: Při simulaci si udržujeme množinu možných stavů. Automaticky převedeme na deterministický automat s 2 n stavy. Často lze nalézt ekvivalentní deterministický automat s méně stavy. 23 / 33

Nedeterministický automat (Non deterministic finite automaton NFA) Přechodová funkce vrací množinu stavů, f : Q A 2 Q, automat si jeden nedeterministicky vybere. Slovo je přijímáno automatem, pokud existuje posloupnost výběrů vedoucí do koncového stavu. Implementace: Při simulaci si udržujeme množinu možných stavů. Automaticky převedeme na deterministický automat s 2 n stavy. Často lze nalézt ekvivalentní deterministický automat s méně stavy. Automat přijímající slova končící na ce Automat přijímající klíčová slova Pythonu. Automat přijímající celá nebo reálná čísla. 23 / 33

Regulární výrazy v Pythonu Jazyk přijímaný konečným automatem = regulární jazyk. Regulární jazyk lze popsat regulárním výrazem. Pro regulární výrazy existují knihovny a nástroje. 24 / 33

Regulární výrazy v Pythonu Jazyk přijímaný konečným automatem = regulární jazyk. Regulární jazyk lze popsat regulárním výrazem. Pro regulární výrazy existují knihovny a nástroje. Syntaxe. jakýkoliv znak [M] jakýkoliv znak z množiny M, lze [a-z] [^M] jakýkoliv znak mimo M * libovolný počet opakování předchozího + jedno a více opakování předchozího? žádné nebo jedno opakování předchozího () skupina alternativy \ následující znak ztrácí speciální význam (Další viz. dokumentace) 24 / 33

Příklad jméno proměnné import re p=re.compile(r [a-za-z_][a-za-z0-9_]* ) print(p.fullmatch("moje_promenna12")) <_sre.sre_match object; span=(0, 15), match='moje_promenna12'> print(p.fullmatch("moje{}_promenna")) None print(p.fullmatch("12moje{}_promenna")) None print(p.match("moje{}_promenna")) <_sre.sre_match object; span=(0, 4), match='moje'> r znamená raw řetězec, bez interpretace \n, \t,... 25 / 33

Příklad jméno proměnné (2) reimplementace is_variable_name variable_name_regexp=re.compile(r [a-za-z_][a-za-z0-9_]* ) def is_variable_name(s): return variable_name_regexp.fullmatch(s) is not None print(is_variable_name("moje_promenna12")) True print(is_variable_name("moje{}_promenna")) False print(is_variable_name("12moje{}_promenna")) False 26 / 33

Příklad reálné číslo p=re.compile(r [+-]?[0-9]+(\.[0-9]*)?([eE][+-]?[0-9]+)? ) print(p.fullmatch("-314")) <_sre.sre_match object; span=(0, 4), match='-314'> print(p.fullmatch("3.14")) <_sre.sre_match object; span=(0, 4), match='3.14'> print(p.fullmatch("2341e-23")) <_sre.sre_match object; span=(0, 8), match='2341e-23'> print(p.fullmatch("-2341e+23")) <_sre.sre_match object; span=(0, 9), match='-2341e+23'> print(p.fullmatch("-2341.e")) None print(p.fullmatch("278h")) None 27 / 33

Přeskakování komentářů a regulární výrazy import sys import re line_pattern=re.compile(r"([^#]*)(#.+)?\n") def preskoc_komentare(f): # vytiskne obsah souboru f s vynechanymi komentari for line in f.readlines(): # čte řádku po řádce print(line_pattern.fullmatch(line).group(1)) if name ==" main ": with open(sys.argv[1], rt ) as f: # otevři textový soubor preskoc_komentare(f) # pokud se povedlo, preskakuj Soubor preskoc_komentare3.py 28 / 33

Terminal> python3 preskoc_komentare3.py preskoc_komentare.py import sys def preskoc_komentare(f): stav=0 while True: c=f.read(1) if c=="": return if stav==0: if c==" stav=1 print(c,end="") if c=="\n": stav=0 print(c,end="") pass if name ==" main ": with open(sys.argv[1],'rt') as f: preskoc_komentare(f) 29 / 33

Přeskakování komentářů a regulární výrazy Verze, kterou nezmate # v řetězci. # Řešení pomocí regulárních výrazů, které nezmate # mezi " " import sys import re line_pattern=re.compile(r (([^#"]*("[^"]*")?)*)(#.+)?\n ) def preskoc_komentare(f): # vytiskne obsah souboru f s vynechanymi komentari for line in f.readlines(): # čte řádku po řádce print(line_pattern.fullmatch(line).group(1)) if name ==" main ": with open(sys.argv[1], rt ) as f: # otevři textový soubor preskoc_komentare(f) # pokud se povedlo, preskakuj 30 / 33

Terminal> python3 preskoc_komentare4.py preskoc_komentare.py import sys def preskoc_komentare(f): stav=0 while True: c=f.read(1) if c=="": return if stav==0: if c=="#": stav=1 print(c,end="") if c=="\n": stav=0 print(c,end="") pass if name ==" main ": with open(sys.argv[1],'rt') as f: preskoc_komentare(f) 31 / 33

Terminal> python3 preskoc_komentare4.py preskoc_komentare.py import sys def preskoc_komentare(f): stav=0 while True: c=f.read(1) if c=="": return if stav==0: if c=="#": stav=1 print(c,end="") if c=="\n": stav=0 print(c,end="") pass if name ==" main ": with open(sys.argv[1],'rt') as f: preskoc_komentare(f) Cvičení: doplňte řetězce oddělené. 31 / 33

Co konečný automat nedovede ani regulární výraz Nemají neomezenou paměť: Příklady neregulárních jazyků: Řetězec 0 n 1 n. Správně uzávorkované výrazy s neomezenou hloubkou uzávorkování. 32 / 33

Co konečný automat nedovede ani regulární výraz Nemají neomezenou paměť: Příklady neregulárních jazyků: Řetězec 0 n 1 n. Správně uzávorkované výrazy s neomezenou hloubkou uzávorkování. Chomského hierachie jazyky regulární bezkontextové kontextové neomezené. 32 / 33

Konečné automaty a regulární výraze Konečné automaty Jednoduchý výpočetní model Rychlý, dobře teoreticky prozkoumaný. Omezující. Složitější implementace, existují nástroje pro její generování. Vhodné pro řízení jednoduchých systémů. Vhodné pro první krok analýzy textu i kódu v programovacích jazycích. Nedeterministické konečné automaty. Regulární výrazy Teoreticky ekvivalentní konečným automatům. Snadné a rychlé použití, řada vyzkoušených a optimalizovaných knihoven. Některé složitější konstrukce jsou značně nepřehledné. Omezené množství výstupních akcí. Nelze použít pro řízení systému. 33 / 33