Разбор некоторого кода Java с Python с использованием ANTLR - PullRequest
2 голосов
/ 10 марта 2020

Я хочу создать синтаксический анализатор Java с использованием ANTLR в Python.

Я загрузил грамматики из репозитория ANTLR:

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

Parser: 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 code 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.

РЕДАКТИРОВАТЬ : Павел Смирнов мне помог ответ, и теперь я не понимаю предупреждение. Но теперь программа кажется очень медленной, и я получаю пустое дерево в качестве вывода.

решено : я печатал 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()

1 Ответ

2 голосов
/ 10 марта 2020

Ваш текстовый файл содержит compilationUnit, а не expression, который вы пытаетесь проанализировать с

tree = parser.expression()

Внимательно просмотрите правила синтаксического анализатора, вам нужно правило

compilationUnit
    : packageDeclaration? importDeclaration* typeDeclaration* EOF
    ;

, который должен называться

tree = parser.compilationUnit()
...