module Main where
import Control.Effects
import Control.Effects.Parser
import Data.Char (isDigit, isSpace)
import Control.Applicative
testParser1 :: Maybe [String]
testParser1 = run $
with (parse "a list of words") $ \p -> do
parseMany p $ itemIf p isSpace
parseMany p $ do
word <- noBacktrack p $ parseMany1 p $ itemIf p (not . isSpace)
parseMany p $ itemIf p isSpace
return word
testParser2 :: IO ()
testParser2 = runBase $ do
input <- base getLine
maybeResult <- with (parse input) $ \p ->
let expr = sum
sum = leftAssoc product [('+', (+)), ('-', (-))]
product = leftAssoc unary [('*', (*)), ('/', div)]
unary = oneOf p [char '-' >> negate <$> unary, atom]
atom = oneOf p [number, char '(' *> expr <* char ')']
number = read <$> digits <* spaces
digits = noBacktrack p $ parseMany1 p $ itemIf p isDigit
spaces = noBacktrack p $ parseMany p $ itemIf p isSpace
char ch = itemIf p (==ch) <* spaces
leftAssoc unit opPairs = do
let ops = map (\(ch, op) -> char ch >> flip op <$> unit) opPairs
foldl (\a op -> op a) <$> unit <*> parseMany p (oneOf p ops)
in spaces *> expr <* parseEnd p
case maybeResult of
Nothing -> base $ putStrLn $ "Syntax error in expression"
Just n -> base $ putStrLn $ "Result: " ++ show (n :: Integer)