module test import StdEnv import Data.Maybe import Data.Functor import Data.Tuple import Data.List import Control.Applicative import Control.Monad import Text.Parsers.Simple.ParserCombinators operators :: [[Char]] operators = [ ['+-'] , ['*/'] , ['^'] ] preprocess :: [[Char]] [Char] -> [Char] preprocess ops c = rep '(' maxb (foldr prep (rep ')' maxb []) c) where maxb = length ops + 1 rep :: Char Int [Char] -> [Char] rep c 0 r = r rep c i r = [c:rep c (i-1) r] prep '(' cs = rep '(' maxb cs prep ')' cs = rep ')' maxb cs prep c cs = maybe [c:cs] (\(_, s)->rep ')' s [c:rep '(' s cs]) (find (isMember c o fst) (zip2 ops [maxb-1,maxb-2..0])) :: Expr = BinOp Expr Char Expr | Lit Int | Var [Char] parseExpr :: Parser Char Expr parseExpr = flip pChainl1 (flip BinOp <$> pOneOf ['+^-/*']) ( Lit o toInt o toString <$> some pDigit <|> Var <$> some pAlpha <|> pToken '(' *> parseExpr <* pToken ')' ) //Start = parse parseExpr (preprocess ['a']) //Start = preprocess operators ['a*1'] Start = runParser parseExpr (preprocess operators ['5+5*5'])