Parsování v Haskellu, knihovna Parsec

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

Zápis programu v jazyce C#

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

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

Programovací jazyk Pascal

Konstruktory překladačů

Operační systémy. Cvičení 3: Programování v C pod Unixem

PB161 Programování v C++ Proudy pro standardní zařízení Souborové proudy Paměťové proudy Manipulátory

Úvod do programovacích jazyků (Java)

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

Jazyk C# a platforma.net

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 5. CVIČENÍ

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ů

Konečný automat. Jan Kybic.

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

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

1. Od Scheme k Lispu

IB015 Neimperativní programování. Organizace a motivace kurzu, programovací jazyk Haskell. Jiří Barnat

A Tutorial. George J. Klir State University of New York (SUNY) Binghamton, New York 13902, USA

Pole a Funkce. Úvod do programování 1 Tomáš Kühr

Standardní algoritmy vyhledávací.

Konec a tak. PB173 Programování v C++11. Vladimír Štill, Jiří Weiser. Fakulta Informatiky, Masarykova Univerzita. 15.

Příklad : String txt1 = new String( Ahoj vsichni! ); //vytvoří instanci třídy String a přiřadí ji vnitřní hodnotu Ahoj vsichni!

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í

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

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

Programování v C++ 1, 5. cvičení

Úvod do programovacích jazyků (Java)

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

Základy programování (IZP)

Algoritmizace a programování

Základy jazyka C. Základy programování 1 Martin Kauer (Tomáš Kühr)

Lekce 2. Řetězce a práce s nimi. Vstup a výstup. C2184 Úvod do programování v Pythonu podzim 2016

Stream API. Petr Krajča. Základy programovaní 4 (Java) Katedra informatiky Univerzita Palackého v Olomouci

2 Datové typy v jazyce C

První kapitola úvod do problematiky

Obsah. Úvodem 15. Zaměření knihy 15 Co v knize najdete 15 Doprovodné CD 17 Poděkování 18

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

Základy programování (IZP)

Algoritmizace a programování

PROGRAMOVACÍ JAZYKY A PŘEKLADAČE STRUKTURA PŘEKLADAČE

Uplatnění metod na zvolený jazyk

Programování v jazyku C# II. 9.kapitola

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

Definice uživatelského typu. Uživatelem definované typy. Součinové datové typy. Součtové datové typy. FLP - Uživatelem definované typy

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

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

Regulární výrazy. Vzory

IB015 Neimperativní programování. Seznamy, Typy a Rekurze. Jiří Barnat Libor Škarvada

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

Výčtový typ strana 67

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

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

Formátová specifikace má tvar (některé sekce nemají smysl pro načítání) %

Datové struktury. alg12 1

MQL4 COURSE. By Coders guru -3 DATA TYPES. Doufám, že předchozí lekce SYNTAX se vám líbila. V té jsme se pokoušeli zodpovědět:

Pokročilé programování v jazyce C pro chemiky (C3220) Vstup a výstup v C++

Úvod do programování 6. hodina

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

Student s Life. Návrhová dokumentace (Design) Lukáš Barák, Jakub Ječmínek, Jaroslav Brchel, Jiří Zmeškal

Zjednodušené základy jazyku C. Josef Podstata

Formátové specifikace formátovací řetězce

Cvičení z programování v C++ ZS 2016/2017 Přemysl Čech

Univerzita Palackého v Olomouci Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 19.2.

Regulární výrazy. jemný úvod. Miloslav Brada

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

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

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

IB015 Neimperativní programování. Časová složitost, Typové třídy, Moduly. Jiří Barnat Libor Škarvada

Lekce 9 IMPLEMENTACE OPERAČNÍHO SYSTÉMU LINUX DO VÝUKY INFORMAČNÍCH TECHNOLOGIÍ JAZYK C

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

Jazyk C# (seminář 6)

Základy programování (IZP)

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

IB015 Neimperativní programování. Redukční strategie, Seznamy program QuickCheck. Jiří Barnat Libor Škarvada

Paradigmata programování 2

zapište obslužnou metodu události Click tlačítka a vyzkoušejte chování polevýsledek.text = polečíslo1.text + polečíslo2.text;

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

VY_32_INOVACE_08_2_04_PR

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

Práce se soubory. Základy programování 2 Tomáš Kühr

1 Knihovní funkce Skupina funkcí bool Skupina funkcí String Testovací program ELDEC Interface X.XX Example...

Java a XML. 10/26/09 1/7 Java a XML

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.

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

Programování v jazyce JavaScript

Poslední aktualizace: 14. října 2011

Textové, datumové a časové funkce

Úvod Informace o prostředí Práce se soubory Regulární výrazy Konec. Programování v C# Soubory a regulární výrazy. Petr Vaněček 1 / 27

Moduly MicroUnit serie. všechny typy s výjimkou řady MU-43x, MU-44x a MU-84x

PROGRAMOVÁNÍ V C++ CVIČENÍ

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

Databázové systémy I

IB111 Programování a algoritmizace. Objektově orientované programování (OOP)

PŘETĚŽOVÁNÍ OPERÁTORŮ

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

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

