📜  Java的抽象语法树 (AST)

📅  最后修改于: 2022-05-13 01:55:47.231000             🧑  作者: Mango

Java的抽象语法树 (AST)

抽象语法树是一种用编程语言编写的源代码抽象句法结构的树表示。树的每个节点表示源代码中出现的一个构造。

AST 在编译器中的应用具有许多重要性,因为抽象语法树是编译器中广泛用于表示程序代码结构的数据结构。 AST 通常是编译器语法分析阶段的结果。它通常通过编译器需要的几个阶段作为程序的中间表示,对编译器的最终输出有很大的影响。

在进一步讨论实现部分之前,让我们先讨论一下 AST 的使用。 AST 主要用于编译器来检查代码的准确性。如果生成的树有错误,编译器会打印错误消息。使用抽象语法树 (AST) 是因为某些构造无法用上下文无关文法表示,例如隐式类型。它们高度特定于编程语言,但对通用语法树的研究正在进行中。

执行:

在这里,我们将编写对应的自定义Java源代码,我们将为与实现中相同的Java源代码提供 AST。

示例 1(A) Java源代码

Java
// Java Custom Source Code
  
// Main class
class GFG {
  
    // Main driver method
    public static void main(String[] args)
    {
  
        // Print statement
        System.out.println("Hello World!");
    }
}


Java
CLASS_DEF -> CLASS_DEF [1:0]
|--MODIFIERS -> MODIFIERS [1:0]
|   `--LITERAL_PUBLIC -> public [1:0]
|--LITERAL_CLASS -> class [1:7]
|--IDENT -> GFG [1:13]
`--OBJBLOCK -> OBJBLOCK [1:17]
    |--LCURLY -> { [1:17]
    |--METHOD_DEF -> METHOD_DEF [2:4]
    |   |--MODIFIERS -> MODIFIERS [2:4]
    |   |   |--LITERAL_PUBLIC -> public [2:4]
    |   |   `--LITERAL_STATIC -> static [2:11]
    |   |--TYPE -> TYPE [2:18]
    |   |   `--LITERAL_VOID -> void [2:18]
    |   |--IDENT -> main [2:23]
    |   |--LPAREN -> ( [2:27]
    |   |--PARAMETERS -> PARAMETERS [2:34]
    |   |   `--PARAMETER_DEF -> PARAMETER_DEF [2:34]
    |   |       |--MODIFIERS -> MODIFIERS [2:34]
    |   |       |--TYPE -> TYPE [2:34]
    |   |       |   `--ARRAY_DECLARATOR -> [ [2:34]
    |   |       |       |--IDENT -> String [2:28]
    |   |       |       `--RBRACK -> ] [2:35]
    |   |       `--IDENT -> args [2:37]
    |   |--RPAREN -> ) [2:41]
    |   `--SLIST -> { [2:43]
    |       |--EXPR -> EXPR [3:26]
    |       |   `--METHOD_CALL -> ( [3:26]
    |       |       |--DOT -> . [3:18]
    |       |       |   |--DOT -> . [3:14]
    |       |       |   |   |--IDENT -> System [3:8]
    |       |       |   |   `--IDENT -> out [3:15]
    |       |       |   `--IDENT -> println [3:19]
    |       |       |--ELIST -> ELIST [3:27]
    |       |       |   `--EXPR -> EXPR [3:27]
    |       |       |       `--STRING_LITERAL -> "Hello World!" [3:27]
    |       |       `--RPAREN -> ) [3:41]
    |       |--SEMI -> ; [3:42]
    |       `--RCURLY -> } [4:4]
    `--RCURLY -> } [5:0]


Java
CLASS_DEF -> CLASS_DEF 
|--MODIFIERS -> MODIFIERS 
|   `--LITERAL_PUBLIC -> public 
|--LITERAL_CLASS -> class 
|--IDENT -> GFG 
`--OBJBLOCK -> OBJBLOCK 
    |--LCURLY -> { 
    |--METHOD_DEF -> METHOD_DEF 
    |   |--MODIFIERS -> MODIFIERS 
    |   |   |--LITERAL_PUBLIC -> public 
    |   |   `--LITERAL_STATIC -> static 
    |   |--TYPE -> TYPE 
    |   |   `--LITERAL_VOID -> void 
    |   |--IDENT -> main 
    |   |--LPAREN -> ( 
    |   |--PARAMETERS -> PARAMETERS 
    |   |   `--PARAMETER_DEF -> PARAMETER_DEF 
    |   |       |--MODIFIERS -> MODIFIERS 
    |   |       |--TYPE -> TYPE 
    |   |       |   `--ARRAY_DECLARATOR -> [ 
    |   |       |       |--IDENT -> String 
    |   |       |       `--RBRACK -> ] 
    |   |       `--IDENT -> args 
    |   |--RPAREN -> ) 
    |   `--SLIST -> { 
    |       |--EXPR -> EXPR 
    |       |   `--METHOD_CALL -> ( 
    |       |       |--DOT -> . 
    |       |       |   |--DOT -> . 
    |       |       |   |   |--IDENT -> System 
    |       |       |   |   `--IDENT -> out 
    |       |       |   `--IDENT -> println
    |       |       |--ELIST -> ELIST 
    |       |       |   `--EXPR -> EXPR 
    |       |       |       `--STRING_LITERAL -> "Hello World!" 
    |       |       `--RPAREN -> ) 
    |       |--SEMI -> ; 
    |       `--RCURLY -> }
    `--RCURLY -> }


