{-# 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