Programování v C++ 1, 1. cvičení

Transkript:

Parsování v Haskellu, knihovna Parsec IB016 Seminář z funkcionálního programování Vladimír Štill, Martin Ukrop Fakulta informatiky, Masarykova univerzita Jaro 2016 IB016: Cvičení 09 Jaro 2016 1 / 12

Regulární výrazy Haskell má několik balíků pro práci s regulárními výrazy: většina se nachází v modulech Text.Regex.* základní posixová implementace v balíku regex-posix pěkný přehled možností různých balíku najdete třeba na https://wiki.haskell.org/regular_expressions Vesměs stejný princip jako u jiných jazyků. IB016: Cvičení 09 Jaro 2016 2 / 12

Syntaktické analyzátory (parsery) Základní regulární výrazy často nestačí. využijeme syntaktické analyzátory (parsery) lexikální analyzátor Alex + syntaktický analyzátor Happy (podobné kombinaci lex/flex + bison/yacc) Parsec knihovna založena na parserových kombinátorech, zvládá i tvorbu lexikálních analyzátorů Attoparsec další kombinátorová knihovna, hlavně pro síťové protokoly a komplikované textové/binární formáty Polyparse alternativní kombinátorová parsovací knihovna IB016: Cvičení 09 Jaro 2016 3 / 12

Parsec myšlenka: definujme parser pomocí většího množství menších/jednodušších parserů balík parsec, není součástí standardní distribuce nejpoužívanější funkce přímo v modulu Text.Parsec pro naše účely hlavně funkce z modulů Text.Parsec.Char a Text.Parsec.Combinators pro zjednodušení typování importujte i modul Text.Parsec.String IB016: Cvičení 09 Jaro 2016 4 / 12

Datový typ Parser myparser :: Parser a myparser je parser, který zpracuje vstup na hodnotu typu a IB016: Cvičení 09 Jaro 2016 5 / 12

Datový typ Parser myparser :: Parser a myparser je parser, který zpracuje vstup na hodnotu typu a Typ Parser a je však pouze specifický případ parseru: type Parser a = Parsec String () a type Parsec s u a = ParsecT s u Identity a ParsecT s u m a představuje parser, který zpracovává typ s, udržuje si stav typu u, pracuje v monádě m a vrací výsledek typu a. IB016: Cvičení 09 Jaro 2016 5 / 12

Aplikace parserů Jelikož dovnitř typu ParsecT s u m a nevidíme, voláme parsery pomocí specializovaných funkcí. parse :: Stream s Identity t => Parsec s () a -> SourceName -> s -> Either ParseError a parse p name input spustí parser p na vstupu input, name se bude používat pouze na identifikaci v chybových hláškách výsledkem je buď sparsovaná hodnota nebo chyba (typu ParseError) IB016: Cvičení 09 Jaro 2016 6 / 12

Aplikace parserů Jelikož dovnitř typu ParsecT s u m a nevidíme, voláme parsery pomocí specializovaných funkcí. parse :: Stream s Identity t => Parsec s () a -> SourceName -> s -> Either ParseError a parse p name input spustí parser p na vstupu input, name se bude používat pouze na identifikaci v chybových hláškách výsledkem je buď sparsovaná hodnota nebo chyba (typu ParseError) parsefromfile :: Parser a -> String -> IO (Either ParseError a) parsefromfile p f spustí parser p na obsahu souboru f importováno z modulu Text.Parsec.String IB016: Cvičení 09 Jaro 2016 6 / 12

Základní znakový parser Pro zpřehlednění typů používáme typové synonymum Parser z modulu Text.Parsec.String (zmiňované parsery jsou obecnější). Parser má instanci pro třídy Functor, Applicative i Monad, což nám usnadní práci s vícero parsery. IB016: Cvičení 09 Jaro 2016 7 / 12

Základní znakový parser Pro zpřehlednění typů používáme typové synonymum Parser z modulu Text.Parsec.String (zmiňované parsery jsou obecnější). Parser má instanci pro třídy Functor, Applicative i Monad, což nám usnadní práci s vícero parsery. satisfy :: (Char -> Bool) -> Parser Char parser satisfy f uspěje, jestliže načtený znak splňuje zadaný predikát (pak vrací tento znak) IB016: Cvičení 09 Jaro 2016 7 / 12

Základní znakový parser Pro zpřehlednění typů používáme typové synonymum Parser z modulu Text.Parsec.String (zmiňované parsery jsou obecnější). Parser má instanci pro třídy Functor, Applicative i Monad, což nám usnadní práci s vícero parsery. satisfy :: (Char -> Bool) -> Parser Char parser satisfy f uspěje, jestliže načtený znak splňuje zadaný predikát (pak vrací tento znak) char, digit, letter, anychar, space, oneof, noneof,... IB016: Cvičení 09 Jaro 2016 7 / 12

Kombinace parserů sekvence Využijeme instanci Parser pro třídu Monad: return x je parser, který nic nečte a vrátí hodnotu x operátor >>= předá sparsovanou hodnotu zleva doprava IB016: Cvičení 09 Jaro 2016 8 / 12

