python 解析 java文件 --- javalang 模块

提示:javalang包分两段理解:一段是代码片段解析成语法树的过程  一段是语法树节点操作

参考文档:https://github.com/c2nes/javalang

语法树

获取语法树

 

>>> import javalang
>>> tree = javalang.parse.parse("package javalang.brewtab.com; class Test {}")

 

解析后将会返回一个CompilationUnit类型实例,这个对象是ast树的根节点,可以利用它来遍历所有节点,然后提取信息

>>> tree.package.name
u'javalang.brewtab.com'
>>> tree.types[0]
ClassDeclaration
>>> tree.types[0].name
u'Test

传递给javalang.parse.parse()的字符串必须一个完整的、有效的java代码片段,其他在javalang.parse模块中的方法不必是完整、有效的代码片段

 

使用语法树

CompilationUnit是javalang.ast.Node的一个子类,它的子节点也是如此,javalang.tree模块定义了不同类型Node子类,每一个代表着java代码中的语法元素,更多的信息在javalang/tree.py

 

Node 实例支持迭代

 

>>> for path, node in tree:
...     print path, node
() CompilationUnit
(CompilationUnit,) PackageDeclaration
(CompilationUnit, [ClassDeclaration]) ClassDeclaration

 

获取方法信息

 

fd = open("./javalangTest.java", "r", encoding="utf-8")
treenode = javalang.parse.parse(fd.read())
for path, node in treenode:
    if isinstance(node, tree.ClassDeclaration):
        #TODO 
        if node.name.startswith("test"):
            print("class_name:  " + node.name)
            for path_1, node_1 in node:
                if isinstance(node_1, tree.MethodDeclaration):
                    if node_1.name.startswith("test"):
                        if node_1.annotations[0].name == "Test":
                            print("function_name:   " + node_1.name)
                            print(node_1.position)
                            for path_2, node_2 in node_1:
                                try:
                                    print(node_2.position[0])
                                except TypeError:
                                    continue

 

组件使用

在内部,javalang.parse.parse 方法创建token流,并用token流创建javalang.parser.Parser实例,然后调用parser的parse()方法,返回结果CompilationUnit实例,tokenizer、Parser这些组件可以单独调用

 

def parse(s):
    tokens = tokenize(s)
    parser = Parser(tokens)
    return parser.parse()

 

分词器(tokenizer)

分词器可以通过javalang.tokenizer.tokenize直接调用tokenizer

 

>>> javalang.tokenizer.tokenize('System.out.println("Hello " + "world");')
<generator object tokenize at 0x1ce5190>

每个token携带位置信息(line, column)和value信息

 

>>> tokens = list(javalang.tokenizer.tokenize('System.out.println("Hello " + "world");'))
>>> tokens[6].value
u'"Hello "'
>>> tokens[6].position
(1, 19)

 

 

 

javalang包下面的模块

 

模块名称

常用类和函数

描述

ast

class MetaNode(type):

class Node(object):语法树节点类

     def children(self):

     def position(self):

def walk_tree(root):通过跟节点遍历语法树

def dump(ast, file): 显示语法树

def load(file):加载文件

  1. 定义tree模块的Node父类,父类中定义了每个节点公用的方法
  2. ast模块的常用函数

javadoc

 

每个javatoken都会带这个,基本无用

parse

def parse(s):

    tokens = tokenize(s)

    parser = Parser(tokens)

    return parser.parse()

对分词器、解析器等封装,提供parse()等方法

parser

tree.CompilationUnit(package=package,                            imports=import_declarations,                    types=type_declarations)

解析器组件,通过指定tokens流创建语法树

tokenizer

 

分词器组件,将代码片段进行分割成token

tree

比如:

class CompilationUnit(Node):

class Import(Node):

class PackageDeclaration(Declaration, Documented):

class ClassDeclaration(TypeDeclaration):

class Annotation(Node):

class MethodDeclaration(Member, Declaration):

 

 

定义了ast模块Node类的子类

util

 

工具类,比如迭代器

 

 

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值