A2

附錄 II

為了讓您更加了解,這裡展示了我們用來自動生成 jlox 語法樹類別的小腳本所產生的程式碼。

A2.1運算式

運算式是我們最早看到的語法樹節點,在「程式碼的表示」中介紹。主要的 Expr 類別定義了用來分派特定運算式型別的訪問者介面,並包含其他運算式子類別作為巢狀類別。

lox/Expr.java
建立新檔案
package com.craftinginterpreters.lox;

import java.util.List;

abstract class Expr {
  interface Visitor<R> {
    R visitAssignExpr(Assign expr);
    R visitBinaryExpr(Binary expr);
    R visitCallExpr(Call expr);
    R visitGetExpr(Get expr);
    R visitGroupingExpr(Grouping expr);
    R visitLiteralExpr(Literal expr);
    R visitLogicalExpr(Logical expr);
    R visitSetExpr(Set expr);
    R visitSuperExpr(Super expr);
    R visitThisExpr(This expr);
    R visitUnaryExpr(Unary expr);
    R visitVariableExpr(Variable expr);
  }

  // Nested Expr classes here...

  abstract <R> R accept(Visitor<R> visitor);
}
lox/Expr.java,建立新檔案

A2.1.1指派運算式

變數指派在「陳述式與狀態」中介紹。

lox/Expr.java
巢狀於 Expr 類別內
  static class Assign extends Expr {
    Assign(Token name, Expr value) {
      this.name = name;
      this.value = value;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitAssignExpr(this);
    }

    final Token name;
    final Expr value;
  }
lox/Expr.java,巢狀於 Expr 類別內

A2.1.2二元運算式

二元運算子在「程式碼的表示」中介紹。

lox/Expr.java
巢狀於 Expr 類別內
  static class Binary extends Expr {
    Binary(Expr left, Token operator, Expr right) {
      this.left = left;
      this.operator = operator;
      this.right = right;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitBinaryExpr(this);
    }

    final Expr left;
    final Token operator;
    final Expr right;
  }
lox/Expr.java,巢狀於 Expr 類別內

A2.1.3呼叫運算式

函式呼叫運算式在「函式」中介紹。

lox/Expr.java
巢狀於 Expr 類別內
  static class Call extends Expr {
    Call(Expr callee, Token paren, List<Expr> arguments) {
      this.callee = callee;
      this.paren = paren;
      this.arguments = arguments;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitCallExpr(this);
    }

    final Expr callee;
    final Token paren;
    final List<Expr> arguments;
  }
lox/Expr.java,巢狀於 Expr 類別內

A2.1.4取得運算式

屬性存取,或是「取得」運算式,在「類別」中介紹。

lox/Expr.java
巢狀於 Expr 類別內
  static class Get extends Expr {
    Get(Expr object, Token name) {
      this.object = object;
      this.name = name;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitGetExpr(this);
    }

    final Expr object;
    final Token name;
  }
lox/Expr.java,巢狀於 Expr 類別內

A2.1.5群組運算式

使用括號來群組運算式在「程式碼的表示」中介紹。

lox/Expr.java
巢狀於 Expr 類別內
  static class Grouping extends Expr {
    Grouping(Expr expression) {
      this.expression = expression;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitGroupingExpr(this);
    }

    final Expr expression;
  }
lox/Expr.java,巢狀於 Expr 類別內

A2.1.6字面值運算式

字面值運算式在「程式碼的表示」中介紹。

lox/Expr.java
巢狀於 Expr 類別內
  static class Literal extends Expr {
    Literal(Object value) {
      this.value = value;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitLiteralExpr(this);
    }

    final Object value;
  }
lox/Expr.java,巢狀於 Expr 類別內

A2.1.7邏輯運算式

邏輯 andor 運算子在「控制流程」中介紹。

lox/Expr.java
巢狀於 Expr 類別內
  static class Logical extends Expr {
    Logical(Expr left, Token operator, Expr right) {
      this.left = left;
      this.operator = operator;
      this.right = right;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitLogicalExpr(this);
    }

    final Expr left;
    final Token operator;
    final Expr right;
  }
lox/Expr.java,巢狀於 Expr 類別內

A2.1.8設定運算式

屬性指派,或是「設定」運算式,在「類別」中介紹。

lox/Expr.java
巢狀於 Expr 類別內
  static class Set extends Expr {
    Set(Expr object, Token name, Expr value) {
      this.object = object;
      this.name = name;
      this.value = value;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitSetExpr(this);
    }

    final Expr object;
    final Token name;
    final Expr value;
  }
lox/Expr.java,巢狀於 Expr 類別內

A2.1.9Super 運算式

super 運算式在「繼承」中介紹。

lox/Expr.java
巢狀於 Expr 類別內
  static class Super extends Expr {
    Super(Token keyword, Token method) {
      this.keyword = keyword;
      this.method = method;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitSuperExpr(this);
    }

    final Token keyword;
    final Token method;
  }
lox/Expr.java,巢狀於 Expr 類別內

A2.1.10This 運算式

this 運算式在「類別」中介紹。

lox/Expr.java
巢狀於 Expr 類別內
  static class This extends Expr {
    This(Token keyword) {
      this.keyword = keyword;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitThisExpr(this);
    }

    final Token keyword;
  }
lox/Expr.java,巢狀於 Expr 類別內

A2.1.11一元運算式

一元運算子在「程式碼的表示」中介紹。

lox/Expr.java
巢狀於 Expr 類別內
  static class Unary extends Expr {
    Unary(Token operator, Expr right) {
      this.operator = operator;
      this.right = right;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitUnaryExpr(this);
    }

    final Token operator;
    final Expr right;
  }
