Advertisement
Guest User

Untitled

a guest
Mar 29th, 2017
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.41 KB | None | 0 0
  1. expr = ((digit +++ do {symb "("; n <- expr; symb ")"; return n})
  2. `chianl1` mulop) `chainl1` addop
  3.  
  4. module Parser where
  5.  
  6. import Prelude hiding (filter)
  7. import Data.Char (isDigit, isSpace, toUpper, ord)
  8.  
  9. newtype Parser a = Parser {
  10. runParser :: (String -> [(a, String)])
  11. }
  12.  
  13. instance Monad Parser where
  14. return a = Parser $ s -> [(a, s)]
  15. p >>= f = Parser $ s ->
  16. concat [runParser (f a) s' | (a, s') <- runParser p s]
  17.  
  18. instance Applicative Parser where
  19. pure a = Parser $ s -> [(a, s)]
  20. k <*> m = Parser $ s ->
  21. [(f a, s'') |
  22. (f, s') <- runParser k s,
  23. (a, s'') <- runParser m s']
  24.  
  25. instance Functor Parser where
  26. fmap f p = Parser $ s ->
  27. [(f a, s') | (a, s') <- runParser p s]
  28.  
  29. applyP :: Parser a -> String -> [(a, String)]
  30. applyP p s = runParser p s
  31.  
  32. emptyP :: Parser a
  33. emptyP = Parser $ s -> []
  34.  
  35. appendP :: Parser a-> Parser a-> Parser a
  36. appendP p q = Parser $ s ->
  37. let xs = runParser p s
  38. ys = runParser q s
  39. in xs ++ ys
  40.  
  41. (+++) :: Parser a -> Parser a -> Parser a
  42. p +++ q = Parser $ s ->
  43. case (runParser (p `appendP` q) s) of
  44. [] -> []
  45. (x:xs) -> return x
  46.  
  47. item :: Parser Char
  48. item = Parser $ cs ->
  49. case cs of
  50. [] -> []
  51. (c:cs) -> [(c, cs)]
  52.  
  53. -- since the function tiem is of type "Parser Char"
  54. -- it can only produce char as a result of computation
  55. filterP :: (Char -> Bool) -> Parser Char
  56. filterP f = item >>= c -> if f c
  57. then return c
  58. else emptyP
  59.  
  60. -- returns ak result if the prefix char matches
  61. char :: Char -> Parser Char
  62. char c = filterP (x -> x == c)
  63.  
  64. -- parses a specific string
  65. string :: String -> Parser String
  66. string [] = return "" -- why it will be an empty list if "emptyP" is used?
  67. string (x:xs) = do c <- char x
  68. cs <- string xs
  69. return (c:cs)
  70.  
  71. many :: Parser a -> Parser [a]
  72. many p = many1 p +++ (return [])
  73.  
  74. many1 :: Parser a -> Parser [a]
  75. many1 p = do c <- p
  76. cs <- many p
  77. return (c:cs)
  78.  
  79. sepby :: Parser a -> Parser b -> Parser [a]
  80. sepby p sep = sepby1 p sep +++ (return [])
  81.  
  82. sepby1 :: Parser a -> Parser b -> Parser [a]
  83. sepby1 p sep = do c <- p
  84. cs <- many (sep >> p)
  85. return (c:cs)
  86.  
  87. chainl :: Parser a -> Parser (a -> a -> a) -> a -> Parser a
  88. chainl p q a = (p `chainl1` q) +++ return a
  89.  
  90. chainl1 :: Parser a -> Parser (a -> a -> a) -> Parser a
  91. p `chainl1` q = do {a <- p; rest a}
  92. where rest a = (do f <- q
  93. b <- p
  94. return (f a b))
  95. +++ return a
  96.  
  97. space :: Parser String
  98. space = many (filterP isSpace)
  99.  
  100. -- parse a given value, throw away trailing space
  101. token :: Parser a -> Parser a
  102. token p = do {a <- p; space; return a}
  103.  
  104. -- parses a given token, throws away trailing space
  105. symb :: String -> Parser String
  106. symb s = token (string s)
  107.  
  108. -- throw away any prefix space, apply parser
  109. apply :: Parser a -> String -> [(a, String)]
  110. apply p = runParser (do {space; p})
  111.  
  112. addop :: Parser (Int -> Int -> Int)
  113. addop = do {symb "+"; return (+)} +++ do {symb "-"; return (-)}
  114.  
  115. mulop :: Parser (Int -> Int -> Int)
  116. mulop = do {symb "*"; return (*)} +++ do {symb "/"; return (div)}
  117.  
  118. digit = do {x <- token (filterP isDigit); return (ord x - ord '0')}
  119. factor = digit +++ do {symb "("; n <- expr; symb ")"; return n}
  120. term = factor `chainl1` mulop
  121. expr = term `chainl1` addop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement