Javaクラスファイル解析(途中まで)
30分プログラム、その109。Javaのクラスファイル解析、もしくはParsecによるバイナリファイルの解析。
最近、Java仮想マシン仕様 (The Java series)を読んでいるので、勉強のために。全部はやりきれなかったので、先頭のフィールドのみ。
こういうのはC言語のほうがいいんじゃないかな?と思いつつもHaskellで。
使い方
$ javad ../../junk/ConvTest.class magic: 0xcafebabe minorVersion: 0 majorVersion: 49
ソースコード
import Control.Monad import System.Environment import Data.Word import Data.Bits import Text.ParserCombinators.Parsec import Text.Printf data ClassFile = ClassFile { magic::Int , minorVersion::Int, majorVersion::Int} instance Show ClassFile where show c = printf (unlines ["magic: 0x%x", "minorVersion: %d", "majorVersion: %d"]) (magic c) (minorVersion c) (majorVersion c) x << n = shift x n type BParser a = GenParser Word8 () a bsatisfy :: (Word8 -> Bool) -> BParser Word8 bsatisfy f = tokenPrim (\s -> show s) (\pos _ _ -> incSourceLine pos 1) (\s -> if f s then Just s else Nothing) u1 :: BParser Int u1 = bsatisfy (const True) >>= return.fromIntegral uN :: Int->BParser Int uN n = do xs <- replicateM n u1 return $ foldl1 (\x y -> (x<<8) + y) xs u2 :: BParser Int u2 = uN 2 u4 :: BParser Int u4 = uN 4 pMagic :: BParser Int pMagic = u4 pMinor = u2 pMajor = u2 pClass :: BParser ClassFile pClass = do m <- pMagic minor <- pMinor major <- pMajor return $ ClassFile m minor major run p input = case (parse p "" input) of Left err -> do putStr "parse error at " print err Right x -> print x --f = run pClass [0xCa,0xfe,0xba,0xbe,0x00,0x01,0x00,0x2] main = do (x:xs) <- getArgs content <- readFile x run pClass $ map (fromIntegral.fromEnum) content