2013-10-03 14:45:30 +00:00
<!DOCTYPE html>
< html >
< head >
< meta charset = "utf-8" >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" >
< meta name = "viewport" content = "width=1024, user-scalable=no" >
2013-10-06 22:35:42 +00:00
< title > Parsec Presentation by Yann Esposito< / title >
2013-10-03 14:45:30 +00:00
<!-- Required stylesheet -->
< link rel = "stylesheet" href = "core/deck.core.css" >
<!-- Extension CSS files go here. Remove or add as needed. -->
< link rel = "stylesheet" href = "extensions/goto/deck.goto.css" >
< link rel = "stylesheet" href = "extensions/menu/deck.menu.css" >
< link rel = "stylesheet" href = "extensions/navigation/deck.navigation.css" >
< link rel = "stylesheet" href = "extensions/status/deck.status.css" >
< link rel = "stylesheet" href = "extensions/hash/deck.hash.css" >
<!-- <link rel="stylesheet" href="extensions/scale/deck.scale.css"> -->
<!-- Transition theme. More available in /themes/transition/ or create your own. -->
<!-- <link rel="stylesheet" href="themes/transition/fade.css"> -->
<!-- Style theme. More available in /themes/style/ or create your own. -->
<!-- <link rel="stylesheet" href="themes/style/web - 2.0.css"> -->
< link rel = "stylesheet" href = "themes/style/y/main.css" / >
< link rel = "stylesheet" href = "themes/style/y/solarized.css" / >
<!-- Required Modernizr file -->
< script src = "modernizr.custom.js" > < / script >
< script >
function gofullscreen(){
var body=document.getElementById('body');
try {
body.requestFullScreen();
} catch(err) {
try {
body.webkitRequestFullScreen();
} catch(err) {
body.mozRequestFullScreen();
}
}
return false;
}
< / script >
< / head >
< body id = "body" class = "deck-container" >
< div style = "display:none" >
\(\newcommand{\F}{\mathbf{F}}\)
\(\newcommand{\E}{\mathbf{E}}\)
\(\newcommand{\C}{\mathcal{C}}\)
\(\newcommand{\D}{\mathcal{D}}\)
\(\newcommand{\id}{\mathrm{id}}\)
\(\newcommand{\ob}[1]{\mathrm{ob}(#1)}\)
\(\newcommand{\hom}[1]{\mathrm{hom}(#1)}\)
\(\newcommand{\Set}{\mathbf{Set}}\)
\(\newcommand{\Mon}{\mathbf{Mon}}\)
\(\newcommand{\Vec}{\mathbf{Vec}}\)
\(\newcommand{\Grp}{\mathbf{Grp}}\)
\(\newcommand{\Rng}{\mathbf{Rng}}\)
\(\newcommand{\ML}{\mathbf{ML}}\)
\(\newcommand{\Hask}{\mathbf{Hask}}\)
\(\newcommand{\Cat}{\mathbf{Cat}}\)
\(\newcommand{\fmap}{\mathtt{fmap}}\)
< / div >
<!-- Begin slides. Just make elements with a class of slide. -->
< section class = "slide" >
< div style = "text-align:center; position:absolute; top: 2em; font-size: .9em; width: 100%" >
< h1 style = "position: relative;" > Parsec< / h1 >
< author > < em class = "base01" > by< / em > Yann Esposito< / author >
< div style = "font-size:.5em" >
< twitter >
< a href = "http://twitter.com/yogsototh" > @yogsototh< / a > ,
< / twitter >
< googleplus >
< a href = "https://plus.google.com/117858550730178181663" > +yogsototh< / a >
< / googleplus >
< / div >
< div class = "base01" style = "font-size: .5em; font-weight: 400; font-variant:italic" >
< div class = "button" style = "margin: .5em auto;border: solid 2px; padding: 5px; width: 8em; border-radius: 1em; background:rgba(255,255,255,0.05);" onclick = "javascript:gofullscreen();" > ENTER FULLSCREEN< / div >
HTML presentation: use arrows, space to navigate.
< / div >
< / div >
< / section >
< section class = "slide" >
2013-10-06 22:35:42 +00:00
< h2 id = "parsing" > Parsing< / h2 >
< p > Latin pars (ōrātiōnis), meaning part (of speech).< / p >
< ul >
< li > < strong > analysing a string of symbols< / strong > < / li >
< li > < strong > formal grammar< / strong > .< / li >
< / ul >
2013-10-03 14:45:30 +00:00
< / section >
< section class = "slide" >
2013-10-07 20:34:27 +00:00
< h2 id = "parsing-in-programming-languages" > Parsing in Programming Languages< / h2 >
< p > Complexity:< / p >
< table >
< thead >
< tr class = "header" >
< th align = "left" > Method< / th >
< th align = "left" > Typical Example< / th >
< th align = "left" > Output Data Structure< / th >
< / tr >
< / thead >
< tbody >
< tr class = "odd" >
< td align = "left" > Splitting< / td >
< td align = "left" > CSV< / td >
< td align = "left" > Array, Map< / td >
< / tr >
< tr class = "even" >
< td align = "left" > Regexp< / td >
< td align = "left" > email< / td >
< td align = "left" > + Fixed Layout Tree< / td >
< / tr >
< tr class = "odd" >
< td align = "left" > Parser< / td >
< td align = "left" > Programming language< / td >
< td align = "left" > + Most Data Structure< / td >
< / tr >
< / tbody >
< / table >
< / section >
< section class = "slide" >
< h2 id = "parser-culture" > Parser < span class = "and" > & < / span > culture< / h2 >
< p > In Haskell Parser are really easy to use.< / p >
< p > Generally:< / p >
< ul >
< li > In most languages: < strong > split< / strong > then < strong > regexp< / strong > then < strong > parse< / strong > < / li >
< li > In Haskell: < strong > split< / strong > then < strong > parse< / strong > < / li >
< / ul >
< / section >
< section class = "slide" >
< h2 id = "parsing-example" > Parsing Example< / h2 >
2013-10-06 22:35:42 +00:00
< p > From String:< / p >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > (< span class = "dv" > 1< / span > < span class = "fu" > +< / span > < span class = "dv" > 3< / span > )< span class = "fu" > *< / span > (< span class = "dv" > 1< / span > < span class = "fu" > +< / span > < span class = "dv" > 5< / span > < span class = "fu" > +< / span > < span class = "dv" > 9< / span > )< / code > < / pre >
< p > To data structure:< / p >
< p > < img src = "parsec/img/mp/AST.png" alt = "AST" / > < br / > < / p >
< / section >
< section class = "slide" >
< h2 id = "parsec" > Parsec< / h2 >
< blockquote >
< p > Parsec lets you construct parsers by combining high-order Combinators to create larger expressions.< / p >
< p > Combinator parsers are written and used within the same programming language as the rest of the program.< / p >
< p > The parsers are first-class citizens of the languages [...]" < / p >
< / blockquote >
< / section >
< section class = "slide" >
2013-10-07 20:34:27 +00:00
< h2 id = "parser-libraries" > Parser Libraries< / h2 >
< p > In reality there are many choices:< / p >
< table >
< tbody >
< tr class = "odd" >
< td align = "left" > attoparsec< / td >
< td align = "left" > fast< / td >
< / tr >
< tr class = "even" >
< td align = "left" > Bytestring-lexing< / td >
< td align = "left" > fast< / td >
< / tr >
< tr class = "odd" >
< td align = "left" > Parsec 3< / td >
< td align = "left" > powerful, nice error reporting< / td >
< / tr >
< / tbody >
< / table >
< / section >
< section class = "slide" >
< h2 id = "haskell-remarks-1" > Haskell Remarks (1)< / h2 >
< p > spaces are meaningful< / p >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > f x < span class = "co" > -- ⇔ f(x) in C-like languages< / span >
f x y < span class = "co" > -- ⇔ f(x,y)< / span > < / code > < / pre >
< / section >
< section class = "slide" >
< h2 id = "haskell-remarks-2" > Haskell Remarks (2)< / h2 >
< p > Don't mind strange operators (< code > < *> < / code > , < code > < $> < / code > ).< br / > Consider them like separators, typically commas.< br / > They are just here to deal with types.< / p >
< p > Informally:< / p >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > toto < span class = "fu" > < $> < / span > x < span class = "fu" > < *> < / span > y < span class = "fu" > < *> < / span > z
< span class = "co" > -- ⇔ toto x y z< / span >
< span class = "co" > -- ⇔ toto(x,y,z) in C-like languages< / span > < / code > < / pre >
2013-10-07 13:56:31 +00:00
< / section >
< section class = "slide" >
2013-10-06 22:35:42 +00:00
< h2 id = "a-parsec-example" > A Parsec Example< / h2 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > whitespaces < span class = "fu" > =< / span > many (oneOf < span class = "st" > " \t " < / span > )
2013-10-07 13:56:31 +00:00
number < span class = "fu" > =< / span > many1 digit
symbol < span class = "fu" > =< / span > oneOf < span class = "st" > " !#$%< span class = "and" > & < / span > |*+-/:< => ?@^_~" < / span > < / code > < / pre >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "st" > " \t " < / span > < span class = "co" > -- whitespaces on " \t " < / span >
< span class = "st" > " " < / span > < span class = "co" > -- whitespaces on " 32" < / span >
< span class = "st" > " 32" < / span > < span class = "co" > -- number on " 32" < / span >
2013-10-06 22:35:42 +00:00
< span class = "co" > -- number on " \t 32 " < / span >
2013-10-07 13:56:31 +00:00
< span class = "st" > " number" < / span > (line < span class = "dv" > 1< / span > , column < span class = "dv" > 1< / span > )< span class = "fu" > :< / span >
2013-10-06 22:35:42 +00:00
unexpected < span class = "st" > " " < / span >
expecting digit< / code > < / pre >
< / section >
< section class = "slide" >
2013-10-07 20:34:27 +00:00
< h2 id = "comparison-with-regexp-parsec" > Comparison with Regexp (Parsec)< / h2 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "kw" > data< / span > < span class = "dt" > IP< / span > < span class = "fu" > =< / span > < span class = "dt" > IP< / span > < span class = "dt" > Word8< / span > < span class = "dt" > Word8< / span > < span class = "dt" > Word8< / span > < span class = "dt" > Word8< / span >
ip < span class = "fu" > =< / span > < span class = "dt" > IP< / span > < span class = "fu" > < $> < / span >
number < span class = "fu" > < *< / span > char < span class = "ch" > ' .' < / span > < span class = "fu" > < *> < / span >
number < span class = "fu" > < *< / span > char < span class = "ch" > ' .' < / span > < span class = "fu" > < *> < / span >
number < span class = "fu" > < *< / span > char < span class = "ch" > ' .' < / span > < span class = "fu" > < *> < / span >
number
number < span class = "fu" > =< / span > < span class = "kw" > do< / span >
x < span class = "ot" > < -< / span > read < span class = "fu" > < $> < / span > many1 digit
guard (< span class = "dv" > 0< / span > < span class = "fu" > < =< / span > x < span class = "fu" > < span class = "and" > & < / span > < span class = "and" > & < / span > < / span > x < span class = "fu" > < < / span > < span class = "dv" > 256< / span > )
return (fromIntegral x)< / code > < / pre >
< / section >
< section class = "slide" >
< h2 id = "comparison-with-regexp-perl-regexp" > Comparison with Regexp (Perl Regexp)< / h2 >
< pre class = "sourceCode perl" > < code class = "sourceCode perl" > < span class = "co" > # remark: 888.999.999.999 is accepted< / span >
\b\d{< span class = "dv" > 1< / span > ,< span class = "dv" > 3< / span > }\.\d{< span class = "dv" > 1< / span > ,< span class = "dv" > 3< / span > }\.\d{< span class = "dv" > 1< / span > ,< span class = "dv" > 3< / span > }\.\d{< span class = "dv" > 1< / span > ,< span class = "dv" > 3< / span > }\b
< span class = "co" > # exact but difficult to read< / span >
\b(?:(?:< span class = "dv" > 25< / span > [< span class = "dv" > 0-5< / span > ]|< span class = "dv" > 2< / span > [< span class = "dv" > 0-4< / span > ][< span class = "dv" > 0-9< / span > ]|[< span class = "dv" > 01< / span > ]?[< span class = "dv" > 0-9< / span > ][< span class = "dv" > 0-9< / span > ]?)\.){< span class = "dv" > 3< / span > }
(?:< span class = "dv" > 25< / span > [< span class = "dv" > 0-5< / span > ]|< span class = "dv" > 2< / span > [< span class = "dv" > 0-4< / span > ][< span class = "dv" > 0-9< / span > ]|[< span class = "dv" > 01< / span > ]?[< span class = "dv" > 0-9< / span > ][< span class = "dv" > 0-9< / span > ]?)\b< / code > < / pre >
< p > Also, regexp are < em > unityped< / em > by nature.< / p >
< / section >
< section class = "slide" >
2013-10-06 22:35:42 +00:00
< h2 id = "monadic-style" > Monadic style< / h2 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > number ::< / span > < span class = "dt" > Parser< / span > < span class = "dt" > String< / span >
number < span class = "fu" > =< / span > many1 digit
< span class = "ot" > number' ::< / span > < span class = "dt" > Parser< / span > < span class = "dt" > Int< / span >
number' < span class = "fu" > =< / span > < span class = "kw" > do< / span >
2013-10-07 20:34:27 +00:00
< span class = "co" > -- digitString :: String< / span >
digitString < span class = "ot" > < -< / span > many1 digit
return (read digitString)< / code > < / pre >
2013-10-06 22:35:42 +00:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "st" > " 32" < / span > < span class = "ot" > ::< / span > [< span class = "dt" > Char< / span > ] < span class = "co" > -- number on " 32" < / span >
< span class = "dv" > 32< / span > < span class = "ot" > ::< / span > < span class = "dt" > Int< / span > < span class = "co" > -- number' on " 32" < / span > < / code > < / pre >
< / section >
< section class = "slide" >
2013-10-07 20:34:27 +00:00
< h2 id = "combining-monadic-style-s-asb-ε" > Combining Monadic style (S = aSb | ε)< / h2 >
2013-10-07 13:56:31 +00:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > s < span class = "fu" > =< / span > (< span class = "kw" > do< / span >
2013-10-07 20:34:27 +00:00
a < span class = "ot" > < -< / span > string < span class = "st" > " a" < / span >
mid < span class = "ot" > < -< / span > s
b < span class = "ot" > < -< / span > string < span class = "st" > " b" < / span >
return (a < span class = "fu" > ++< / span > mid < span class = "fu" > ++< / span > b)
2013-10-07 13:56:31 +00:00
< span class = "fu" > < |> < / span > string < span class = "st" > " " < / span > < / code > < / pre >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "st" > " " < / span > < span class = "co" > -- s on " " < / span >
< span class = "st" > " aaabbb" < / span > < span class = "co" > -- s on " aaabbb" < / span >
< span class = "st" > " aabb" < / span > < span class = "co" > -- s on " aabbb" < / span >
< span class = "co" > -- s on " aaabb" < / span >
< span class = "dt" > S< / span > (line1 < span class = "dv" > 1< / span > , column < span class = "dv" > 4< / span > )< span class = "fu" > :< / span >
unexpected end < span class = "kw" > of< / span > input
expecting < span class = "st" > " b" < / span > < / code > < / pre >
< / section >
< section class = "slide" >
2013-10-07 20:34:27 +00:00
< h2 id = "combining-applicative-style-s-asb-ε" > Combining Applicative style (S = aSb | ε)< / h2 >
2013-10-07 13:56:31 +00:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > s < span class = "fu" > =< / span > concat3 < span class = "fu" > < $> < / span > string < span class = "st" > " a" < / span > < span class = "fu" > < *> < / span > s < span class = "fu" > < *> < / span > char < span class = "st" > " b" < / span >
< span class = "fu" > < |> < / span > string < span class = "st" > " " < / span >
< span class = "kw" > where< / span >
concat3 x y z < span class = "fu" > =< / span > x < span class = "fu" > ++< / span > y < span class = "fu" > ++< / span > z< / code > < / pre >
< / section >
< section class = "slide" >
< h2 id = "applicative-style-usefull-with-data-types" > Applicative Style usefull with Data types< / h2 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "kw" > data< / span > < span class = "dt" > IP< / span > < span class = "fu" > =< / span > < span class = "dt" > IP< / span > < span class = "dt" > Int< / span > < span class = "dt" > Int< / span > < span class = "dt" > Int< / span > < span class = "dt" > Int< / span >
parseIP < span class = "fu" > =< / span > < span class = "dt" > IP< / span > < span class = "fu" > < $> < / span >
number < span class = "fu" > < *< / span > char < span class = "ch" > ' .' < / span > < span class = "fu" > < *> < / span >
number < span class = "fu" > < *< / span > char < span class = "ch" > ' .' < / span > < span class = "fu" > < *> < / span >
number < span class = "fu" > < *< / span > char < span class = "ch" > ' .' < / span > < span class = "fu" > < *> < / span >
number
monadicParseIP < span class = "fu" > =< / span > < span class = "kw" > do< / span >
d1 < span class = "ot" > < -< / span > number
char < span class = "ch" > ' .' < / span >
d2 < span class = "ot" > < -< / span > number
char < span class = "ch" > ' .' < / span >
d3 < span class = "ot" > < -< / span > number
char < span class = "ch" > ' .' < / span >
d4 < span class = "ot" > < -< / span > number
2013-10-07 20:34:27 +00:00
return (< span class = "dt" > IP< / span > d1 d2 d3 d4)< / code > < / pre >
2013-10-07 13:56:31 +00:00
< / section >
< section class = "slide" >
< h2 id = "write-number-correctly" > Write number correctly< / h2 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > number ::< / span > < span class = "dt" > Parser< / span > < span class = "dt" > Int< / span >
number < span class = "fu" > =< / span > < span class = "kw" > do< / span >
2013-10-07 20:34:27 +00:00
x < span class = "ot" > < -< / span > read < span class = "fu" > < $> < / span > many1 digit
2013-10-07 13:56:31 +00:00
guard (< span class = "dv" > 0< / span > < span class = "fu" > < =< / span > x < span class = "fu" > < span class = "and" > & < / span > < span class = "and" > & < / span > < / span > x < span class = "fu" > < < / span > < span class = "dv" > 256< / span > ) < span class = "fu" > < ?> < / span >
2013-10-07 20:34:27 +00:00
< span class = "st" > " Number between 0 and 255 (here " < / span > < span class = "fu" > ++< / span > show x < span class = "fu" > ++< / span > < span class = "st" > " )" < / span >
return (fromIntegral x)< / code > < / pre >
2013-10-07 13:56:31 +00:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "fu" > > > > < / span > test parseIP < span class = "st" > " parseIP" < / span > < span class = "st" > " 823.32.80.113" < / span >
< span class = "st" > " parseIP" < / span > (line < span class = "dv" > 1< / span > , column < span class = "dv" > 4< / span > )< span class = "fu" > :< / span >
unexpected < span class = "st" > " ." < / span >
2013-10-07 20:34:27 +00:00
expecting digit or < span class = "dt" > Number< / span > between < span class = "dv" > 0< / span > and < span class = "dv" > 255< / span > (here < span class = "dv" > 823< / span > )< / code > < / pre >
2013-10-07 13:56:31 +00:00
< / section >
< section class = "slide" >
< h2 id = "so" > So< / h2 >
< ul >
< li > combination of simple parsers< / li >
< li > error messages with < code > (< ?> )< / code > < / li >
< li > embed result in data type using Applicative style< / li >
< li > Not shown, use another monad with the parser< / li >
< / ul >
< p > Time to do something cool< / p >
< / section >
< section class = "slide" >
< h2 id = "a-simple-dsl" > A Simple DSL< / h2 >
< p > Let's write a minimal DSL< / p >
< / section >
< section class = "slide" >
< h2 id = "useful-definitions" > Useful definitions< / h2 >
< p > < code > try< / code > tries to parse and backtracks if it fails.< / p >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > (< span class = "fu" > < ||> < / span > ) parser1 parser2 < span class = "fu" > =< / span > try parser1 < span class = "fu" > < |> < / span > parser2< / code > < / pre >
< p > < code > lexeme< / code > , just skip spaces.< / p >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > lexeme parser < span class = "fu" > =< / span > whitespaces < span class = "fu" > *> < / span > parser < span class = "fu" > < *< / span > whitespaces< / code > < / pre >
< / section >
< section class = "slide" >
2013-10-07 21:29:37 +00:00
< h2 id = "scheme" > Scheme< / h2 >
< p > < a href = "https://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours" > Write Yourself a Scheme in 48 hours< / a > < / p >
< p > Remember from text to data structure. Our data structure:< / p >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "kw" > data< / span > < span class = "dt" > LispVal< / span > < span class = "fu" > =< / span > < span class = "dt" > Atom< / span > < span class = "dt" > String< / span >
< span class = "fu" > |< / span > < span class = "dt" > List< / span > [< span class = "dt" > LispVal< / span > ]
< span class = "fu" > |< / span > < span class = "dt" > DottedList< / span > [< span class = "dt" > LispVal< / span > ] < span class = "dt" > LispVal< / span >
< span class = "fu" > |< / span > < span class = "dt" > Number< / span > < span class = "dt" > Integer< / span >
< span class = "fu" > |< / span > < span class = "dt" > String< / span > < span class = "dt" > String< / span >
< span class = "fu" > |< / span > < span class = "dt" > Bool< / span > < span class = "dt" > Bool< / span > < / code > < / pre >
< / section >
< section class = "slide" >
< h2 id = "parse-string" > Parse String< / h2 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > parseString ::< / span > < span class = "dt" > Parser< / span > < span class = "dt" > LispVal< / span >
parseString < span class = "fu" > =< / span > < span class = "kw" > do< / span >
char < span class = "ch" > ' " ' < / span >
x < span class = "ot" > < -< / span > many (noneOf < span class = "st" > " \" " < / span > )
char < span class = "ch" > ' " ' < / span >
return (< span class = "dt" > String< / span > x)< / code > < / pre >
< pre > < code > -- parseString on ' " toto" '
(String " toto" ) :: LispVal
-- parseString on ' " hello" '
(String " hello" ) :: LispVal< / code > < / pre >
< / section >
< section class = "slide" >
< h2 id = "parse-atom" > Parse Atom< / h2 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > symbol ::< / span > < span class = "dt" > Parser< / span > < span class = "dt" > Char< / span >
symbol < span class = "fu" > =< / span > oneOf < span class = "st" > " !#$%< span class = "and" > & < / span > |*+-/:< => ?@^_~" < / span >
< span class = "ot" > parseAtom ::< / span > < span class = "dt" > Parser< / span > < span class = "dt" > LispVal< / span >
parseAtom < span class = "fu" > =< / span > < span class = "kw" > do< / span >
first < span class = "ot" > < -< / span > letter < span class = "fu" > < |> < / span > symbol
rest < span class = "ot" > < -< / span > many (letter < span class = "fu" > < |> < / span > digit < span class = "fu" > < |> < / span > symbol)
< span class = "kw" > let< / span > atom < span class = "fu" > =< / span > first< span class = "fu" > :< / span > rest
return < span class = "fu" > $< / span > < span class = "kw" > case< / span > atom < span class = "kw" > of< / span >
< span class = "st" > " #t" < / span > < span class = "ot" > -> < / span > < span class = "dt" > Bool< / span > < span class = "dt" > True< / span >
< span class = "st" > " #f" < / span > < span class = "ot" > -> < / span > < span class = "dt" > Bool< / span > < span class = "dt" > False< / span >
_ < span class = "ot" > -> < / span > < span class = "dt" > Atom< / span > atom< / code > < / pre >
< / section >
< section class = "slide" >
< h2 id = "test-parseatom" > Test < code > parseAtom< / code > < / h2 >
< pre > < code > -- parseAtom on ' #t'
(Bool True) :: LispVal
-- parseAtom on ' #f'
(Bool False) :: LispVal
-- parseAtom on ' some-atom'
(Atom " some-atom" ) :: LispVal< / code > < / pre >
< / section >
< section class = "slide" >
< h2 id = "parse-number" > Parse Number< / h2 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > parseNumber ::< / span > < span class = "dt" > Parser< / span > < span class = "dt" > LispVal< / span >
parseNumber < span class = "fu" > =< / span > < span class = "dt" > Number< / span > < span class = "fu" > .< / span > read < span class = "fu" > < $> < / span > many1 digit< / code > < / pre >
< pre > < code > -- parseNumber on ' 18'
Number 18 :: LispVal
-- parseNumber on ' 188930992344321234'
Number 188930992344321234 :: LispVal< / code > < / pre >
< / section >
< section class = "slide" >
< h2 id = "compose-all-parsers" > Compose all parsers< / h2 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > parseExpr ::< / span > < span class = "dt" > Parser< / span > < span class = "dt" > LispVal< / span >
parseExpr < span class = "fu" > =< / span > parseAtom
< span class = "fu" > < ||> < / span > parseString
< span class = "fu" > < ||> < / span > parseNumber< / code > < / pre >
< / section >
< section class = "slide" >
< h2 id = "test-the-parser" > Test the parser< / h2 >
< pre > < code > -- parseExpr on ' 188930992344321234'
Number 188930992344321234 :: LispVal
-- parseExpr on ' #t'
Bool True :: LispVal
-- parseExpr on ' just-some-word'
Atom " just-some-word" :: LispVal
-- parseExpr on ' %-symbol-start'
Atom " %-symbol-start" :: LispVal
-- parseExpr on ' " a String" '
String " a String" :: LispVal< / code > < / pre >
< / section >
< section class = "slide" >
< h2 id = "recursive-parsers" > Recursive Parsers< / h2 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > parseList ::< / span > < span class = "dt" > Parser< / span > < span class = "dt" > LispVal< / span >
parseList < span class = "fu" > =< / span > < span class = "dt" > List< / span > < span class = "fu" > < $> < / span >
(char < span class = "ch" > ' (' < / span > < span class = "fu" > *> < / span > sepBy parseExpr' spaces < span class = "fu" > < *< / span > char < span class = "ch" > ' )' < / span > )
< span class = "ot" > parseExpr' ::< / span > < span class = "dt" > Parser< / span > < span class = "dt" > LispVal< / span >
parseExpr' < span class = "fu" > =< / span > parseAtom
< span class = "fu" > < ||> < / span > parseString
< span class = "fu" > < ||> < / span > parseNumber
< span class = "fu" > < ||> < / span > parseList< / code > < / pre >
< / section >
< section class = "slide" >
< h2 id = "test-parse-list" > Test Parse List< / h2 >
< pre > < code > -- parseExpr' on ' (foo (bar baz))'
List [Atom " foo" ,List [Atom " bar" ,Atom " baz" ]] :: LispVal
-- parseExpr' on ' (foo (bar)'
" parseExpr' " (line 1, column 11):
unexpected end of input
expecting white space, letter, " \" " , digit, " (" or " )"
-- parseExpr' on ' (((foo)) bar)'
List [List [List [Atom " foo" ]],Atom " bar" ] :: LispVal< / code > < / pre >
< / section >
< section class = "slide" >
< h2 id = "conclusion" > Conclusion< / h2 >
< p > So Parser are more powerful than regular expression.< br / > Parsec make it very easy to use.< br / > Easy to read and to manipulate.< / p >
< p > Notice how you could use parser as any other object in Haskell. You could < code > mapM< / code > them for example.< / p >
< p > Any question?< / p >
2013-10-03 14:45:30 +00:00
< / section >
<!-- End slides. -->
<!-- Begin extension snippets. Add or remove as needed. -->
<!-- deck.navigation snippet -->
< a href = "#" class = "deck-prev-link" title = "Previous" > ← < / a >
< a href = "#" class = "deck-next-link" title = "Next" > → < / a >
<!-- deck.status snippet -->
< p class = "deck-status" >
< span class = "deck-status-current" > < / span >
/
< span class = "deck-status-total" > < / span >
< / p >
<!-- deck.goto snippet -->
< form action = "." method = "get" class = "goto-form" >
< label for = "goto-slide" > Go to slide:< / label >
< input type = "text" name = "slidenum" id = "goto-slide" list = "goto-datalist" >
< datalist id = "goto-datalist" > < / datalist >
< input type = "submit" value = "Go" >
< / form >
<!-- deck.hash snippet -->
< a href = "." title = "Permalink to this slide" class = "deck-permalink" > #< / a >
<!-- End extension snippets. -->
<!-- Required JS files. -->
< script src = "jquery-1.7.2.min.js" > < / script >
< script src = "core/deck.core.js" > < / script >
<!-- Extension JS files. Add or remove as needed. -->
< script src = "core/deck.core.js" > < / script >
< script src = "extensions/hash/deck.hash.js" > < / script >
< script src = "extensions/menu/deck.menu.js" > < / script >
< script src = "extensions/goto/deck.goto.js" > < / script >
< script src = "extensions/status/deck.status.js" > < / script >
< script src = "extensions/navigation/deck.navigation.js" > < / script >
<!-- <script src="extensions/scale/deck.scale.js"></script> -->
<!-- Initialize the deck. You can put this in an external file if desired. -->
< script >
$(function() {
$.deck('.slide');
});
< / script >
<!-- Y theme -->
< script src = "js/mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML" > < / script >
< script src = "js/highlight/highlight.pack.js" > < / script >
< script >
hljs.initHighlightingOnLoad();
< / script >
< / body >
< / html >