Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Functional parsers
A parser checks whether the input string is syntacticallycorrect (according to a grammar) and constructs acorresponding abstract syntax tree.
1+ 2 ∗ 3
+
1 ∗
2 3
Kalmer Apinis Monadic parsing Functional Programming, Spring 2015
2
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Functional parsers
Type of parserstype Parser a = String -> [(a,String)]
Applying a parserrunParser :: Parser a -> String -> [(a, String)]runParser p str = p str
3
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Functional parsers
Primitive parsersfailp :: Parser afailp = \str -> []
succp :: a -> Parser asuccp x = \str -> [(x, str)]
symp :: Char -> Parser Charsymp x = \str -> case str of
[] -> []c:cs -> [(c,cs) | c == x]
4
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Functional parsers
Sequential compositioninfixr 6 <*>(<*>) :: Parser a -> Parser b -> Parser (a,b)p1 <*> p2 = \str -> [((v1,v2),cs2) | (v1,cs1) <- p1 str,
(v2,cs2) <- p2 cs1]
Parallel compositioninfixr 4 <|>(<|>) :: Parser a -> Parser a -> Parser ap1 <|> p2 = \str -> p1 str ++ p2 str
5
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Functional parsers
Manipulating valuesinfixr 5 <@(<@) :: Parser a -> (a -> b) -> Parser bp <@ f = \str -> [(f v, cs) | (v,cs) <- p str]
Exampledata Tree = Nil | Bin Tree Tree
parens :: Parser Treeparens = symp ’(’ <*> parens <*> symp ’)’ <*> parens
<@ (\ (_,(x,(_,y))) -> Bin x y)<|> succp Nil
6
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Parser monad
Type of parsersnewtype Parser a = P {runP :: (String -> [(a,String)])}
Parser monadinstance Monad Parser where
return a = P $ \str -> [(a, str)]p >>= f = P $ \str -> concat [runP (f a) cs |
(a,cs) <- runP p str]
instance MonadPlus Parser wheremzero = P $ \str -> []mplus p q = P $ \str -> runP p str ++ runP q str
7
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Parser monad
Primitive combinatorsitem :: Parser Charitem = P $ \str -> [(head str, tail str) | not (null str)]
first :: Parser a -> Parser afirst p = P $ \str -> case runP p str of
[] -> [](x:xs) -> [x]
8
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Simple parser combinators
Derived combinatorssat :: (Char -> Bool) -> Parser Charsat p = do c <- item
if p c thenreturn c
elsemzero
char :: Char -> Parser Charchar c = sat (c ==)
(<|>) :: Parser a -> Parser a -> Parser ap <|> q = first (p ‘mplus‘ q)
Exampleparens :: Parser Treeparens = do char ’(’
t1 <- parenschar ’)’t2 <- parensreturn (Bin t1 t2)
<|> return Nil
8
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Simple parser combinators
Derived combinatorssat :: (Char -> Bool) -> Parser Charsat p = do c <- item
if p c thenreturn c
elsemzero
char :: Char -> Parser Charchar c = sat (c ==)
(<|>) :: Parser a -> Parser a -> Parser ap <|> q = first (p ‘mplus‘ q)
Exampleparens :: Parser Treeparens = do char ’(’
t1 <- parenschar ’)’t2 <- parensreturn (Bin t1 t2)
<|> return Nil
9
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Simple parser combinators
Iterationmany :: Parser a -> Parser [a]many p = many1 p <|> return []
many1 :: Parser a -> Parser [a]many1 p = do a <- p
as <- many preturn (a:as)
10
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Simple parser combinators
Keywordsstring :: String -> Parser Stringstring "" = return ""string (c:cs) = do char c
string csreturn (c:cs)
Identifiersidentifier :: Parser Stringidentifier = do c <- lower
cs <- many alphanumreturn (c:cs)
11
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Simple parser combinators
Natural numbersdigit :: Parser Intdigit = do c <- sat isDigit
return (ord c - ord ’0’)
natural :: Parser Intnatural = do ds <- many1 digit
return (foldl1 (\a b -> 10*a + b) ds)
Integersinteger :: Parser Intinteger = do {char ’-’; n <- natural; return (-n)}
<|> natural
12
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Simple parser combinators
Floating point numbersfraction :: Parser Doublefraction = do char ’.’
ds <- many1 digitreturn (foldr op 0 ds)
where d ‘op‘ x = (x + fromIntegral d)/10
floating :: Parser Doublefloating = do i <- integer
f <- fraction <|> return 0return (fromIntegral i + f)
13
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Simple parser combinators
Spacesspace :: Parser Stringspace = many (sat isSpace)
token :: Parser a -> Parser atoken p = do a <- p
spacereturn a
keyw cs = token (string cs)ident = token identifiernat = token naturalint = token integerfloat = token floating
14
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Simple parser combinators
Bracketing constructionspack :: Parser a -> Parser b -> Parser c -> Parser bpack s1 p s2 = do s1
x <- ps2return x
paren p = pack (keyw "(") p (keyw ")")brack p = pack (keyw "[") p (keyw "]")block p = pack (keyw "begin") p (keyw "end")
15
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Simple parser combinators
Sequencessepby :: Parser a -> Parser b -> Parser [a]p ‘sepby‘ sep = (p ‘sepby1‘ sep) <|> return []
sepby1 :: Parser a -> Parser b -> Parser [a]p ‘sepby1‘ sep = do a <- p
as <- many (sep >> p)return (a:as)
commaList p = sepby p (keyw ",")semicList p = sepby p (keyw ";")
16
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Simple parser combinators
Sequenceschainl :: Parser a -> Parser (a->a->a) -> Parser achainl p s = do
x <- pys <- many (do {op <- s; y <- p; return (op,y)})return (foldl (\a (op,y) -> a ‘op‘ y) x ys)
chainr :: Parser a -> Parser (a->a->a) -> Parser achainr p s = do
ys <- many (do {y <- p; op <- s; return (y,op)})x <- preturn (foldr (\(y,op) b -> y ‘op‘ b) x ys)
17
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Simple parser combinators
Parsing the whole inputparse :: Parser a -> String -> aparse p cs = case runP (first (space >> p)) cs of
[(x,"")] -> x_ -> error "Parse error"
Example: parsing arithmetic expressions
19
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Arithmetic expressions
Grammarexpr = int | expr + expr | expr - expr
| expr * expr | expr / expr | expr ^ expr| (expr)
Abstract syntax treedata Expr = Num Int
| Expr :+: Expr| Expr :-: Expr| Expr :*: Expr| Expr :/: Expr| Expr :^: Expr
20
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Arithmetic expressions
Parser ver. 0expr0 = do { e0 <- expr0; keyw "+";
e1 <- expr0; return(e0 :+: e1)}<|> do { e0 <- expr0; keyw "-";
e1 <- expr0; return(e0 :-: e1)}<|> ...<|> do { e0 <- expr0; keyw "^";
e1 <- expr0; return(e0 :^: e1)}<|> do {i <- int; return (Num i)}<|> paren expr0
NB!Doesn’t work, as the grammar is left
recursive!!
20
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Arithmetic expressions
Parser ver. 0expr0 = do { e0 <- expr0; keyw "+";
e1 <- expr0; return(e0 :+: e1)}<|> do { e0 <- expr0; keyw "-";
e1 <- expr0; return(e0 :-: e1)}<|> ...<|> do { e0 <- expr0; keyw "^";
e1 <- expr0; return(e0 :^: e1)}<|> do {i <- int; return (Num i)}<|> paren expr0
NB!Doesn’t work, as the grammar is left
recursive!!
21
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Arithmetic expressions
Parser ver. 1expr1 = do a <- atom1
op <- oper1e <- expr1return (a ‘op‘ e)
<|> atom1
oper1 = (keyw "+" >> return (:+:))<|> (keyw "-" >> return (:-:))<|> (keyw "*" >> return (:*:))<|> (keyw "/" >> return (:/:))<|> (keyw "^" >> return (:^:))
atom1 = do {i <- int; return (Num i)}<|> paren expr1
NB!”Works” but doesn’t take account
operatorspriorities and associativities!
21
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Arithmetic expressions
Parser ver. 1expr1 = do a <- atom1
op <- oper1e <- expr1return (a ‘op‘ e)
<|> atom1
oper1 = (keyw "+" >> return (:+:))<|> (keyw "-" >> return (:-:))<|> (keyw "*" >> return (:*:))<|> (keyw "/" >> return (:/:))<|> (keyw "^" >> return (:^:))
atom1 = do {i <- int; return (Num i)}<|> paren expr1
NB!”Works” but doesn’t take account
operatorspriorities and associativities!
22
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Arithmetic expressions
Parser ver. 2expr2 :: Parser Exprexpr2 = chainl term2 ( (keyw "+" >> return (:+:))
<|> (keyw "-" >> return (:-:)))
term2 :: Parser Exprterm2 = chainl fact2 ( (keyw "*" >> return (:*:))
<|> (keyw "/" >> return (:/:)))
fact2 :: Parser Exprfact2 = chainr atom2 (keyw "^" >> return (:^:))
atom2 :: Parser Expratom2 = do {i <- int; return (Num i)}
<|> paren expr2
23
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Arithmetic expressions
Evaluatorexpr3 :: Parser Intexpr3 = chainl term3 ( (keyw "+" >> return (+))
<|> (keyw "-" >> return (-)))
term3 :: Parser Intterm3 = chainl fact3 ( (keyw "*" >> return (*))
<|> (keyw "/" >> return div))
fact3 :: Parser Intfact3 = chainr atom3 (keyw "^" >> return (^))
atom3 :: Parser Intatom3 = int <|> paren expr3
24
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Parsec
data ParsecT s u m a
is a parser with
• stream type s,• user state type u,• underlying monad m, and• return type a.
25
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Type
data ParsecT s u m a= ParsecT {unParser :: forall b .
State s u-> (a -> State s u -> ParseError -> m b) -- consumed ok-> (ParseError -> m b) -- consumed err-> (a -> State s u -> ParseError -> m b) -- empty ok-> (ParseError -> m b) -- empty err-> m b
}
26
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Parsec
• Text.ParsecrunParser :: Stream s Identity t => Parsec s u a -> u -> SourceName -> s -> Either ParseError a
(<|>) :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m atry :: ParsecT s u m a -> ParsecT s u m amany :: Stream s m t => ParsecT s u m a -> ParsecT s u m [a]many1 :: Stream s m t => ParsecT s u m a -> ParsecT s u m [a]sepBy :: Stream s m t => ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
• Text.Parsec.Charletter :: Stream s m Char => ParsecT s u m Charstring :: Stream s m Char => String -> ParsecT s u m StringanyChar :: Stream s m Char => ParsecT s u m CharoneOf :: Stream s m Char => [Char] -> ParsecT s u m Charsatisfy :: Stream s m Char => (Char -> Bool) -> ParsecT s u m Char
27
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Monad Transformer
runParserT :: Stream s m t => ParsecT s u m a -> u -> SourceName-> s -> m (Either ParseError a)
class MonadTrans (t :: (* -> *) -> * -> *) wherelift :: Monad m => m a -> t m a
instance MonadTrans (ParsecT s u)
ExampleokP = do
string "ok"lift $ putStrLn "read ok!"
parseOk = runParserT okP () "test source" "ok"
*Hw4_2> parseOkread ok!Right ()
27
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Monad Transformer
runParserT :: Stream s m t => ParsecT s u m a -> u -> SourceName-> s -> m (Either ParseError a)
class MonadTrans (t :: (* -> *) -> * -> *) wherelift :: Monad m => m a -> t m a
instance MonadTrans (ParsecT s u)
ExampleokP = do
string "ok"lift $ putStrLn "read ok!"
parseOk = runParserT okP () "test source" "ok"
*Hw4_2> parseOkread ok!Right ()
27
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
Monad Transformer
runParserT :: Stream s m t => ParsecT s u m a -> u -> SourceName-> s -> m (Either ParseError a)
class MonadTrans (t :: (* -> *) -> * -> *) wherelift :: Monad m => m a -> t m a
instance MonadTrans (ParsecT s u)
ExampleokP = do
string "ok"lift $ putStrLn "read ok!"
parseOk = runParserT okP () "test source" "ok"
*Hw4_2> parseOkread ok!Right ()
28
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
State
getState :: Monad m => ParsecT s u m uputState :: Monad m => u -> ParsecT s u m ()modifyState :: Monad m => (u -> u) -> ParsecT s u m ()
ExamplestateP :: ParsecT [Char] Int Identity IntstateP = do
x <- getStateputState 10return x
parseSt = runParser stateP 5 "test source" "ok"
*Hw4_2> parseStRight 5
28
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
State
getState :: Monad m => ParsecT s u m uputState :: Monad m => u -> ParsecT s u m ()modifyState :: Monad m => (u -> u) -> ParsecT s u m ()
ExamplestateP :: ParsecT [Char] Int Identity IntstateP = do
x <- getStateputState 10return x
parseSt = runParser stateP 5 "test source" "ok"
*Hw4_2> parseStRight 5
28
TARTU ÜLIKOOLI TUNNUSGRAAFIKA LOGO HELEDAL TAUSTAL
Sõltuvalt kujunduslikest eesmärkidest ja tehnilistest võimalustest võib logo olla heledal taustal SININE, HALL/HÕBE või MUST.
State
getState :: Monad m => ParsecT s u m uputState :: Monad m => u -> ParsecT s u m ()modifyState :: Monad m => (u -> u) -> ParsecT s u m ()
ExamplestateP :: ParsecT [Char] Int Identity IntstateP = do
x <- getStateputState 10return x
parseSt = runParser stateP 5 "test source" "ok"
*Hw4_2> parseStRight 5