Java
+ BinaryExpression
 - type: +
 - left_value: 
  LiteralExpr:
   value: 1
 - right_vaue:
  LiteralExpr:
   value: 2


示例 1(B)上述源代码的 AST



Java

CLASS_DEF -> CLASS_DEF [1:0]
|--MODIFIERS -> MODIFIERS [1:0]
|   `--LITERAL_PUBLIC -> public [1:0]
|--LITERAL_CLASS -> class [1:7]
|--IDENT -> GFG [1:13]
`--OBJBLOCK -> OBJBLOCK [1:17]
    |--LCURLY -> { [1:17]
    |--METHOD_DEF -> METHOD_DEF [2:4]
    |   |--MODIFIERS -> MODIFIERS [2:4]
    |   |   |--LITERAL_PUBLIC -> public [2:4]
    |   |   `--LITERAL_STATIC -> static [2:11]
    |   |--TYPE -> TYPE [2:18]
    |   |   `--LITERAL_VOID -> void [2:18]
    |   |--IDENT -> main [2:23]
    |   |--LPAREN -> ( [2:27]
    |   |--PARAMETERS -> PARAMETERS [2:34]
    |   |   `--PARAMETER_DEF -> PARAMETER_DEF [2:34]
    |   |       |--MODIFIERS -> MODIFIERS [2:34]
    |   |       |--TYPE -> TYPE [2:34]
    |   |       |   `--ARRAY_DECLARATOR -> [ [2:34]
    |   |       |       |--IDENT -> String [2:28]
    |   |       |       `--RBRACK -> ] [2:35]
    |   |       `--IDENT -> args [2:37]
    |   |--RPAREN -> ) [2:41]
    |   `--SLIST -> { [2:43]
    |       |--EXPR -> EXPR [3:26]
    |       |   `--METHOD_CALL -> ( [3:26]
    |       |       |--DOT -> . [3:18]
    |       |       |   |--DOT -> . [3:14]
    |       |       |   |   |--IDENT -> System [3:8]
    |       |       |   |   `--IDENT -> out [3:15]
    |       |       |   `--IDENT -> println [3:19]
    |       |       |--ELIST -> ELIST [3:27]
    |       |       |   `--EXPR -> EXPR [3:27]
    |       |       |       `--STRING_LITERAL -> "Hello World!" [3:27]
    |       |       `--RPAREN -> ) [3:41]
    |       |--SEMI -> ; [3:42]
    |       `--RCURLY -> } [4:4]
    `--RCURLY -> } [5:0]

现在您一定想知道如何制作 AST 或如何按照按顺序列出的简单步骤为该极客生成上述代码。

  • 在本地环境中运行源代码。
  • 下载 Checkstyle 命令行
checkstyle-8.43-all.jar 
  • 借助终端中的 Checkstyle 审核程序:
java -jar checkstyle-8.43-all.jar -c /google_checks.xml YourFile.java
  • 审核后,在终端中运行此命令以获取首选代码的 AST: Java -jar checkstyle-8.43-all.jar -t YourFile。Java
  • AST 现在准备好了。但是等待极客,

请记住:要更新 AST,我们必须执行以下两个步骤

第 1 步:我们应该更换

">" with ">" and "<" with "<"

第 2 步:删除代码行

Example 1(C)更新后的 AST 上面代码的例子如下:

Java

CLASS_DEF -> CLASS_DEF 
|--MODIFIERS -> MODIFIERS 
|   `--LITERAL_PUBLIC -> public 
|--LITERAL_CLASS -> class 
|--IDENT -> GFG 
`--OBJBLOCK -> OBJBLOCK 
    |--LCURLY -> { 
    |--METHOD_DEF -> METHOD_DEF 
    |   |--MODIFIERS -> MODIFIERS 
    |   |   |--LITERAL_PUBLIC -> public 
    |   |   `--LITERAL_STATIC -> static 
    |   |--TYPE -> TYPE 
    |   |   `--LITERAL_VOID -> void 
    |   |--IDENT -> main 
    |   |--LPAREN -> ( 
    |   |--PARAMETERS -> PARAMETERS 
    |   |   `--PARAMETER_DEF -> PARAMETER_DEF 
    |   |       |--MODIFIERS -> MODIFIERS 
    |   |       |--TYPE -> TYPE 
    |   |       |   `--ARRAY_DECLARATOR -> [ 
    |   |       |       |--IDENT -> String 
    |   |       |       `--RBRACK -> ] 
    |   |       `--IDENT -> args 
    |   |--RPAREN -> ) 
    |   `--SLIST -> { 
    |       |--EXPR -> EXPR 
    |       |   `--METHOD_CALL -> ( 
    |       |       |--DOT -> . 
    |       |       |   |--DOT -> . 
    |       |       |   |   |--IDENT -> System 
    |       |       |   |   `--IDENT -> out 
    |       |       |   `--IDENT -> println
    |       |       |--ELIST -> ELIST 
    |       |       |   `--EXPR -> EXPR 
    |       |       |       `--STRING_LITERAL -> "Hello World!" 
    |       |       `--RPAREN -> ) 
    |       |--SEMI -> ; 
    |       `--RCURLY -> }
    `--RCURLY -> } 

例2:表示1+2可以用AST表示

Java

+ BinaryExpression
 - type: +
 - left_value: 
  LiteralExpr:
   value: 1
 - right_vaue:
  LiteralExpr:
   value: 2