Comment analyser le code source Java avec AST (Abstract Syntax Tree) en utilisant ANTLR et Python

1.Tout d'abord

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.

overviewAstForJavaByAntlr.jpg

1.1 Qu'est-ce que AST (Abstract Syntax Tree)?

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.

1.2 Qu'est-ce que l'ANTLR?

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.

Lexer: analyse de phrases

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.

Analyseur: analyse syntaxique

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.

Listener: écouteur d'événements

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é.

2. ANTLR génère automatiquement un analyseur

2.1. Obtention d'ANTLR

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.

2.2. Obtention du fichier de grammaire (g4)

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

2.3. Lexer, Parser, génération d'écouteur par défaut

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.

2.4. (Référence) Génération de Lexer, Parser et Listener par défaut pour Java

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

3. Créez un programme d'analyse syntaxique

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.

3.1. Informations acquises par l'auditeur

3.2. Structure du répertoire

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.

3.3. Traitement principal

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)

★ Point 1

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.

3.4. Processus d'exécution de Listener

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

★ Point 2

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.

3.5. Traitement propriétaire de l'auditeur

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.

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

★ Point 3

Étendez (héritez) de JavaParserListener pour définir votre propre écouteur, BasicInfoListener.

★ Point 4

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.

★ Point 5

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.

★ Point 6

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.

★ Point 7

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.

4. Test

Une 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.

5. Enfin

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.

exampleUsecaseOfUsingAntlr.jpg

6. Liste des fonctions de point d'accroche (référence)

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

Comment analyser le code source Java avec AST (Abstract Syntax Tree) en utilisant ANTLR et Python
Comment créer un environnement d'exécution Python et Jupyter avec VSCode
MessagePack-Try pour lier Java et Python avec RPC
Stratégie sur la façon de monétiser avec Python Java
Compilateur en Python: Arbre de syntaxe abstraite PL / 0 (AST)
Comment créer un package Python à l'aide de VS Code
[Python] Comment jouer avec les variables de classe avec décorateur et métaclasse
[Python / Ruby] Comprendre le code Comment obtenir des données en ligne et les écrire au format CSV
Comment mettre à jour le blog FC2, etc. en utilisant XMLRPC avec Python
PyArmor ~ Un moyen facile de chiffrer et de fournir du code source Python ~
Comment se connecter à AtCoder avec Python et soumettre automatiquement
Premiers pas avec le module ast de Python (en suivant l'arborescence de la syntaxe abstraite)
Comment obtenir des abonnés et des abonnés de Python à l'aide de l'API Mastodon
Comment créer une caméra de surveillance (caméra de sécurité) avec Opencv et Python
Comment se connecter à Cloud Firestore à partir de Google Cloud Functions avec du code Python
Comment gérer les erreurs lors de l'installation de Python et de pip avec choco
Comment mettre à jour une source de données de classeur packagée Tableau à l'aide de Python
Comment afficher les octets de la même manière en Java et Python
Comment installer Python à l'aide d'Anaconda
Python: comment utiliser async avec
[Introduction à Python] Comment analyser JSON
Comment démarrer avec Python
Comment calculer la date avec python
[Circuit x Python] Comment développer et calculer les fonctions de transfert à l'aide de Lcapy
[Introduction à Python] Comment juger de l'authenticité avec l'instruction if (True et None)
Comment gérer l'erreur OAuth2 lors de l'utilisation des API Google à partir de Python
Comment obtenir la différence de date et d'heure en secondes avec Python
Code Python pour former et tester avec Custom Vision of Cognitive Service
Comment rechercher à l'aide de l'Astroquery de Python et obtenir des images ajustées avec Skyview
Comment générer un code QR et un code à barres en Python et le lire normalement ou en temps réel avec OpenCV
Comment empaqueter et distribuer des scripts Python
De Python à l'utilisation de MeCab (et CaboCha)
Utilisation de Python et MeCab avec Azure Databricks
Différences entre la syntaxe Python et Java
Fractal pour faire et jouer avec Python
Comment utiliser BigQuery en Python
Comment faire un test de sac avec python
Comment afficher le japonais python avec lolipop
python: Comment utiliser les locals () et globals ()
Comment entrer le japonais avec les malédictions Python
[Python] Comment calculer MAE et RMSE
Comment utiliser le zip Python et énumérer
J'utilise tox et Python 3.3 avec Travis-CI
Comment utiliser is et == en Python
Comment installer python3 avec docker centos
Comment démarrer le projet Python en 2020 (Windows WSL et Mac commun)
Trois choses auxquelles j'étais accro lors de l'utilisation de Python et MySQL avec Docker
Comment utiliser OAuth et API de compte de service avec le client API Google pour python
Différences dans la façon d'écrire du code source externe entre Ruby et Python
[Python] Comment créer un environnement de serveur Web local avec SimpleHTTPServer et CGIHTTPServer
Comment télécharger avec Heroku, Flask, Python, Git (4)
Comment lire un fichier CSV avec Python 2/3
Grattage de la nourriture avec python et sortie en CSV
Comment profiter de la programmation avec Minecraft (Ruby, Python)
[REAPER] Comment jouer à Reascript avec Python