Guest User

Untitled

a guest
Apr 24th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.67 KB | None | 0 0
  1.  
  2. import Text.ParserCombinators.Parsec
  3.  
  4. -- Data Types
  5.  
  6. type Position = (Int,Int)
  7.  
  8. data PState = PState Position
  9.  
  10. data Token body = Token Position body
  11.  
  12. data ApplyFunction = ApplyFunction Expr Expr
  13.  
  14. data Bracket = Bracket Expr
  15.  
  16. data Expr = AtomicExpr String
  17. | ApplyFunctionExpr ApplyFunction | BracketExpr Bracket
  18.  
  19. instance (Show body) => Show (Token body) where
  20. show (Token (line,column) body)
  21. = show line++","++show column++" "++show body
  22.  
  23. instance Show ApplyFunction where
  24. show (ApplyFunction func param)
  25. = "["++show func++" "++show param++"]"
  26.  
  27. instance Show Bracket where
  28. show (Bracket expr)
  29. = "("++show expr++")"
  30.  
  31. instance Show Expr where
  32. show (AtomicExpr str)
  33. = str
  34. show (ApplyFunctionExpr expr)
  35. = show expr
  36. show (BracketExpr expr)
  37. = show expr
  38.  
  39. -- Position
  40.  
  41. nextPos :: String -> Position -> Position
  42. nextPos str pos = foldl countUpPos pos str
  43. where
  44. countUpPos (line,column) '\n' = (line+1,0)
  45. countUpPos (line,column) _ = (line,column+1)
  46.  
  47. -- Tokenizer
  48.  
  49. parseToken :: (String -> t)
  50. -> (GenParser Char PState String)
  51. -> (GenParser Char PState (Token t))
  52. parseToken func strParser
  53. = do string <- strParser
  54. (PState currentPos) <- getState
  55. whitespace <- spacesAndComments
  56. setState (PState (nextPos (string++whitespace) currentPos))
  57. return (Token currentPos (func string))
  58.  
  59. spaceToken :: GenParser Char PState String
  60. spaceToken = many1 space
  61.  
  62. lineCommentToken :: GenParser Char PState String
  63. lineCommentToken
  64. = do try (string "--")
  65. body <- manyTill anyChar
  66. (((char '\n')>>=(\_ -> return ())) <|> eof)
  67. return ("--"++body++"\n")
  68.  
  69. blockCommentToken :: GenParser Char PState String
  70. blockCommentToken
  71. = do string "{-"
  72. body <- manyTill anyChar (try (string "-}"))
  73. return ("{-"++body++"-}")
  74.  
  75. spacesAndComments :: GenParser Char PState String
  76. spacesAndComments
  77. = do body <- many (spaceToken <|> lineCommentToken <|> blockCommentToken)
  78. return $ concat body
  79.  
  80. symbolToken :: GenParser Char PState (Token String)
  81. symbolToken = parseToken id
  82. (many1 (oneOf "!#$%&*+-./:<=>?@^"))
  83.  
  84. nameToken :: GenParser Char PState (Token String)
  85. nameToken = parseToken id
  86. (do c <- (letter <|> char '_')
  87. cs <- many (alphaNum <|> char '_')
  88. return (c:cs))
  89.  
  90. numberToken :: GenParser Char PState (Token String)
  91. numberToken = parseToken id
  92. (do integer <- many1 digit
  93. do char '.'
  94. fractional <- many1 digit
  95. return (integer++"."++fractional)
  96. <|> (return integer))
  97.  
  98. eofToken :: GenParser Char PState (Token ())
  99. eofToken = parseToken (const ())
  100. (do eof
  101. return "")
  102.  
  103. -- Parser
  104.  
  105. exprParser :: GenParser Char PState Expr
  106. exprParser = applyFunctionParser
  107.  
  108. toplevelExprParser :: GenParser Char PState Expr
  109. toplevelExprParser
  110. = (bracketParser>>=(return.BracketExpr))
  111. <|> (nameToken>>=(\(Token pos body) -> return $ AtomicExpr body))
  112. <|> (numberToken>>=(\(Token pos body) -> return $ AtomicExpr body))
  113.  
  114. applyFunctionParser :: GenParser Char PState Expr
  115. applyFunctionParser
  116. = chainl1 toplevelExprParser $ return (\l r -> ApplyFunctionExpr $ ApplyFunction l r)
  117.  
  118. bracketParser :: GenParser Char PState Bracket
  119. bracketParser
  120. = do parseToken (const ()) (string "(")
  121. body <- applyFunctionParser
  122. parseToken (const ()) (string ")")
  123. return $ Bracket body
  124.  
  125. myParseFromFile p s filename
  126. = do input <- readFile filename
  127. return (runParser p s filename input)
  128.  
  129. myParseTest filename
  130. = do result <- myParseFromFile
  131. exprParser (PState (0,0)) filename
  132. case result of
  133. Left err -> print err
  134. Right result -> print result
Add Comment
Please, Sign In to add comment