HJVM-0.1: src/Language/Java/JVM/JavapParser.hs
{-# LANGUAGE RankNTypes #-}
module Language.Java.JVM.JavapParser where
import Language.Java.JVM.Types
import Control.Monad
import Data.Functor.Identity
import Data.List
import Data.Maybe
import Text.Parsec
import qualified Text.Parsec.Token as P
import Text.Parsec.Language (javaStyle)
data TypeDecl=TypeDecl {
td_name::ClassName
,td_supers::[ClassName]
,td_decls::[JDecl]
}
deriving (Show,Read,Eq,Ord)
data JDecl=JMethodDecl {
d_name::String
,d_signature::String
,d_static::Bool
}
| JFieldDecl {
d_name::String
,d_signature::String
,d_static::Bool
}
deriving (Show,Read,Eq,Ord)
parseTypeDecl :: String -> Either ParseError TypeDecl
parseTypeDecl contents= parse typeDecl "unknown" contents
typeDecl ::ParsecT String u Identity TypeDecl
typeDecl=do
modifiers
choice [symbol "class",symbol "interface"]
name<-className
extends<-optionMaybe (do
symbol "extends"
classList
)
implements<-optionMaybe (do
symbol "implements"
classList
)
decls<-braces (do
decls<-many $ decl
return $ catMaybes decls)
return $ TypeDecl name (concat $ catMaybes [extends,implements]) decls
decl :: ParsecT String u Identity (Maybe JDecl)
decl = do
sta<-static
choice [(do
staticBlock
return Nothing)
,(do
className
(name,meth)<-choice [(do
parens (classList0)
return ("<init>",True)
),
(do
name <-identifier
p<-optionMaybe $ parens (classList0)
return (name,isJust p)
)
]
when meth (optional (do
symbol "throws"
classList
))
semi
sign<-signature
return $ if meth
then Just $ JMethodDecl name sign sta
else Just $ JFieldDecl name sign sta
)]
--methodDecl :: ParsecT String u Identity (Bool -> Decl)
--methodDecl=do
-- className
-- name<-choice [(do
-- parens (classList0)
-- return "<init>"
-- ),
-- (do
-- name <-identifier
-- parens (classList0)
-- return name
-- )
-- ]
-- optional (do
-- symbol "throws"
-- classList
-- )
-- semi
-- sign<-signature
-- return $ MethodDecl name sign
--
--fieldDecl :: ParsecT String u Identity (Bool -> Decl)
--fieldDecl=do
-- className
-- name<-identifier
-- semi
-- sign<-signature
-- return $ FieldDecl name sign
signature :: ParsecT String u Identity String
signature=do
symbol "Signature"
colon
manyTill anyToken (try (newline))
staticBlock :: ParsecT String u Identity ()
staticBlock=do
braces whiteSpace
semi
signature
return ()
classList :: ParsecT String u Identity [ClassName]
classList=sepBy1 className comma
classList0 :: ParsecT String u Identity [ClassName]
classList0=sepBy className comma
className ::ParsecT String u Identity ClassName
className = do
names<-sepBy1 identifier dot
optionMaybe $ brackets whiteSpace
return $ intercalate "/" names
static :: ParsecT String u Identity Bool
static = do
mds<-modifiers
return $ elem "static" mds
modifiers ::ParsecT String u Identity [String]
modifiers = many $ try $ choice [
try $ symbol "public"
,try $ symbol "protected"
,symbol "private"
,symbol "static"
,symbol "volatile"
,symbol "transient"
,symbol "final"
,symbol "native"]
lexer ::P.GenTokenParser String u Identity
lexer=P.makeTokenParser javaStyle
parens :: ParsecT String u Identity a -> ParsecT String u Identity a
parens = P.parens lexer
braces :: ParsecT String u Identity a -> ParsecT String u Identity a
braces = P.braces lexer
brackets :: ParsecT String u Identity a -> ParsecT String u Identity a
brackets = P.brackets lexer
identifier :: ParsecT String u Identity String
identifier = P.identifier lexer
symbol :: String -> ParsecT String u Identity String
symbol = P.symbol lexer
dot :: ParsecT String u Identity String
dot = P.dot lexer
comma :: ParsecT String u Identity String
comma = P.comma lexer
colon :: ParsecT String u Identity String
colon = P.colon lexer
semi :: ParsecT String u Identity String
semi = P.semi lexer
whiteSpace :: ParsecT String u Identity ()
whiteSpace = P.whiteSpace lexer