Cette fois, je voudrais expliquer comment utiliser ANTLR et Python pour analyser le code source Java avec AST (Abstract Syntax Tree). La raison de Python est que Python est plus facile et que je suis juste fou de Python ces jours-ci, et je l'ai déjà fait en Java, donc cette fois c'est comme Python. S'il y a une requête Java, j'aimerais écrire un article sur Qiita. Les objectifs de cet article sont les trois points suivants.
Arbre de syntaxe abstraite dans wikipedia S'explique (en partie) comme suit.
Un arbre de syntaxe abstraite (AST) est un arbre de syntaxe ordinaire (également appelé arbre de syntaxe concret ou arbre d'analyse) qui supprime les informations qui ne sont pas liées à la signification du langage et extrait uniquement les informations pertinentes pour la signification. Il s'agit d'une structure de données arborescente (abstraite).
[Arborescence de syntaxe abstraite avec image Google](https://www.google.com/search?client=firefox-b&biw=1314&bih=959&tbm=isch&sa=1&ei=ATyOW9_CN8it8QXrhIGwCQ&q=%E6%8A%BD%E8%B1%A1% E6% A7% 8B% E6% 96% 87% E6% 9C% A8 & oq =% E6% 8A% BD% E8% B1% A1% E6% A7% 8B% E6% 96% 87% E6% 9C% A8 & gs_l = img 3..0j0i24k1l4.4434.5025.0.5921.5.5.0.0.0.0.78.375.5.5.0 .... 0 ... 1c.1.64.img..0.2.152 .... 0.6gcyAKZr7NM) Je pense que vous pouvez obtenir une image. Cependant, c'est encore difficile.
Pour le dire simplement, je pense aux trois points suivants.
ANTLR (http://www.antlr.org/) est un outil qui prend un fichier de grammaire (fichier g4) en entrée et génère automatiquement une fonction requise pour analyser un arbre de syntaxe abstraite, un soi-disant analyseur. Puisque le fichier de grammaire ne dépend pas du langage de programmation de l'analyseur, il est possible de générer un analyseur pour plusieurs langages de programmation. Cette fois, nous allons générer le code de l'analyseur pour Python.
Les principaux composants de l'analyseur sont répertoriés ci-dessous.
Explication de l 'Analyse des phrases dans wikipedia (partie) Est comme suit.
L'analyse de phrase (analyse lexicale) est la première moitié de l'analyse syntaxique au sens large, qui analyse les chaînes de caractères telles que les phrases en langage naturel et le code source dans le langage de programmation, et au sens étroit de la seconde moitié. Il s'agit d'une procédure pour obtenir une séquence de "jetons" (phrases), qui est la plus petite unité (symbole de terminaison) dans l'analyse syntaxique. Le programme qui effectue l'analyse de phrases est un analyseur de phrases. Voir Analyse morphologique pour l'analyse des phrases en langage naturel.
c'est difficile. En termes simples, il s'agit de vérifier si elle est écrite dans une chaîne qui peut être utilisée comme spécification de langage de programmation. Par exemple, en Python, les mots «from», «def», «elif», etc. sont disponibles sous forme de syntaxe, mais en Java, ces mots ne peuvent pas être utilisés comme syntaxe. Lexer fait cela pour vous. Puisque Lexer suit les spécifications du fichier de grammaire, il utilise essentiellement le Lexer généré par ANTLR tel quel.
Explication de l 'analyse de syntaxe dans wikipedia (partiel) Est comme suit.
L'analyse syntaxique (analyse syntaxique ou analyse syntaxique) divise une chaîne de caractères solide sans notes telles que des phrases, en particulier des balises, en éléments morphologiques en langage naturel, et entre les deux. C'est une procédure pour clarifier (analyser) une relation syntaxique (syntaxique) telle qu'une relation (modification-modifiée, etc.). Le langage naturel est l'un des principaux points du traitement du langage naturel, et dans le cas des langages formels tels que les langages de programmation, un arbre syntaxique est obtenu selon la grammaire formelle. Le mécanisme pour effectuer l'analyse de syntaxe est appelé un analyseur de syntaxe (parser).
c'est difficile. Comme l'indique le libellé de «l'analyse syntaxique», il s'agit d'un processus pour lire le texte à analyser et le décomposer en un arbre syntaxique. C'est exactement ce que vous imaginez. Puisque Parser suit les spécifications du fichier de grammaire, il utilise essentiellement l'analyseur généré par ANTLR tel quel.
Lexer et Parser sont les principaux processus qui apparaissent dans le traitement du langage naturel, mais Listener est une API permettant aux utilisateurs de créer leurs propres analyseurs. Quel type d'API est le point d'accroche de l'événement qui se produit lorsque le nœud de l'arborescence de syntaxe change. En prenant Java, qui fait l'objet de cette analyse, comme exemple, nous sommes entrés dans le contexte de la définition de classe et le contexte est terminé, nous sommes entrés dans le contexte de la définition de la méthode et le contexte est terminé, et ainsi de suite. Le Listener généré automatiquement par ANTLR n'est implémenté que par défaut, donc contrairement à Lexer et Parser, le Listener généré est étendu (hérité) et utilisé.
La possibilité de générer un analyseur ANTLR est fournie sous forme de programme Java. Obtenez http://www.antlr.org/download/antlr-runtime-4.7.1.jar et stockez-le dans n'importe quel répertoire. Si vous n'avez pas installé le JDK, veuillez l'installer.
Un fichier de grammaire (g4) pour le langage de programmation est disponible sur la page GitHub d'ANTLR.
Java a différents fichiers de grammaire pour chaque version. Cette fois, récupérez le fichier de grammaire pour Java 8 sur https://github.com/antlr/grammars-v4/tree/master/java.
Stockez les fichiers obtenus (JavaLexer.g4
, JavaParser.g4
) dans n'importe quel répertoire (exemple: grammar).
Avant la génération
.
│ antlr-4.7.1-complete.jar
│
└─grammar
JavaLexer.g4
JavaParser.g4
La commande pour générer Leexer, Parser et Listener pour Python3 avec ANTLR est indiquée ci-dessous.
Spécifiez le langage de programmation de l'analyseur avec l'option -Dlanguage
.
Notez que pour Python, Python 3 et Python 2 sont différents.
Commandes pour générer Lexer, Parser, Listener pour Python3
java -jar antlr-4.7.1-complete.jar -Dlanguage=Python3 grammar\*.g4
Après génération
.
│ antlr-4.7.1-complete.jar
│
└─grammar
JavaLexer.g4
JavaParser.g4
JavaLexer.interp
JavaLexer.py
JavaLexer.tokens
JavaParser.interp
JavaParser.py
JavaParser.tokens
JavaParserListener.py
Vous disposez maintenant du code source de l'analyseur (JavaLexer.py
, JavaParser.py
, JavaParserListener.py
) requis pour l'analyse du code source Java.
Ensuite, nous utiliserons ce fichier pour implémenter notre propre programme d'analyse syntaxique.
Pour référence, les commandes pour générer Lexer, Parser et Linstener pour Java sont indiquées ci-dessous.
Vous pouvez spécifier un package Java avec l'option -package
.
Commandes pour générer Lexer, Parser, Linstener pour Java
// com.example.service.Sortie en tant que package antlr
java -jar antlr-4.7.1-complete.jar -Dlanguage=Java -encoding utf-8 -package com.example.service.antlr grammar\*.g4
Installez ʻantlr4-python3-runtime` pour utiliser ANTLR avec Python. Veuillez noter qu'il existe des bibliothèques distinctes pour Python2 et Python3.
runtime d'antlr installé avec pip
antlr4-python3-runtime 4.7.1
Comme mentionné ci-dessus, créez un écouteur pour chaque objectif que vous souhaitez analyser. Cette fois, je voudrais créer un écouteur qui obtient les informations de base et les appels de méthode de la classe Java.
Structure du répertoire
C:/temp/sample
├─logs
│ utiltools.log
│
├─resources
│ └─logging
│ utiltools_log.conf
│
└─src
│ ast_analyze_executor.py
│
└─ast
ast_processor.py
basic_info_listener.py
JavaLexer.py
JavaParser.py
JavaParserListener.py
__init__.py
JavaLexer.py
, JavaParser.py
et JavaParserListener.py
copient les fichiers automatiquement générés par ANTLR tels quels.
Il s'agit d'un processus avec une fonction principale. Le chemin du fichier est écrit directement pour l'explication, mais veuillez le corriger en conséquence.
ast_analyze_executor.py
import logging.config
from ast.ast_processor import AstProcessor
from ast.basic_info_listener import BasicInfoListener
if __name__ == '__main__':
logging_setting_path = '../resources/logging/utiltools_log.conf'
logging.config.fileConfig(logging_setting_path)
logger = logging.getLogger(__file__)
target_file_path = 'C:/temp/Fichier à analyser.java'
#★ Point 1
ast_info = AstProcessor(logging, BasicInfoListener()).execute(target_file_path)
Après avoir créé votre propre instance d'écouteur, créez une instance de ʻAst Processor, qui sera décrite plus tard. Exécutez la méthode ʻexecute
de ʻAstProcessor` avec le chemin du fichier à analyser comme argument pour exécuter l'analyse du code source.
«La valeur de retour de la méthode execute» est le résultat de l'analyse.
J'ai expliqué que c'est Listener qui effectue son propre traitement d'analyse. Par conséquent, vous créez généralement plusieurs auditeurs en fonction de votre objectif. Cependant, le processus d'exécution de Listener ne change pas, nous allons donc implémenter le processus d'exécution de Listener à des fins générales.
ast_processor.py
from antlr4 import FileStream, CommonTokenStream, ParseTreeWalker
from ast.JavaLexer import JavaLexer
from ast.JavaParser import JavaParser
from pprint import pformat
class AstProcessor:
def __init__(self, logging, listener):
self.logging = logging
self.logger = logging.getLogger(self.__class__.__name__)
self.listener = listener
#★ Point 2
def execute(self, input_source):
parser = JavaParser(CommonTokenStream(JavaLexer(FileStream(input_source, encoding="utf-8"))))
walker = ParseTreeWalker()
walker.walk(self.listener, parser.compilationUnit())
self.logger.debug('Display all data extracted by AST. \n' + pformat(self.listener.ast_info, width=160))
return self.listener.ast_info
Créez une instance de JavaLexer
à partir du fichier à analyser et utilisez-la pour générer une instance de JavaParser
.
L'analyse est effectuée en appelant la méthode «walk» de l'instance «ParseTreeWalker».
Ce flux est le même même si le traitement de l'auditeur est différent.
Cette section décrit comment implémenter le Listener d'origine, qui est le point clé de l'analyse du code source. Cependant, il n'y a que trois points.
JavaParserListener
généré automatiquement par ANTLR et définissez votre propre écouteur.JavaParserListener
et implémentez le traitement selon l'analyse.basic_info_listener.py
from ast.JavaParserListener import JavaParserListener
from ast.JavaParser import JavaParser
#★ Point 3
class BasicInfoListener(JavaParserListener):
#★ Point 4
def __init__(self):
self.call_methods = []
self.ast_info = {
'packageName': '',
'className': '',
'implements': [],
'extends': '',
'imports': [],
'fields': [],
'methods': []
}
#★ Point 5
# Enter a parse tree produced by JavaParser#packageDeclaration.
def enterPackageDeclaration(self, ctx:JavaParser.PackageDeclarationContext):
self.ast_info['packageName'] = ctx.qualifiedName().getText()
# Enter a parse tree produced by JavaParser#importDeclaration.
def enterImportDeclaration(self, ctx:JavaParser.ImportDeclarationContext):
import_class = ctx.qualifiedName().getText()
self.ast_info['imports'].append(import_class)
# Enter a parse tree produced by JavaParser#methodDeclaration.
def enterMethodDeclaration(self, ctx:JavaParser.MethodDeclarationContext):
print("{0} {1} {2}".format(ctx.start.line, ctx.start.column, ctx.getText()))
self.call_methods = []
# Exit a parse tree produced by JavaParser#methodDeclaration.
def exitMethodDeclaration(self, ctx:JavaParser.MethodDeclarationContext):
#★ Point 6
c1 = ctx.getChild(0).getText() # ---> return type
c2 = ctx.getChild(1).getText() # ---> method name
# c3 = ctx.getChild(2).getText() # ---> params
params = self.parse_method_params_block(ctx.getChild(2))
method_info = {
'returnType': c1,
'methodName': c2,
'params': params,
'callMethods': self.call_methods
}
self.ast_info['methods'].append(method_info)
# Enter a parse tree produced by JavaParser#methodCall.
def enterMethodCall(self, ctx:JavaParser.MethodCallContext):
#★ Point 7
line_number = str(ctx.start.line)
column_number = str(ctx.start.column)
self.call_methods.append(line_number + ' ' + column_number + ' ' + ctx.parentCtx.getText())
# Enter a parse tree produced by JavaParser#classDeclaration.
def enterClassDeclaration(self, ctx:JavaParser.ClassDeclarationContext):
child_count = int(ctx.getChildCount())
if child_count == 7:
# class Foo extends Bar implements Hoge
# c1 = ctx.getChild(0) # ---> class
c2 = ctx.getChild(1).getText() # ---> class name
# c3 = ctx.getChild(2) # ---> extends
c4 = ctx.getChild(3).getChild(0).getText() # ---> extends class name
# c5 = ctx.getChild(4) # ---> implements
# c7 = ctx.getChild(6) # ---> method body
self.ast_info['className'] = c2
self.ast_info['implements'] = self.parse_implements_block(ctx.getChild(5))
self.ast_info['extends'] = c4
elif child_count == 5:
# class Foo extends Bar
# or
# class Foo implements Hoge
# c1 = ctx.getChild(0) # ---> class
c2 = ctx.getChild(1).getText() # ---> class name
c3 = ctx.getChild(2).getText() # ---> extends or implements
# c5 = ctx.getChild(4) # ---> method body
self.ast_info['className'] = c2
if c3 == 'implements':
self.ast_info['implements'] = self.parse_implements_block(ctx.getChild(3))
elif c3 == 'extends':
c4 = ctx.getChild(3).getChild(0).getText() # ---> extends class name or implements class name
self.ast_info['extends'] = c4
elif child_count == 3:
# class Foo
# c1 = ctx.getChild(0) # ---> class
c2 = ctx.getChild(1).getText() # ---> class name
# c3 = ctx.getChild(2) # ---> method body
self.ast_info['className'] = c2
# Enter a parse tree produced by JavaParser#fieldDeclaration.
def enterFieldDeclaration(self, ctx:JavaParser.FieldDeclarationContext):
field = {
'fieldType': ctx.getChild(0).getText(),
'fieldDefinition': ctx.getChild(1).getText()
}
self.ast_info['fields'].append(field)
def parse_implements_block(self, ctx):
implements_child_count = int(ctx.getChildCount())
result = []
if implements_child_count == 1:
impl_class = ctx.getChild(0).getText()
result.append(impl_class)
elif implements_child_count > 1:
for i in range(implements_child_count):
if i % 2 == 0:
impl_class = ctx.getChild(i).getText()
result.append(impl_class)
return result
def parse_method_params_block(self, ctx):
params_exist_check = int(ctx.getChildCount())
result = []
# () ---> 2
# (Foo foo) ---> 3
# (Foo foo, Bar bar) ---> 3
# (Foo foo, Bar bar, int count) ---> 3
if params_exist_check == 3:
params_child_count = int(ctx.getChild(1).getChildCount())
if params_child_count == 1:
param_type = ctx.getChild(1).getChild(0).getChild(0).getText()
param_name = ctx.getChild(1).getChild(0).getChild(1).getText()
param_info = {
'paramType': param_type,
'paramName': param_name
}
result.append(param_info)
elif params_child_count > 1:
for i in range(params_child_count):
if i % 2 == 0:
param_type = ctx.getChild(1).getChild(i).getChild(0).getText()
param_name = ctx.getChild(1).getChild(i).getChild(1).getText()
param_info = {
'paramType': param_type,
'paramName': param_name
}
result.append(param_info)
return result
Étendez (héritez) de JavaParserListener
pour définir votre propre écouteur, BasicInfoListener
.
Définissez ʻast_info` pour contenir les résultats de l'analyse. Veuillez modifier le nom et le contenu de la propriété en fonction de l'objectif que vous souhaitez analyser.
Il remplace la fonction de hookpoint définie dans JavaParserListener
et implémente son propre processus d'analyse.
Par exemple, ʻenter Package Declaration, comme son nom l'indique, est appelé là où commence la définition du package du code source Java. L'argument
ctx` est d'un type différent, mais comme il a une classe parente, n'importe quelle classe de contexte peut accéder aux informations de base nécessaires à l'analyse syntaxique.
Comme le nom d'AST (Abstract Syntax Tree) l'indique, ctx
a une structure arborescente. Vous pouvez accéder aux nœuds enfants de ce contexte avec la fonction getChild
. Le contenu des nœuds enfants dépend du contexte.
Normalement, AST (Abstract Syntax Tree) ne conserve pas les numéros de ligne et les positions de caractères concrets, mais ANTLR conserve ces informations dans leur contexte. Encore une fois, ces informations sont utiles lors de l'analyse du code source, alors utilisez-les au besoin.
ctx.start.line
: Numéro de ligne sur le code source du contextectx.start.column
: Position des caractères sur le code source du contexteUne classe de l'exemple d'application TEARASOLUNA 5.xを対象に解析を行ってみたいと思います。
TourInfoServiceImpl.java
/*
* Copyright (C) 2013-2018 NTT DATA Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.terasoluna.tourreservation.domain.service.tourinfo;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.terasoluna.tourreservation.domain.model.TourInfo;
import org.terasoluna.tourreservation.domain.repository.tourinfo.TourInfoRepository;
import org.terasoluna.tourreservation.domain.repository.tourinfo.TourInfoSearchCriteria;
@Service
@Transactional
public class TourInfoServiceImpl implements TourInfoService {
@Inject
TourInfoRepository tourInfoRepository;
@Override
public Page<TourInfo> searchTour(TourInfoSearchCriteria criteria,
Pageable pageable) {
long total = tourInfoRepository.countBySearchCriteria(criteria);
List<TourInfo> content;
if (0 < total) {
content = tourInfoRepository.findPageBySearchCriteria(criteria,
pageable);
} else {
content = Collections.emptyList();
}
Page<TourInfo> page = new PageImpl<TourInfo>(content, pageable, total);
return page;
}
}
Résultats d'analyse
{'className': 'TourInfoServiceImpl',
'extends': '',
'fields': [{'fieldDefinition': 'tourInfoRepository', 'fieldType': 'TourInfoRepository'}],
'implements': ['TourInfoService'],
'imports': ['java.util.Collections',
'java.util.List',
'javax.inject.Inject',
'org.springframework.data.domain.Page',
'org.springframework.data.domain.PageImpl',
'org.springframework.data.domain.Pageable',
'org.springframework.stereotype.Service',
'org.springframework.transaction.annotation.Transactional',
'org.terasoluna.tourreservation.domain.model.TourInfo',
'org.terasoluna.tourreservation.domain.repository.tourinfo.TourInfoRepository',
'org.terasoluna.tourreservation.domain.repository.tourinfo.TourInfoSearchCriteria'],
'methods': [{'callMethods': ['43 40 tourInfoRepository.countBySearchCriteria(criteria)',
'46 41 tourInfoRepository.findPageBySearchCriteria(criteria,pageable)',
'49 34 Collections.emptyList()'],
'methodName': 'searchTour',
'params': [{'paramName': 'criteria', 'paramType': 'TourInfoSearchCriteria'}, {'paramName': 'pageable', 'paramType': 'Pageable'}],
'returnType': 'Page<TourInfo>'}],
'packageName': 'org.terasoluna.tourreservation.domain.service.tourinfo'}
Si vous regardez les résultats de l'analyse, vous pouvez voir que la structure de la classe et le contenu du traitement peuvent être compris.
Cette fois, j'ai expliqué comment utiliser ANTLR et Python pour analyser le code source Java avec AST (Abstract Syntax Tree). J'espère que vous comprenez que l'utilisation d'ANTLR le rend plus facile et plus structuré que l'analyse de texte comme Grep. Bien qu'elles ne soient pas obtenues dans l'échantillon, les informations suivantes peuvent également être obtenues.
En incorporant l'analyse syntaxique à l'aide d'ANTLR, vous serez en mesure de créer des outils et des applications qui utilisent le code source comme entrée.
Pour référence, une liste des fonctions de point de raccordement du récepteur est présentée ci-dessous.
Liste des fonctions de point de crochet (208 au total)
def enterCompilationUnit(self, ctx:JavaParser.CompilationUnitContext):
def exitCompilationUnit(self, ctx:JavaParser.CompilationUnitContext):
def enterPackageDeclaration(self, ctx:JavaParser.PackageDeclarationContext):
def exitPackageDeclaration(self, ctx:JavaParser.PackageDeclarationContext):
def enterImportDeclaration(self, ctx:JavaParser.ImportDeclarationContext):
def exitImportDeclaration(self, ctx:JavaParser.ImportDeclarationContext):
def enterTypeDeclaration(self, ctx:JavaParser.TypeDeclarationContext):
def exitTypeDeclaration(self, ctx:JavaParser.TypeDeclarationContext):
def enterModifier(self, ctx:JavaParser.ModifierContext):
def exitModifier(self, ctx:JavaParser.ModifierContext):
def enterClassOrInterfaceModifier(self, ctx:JavaParser.ClassOrInterfaceModifierContext):
def exitClassOrInterfaceModifier(self, ctx:JavaParser.ClassOrInterfaceModifierContext):
def enterVariableModifier(self, ctx:JavaParser.VariableModifierContext):
def exitVariableModifier(self, ctx:JavaParser.VariableModifierContext):
def enterClassDeclaration(self, ctx:JavaParser.ClassDeclarationContext):
def exitClassDeclaration(self, ctx:JavaParser.ClassDeclarationContext):
def enterTypeParameters(self, ctx:JavaParser.TypeParametersContext):
def exitTypeParameters(self, ctx:JavaParser.TypeParametersContext):
def enterTypeParameter(self, ctx:JavaParser.TypeParameterContext):
def exitTypeParameter(self, ctx:JavaParser.TypeParameterContext):
def enterTypeBound(self, ctx:JavaParser.TypeBoundContext):
def exitTypeBound(self, ctx:JavaParser.TypeBoundContext):
def enterEnumDeclaration(self, ctx:JavaParser.EnumDeclarationContext):
def exitEnumDeclaration(self, ctx:JavaParser.EnumDeclarationContext):
def enterEnumConstants(self, ctx:JavaParser.EnumConstantsContext):
def exitEnumConstants(self, ctx:JavaParser.EnumConstantsContext):
def enterEnumConstant(self, ctx:JavaParser.EnumConstantContext):
def exitEnumConstant(self, ctx:JavaParser.EnumConstantContext):
def enterEnumBodyDeclarations(self, ctx:JavaParser.EnumBodyDeclarationsContext):
def exitEnumBodyDeclarations(self, ctx:JavaParser.EnumBodyDeclarationsContext):
def enterInterfaceDeclaration(self, ctx:JavaParser.InterfaceDeclarationContext):
def exitInterfaceDeclaration(self, ctx:JavaParser.InterfaceDeclarationContext):
def enterClassBody(self, ctx:JavaParser.ClassBodyContext):
def exitClassBody(self, ctx:JavaParser.ClassBodyContext):
def enterInterfaceBody(self, ctx:JavaParser.InterfaceBodyContext):
def exitInterfaceBody(self, ctx:JavaParser.InterfaceBodyContext):
def enterClassBodyDeclaration(self, ctx:JavaParser.ClassBodyDeclarationContext):
def exitClassBodyDeclaration(self, ctx:JavaParser.ClassBodyDeclarationContext):
def enterMemberDeclaration(self, ctx:JavaParser.MemberDeclarationContext):
def exitMemberDeclaration(self, ctx:JavaParser.MemberDeclarationContext):
def enterMethodDeclaration(self, ctx:JavaParser.MethodDeclarationContext):
def exitMethodDeclaration(self, ctx:JavaParser.MethodDeclarationContext):
def enterMethodBody(self, ctx:JavaParser.MethodBodyContext):
def exitMethodBody(self, ctx:JavaParser.MethodBodyContext):
def enterTypeTypeOrVoid(self, ctx:JavaParser.TypeTypeOrVoidContext):
def exitTypeTypeOrVoid(self, ctx:JavaParser.TypeTypeOrVoidContext):
def enterGenericMethodDeclaration(self, ctx:JavaParser.GenericMethodDeclarationContext):
def exitGenericMethodDeclaration(self, ctx:JavaParser.GenericMethodDeclarationContext):
def enterGenericConstructorDeclaration(self, ctx:JavaParser.GenericConstructorDeclarationContext):
def exitGenericConstructorDeclaration(self, ctx:JavaParser.GenericConstructorDeclarationContext):
def enterConstructorDeclaration(self, ctx:JavaParser.ConstructorDeclarationContext):
def exitConstructorDeclaration(self, ctx:JavaParser.ConstructorDeclarationContext):
def enterFieldDeclaration(self, ctx:JavaParser.FieldDeclarationContext):
def exitFieldDeclaration(self, ctx:JavaParser.FieldDeclarationContext):
def enterInterfaceBodyDeclaration(self, ctx:JavaParser.InterfaceBodyDeclarationContext):
def exitInterfaceBodyDeclaration(self, ctx:JavaParser.InterfaceBodyDeclarationContext):
def enterInterfaceMemberDeclaration(self, ctx:JavaParser.InterfaceMemberDeclarationContext):
def exitInterfaceMemberDeclaration(self, ctx:JavaParser.InterfaceMemberDeclarationContext):
def enterConstDeclaration(self, ctx:JavaParser.ConstDeclarationContext):
def exitConstDeclaration(self, ctx:JavaParser.ConstDeclarationContext):
def enterConstantDeclarator(self, ctx:JavaParser.ConstantDeclaratorContext):
def exitConstantDeclarator(self, ctx:JavaParser.ConstantDeclaratorContext):
def enterInterfaceMethodDeclaration(self, ctx:JavaParser.InterfaceMethodDeclarationContext):
def exitInterfaceMethodDeclaration(self, ctx:JavaParser.InterfaceMethodDeclarationContext):
def enterInterfaceMethodModifier(self, ctx:JavaParser.InterfaceMethodModifierContext):
def exitInterfaceMethodModifier(self, ctx:JavaParser.InterfaceMethodModifierContext):
def enterGenericInterfaceMethodDeclaration(self, ctx:JavaParser.GenericInterfaceMethodDeclarationContext):
def exitGenericInterfaceMethodDeclaration(self, ctx:JavaParser.GenericInterfaceMethodDeclarationContext):
def enterVariableDeclarators(self, ctx:JavaParser.VariableDeclaratorsContext):
def exitVariableDeclarators(self, ctx:JavaParser.VariableDeclaratorsContext):
def enterVariableDeclarator(self, ctx:JavaParser.VariableDeclaratorContext):
def exitVariableDeclarator(self, ctx:JavaParser.VariableDeclaratorContext):
def enterVariableDeclaratorId(self, ctx:JavaParser.VariableDeclaratorIdContext):
def exitVariableDeclaratorId(self, ctx:JavaParser.VariableDeclaratorIdContext):
def enterVariableInitializer(self, ctx:JavaParser.VariableInitializerContext):
def exitVariableInitializer(self, ctx:JavaParser.VariableInitializerContext):
def enterArrayInitializer(self, ctx:JavaParser.ArrayInitializerContext):
def exitArrayInitializer(self, ctx:JavaParser.ArrayInitializerContext):
def enterClassOrInterfaceType(self, ctx:JavaParser.ClassOrInterfaceTypeContext):
def exitClassOrInterfaceType(self, ctx:JavaParser.ClassOrInterfaceTypeContext):
def enterTypeArgument(self, ctx:JavaParser.TypeArgumentContext):
def exitTypeArgument(self, ctx:JavaParser.TypeArgumentContext):
def enterQualifiedNameList(self, ctx:JavaParser.QualifiedNameListContext):
def exitQualifiedNameList(self, ctx:JavaParser.QualifiedNameListContext):
def enterFormalParameters(self, ctx:JavaParser.FormalParametersContext):
def exitFormalParameters(self, ctx:JavaParser.FormalParametersContext):
def enterFormalParameterList(self, ctx:JavaParser.FormalParameterListContext):
def exitFormalParameterList(self, ctx:JavaParser.FormalParameterListContext):
def enterFormalParameter(self, ctx:JavaParser.FormalParameterContext):
def exitFormalParameter(self, ctx:JavaParser.FormalParameterContext):
def enterLastFormalParameter(self, ctx:JavaParser.LastFormalParameterContext):
def exitLastFormalParameter(self, ctx:JavaParser.LastFormalParameterContext):
def enterQualifiedName(self, ctx:JavaParser.QualifiedNameContext):
def exitQualifiedName(self, ctx:JavaParser.QualifiedNameContext):
def enterLiteral(self, ctx:JavaParser.LiteralContext):
def exitLiteral(self, ctx:JavaParser.LiteralContext):
def enterIntegerLiteral(self, ctx:JavaParser.IntegerLiteralContext):
def exitIntegerLiteral(self, ctx:JavaParser.IntegerLiteralContext):
def enterFloatLiteral(self, ctx:JavaParser.FloatLiteralContext):
def exitFloatLiteral(self, ctx:JavaParser.FloatLiteralContext):
def enterAnnotation(self, ctx:JavaParser.AnnotationContext):
def exitAnnotation(self, ctx:JavaParser.AnnotationContext):
def enterElementValuePairs(self, ctx:JavaParser.ElementValuePairsContext):
def exitElementValuePairs(self, ctx:JavaParser.ElementValuePairsContext):
def enterElementValuePair(self, ctx:JavaParser.ElementValuePairContext):
def exitElementValuePair(self, ctx:JavaParser.ElementValuePairContext):
def enterElementValue(self, ctx:JavaParser.ElementValueContext):
def exitElementValue(self, ctx:JavaParser.ElementValueContext):
def enterElementValueArrayInitializer(self, ctx:JavaParser.ElementValueArrayInitializerContext):
def exitElementValueArrayInitializer(self, ctx:JavaParser.ElementValueArrayInitializerContext):
def enterAnnotationTypeDeclaration(self, ctx:JavaParser.AnnotationTypeDeclarationContext):
def exitAnnotationTypeDeclaration(self, ctx:JavaParser.AnnotationTypeDeclarationContext):
def enterAnnotationTypeBody(self, ctx:JavaParser.AnnotationTypeBodyContext):
def exitAnnotationTypeBody(self, ctx:JavaParser.AnnotationTypeBodyContext):
def enterAnnotationTypeElementDeclaration(self, ctx:JavaParser.AnnotationTypeElementDeclarationContext):
def exitAnnotationTypeElementDeclaration(self, ctx:JavaParser.AnnotationTypeElementDeclarationContext):
def enterAnnotationTypeElementRest(self, ctx:JavaParser.AnnotationTypeElementRestContext):
def exitAnnotationTypeElementRest(self, ctx:JavaParser.AnnotationTypeElementRestContext):
def enterAnnotationMethodOrConstantRest(self, ctx:JavaParser.AnnotationMethodOrConstantRestContext):
def exitAnnotationMethodOrConstantRest(self, ctx:JavaParser.AnnotationMethodOrConstantRestContext):
def enterAnnotationMethodRest(self, ctx:JavaParser.AnnotationMethodRestContext):
def exitAnnotationMethodRest(self, ctx:JavaParser.AnnotationMethodRestContext):
def enterAnnotationConstantRest(self, ctx:JavaParser.AnnotationConstantRestContext):
def exitAnnotationConstantRest(self, ctx:JavaParser.AnnotationConstantRestContext):
def enterDefaultValue(self, ctx:JavaParser.DefaultValueContext):
def exitDefaultValue(self, ctx:JavaParser.DefaultValueContext):
def enterBlock(self, ctx:JavaParser.BlockContext):
def exitBlock(self, ctx:JavaParser.BlockContext):
def enterBlockStatement(self, ctx:JavaParser.BlockStatementContext):
def exitBlockStatement(self, ctx:JavaParser.BlockStatementContext):
def enterLocalVariableDeclaration(self, ctx:JavaParser.LocalVariableDeclarationContext):
def exitLocalVariableDeclaration(self, ctx:JavaParser.LocalVariableDeclarationContext):
def enterLocalTypeDeclaration(self, ctx:JavaParser.LocalTypeDeclarationContext):
def exitLocalTypeDeclaration(self, ctx:JavaParser.LocalTypeDeclarationContext):
def enterStatement(self, ctx:JavaParser.StatementContext):
def exitStatement(self, ctx:JavaParser.StatementContext):
def enterCatchClause(self, ctx:JavaParser.CatchClauseContext):
def exitCatchClause(self, ctx:JavaParser.CatchClauseContext):
def enterCatchType(self, ctx:JavaParser.CatchTypeContext):
def exitCatchType(self, ctx:JavaParser.CatchTypeContext):
def enterFinallyBlock(self, ctx:JavaParser.FinallyBlockContext):
def exitFinallyBlock(self, ctx:JavaParser.FinallyBlockContext):
def enterResourceSpecification(self, ctx:JavaParser.ResourceSpecificationContext):
def exitResourceSpecification(self, ctx:JavaParser.ResourceSpecificationContext):
def enterResources(self, ctx:JavaParser.ResourcesContext):
def exitResources(self, ctx:JavaParser.ResourcesContext):
def enterResource(self, ctx:JavaParser.ResourceContext):
def exitResource(self, ctx:JavaParser.ResourceContext):
def enterSwitchBlockStatementGroup(self, ctx:JavaParser.SwitchBlockStatementGroupContext):
def exitSwitchBlockStatementGroup(self, ctx:JavaParser.SwitchBlockStatementGroupContext):
def enterSwitchLabel(self, ctx:JavaParser.SwitchLabelContext):
def exitSwitchLabel(self, ctx:JavaParser.SwitchLabelContext):
def enterForControl(self, ctx:JavaParser.ForControlContext):
def exitForControl(self, ctx:JavaParser.ForControlContext):
def enterForInit(self, ctx:JavaParser.ForInitContext):
def exitForInit(self, ctx:JavaParser.ForInitContext):
def enterEnhancedForControl(self, ctx:JavaParser.EnhancedForControlContext):
def exitEnhancedForControl(self, ctx:JavaParser.EnhancedForControlContext):
def enterParExpression(self, ctx:JavaParser.ParExpressionContext):
def exitParExpression(self, ctx:JavaParser.ParExpressionContext):
def enterExpressionList(self, ctx:JavaParser.ExpressionListContext):
def exitExpressionList(self, ctx:JavaParser.ExpressionListContext):
def enterMethodCall(self, ctx:JavaParser.MethodCallContext):
def exitMethodCall(self, ctx:JavaParser.MethodCallContext):
def enterExpression(self, ctx:JavaParser.ExpressionContext):
def exitExpression(self, ctx:JavaParser.ExpressionContext):
def enterLambdaExpression(self, ctx:JavaParser.LambdaExpressionContext):
def exitLambdaExpression(self, ctx:JavaParser.LambdaExpressionContext):
def enterLambdaParameters(self, ctx:JavaParser.LambdaParametersContext):
def exitLambdaParameters(self, ctx:JavaParser.LambdaParametersContext):
def enterLambdaBody(self, ctx:JavaParser.LambdaBodyContext):
def exitLambdaBody(self, ctx:JavaParser.LambdaBodyContext):
def enterPrimary(self, ctx:JavaParser.PrimaryContext):
def exitPrimary(self, ctx:JavaParser.PrimaryContext):
def enterClassType(self, ctx:JavaParser.ClassTypeContext):
def exitClassType(self, ctx:JavaParser.ClassTypeContext):
def enterCreator(self, ctx:JavaParser.CreatorContext):
def exitCreator(self, ctx:JavaParser.CreatorContext):
def enterCreatedName(self, ctx:JavaParser.CreatedNameContext):
def exitCreatedName(self, ctx:JavaParser.CreatedNameContext):
def enterInnerCreator(self, ctx:JavaParser.InnerCreatorContext):
def exitInnerCreator(self, ctx:JavaParser.InnerCreatorContext):
def enterArrayCreatorRest(self, ctx:JavaParser.ArrayCreatorRestContext):
def exitArrayCreatorRest(self, ctx:JavaParser.ArrayCreatorRestContext):
def enterClassCreatorRest(self, ctx:JavaParser.ClassCreatorRestContext):
def exitClassCreatorRest(self, ctx:JavaParser.ClassCreatorRestContext):
def enterExplicitGenericInvocation(self, ctx:JavaParser.ExplicitGenericInvocationContext):
def exitExplicitGenericInvocation(self, ctx:JavaParser.ExplicitGenericInvocationContext):
def enterTypeArgumentsOrDiamond(self, ctx:JavaParser.TypeArgumentsOrDiamondContext):
def exitTypeArgumentsOrDiamond(self, ctx:JavaParser.TypeArgumentsOrDiamondContext):
def enterNonWildcardTypeArgumentsOrDiamond(self, ctx:JavaParser.NonWildcardTypeArgumentsOrDiamondContext):
def exitNonWildcardTypeArgumentsOrDiamond(self, ctx:JavaParser.NonWildcardTypeArgumentsOrDiamondContext):
def enterNonWildcardTypeArguments(self, ctx:JavaParser.NonWildcardTypeArgumentsContext):
def exitNonWildcardTypeArguments(self, ctx:JavaParser.NonWildcardTypeArgumentsContext):
def enterTypeList(self, ctx:JavaParser.TypeListContext):
def exitTypeList(self, ctx:JavaParser.TypeListContext):
def enterTypeType(self, ctx:JavaParser.TypeTypeContext):
def exitTypeType(self, ctx:JavaParser.TypeTypeContext):
def enterPrimitiveType(self, ctx:JavaParser.PrimitiveTypeContext):
def exitPrimitiveType(self, ctx:JavaParser.PrimitiveTypeContext):
def enterTypeArguments(self, ctx:JavaParser.TypeArgumentsContext):
def exitTypeArguments(self, ctx:JavaParser.TypeArgumentsContext):
def enterSuperSuffix(self, ctx:JavaParser.SuperSuffixContext):
def exitSuperSuffix(self, ctx:JavaParser.SuperSuffixContext):
def enterExplicitGenericInvocationSuffix(self, ctx:JavaParser.ExplicitGenericInvocationSuffixContext):
def exitExplicitGenericInvocationSuffix(self, ctx:JavaParser.ExplicitGenericInvocationSuffixContext):
def enterArguments(self, ctx:JavaParser.ArgumentsContext):
def exitArguments(self, ctx:JavaParser.ArgumentsContext):
Recommended Posts