CS代考 {-# LANGUAGE RecordWildCards, FlexibleContexts #-}

{-# LANGUAGE RecordWildCards, FlexibleContexts #-}
module MinHS.Parse where

import MinHS.Syntax

Copyright By PowCoder代写 加微信 powcoder

import Text.Parsec
import qualified Text.Parsec.Token as T
import qualified Text.Parsec.Language as L
import Text.Parsec.Expr
import Data.List (foldl1′)
import Control.Applicative hiding ( (<|>), many )
import Data.List (sortBy)
import Data.Ord (comparing)

parseProgram = parse program

language = L.haskellStyle { T.reservedOpNames = [ “+”,”-“,”/”,”*”,”%”
, “==”,”<=",">=”,”<",">“,”/=”
,”::”,”->”,”\\”,”=>”,”=”
, T.reservedNames = [ “case”,”of”,”let”,”in”,”if”,”then”,”else”
, “recfun”,”Int”,”Bool”
, “letrec”, “forall”, “fst”,”snd”
, T.identStart = letter <|> oneOf “_”

T.TokenParser {..} = T.makeTokenParser language

program = do whiteSpace; v <- many1 (bind <* semi); eof; return v bind = Bind <$> varName
<*> ((Just <$ reservedOp "::" <*> qtyp) <|> pure Nothing)
<*> many varName <* reservedOp "=" <*> expr
“binding”

conName = constructor identifier <|> parens (constructor operator) “constructor”
varName = variable identifier <|> parens (variable operator) “variable”
constructor f = lookAhead isConstructor *> f
variable f = isConstructor *> unexpected “Constructor tag where variable expected!”
isConstructor = pure <$> upper <|> string “:”

expr = buildExpressionParser [ [Prefix (reservedOp “-” >> return (App ( ))) ]
, [Infix (binApply <$> multDivRem) AssocLeft]
, [Infix (binApply <$> plusMinus) AssocLeft]
, [Infix (binApply <$> comparison) AssocNone]
, [Infix (binApply <$> customOp) AssocNone]
] (foldl1′ App <$> many1 term) “expression”
where op s p = reservedOp s *> pure (Prim p)
plusMinus = op “+” Add
<|> op “-” Sub
multDivRem = op “*” Mul
<|> op “/” Quot
<|> op “%” Rem
comparison = op “>=” Ge
<|> op “<=" Le <|> op “<" Lt <|> op “>” Gt
<|> op “==” Eq
<|> op “/=” Ne
customOp = id <$ char '`' <*> conOrVar identifier <* char '`' <* whiteSpace conOrVar f = Con <$> constructor f
<|> Var <$> f
term = If <$ reserved "if" <*> expr <* reserved "then" <*> expr <* reserved "else" <*> expr
<|> Let <$ reserved "let" <*> many1 (bind <* semi) <* reserved "in" <*> expr
<|> Recfun <$ reserved "recfun" <*> bind
<|> Letrec <$ reserved "letrec" <*> many1 (bind <* semi) <* reserved "in" <*> expr
<|> Case <$ reserved "case" <*> expr <* reserved "of" <*> (sortBy (comparing altTag) <$> many1 (alt <* semi)) <|> try (parens (plusMinus
<|> multDivRem
<|> comparison
<|> conOrVar operator))
<|> parens (tuples <$> expr `sepBy` comma)
<|> Num <$> natural
<|> <$ reserved "fst" <|> <$ reserved "snd" <|> conOrVar identifier
“term”
where tuples [] = Con “()”
tuples [a] = a
tuples (x:xs) = binApply (Con “Pair”) x (tuples xs)
altTag (Alt t _ _) = t

alt = Alt <$> constructor identifier
<*> manyTill identifier (reserved “->”)
“alternative”

qtyp = Forall <$ reserved "forall" <*> identifier <* char '.' <* whiteSpace <*> qtyp
<|> Ty <$> typ

typ = buildExpressionParser [ [Infix (reservedOp “+” *> pure Sum) AssocRight]
, [Infix (reservedOp “*” *> pure Prod) AssocRight]
, [Infix (reservedOp “->” *> pure Arrow) AssocRight]
] term “type”
where term = parens (typ
<|> pure (Base Unit))
<|> reserved “Bool” *> pure (Base Bool)
<|> reserved “Int” *> pure (Base Int)
<|> (TypeVar <$> variable identifier)

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com