lox/Expr.java,巢狀於 Expr 類別內

A2.1.12變數運算式

變數存取運算式在「陳述式與狀態」中介紹。

lox/Expr.java
巢狀於 Expr 類別內
  static class Variable extends Expr {
    Variable(Token name) {
      this.name = name;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitVariableExpr(this);
    }

    final Token name;
  }
lox/Expr.java,巢狀於 Expr 類別內

A2.2陳述式

陳述式形成獨立於運算式的第二個語法樹節點階層。我們在「陳述式與狀態」中加入最開始的幾個陳述式。

lox/Stmt.java
建立新檔案
package com.craftinginterpreters.lox;

import java.util.List;

abstract class Stmt {
  interface Visitor<R> {
    R visitBlockStmt(Block stmt);
    R visitClassStmt(Class stmt);
    R visitExpressionStmt(Expression stmt);
    R visitFunctionStmt(Function stmt);
    R visitIfStmt(If stmt);
    R visitPrintStmt(Print stmt);
    R visitReturnStmt(Return stmt);
    R visitVarStmt(Var stmt);
    R visitWhileStmt(While stmt);
  }

  // Nested Stmt classes here...

  abstract <R> R accept(Visitor<R> visitor);
}
lox/Stmt.java,建立新檔案

A2.2.1區塊陳述式

定義區域範圍的括號區塊陳述式在「陳述式與狀態」中介紹。

lox/Stmt.java
巢狀於 Stmt 類別內
  static class Block extends Stmt {
    Block(List<Stmt> statements) {
      this.statements = statements;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitBlockStmt(this);
    }

    final List<Stmt> statements;
  }
lox/Stmt.java,巢狀於 Stmt 類別內

A2.2.2類別陳述式

類別宣告在「類別」中介紹,這點應該不意外。

lox/Stmt.java
巢狀於 Stmt 類別內
  static class Class extends Stmt {
    Class(Token name,
          Expr.Variable superclass,
          List<Stmt.Function> methods) {
      this.name = name;
      this.superclass = superclass;
      this.methods = methods;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitClassStmt(this);
    }

    final Token name;
    final Expr.Variable superclass;
    final List<Stmt.Function> methods;
  }
lox/Stmt.java,巢狀於 Stmt 類別內

A2.2.3運算式陳述式

運算式陳述式在「陳述式與狀態」中介紹。

lox/Stmt.java
巢狀於 Stmt 類別內
  static class Expression extends Stmt {
    Expression(Expr expression) {
      this.expression = expression;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitExpressionStmt(this);
    }

    final Expr expression;
  }
lox/Stmt.java,巢狀於 Stmt 類別內

A2.2.4函式陳述式

函式宣告在「函式」中介紹,您應該猜到了。

lox/Stmt.java
巢狀於 Stmt 類別內
  static class Function extends Stmt {
    Function(Token name, List<Token> params, List<Stmt> body) {
      this.name = name;
      this.params = params;
      this.body = body;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitFunctionStmt(this);
    }

    final Token name;
    final List<Token> params;
    final List<Stmt> body;
  }
lox/Stmt.java,巢狀於 Stmt 類別內

A2.2.5If 陳述式

if 陳述式在「控制流程」中介紹。

lox/Stmt.java
巢狀於 Stmt 類別內
  static class If extends Stmt {
    If(Expr condition, Stmt thenBranch, Stmt elseBranch) {
      this.condition = condition;
      this.thenBranch = thenBranch;
      this.elseBranch = elseBranch;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitIfStmt(this);
    }

    final Expr condition;
    final Stmt thenBranch;
    final Stmt elseBranch;
  }
lox/Stmt.java,巢狀於 Stmt 類別內

A2.2.6Print 陳述式

print 陳述式在「陳述式與狀態」中介紹。

lox/Stmt.java
巢狀於 Stmt 類別內
  static class Print extends Stmt {
    Print(Expr expression) {
      this.expression = expression;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitPrintStmt(this);
    }

    final Expr expression;
  }
lox/Stmt.java,巢狀於 Stmt 類別內

A2.2.7Return 陳述式

您需要一個函式來返回,所以 return 陳述式在「函式」中介紹。

lox/Stmt.java
巢狀於 Stmt 類別內
  static class Return extends Stmt {
    Return(Token keyword, Expr value) {
      this.keyword = keyword;
      this.value = value;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitReturnStmt(this);
    }

    final Token keyword;
    final Expr value;
  }
lox/Stmt.java,巢狀於 Stmt 類別內

A2.2.8變數陳述式

變數宣告在「陳述式與狀態」中介紹。

lox/Stmt.java
巢狀於 Stmt 類別內
  static class Var extends Stmt {
    Var(Token name, Expr initializer) {
      this.name = name;
      this.initializer = initializer;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitVarStmt(this);
    }

    final Token name;
    final Expr initializer;
  }
lox/Stmt.java,巢狀於 Stmt 類別內

A2.2.9While 陳述式

while 陳述式在「控制流程」中介紹。

lox/Stmt.java
巢狀於 Stmt 類別內
  static class While extends Stmt {
    While(Expr condition, Stmt body) {
      this.condition = condition;
      this.body = body;
    }

    @Override
    <R> R accept(Visitor<R> visitor) {
      return visitor.visitWhileStmt(this);
    }

    final Expr condition;
    final Stmt body;
  }
lox/Stmt.java,巢狀於 Stmt 類別內