Advertisement
Guest User

While parser in haskell

a guest
Apr 13th, 2015
275
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import System.IO
  2. import Control.Monad
  3. import Text.ParserCombinators.Parsec
  4. import Text.ParserCombinators.Parsec.Expr
  5. import Text.ParserCombinators.Parsec.Language
  6. import qualified Text.ParserCombinators.Parsec.Token as Token
  7. import qualified Data.Map as M
  8.  
  9. data BExpr = BoolConst Bool
  10.            | Not BExpr
  11.            | BBinary BBinOp BExpr BExpr
  12.            | RBinary RBinOp AExpr AExpr
  13.              deriving (Show)
  14.  
  15. data BBinOp = And | Or deriving (Show)
  16.  
  17. data AExpr = Var String
  18.            | IntConst Integer
  19.            | Neg AExpr
  20.            | ABinary ABinOp AExpr AExpr
  21.              deriving (Show)
  22.  
  23. data ABinOp = Add | Subtract | Multiply | Divide deriving (Show)
  24.  
  25. data RBinOp = Greater | Less deriving (Show)
  26.  
  27. data Stmt = Seq [Stmt]
  28.           | Assign String AExpr
  29.           | If BExpr Stmt Stmt
  30.           | While BExpr Stmt
  31.           | Skip
  32.             deriving (Show)
  33.  
  34. languageDef =
  35.     emptyDef { Token.commentStart = "{-"
  36.              , Token.commentEnd = "-}"
  37.              , Token.commentLine = "//"
  38.              , Token.identStart = letter
  39.              , Token.identLetter = alphaNum
  40.              , Token.reservedNames = [ "if"
  41.                                      , "then"
  42.                                      , "else"
  43.                                      , "while"
  44.                                      , "do"
  45.                                      , "skip"
  46.                                      , "true"
  47.                                      , "false"
  48.                                      , "not"
  49.                                      , "and"
  50.                                      , "or"
  51.                                      ]
  52.              , Token.reservedOpNames = [ "+", "-", "*", "/", ":="
  53.                                        , "<", ">", "and", "or", "not"
  54.                                        ]
  55.              }
  56.  
  57. lexer = Token.makeTokenParser languageDef
  58.  
  59. identifier = Token.identifier lexer
  60. reserved = Token.reserved lexer
  61. reservedOp = Token.reservedOp lexer
  62. parens = Token.parens lexer
  63. braces = Token.braces lexer
  64. integer = Token.integer lexer
  65. semi = Token.semi lexer
  66. whiteSpace = Token.whiteSpace lexer
  67.  
  68. whileParser :: Parser Stmt
  69. whileParser = whiteSpace >> statement
  70.  
  71. statement :: Parser Stmt
  72. statement = braces statement
  73.            <|> sequenceOfStmt
  74.  
  75. sequenceOfStmt =
  76.     do list <- (sepBy1 statment' semi)
  77.       return $ if length list == 1 then head list else Seq list
  78.  
  79. statment' :: Parser Stmt
  80. statment' = ifStmt
  81.            <|> whileStmt
  82.            <|> skipStmt
  83.            <|> assignStmt
  84.  
  85. ifStmt :: Parser Stmt
  86. ifStmt =
  87.    do reserved "if"
  88.       cond <- bExpression
  89.       reserved "then"
  90.       stmt1 <- statement
  91.       reserved "else"
  92.       stmt2 <- statement
  93.       return $ If cond stmt1 stmt2
  94.  
  95. whileStmt :: Parser Stmt
  96. whileStmt =
  97.    do reserved "while"
  98.       cond <- bExpression
  99.       reserved "do"
  100.       stmt <- statement
  101.       return $ While cond stmt
  102.  
  103. assignStmt :: Parser Stmt
  104. assignStmt =
  105.    do var <- identifier
  106.       reservedOp ":="
  107.       expr <- aExpression
  108.       return $ Assign var expr
  109.  
  110. skipStmt :: Parser Stmt
  111. skipStmt = reserved "skip" >> return Skip
  112.  
  113. aExpression :: Parser AExpr
  114. aExpression = buildExpressionParser aOperators aTerm
  115.  
  116. bExpression :: Parser BExpr
  117. bExpression = buildExpressionParser bOperators bTerm
  118.  
  119. aOperators = [ [Prefix (reservedOp "-" >> return (Neg ))]
  120.             , [Infix (reservedOp "/" >> return (ABinary Divide )) AssocLeft]
  121.             , [Infix (reservedOp "*" >> return (ABinary Multiply )) AssocLeft]
  122.             , [Infix (reservedOp "+" >> return (ABinary Add )) AssocLeft]
  123.             , [Infix (reservedOp "-" >> return (ABinary Subtract )) AssocLeft]
  124.             ]
  125.  
  126. bOperators = [ [Prefix (reservedOp "not" >> return (Not  )) ]
  127.             , [Infix (reservedOp "and" >> return (BBinary And )) AssocLeft]
  128.             , [Infix (reservedOp "or" >> return (BBinary Or )) AssocLeft]
  129.             ]
  130.  
  131.  
  132. aTerm = parens aExpression
  133.        <|> liftM Var identifier
  134.        <|> liftM IntConst integer
  135.  
  136.  
  137. bTerm = parens bExpression
  138.        <|> (reserved "true" >> return (BoolConst True))
  139.        <|> (reserved "false" >> return (BoolConst False))
  140.        <|> rExpression
  141.  
  142. rExpression =
  143.    do a1 <- aExpression
  144.       op <- relation
  145.       a2 <- aExpression
  146.       return $ RBinary op a1 a2
  147.  
  148. relation = (reservedOp ">" >> return Greater)
  149.           <|> (reservedOp "<" >> return Less)
  150.  
  151. parseString :: String -> Stmt
  152. parseString str =
  153.    case parse whileParser "" str of
  154.      Left e -> error $ show e
  155.      Right r -> r
  156.  
  157. parseFile :: String -> IO Stmt
  158. parseFile file =
  159.    do program <- readFile file
  160.       case parse whileParser "" program of
  161.         Left e -> print e >> fail "parser error"
  162.         Right r -> return r
  163.  
  164.  
  165. main = do
  166.  program <- getContents
  167.  let ast = parseString program
  168.  putStrLn $ show ast
  169.  --mapM_ (\(x, y) -> putStrLn $ x ++ " " ++ (show y)) res
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement