c03xp 发表于 2020-10-12 14:46

ply之解析java文件,找出包名、类名、依赖类

暂不支持多重继承

plyjava.py:

tokens = (
    'PACKAGE',
    'PACKAGENAME',
    'COMMA',
    'ID',
    'PUBLIC',
    'CLASS',
    'LBRACE',
    'INTERFACE',
    'EXTENDS',
    'IMPLEMENTS',
    'PACKAGEPATH',
    'IMPORT'
    )

states = (
    ('multicomment','exclusive'),
    ('package','exclusive'),
)


reserved = {
    'public' : 'PUBLIC',
    'class' : 'CLASS',
    'extends' : 'EXTENDS',
    'implements' : 'IMPLEMENTS',
    'interface' : 'INTERFACE',
    'import'    : 'IMPORT'
}



def t_LBRACE(t):
    r'\{'
    return t


def t_COMMENT(t):
    r'\/\/.*'


def t_PACKAGE(t):
   r'\bpackage\b'
   t.lexer.begin('package')
   return t
   
def t_package_PACKAGENAME(t):
    r'(*)(\.*)*'
    return t

t_package_ignore = " \t"
   
def t_package_COMMA(t):
    r';'
    t.lexer.begin('INITIAL')
    return t
   
def t_package_error(t):
    print("Illegal character '%s'" % t.value)
    t.lexer.skip(ply_java_filelen)
   

   
def t_LCOMMENT(t):
   r'\/\*'
   t.lexer.begin('multicomment')

def t_multicomment_newline(t):
   r'[\r\n]+'   
   
def t_multicomment_RCOMMENT(t):
    r'\*\/'
    t.lexer.begin('INITIAL')
   
def t_multicomment_MCOMMENT(t):
    r'((?!\*\/).)+'
   
def t_multicomment_error(t):
    print("Illegal character '%s'" % t.value)
    t.lexer.skip(ply_java_filelen)   
   
t_multicomment_ignore = ""      


def t_PACKAGEPATH(t):
    r'(*)(\.*)+'
    return t



def t_ID(t):
   r'*'
   t.type = reserved.get(t.value,'ID')    # Check for reserved words
   return t   
   
def t_COMMA(t):
    r';'
    return t

   
   
def t_newline(t):
   r'[\r\n]+'      
   
def t_error(t):
    #print("Illegal character '%s'" % t.value)
    t.lexer.skip(ply_java_filelen)
   
# Ignored characters
t_ignore = " \t"


def p_error(t):
    #print("Syntax error at '%s'" % t.value)
    pass


   
def p_prog_java(t):
    '''prog : pkgline importlines decors PUBLIC decors CLASS ID extend PACKAGEPATH LBRACE
            | pkgline importlines decors PUBLIC decors INTERFACE ID extend PACKAGEPATH LBRACE
            | pkgline importlines decors PUBLIC decors CLASS ID extend ID LBRACE
            | pkgline importlines decors PUBLIC decors INTERFACE ID extend ID LBRACE            
            | pkgline importlines decors PUBLIC decors CLASS ID LBRACE
            | pkgline importlines decors PUBLIC decors INTERFACE ID LBRACE'''      
    global ply_java_classname
    ply_java_classname = t
   
   

def p_importlines_java(t):
    '''importlines : importline
                  | '''
   
def p_importline_java(t):
    '''importline : importline import
            | import'''

      

def p_import_java(t):
    'import : IMPORT PACKAGEPATH COMMA'
    global ply_java_depends
    ply_java_depends.append(t)
   
def p_pkgline_java(t):
    "pkgline : PACKAGE pkgname COMMA"
    global ply_java_pkgname
    ply_java_pkgname = t

def p_extend_java(t):
    '''extend : EXTENDS
            | IMPLEMENTS'''

   

   
def p_pkgname_java(t):
    'pkgname : PACKAGENAME'
    t = t
   
def p_decors_java(t):
    '''decors : decor
            | '''

def p_decor_java(t):   
    '''decor : decor ID
            | ID'''
   




   
   
ply_java_filelen = 0   
ply_java_pkgname = ''
ply_java_classname = ''
ply_java_depends = []   
   
   
import ply.lex as lex
lexer = lex.lex()   
   
   
import ply.yacc as yacc
parser = yacc.yacc()



def analyzeJava(fname):
    global ply_java_pkgname,ply_java_classname,ply_java_depends,ply_java_filelen
    ply_java_pkgname = ""
    ply_java_classname = ""
    ply_java_depends.clear()
    ply_java_filelen = 0
    try:
      f = open(fname,"r")
      f.seek(0,2)
      ply_java_filelen = f.tell()
      f.seek(0,0)
      buffer = f.read(ply_java_filelen)
      f.close()      
    except Exception as e:
      print(str(e))
      
      
    parser.parse(buffer)
    return {'pkgname':ply_java_pkgname,'classname':ply_java_classname,'depends':ply_java_depends}



client.py:
import plyjava



print(plyjava.analyzeJava("Socket.java"))

puz_zle 发表于 2020-10-12 15:37

可是 正常情况 大家都会整成 jar包啊

不过不得不说 这正则写的很有灵性

c03xp 发表于 2020-10-12 15:50

puz_zle 发表于 2020-10-12 15:37
可是 正常情况 大家都会整成 jar包啊

不过不得不说 这正则写的很有灵性

这是第一步,下一步准备画出当前目录下所有java类之间的依赖图
页: [1]
查看完整版本: ply之解析java文件,找出包名、类名、依赖类