module test import StdEnv import Data.Functor import Control.Applicative import Control.Monad import Control.Monad.State import Text.Parsers.Simple.Core :: In a b = (:.) infix 0 a b :: Gram = Def (Gram -> In Gram Gram) | Def2 ((Gram,Gram) -> In (Gram, Gram) Gram) | Lit String | Int | (-.) infixr 2 Gram Gram | (|.) infix 1 Gram Gram :: Gast = INT Int | LIT String | BIN Gast Gast parseFromGram :: Gram -> Parser String Gast parseFromGram (Def g) = let (body :. gram) = g body in parseFromGram gram parseFromGram Int = INT o toInt <$> pSatisfy (\s->toString (toInt s) == s) parseFromGram (Lit i) = LIT <$> pSatisfy ((==)i) parseFromGram (a -. b) = BIN <$> parseFromGram a <*> parseFromGram b parseFromGram (a |. b) = parseFromGram a <|> parseFromGram b //Start = runParser (parseFromGram gram) [".","."] Start = parse (parseFromGram gram) ["5"] where gram = Def \lit = Int |. Lit "(" -. expr -. Lit ")" Def \fac = lit -. Lit "*" -. fac |. lit -. Lit "/" -. fac |. lit :. Def \expr= fac -. Lit "+" -. expr |. fac -. Lit "-" -. expr |. fac :. expr