{-# LINE 1 "-" #-} module ExprParser where {-# LINE 3 "-" #-} import Char {-# LINE 5 "-" #-} import Arrow {-# LINE 6 "-" #-} import ArrowExcept {-# LINE 8 "-" #-} import KleisliArrow {-# LINE 9 "-" #-} import Parser {-# LINE 13 "-" #-} data ESym = LPar | RPar | Plus | Minus | Mult | Div | Number | Unknown | EOF deriving (Show, Eq, Ord) {-# LINE 16 "-" #-} instance Symbol ESym where {-# LINE 17 "-" #-} eof = EOF {-# LINE 19 "-" #-} type ExprParser = Parser ESym String (->) {-# LINE 20 "-" #-} type ExprSym = Sym ESym String {-# LINE 24 "-" #-} expr :: ExprParser () Int {-# LINE 25 "-" #-} expr = (term >>> expr') {-# LINE 29 "-" #-} expr' :: ExprParser Int Int {-# LINE 30 "-" #-} expr' = ((returnA <+> (arr (\ x -> ((), x)) >>> (first (symbol Plus) >>> arr (\ (_, x) -> ((), x))) >>> (first term >>> arr (\ (y, x) -> x + y)) >>> expr')) <+> (arr (\ x -> ((), x)) >>> (first (symbol Minus) >>> arr (\ (_, x) -> ((), x))) >>> (first term >>> arr (\ (y, x) -> x - y)) >>> expr')) {-# LINE 41 "-" #-} term :: ExprParser () Int {-# LINE 42 "-" #-} term = (factor >>> term') {-# LINE 46 "-" #-} term' :: ExprParser Int Int {-# LINE 47 "-" #-} term' = ((returnA <+> (arr (\ x -> ((), x)) >>> (first (symbol Mult) >>> arr (\ (_, x) -> ((), x))) >>> (first factor >>> arr (\ (y, x) -> x * y)) >>> term')) <+> (arr (\ x -> ((), x)) >>> (first (symbol Div) >>> arr (\ (_, x) -> ((), x))) >>> (first factor >>> arr (\ (y, x) -> x `div` y)) >>> term')) {-# LINE 58 "-" #-} factor :: ExprParser () Int {-# LINE 59 "-" #-} factor = (((symbol Number >>> arr (\ v -> read v :: Int)) <+> ((symbol Minus >>> arr (\ _ -> ())) >>> (factor >>> arr (\ v -> - v)))) <+> ((symbol LPar >>> arr (\ _ -> ())) >>> (expr >>> arr (\ v -> ((), v))) >>> (first (symbol RPar) >>> arr (\ (_, v) -> v)))) {-# LINE 74 "-" #-} lexer :: String -> [ExprSym] {-# LINE 75 "-" #-} lexer [] = [] {-# LINE 76 "-" #-} lexer ('(' : cs) = Sym LPar "(" : lexer cs {-# LINE 77 "-" #-} lexer (')' : cs) = Sym RPar ")" : lexer cs {-# LINE 78 "-" #-} lexer ('+' : cs) = Sym Plus "+" : lexer cs {-# LINE 79 "-" #-} lexer ('-' : cs) = Sym Minus "-" : lexer cs {-# LINE 80 "-" #-} lexer ('*' : cs) = Sym Mult "*" : lexer cs {-# LINE 81 "-" #-} lexer ('/' : cs) = Sym Div "/" : lexer cs {-# LINE 82 "-" #-} lexer (c : cs) | isSpace c = lexer cs | isDigit c = Sym Number (c : w) : lexer cs' | otherwise = Sym Unknown [c] : lexer cs where {-# LINE 86 "-" #-} (w, cs') = span isDigit cs {-# LINE 88 "-" #-} run parser = runExcept (runParser parser) (\ (_, err) -> error ("parse error: " ++ err)) . lexer {-# LINE 91 "-" #-} t = run expr