开发者社区> 问答> 正文

使用ANTLR用Python解析一些Java代码

我想在Python中使用ANTLR构建Java解析器。

我从ANTLR存储库下载了语法:

Lexer:https://github.com/antlr/grammars-v4/blob/master/java/java/JavaLexer.g4

解析器:https : //github.com/antlr/grammars-v4/blob/master/java/java/JavaParser.g4

然后我用script.bat生成了我需要的python代码:

java -jar antlr-4.8-complete.jar -Dlanguage=Python3 Java8Lexer.g4
java -jar antlr-4.8-complete.jar -Dlanguage=Python3 Java8Parser.g4

antlr-4.8-complete.jar在此处下载:https : //www.antlr.org/download/antlr-4.8-complete.jar

这生成了以下文件列表:

  • Java8Lexer.interp
  • Java8Lexer.py
  • Java8Lexer.tokens
  • Java8Parser.interp
  • Java8Parser.py
  • Java8Parser.tokens
  • Java8ParserListener.py

然后,我编写了以下代码来解析Java文件:

import antlr4
from antlr4 import \*        from java.antlr_unit2 import Java8Parser, Java8Lexer

def main():
    code = open('test.txt', 'r').read()
    lexer = Java8Lexer.Java8Lexer(antlr4.InputStream(code))
    stream = antlr4.CommonTokenStream(lexer)
    parser = Java8Parser.Java8Parser(stream)
    tree = parser.expression()
    print (tree)

if __name__ == '__main__':
    main()

我的测试Java代码test.txt是这样的:

package org.jabref.gui.fieldeditors;
import java.util.ArrayList;
/\*
 * This class contains some code
 \*
public class TextInputControlBehavior {

    private static final boolean SHOW_HANDLES = Properties.IS_TOUCH_SUPPORTED && !OS.OS_X;

}

由于这太短了,因此以下是我要解析的代码示例:https : //pastebin.com/KNxfasKQ

当我运行此代码时,我得到了:

line 1:0 extraneous input 'package' expecting {'boolean', 'byte', 'char', 'double', 'float', 'int', 'long', 'new', 'short', 'super', 'this', 'void', IntegerLiteral, FloatingPointLiteral, BooleanLiteral, CharacterLiteral, StringLiteral, 'null', '(', '!', '~', '++', '--', '+', '-', Identifier, '@'}
[]

难道我做错了什么?我没有写语法,只是从ANTLR回购中获取的。

编辑:* Pavel Smirnov *的回答帮助了我,现在我没有得到警告。但是现在程序看起来真的很慢,我得到一棵空树作为输出。

解决:我正在打印tree但我必须print(tree.toStringTree(recog = parser))

所以最终的代码是:

import antlr4
from antlr4 import \*        from java.antlr_unit2 import Java8Parser, Java8Lexer

def main():
    code = open('test.txt', 'r').read()
    lexer = Java8Lexer.Java8Lexer(antlr4.InputStream(code))
    stream = antlr4.CommonTokenStream(lexer)
    parser = Java8Parser.Java8Parser(stream)
    tree = parser.compilationUnit()
    print(tree.toStringTree(recog=parser))

if __name__ == '__main__':
    main()

问题来源:stackoverflow

展开
收起
is大龙 2020-03-24 12:28:36 2974 0
1 条回答
写回答
取消 提交回答
  • 您的文本文件包含一个compilationUnit,而不是您尝试解析的expression

    tree = parser.expression()
    

    仔细查看解析器规则,您需要的规则是

    compilationUnit
        : packageDeclaration? importDeclaration* typeDeclaration* EOF
        ;
    

    这必须称为

    tree = parser.compilationUnit()
    

    回答来源:stackoverflow

    2020-03-24 12:28:42
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载

相关镜像