附录 II:生成的语法树类(Generated Syntax Tree Classes)
原文:Robert Nystrom, Crafting Interpreters, Appendix II。原书以 CC BY-NC-SA 4.0 协议发布;本译文用于学习与研究。
这里列出本书为 jlox 自动生成语法树类的小脚本所产生的代码。表达式节点最先在第 5 章“表示代码”出现;Expr 定义用来分派到具体表达式类型的 Visitor 接口,其余节点作为嵌套类存在。
表达式(Expressions)
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);
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
abstract <R> R accept(Visitor<R> visitor);
}
赋值节点在第 8 章引入;二元、分组、字面量与一元表达式在第 5 章;调用节点在第 10 章;属性 Get/Set 与 This 在第 12 章;逻辑 and/or 在第 9 章;Super 在第 13 章。每个节点都保存其组成部分,构造器写入 final 字段,accept() 将控制权派发给对应 Visitor 方法。
语句(Statements)
语句构成与表达式独立的第二棵节点层级,最初几个在第 8 章加入:
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);
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
abstract <R> R accept(Visitor<R> visitor);
}
块、表达式、输出和变量语句在第 8 章;if、while 在第 9 章;函数和 return 在第 10 章;类声明在第 12 章。生成器将“增加节点时同步维护字段、构造器、Visitor 与 accept()”这一机械任务集中起来,降低漏改造成编译错误或行为缺失的风险。