import Text.ParserCombinators.Parsec
import Text.Printf
structure = do
char '{';
name <- many1 (letter <|> oneOf "_?")
char '=';
t <- many (typename <|> array)
char '}';
skipMany digit;
if t == []
then return $ "struct " ++ name ++ " {}"
else return $ "struct " ++ name ++ " {" ++ (foldr1 (\a b -> a ++ "; " ++ b) t) ++ "}"
typename = do { char 'c'; skipMany digit; return "char" }
<|> do { char 's'; skipMany digit; return "short" }
<|> do { char 'i'; skipMany digit; return "int" }
<|> do { char 'l'; skipMany digit; return "long" }
<|> do { char 'q'; skipMany digit; return "long long" }
<|> do { char 'C'; skipMany digit; return "unsigned char" }
<|> do { char 'S'; skipMany digit; return "unsigned short" }
<|> do { char 'I'; skipMany digit; return "unsigned int" }
<|> do { char 'L'; skipMany digit; return "unsigned long" }
<|> do { char 'Q'; skipMany digit; return "unsigned long long" }
<|> do { char 'f'; skipMany digit; return "float" }
<|> do { char 'd'; skipMany digit; return "double" }
<|> do { char 'B'; skipMany digit; return "bool" }
<|> do { char 'v'; skipMany digit; return "void" }
<|> do { char '*'; skipMany digit; return "char *" }
<|> do { char '@'; skipMany digit; return "id" }
<|> do { char '#'; skipMany digit; return "Class" }
<|> do { char ':'; skipMany digit; return "SEL" }
<|> do { char 'b'; d <- many1 digit; return $ "unsigned int : " ++ d }
<?> "typename"
pointer = do
char '^'
s <- typename <|> structure <|> pointer
return $ s ++ " *"
array = do
char '['
d <- many1 digit
s <- typename
char ']'
return $ s ++ "[" ++ d ++ "]"
constant = do
char 'r'
s <- typename <|> pointer <|> structure
return $ "const " ++ s
funcname =
try (many $ do { f <- many1 (letter <|> digit <|> char '_'); char ':'; return f })
<|>
do { f <- many1 (letter <|> digit <|> char '_'); return [f] }
parser = do
f <- funcname
char ','
s <- many1 (constant <|> pointer <|> array <|> structure <|> typename)
eof
return (f, s)
run p line = case (parse p "" line) of
Left err -> do { putStr "parse error at "; print err }
Right x -> putStrLn $ "(" ++ r ++ ")" ++ f
where
r = head $ snd x
args = drop 3 $ snd x
f = if args == []
then head $ fst x
else foldl1 (++) $ zipWith (\m a -> m ++ ":(" ++ a ++ ")") (fst x) args
-- main = getContents >>= mapM_ (run parser) . lines
main = do
run parser "getBytes:maxLength:usedLength:encoding:options:range:remainingRange:,c40@0:4^v8I12^I16I20I24{_NSRange=II}28^{_NSRange=II}36"
run parser "_getBracketedStringFromBuffer:string:,@16@0:4^{_NSStringBuffer=II@II[32S]SS}8@12"