使用 ANTLR 用 Python 解析一些 Java 代码
Parsing some Java code with Python using ANTLR
我想在 Python 中使用 ANTLR 构建一个 Java 解析器。
我从 ANTLR 存储库下载了语法:
词法分析器: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 repo 拿来的。
EDIT: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()
您的文本文件包含 compilationUnit
,而不是您尝试使用
解析的 expression
tree = parser.expression()
仔细看解析器规则,你需要的规则是
compilationUnit
: packageDeclaration? importDeclaration* typeDeclaration* EOF
;
它必须被称为
tree = parser.compilationUnit()
我想在 Python 中使用 ANTLR 构建一个 Java 解析器。
我从 ANTLR 存储库下载了语法:
词法分析器: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 repo 拿来的。
EDIT: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()
您的文本文件包含 compilationUnit
,而不是您尝试使用
expression
tree = parser.expression()
仔细看解析器规则,你需要的规则是
compilationUnit
: packageDeclaration? importDeclaration* typeDeclaration* EOF
;
它必须被称为
tree = parser.compilationUnit()