Kombinace parserů sekvence Využijeme instanci Parser pro třídu Monad: return x je parser, který nic nečte a vrátí hodnotu x operátor >>= předá sparsovanou hodnotu zleva doprava Parser pro 2 libovolné znaky: twochars = do char1 <- anychar char2 <- anychar return [char1, char2] IB016: Cvičení 09 Jaro 2016 8 / 12

Kombinace parserů sekvence Využijeme instanci Parser pro třídu Monad: return x je parser, který nic nečte a vrátí hodnotu x operátor >>= předá sparsovanou hodnotu zleva doprava Parser pro 2 libovolné znaky: twochars = do char1 <- anychar char2 <- anychar return [char1, char2] string, between, count,... IB016: Cvičení 09 Jaro 2016 8 / 12

Kombinace parserů alternativa < > :: Parser a -> Parser a -> Parser a p < > q se pokusí nejdříve použít parser p a jestli uspěje, vrátí jeho výsledek jestli p selže bez toho, aby spotřeboval nějaký vstup, použije se parser q IB016: Cvičení 09 Jaro 2016 9 / 12

Kombinace parserů alternativa < > :: Parser a -> Parser a -> Parser a p < > q se pokusí nejdříve použít parser p a jestli uspěje, vrátí jeho výsledek jestli p selže bez toho, aby spotřeboval nějaký vstup, použije se parser q Parser pro pozdrav: greeting = string "hello" < > string "ahoj" IB016: Cvičení 09 Jaro 2016 9 / 12

Kombinace parserů alternativa < > :: Parser a -> Parser a -> Parser a p < > q se pokusí nejdříve použít parser p a jestli uspěje, vrátí jeho výsledek jestli p selže bez toho, aby spotřeboval nějaký vstup, použije se parser q Parser pro pozdrav: greeting = string "hello" < > string "ahoj" many, many1, option, optional, sepby, sepby1,... IB016: Cvičení 09 Jaro 2016 9 / 12

Kombinace parserů alternativa greeting2 = string "hello" < > string "how-are-you" IB016: Cvičení 09 Jaro 2016 10 / 12

Kombinace parserů alternativa greeting2 = string "hello" < > string "how-are-you" greeting2 na řetězci "how-are-you" selže levá alternativa sice selhala, ale spotřebovala vstup! IB016: Cvičení 09 Jaro 2016 10 / 12

Kombinace parserů alternativa greeting2 = string "hello" < > string "how-are-you" greeting2 na řetězci "how-are-you" selže levá alternativa sice selhala, ale spotřebovala vstup! try :: ParsecT s u m a -> ParsecT s u m a try p se chová stejně jako parser p, ale když p selže, vrátí se ve vstupu, jako by žádný nebyl parserem p spotřebován Pozor: používání try zvyšuje složitost parsování! (Ale na druhou stranu nám umožňuje mít libovolný lookahead.) IB016: Cvičení 09 Jaro 2016 10 / 12

Instance pro Applicative, Monad >> spaces >> identifier IB016: Cvičení 09 Jaro 2016 11 / 12

Instance pro Applicative, Monad >> spaces >> identifier liftax lifta2 (+) number number IB016: Cvičení 09 Jaro 2016 11 / 12

Instance pro Applicative, Monad >> spaces >> identifier liftax lifta2 (+) number number <$> (++"!") <$> greeting IB016: Cvičení 09 Jaro 2016 11 / 12

Instance pro Applicative, Monad >> spaces >> identifier liftax lifta2 (+) number number <$> (++"!") <$> greeting <$ "greeting here" <$ greeting IB016: Cvičení 09 Jaro 2016 11 / 12

Instance pro Applicative, Monad >> spaces >> identifier liftax lifta2 (+) number number <$> (++"!") <$> greeting <$ "greeting here" <$ greeting <*> (,) <$> key <*> value IB016: Cvičení 09 Jaro 2016 11 / 12

Instance pro Applicative, Monad >> spaces >> identifier liftax lifta2 (+) number number <$> (++"!") <$> greeting <$ "greeting here" <$ greeting <*> (,) <$> key <*> value <* string "Hello" <* spaces <* name IB016: Cvičení 09 Jaro 2016 11 / 12

Instance pro Applicative, Monad >> spaces >> identifier liftax lifta2 (+) number number <$> (++"!") <$> greeting <$ "greeting here" <$ greeting <*> (,) <$> key <*> value <* string "Hello" <* spaces <* name *> string "Hello" *> spaces *> name IB016: Cvičení 09 Jaro 2016 11 / 12

Samostatná práce Napište parser pro: čísla která můžou mít desetinnou část "12", "12.54" správně uzávorkované výrazy "(()())()" datum "2015-04-14" rozpoznaný řetězec číslic můžete konvertovat funkcí read, výsledek ať je vámi definovaného typu Date, rozsah kontrolovat nemusíte výraz s přirozenými čísly a operacemi (2+5)*2 precedenci operátorů neřešte, parser ať výraz rovnou vyhodnotí, tj. ať je typu Parser Int IB016: Cvičení 09 Jaro 2016 12 / 12