A parser checks whether the input string is syntactically ...kodu.ut.ee/~kalmera/fp15/parsing.pdfTA...

Preview:

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

Recommended