1
Name:
Anonymous
2011-05-15 20:11
Lisp
pSym A [B:A@Rest] -> [[B Rest]]
Haskell
pSym a (b:rest) = if a == b then [(b,rest)] else []
pSym a [] = []
Lisp
Tree =: [[n 5 [n 5 n]] 4 [[n 5 n] 6 n]]
Haskell
data Tree a = Empty | Node (Tree a) a (Tree a)
tree = Node (Node Empty 5 (Node Empty 5 Empty)) 4 (Node (Node Empty 5 Empty) 6 Empty)
9
Name:
Anonymous
2011-05-16 7:03
Lisp
digit X:{\0;\1;\2;\3;\4;\5;\6;\7;\8;\9} -> X,asInt-(\0),asInt
number [@Xs] -> {N [X:!digit @Xs] -> r 10N+X Xs; N [] -> N} 0 Xs
op [X:{\+; \-; \*; \/}]->X,asSym
term [\( A:@expr \)]->[A]; [A:@number]->A
expr [A:@term O:@op B:@expr]->[O A B]; [A:@term]->A
parse X -> strip \Space X,asList | expr
Haskell
import Data.List
import Control.Monad
import Data.Char
import Debug.Trace
data Parser a = Parser (String -> [(a, String)])
parse :: Parser a -> String -> [(a, String)]
parse (Parser p) = p
instance Monad Parser
where
return a = Parser (\cs -> [(a, cs)])
p >>= f = Parser (\cs -> concat [parse (f a) cs' | (a, cs') <- parse p cs])
instance MonadPlus Parser
where
mzero = Parser (\cs -> [])
mplus p q = Parser (\cs -> parse p cs ++ parse q cs)
(+++) :: Parser a -> Parser a -> Parser a
p +++ q = Parser (\cs -> case parse (mplus p q) cs of
[] -> []
(x:xs) -> [x])
item :: Parser Char
item = Parser (\cs -> case cs of
"" -> []
(c:cs) -> [(c, cs)])
sat :: (Char -> Bool) -> Parser Char
sat p = do
c <- item
if p c then return c else mzero
char :: Char -> Parser Char
char c = sat (==c)
notDigits = many $ sat (not . isDigit)
string :: String -> Parser String
string "" = return ""
string (c:cs) = do
char c
string cs
return (c:cs)
many :: Parser a -> Parser [a]
many p = many1 p +++ return []
many1 :: Parser a -> Parser [a]
many1 p = do
a <- p
as <- many p
return (a:as)
sepby :: 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 (do {sep; p})
return (a:as)
chainl :: Parser a -> Parser (a -> a -> a) -> a -> Parser a
chainl p op a = (p `chainl1` op) +++ return a
chainl1 :: Parser a -> Parser (a -> a -> a) -> Parser a
p `chainl1` op = do {a <- p; rest a}
where
rest a = (do {f <- op; b <- p; rest (f a b)}) +++ return a
space :: Parser String
space = many (sat isSpace)
token :: Parser a -> Parser a
token p = do
a <- p
space
return a
symb :: String -> Parser String
symb cs = token (string cs)
apply :: Parser a -> String -> [(a,String)]
apply p = parse (do {space; p})
expr :: Parser Int
addop :: Parser (Int -> Int -> Int)
mulop :: Parser (Int -> Int -> Int)
expr = term `chainl1` addop
term = factor `chainl1` mulop
factor = digit +++ do {symb "("; n <- expr; symb ")"; return n}
digit = do {x <- token (sat isDigit); return (ord x - ord '0')}
addop = do {symb "+"; return (+)} +++ do {symb "-"; return (-)}
mulop = do {symb "*"; return (*)} +++ do {symb "/"; return (div)}
apply expr "2 + 4 - 5 * (6/2)" -- [(-9,"")]