import Data.List (elemIndex) type Parser = String -> Either String String parseMolekyl :: Parser parseMolekyl cs = parseAtom cs >>= parseNum parseAtom :: Parser parseAtom cs = parseBig cs >>= parseSmall parseBig :: Parser parseBig (c : cs) = if c `elem` "ABCDEFGHIJKLMNOPQRSTUVWXYZ" then Right cs else Left $ "Saknad stor bokstav vid radslutet " ++ (c : cs) parseBig "" = Left "Saknad stor bokstav vid radslutet " parseSmall :: Parser parseSmall (c : cs) = Right $ if c `elem` "abcdefghijklmnopqrstuvwxyz" then cs else c : cs parseSmall "" = Right "" parseNum :: Parser parseNum "" = Right "" parseNum cs = let (x, cs') = parseNum' 0 cs in if x >= 2 then Right cs' else Left ("För litet tal vid radslutet " ++ cs') where parseNum' n (c : cs) = case c `elemIndex` "0123456789" of Just x -> parseNum' (n * 10 + x) cs Nothing -> (n, c : cs) parseNum' n "" = (n, "") output (Right _) = "Formeln är syntaktiskt korrekt" output (Left s) = s main = interact (unlines . map (output . parseMolekyl) . takeWhile (/= "#") . lines)