How to parse Java source code with AST (Abstract Syntax Tree) using ANTLR and Python

1.First of all

This time, I would like to explain how to parse Java source code with AST (Abstract Syntax Tree) using ANTLR and Python. The reason for Python is that Python is easier and I'm just crazy about Python these days, and I've done it before in Java, so this time it's like Python. If there is a Java request, I would like to write an article on Qiita. The goals of this article are the following three points.

overviewAstForJavaByAntlr.jpg

1.1. What is AST (Abstract Syntax Tree)?

[Abstract Syntax Tree in wikipedia](https://ja.wikipedia.org/wiki/%E6%8A%BD%E8%B1%A1%E6%A7%8B%E6%96%87%E6%9C%A8 The explanation (part) of) is as follows.

An abstract syntax tree (AST) is an ordinary syntax tree (also called a concrete syntax tree or analysis tree) that removes information that is not related to the meaning of the language and extracts only the information that is relevant to the meaning. It is a (abstract) tree-structured data structure.

[Abstract Syntax Tree with Google Image](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) I think you can get an image. However, it is still difficult.

To put it simply, I think the following three points.

1.2. What is ANTLR?

ANTLR (http://www.antlr.org/) is a tool that takes a grammar file (g4 file) as input and automatically generates a function required for parsing an abstract syntax tree, a so-called analyzer. Since the grammar file does not depend on the programming language of the analyzer, it is possible to generate an analyzer for multiple programming languages. This time we will generate the parser code for Python.

The main components of the analyzer are listed below.

Lexer: Lexical analysis

Explanation of Lexical analysis in wikipedia (partial) Is as follows.

Lexical Analysis (Lexical Analysis) is the first half of parsing in a broad sense, which analyzes character strings such as natural language sentences and source code in programming languages, and in the narrow sense of the second half. This is a procedure for obtaining a sequence of "tokens" (lexicals), which is the smallest unit (termination symbol) in parsing. The program that performs lexical analysis is a lexical analyzer. See Morphological Analysis for lexical analysis in natural language.

it's difficult. Simply put, it's the process of checking if it's written in a string that can be used as a programming language specification. For example, in Python the words from, def, ʻelif`, etc. are available as syntax, but in Java these words cannot be used as syntax. Lexer does this for you. Since Lexer follows the specifications of the grammar file, it basically uses the Lexer generated by ANTLR as it is.

Parser: Parsing

Explanation of Parsing in wikipedia (partial) Is as follows.

Syntactic analysis (syntactic analysis or parse) is a sentence, specifically a solid character string without notes such as markups, divided into morphological elements in natural language, and in between. It is a procedure to clarify (parse) syntactic (syntactic) relationships such as relations (modification-modified, etc.). Natural language is one of the main points in natural language processing, and in the case of formal languages such as programming languages, a syntax tree is obtained according to the formal grammar. The mechanism that performs parsing is called a parser.

it's difficult. As the wording of "syntax analysis" indicates, it is a process to read the text to be analyzed and decompose it into a syntax tree. It's exactly what you imagine. Since Parser follows the specifications of the grammar file, it basically uses the Parser generated by ANTLR as it is.

Listener: Event listener

Lexer and Parser are the main processes that appear in natural language processing, but Listener is an API for users to create their own analyzers. What kind of API is the hook point of the event that occurs when the node of the syntax tree switches. Taking Java, which is the subject of this analysis, as an example, we have entered the context of the class definition & the context has ended, we have entered the context of the method definition & the context has ended, and so on. Since the Listener automatically generated by ANTLR is only implemented by default, unlike Lexer and Parser, the generated Listener is extended (inherited) and used.

2. ANTLR automatically generates an analyzer

2.1. Obtaining ANTLR

The ability to generate an ANTLR parser is provided as a Java program. Get http://www.antlr.org/download/antlr-runtime-4.7.1.jar and store it in any directory. If you do not have the JDK installed, please install it.

2.2. Obtaining the grammar file (g4)

A grammar file (g4) for the programming language is available on ANTLR's GitHub page. Java has different grammar files for each version. This time, get the grammar file for Java8 from https://github.com/antlr/grammars-v4/tree/master/java. Store the obtained files (JavaLexer.g4, JavaParser.g4) in any directory (example: grammar).

Before generation


.
│  antlr-4.7.1-complete.jar
│
└─grammar
        JavaLexer.g4
        JavaParser.g4

2.3. Lexer, Parser, default Listener generation

The command to generate Lexer, Parser and Listener for Python3 with ANTLR is shown below. Specify the parser programming language with the -Dlanguage option. Note that for Python, Python3 and Python2 are different.

Command to generate Lexer, Parser, Listener for Python3


java -jar antlr-4.7.1-complete.jar -Dlanguage=Python3 grammar\*.g4

After generation


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

You now have the analyzer source code (JavaLexer.py, JavaParser.py, JavaParserListener.py) required for Java source code analysis. After that, we will implement our own parsing program using this file.

2.4. (Reference) Generation of Lexer, Parser and default Listener for Java

For reference, the commands to generate Lexer, Parser, and Linstener for Java are shown below. You can specify a Java package with the -package option.

Commands to generate Lexer, Parser, Linstener for Java


// com.example.service.Output as antlr package
java -jar antlr-4.7.1-complete.jar -Dlanguage=Java -encoding utf-8 -package com.example.service.antlr grammar\*.g4

3. Create a parsing program

Install ʻantlr4-python3-runtime` to use ANTLR with Python. Please note that there are separate libraries for Python2 and Python3.

runtime of antlr installed with pip


antlr4-python3-runtime             4.7.1

As mentioned above, Listener is created for each purpose you want to analyze. This time I would like to create a Listener that gets the basic information and method calls of the Java class.

3.1. Information acquired by Listener

3.2. Directory structure

Directory structure


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, and JavaParserListener.py copy the files automatically generated by ANTLR as they are.

3.3. Main processing

This is a process with a main function. The file path is written directly for the explanation, but please correct it accordingly.

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/File to be analyzed.java'

    #★ Point 1
    ast_info = AstProcessor(logging, BasicInfoListener()).execute(target_file_path)

★ Point 1

After creating an instance of Listener implemented independently, create an instance of ʻAst Processor described later. Execute the ʻexecute method of ʻAstProcessor with the file path of the file to be analyzed as an argument, and execute the analysis of the source code. ʻThe return value of the execute method is the analysis result.

3.4. Process to execute Listener

I explained that it is Listener that performs its own analysis processing. Therefore, you usually create multiple Listeners according to your purpose. However, the process of executing Listener does not change, so we will implement the process of executing Listener for general purposes.

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

Create an instance of JavaLexer from the file to be analyzed, and use it to create an instance of JavaParser. Parsing is done by calling the walk method of an instance of ParseTreeWalker. This flow is the same even if the Listener processing is different.

3.5. Proprietary Listener processing

This section describes how to implement the original Listener, which is the key point of source code analysis. However, there are only three 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

Extend (inherit) JavaParserListener to define your own Listener, BasicInfoListener.

★ Point 4

Define ʻast_info` to hold the analysis result. Please modify the name and contents of the property as appropriate according to the purpose you want to analyze.

★ Point 5

It overrides the hookpoint function defined in JavaParserListener and implements its own parsing process. For example, ʻenterPackageDeclaration, as the name implies, is called at the beginning of the Java source code package definition. The argument ctx` is of a different type, but because it has a parent class, any context class can access the basic information needed for parsing.

★ Point 6

As the name of AST (Abstract Syntax Tree) suggests, ctx has a tree structure. You can access the child nodes in that context with the getChild function. The content of the child node depends on the context.

★ Point 7

Normally, AST (Abstract Syntax Tree) does not hold line numbers and character positions that are concrete information, but ANTLR holds such information in context. After all, this information is useful when analyzing the source code, so please use it as needed.

4. Test

One class of TEARASOLUNA 5.x sample applicationを対象に解析を行ってみたいと思います。

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;
    }
}

Analysis result


{'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'}

If you look at the analysis results, you can see that you can understand the structure of the class and the processing contents.

5. Finally

This time, I explained how to parse Java source code with AST (Abstract Syntax Tree) using ANTLR and Python. I hope you understand that using ANTLR makes it easier and more structured than text analysis such as Grep. Although not obtained in the sample, the following information can also be obtained.

By incorporating parsing using ANTLR, you will be able to create tools and applications that use source code as input.

exampleUsecaseOfUsingAntlr.jpg

6. List of hookpoint functions (reference)

For reference, a list of Listener hookpoint functions is shown below.

List of hookpoint functions (208 in 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

How to parse Java source code with AST (Abstract Syntax Tree) using ANTLR and Python
How to build Python and Jupyter execution environment with VS Code
MessagePack-Try to link Java and Python with RPC
Strategy on how to monetize with Python Java
Compiler in Python: PL / 0 Abstract Syntax Tree (AST)
How to make a Python package using VS Code
[Note] How to write QR code and description in the same image with python
[Python] How to play with class variables with decorator and metaclass
How to do Bulk Update with PyMySQL and notes [Python]
[Python / Ruby] Understanding with code How to get data from online and write it to CSV
How to update FC2 blog etc. using XMLRPC with python
PyArmor ~ Easy way to encrypt and deliver python source code ~
How to log in to AtCoder with Python and submit automatically
Getting Started with Python's ast Module (Following the Abstract Syntax Tree)
How to get followers and followers from python using the Mastodon API
How to make a surveillance camera (Security Camera) with Opencv and Python
How to connect to Cloud Firestore from Google Cloud Functions with python code
How to deal with errors when installing Python and pip with choco
How to update a Tableau packaged workbook data source using Python
How to use Python with Jw_cad (Part 2 Command explanation and operation)
How to display bytes in the same way in Java and Python
How to install python using anaconda
Python: How to use async with
[Introduction to Python] How to parse JSON
How to get started with Python
How to use FTP with Python
How to calculate date with python
[Circuit x Python] How to expand and calculate transfer functions using Lcapy
[Introduction to Python] How to judge authenticity with if statement (True and None)
How to deal with OAuth2 error when using Google APIs from Python
How to get the date and time difference in seconds with python
Python code to train and test with Custom Vision of Cognitive Service
How to search using python's astroquery and get fits images with skyview
How to generate a QR code and barcode in Python and read it normally or in real time with OpenCV
How to package and distribute Python scripts
From Python to using MeCab (and CaboCha)
Using Python and MeCab with Azure Databricks
Differences in syntax between Python and Java
Fractal to make and play with Python
How to work with BigQuery in Python
How to do portmanteau test with python
How to display python Japanese with lolipop
python: How to use locals () and globals ()
How to enter Japanese with Python curses
[Python] How to calculate MAE and RMSE
How to use Python zip and enumerate
[Python] How to deal with module errors
I'm using tox and Python 3.3 with Travis-CI
How to use is and == in Python
How to install python3 with docker centos
How to get started with the 2020 Python project (windows wsl and mac standardization)
An introduction to Python's AST (Abstract Syntax Tree) starting from just one line
Three things I was addicted to when using Python and MySQL with Docker
How to use Service Account OAuth and API with Google API Client for python
Difference in writing method to read external source code between Ruby and Python
[Python] How to create a local web server environment with SimpleHTTPServer and CGIHTTPServer
How to upload with Heroku, Flask, Python, Git (4)
How to read a CSV file with Python 2/3
Scraping tabelog with python and outputting to CSV
How to enjoy programming with Minecraft (Ruby, Python)
[REAPER] How to play with Reascript in Python