Subato

Parser Kombinatoren

Studieren Sie das Aufgaben-Papier zu Parser-Kombinatoren und lösen Sie die dort enthaltenen Aufgaben.


> module OurParserLib where > import Data.Char > import Data.Maybe > type ParsResult token result = (result,[token]) > type Parser token result = [token] -> [ParsResult token result] > satisfy :: (t -> Bool) -> Parser t t > satisfy p [] = [] > satisfy p (x:xs) > |p x = [(x,xs)] > |otherwise = [] > terminal :: Eq t => t -> Parser t t > terminal t = satisfy ((==) t) > epsilon :: Parser t [t] > epsilon xs = [([],xs)] > infixl 9 +- > infixl 9 +-- > infix 6 <<- > infixl 3 !|+ > infixl 3 |+ > (+-) :: Parser t r1 -> Parser t r2 -> Parser t (r1,r2) > (+-) p1 p2 = \xs -> [((r1,r2),ts2)| (r1,ts1)<-p1 xs, (r2,ts2)<-p2 ts1] > (|+) :: Parser t r -> Parser t r -> Parser t r > (|+) p1 p2 xs = p1 xs ++ p2 xs > (!|+) :: Parser t r -> Parser t r -> Parser t r > (!|+) p1 p2 xs > |null p1res = p2 xs > |otherwise = p1res > where p1res = p1 xs > (<<-) :: Parser t r1 -> (r1 -> r2) -> Parser t r2 > (<<-) p f = \xs -> [(f result,rest) |(result,rest) <- p xs] > optional p > = p <<- (\x-> [x]) > !|+ epsilon <<- (\_-> []) > zeroToN :: Parser t r -> Parser t [r] > zeroToN = zeroToN2 [] > where > zeroToN2 acc p xs > | null res1 = [(reverse acc,xs)] > | otherwise = zeroToN2 (r1: acc) p rest > where > res1 = p xs > (r1,rest) = head res1 > oneToN :: Parser t r -> Parser t [r] > oneToN p = p +- zeroToN p <<- \(x,xs)-> (x:xs) > ignoreSpace :: Parser Char r -> Parser Char r > ignoreSpace p = \xs -> p (dropWhile isSpace xs) > (+--) p1 p2 = p1 +- ignoreSpace p2 > rep p = zeroToN (ignoreSpace p) > filtere :: (r -> Bool) -> Parser t r -> Parser t r > filtere pred p = \xs -> filter (\(r,_) -> pred r) (p xs) > data Prog = Prog [Fundef] Expr > deriving (Show,Eq) > data Fundef = Fun String [String] [Statement] > deriving (Show,Eq) > data Statement = Simple Expr > |While Expr [Statement] > |Assignment String Expr > deriving (Show,Eq) > data Expr = > Number Integer > |Variable String > |FunCall String [Expr] > |BinOp Expr Operator Expr > |IfExpr Expr Expr Expr > deriving (Eq,Show) > data Operator = OR|AND|OEQ|NEQ|LE|GE|OLT|OGT|ADD|SUB|MULT|DIV|MOD > deriving (Eq,Show) > ident = oneToN (satisfy isLetter) > number = oneToN (satisfy isDigit) <<- \xs -> (read xs)::Integer > keyword xs > = (foldl (\p1 p2 -> p1 +- p2 <<- (\_ -> [])) > epsilon > (map terminal xs)) > <<- \_ -> xs > expr :: Parser Char Expr > expr = ifExpr !|+ booleanExpr > ifExpr = > keyword "if" +-- expr +-- > keyword "then" +-- expr +-- > keyword "else" +-- expr > <<- (\(((((_,c),_),a1),_),a2) -> IfExpr c a1 a2) > booleanExpr :: Parser Char Expr > booleanExpr = compareExpr +-- (rep (booleanOperator+--compareExpr)) > <<- (\(x,os) -> mkOpEx x os) > booleanOperator = pOp [("&&",AND),("||",OR)] > pOp ops = foldl1 (!|+) [keyword s <<- \_-> op |(s,op)<-ops] > mkOpEx e = foldl (\e1 (op,e2)-> BinOp e1 op e2) e > compareExpr :: Parser Char Expr > compareExpr = \xs ->[] > addExpr :: Parser Char Expr > addExpr = \xs ->[] > multExpr :: Parser Char Expr > multExpr = \xs ->[] > atom :: Parser Char Expr > atom = \xs ->[] > varOrFunCall :: Parser Char Expr > varOrFunCall = \xs ->[] > stat :: Parser Char Statement > stat = whileStat > !|+ assignment +--terminal ';' <<- fst > !|+ simpleExpr +--terminal ';' <<- fst > assignment :: Parser Char Statement > assignment = \xs ->[] > body :: Parser Char [Statement] > body = \xs ->[] > whileStat :: Parser Char Statement > whileStat = \xs ->[] > simpleExpr :: Parser Char Statement > simpleExpr = \xs ->[] > fundef :: Parser Char Fundef > fundef = \xs ->[] > prog :: Parser Char Prog > prog = \xs ->[] > type VarName = String > type Env = [(VarName,Integer)] > getOp :: Operator -> Integer -> Integer -> Integer > getOp ADD = (+) > getOp SUB = (-) > getOp MULT = (*) > getOp DIV = div > getOp MOD = mod > getOp OEQ = \x y -> toInteger$fromEnum (x==y) > getOp NEQ = \x y -> toInteger$fromEnum (x/=y) > getOp GE = \x y -> toInteger$fromEnum (x>=y) > getOp LE = \x y -> toInteger$fromEnum (x<=y) > getOp OLT = \x y -> toInteger$fromEnum (x<y) > getOp OGT = \x y -> toInteger$fromEnum (x>y) > getOp AND = \x y -> toInteger$fromEnum > ((toEnum$fromIntegral x)&&(toEnum$fromIntegral y)) > getOp OR = \x y -> toInteger$fromEnum > ((toEnum.fromIntegral) x||(toEnum.fromIntegral) y) > getFun :: VarName -> [Fundef] -> Fundef > getFun n [] = error ("function not defined "++n) > getFun n (f@(Fun fn args body):fs) > |n==fn = f > |otherwise = getFun n fs > eval :: Env -> [Fundef] -> Expr -> Integer > eval _ _ (Number i) = i > eval env _ (Variable s) = fromJust $lookup s env > eval env fs (IfExpr c a1 a2) = 0 > eval env fs (BinOp left op right) = 0 > eval env fs (FunCall n args) = 0 > run :: Env -> [Fundef] -> Statement -> (Env,Integer) > run env fs (Simple e) = (env,eval env fs e) > run env fs (Assignment v e) = ((v,r):env,r) > where r = eval env fs e > run env fs w@(While c body) = (env,0) > runStats env fs [stat] = run env fs stat > runStats env fs (st:sts) = runStats (fst$run env fs st) fs sts > runProg (Prog fs e) = eval [] fs e
lhs
You are not logged in and therefore you cannot submit a solution.