From bfd14c4de7b41f67dcbff3c58f4c263e3f1d2a52 Mon Sep 17 00:00:00 2001 From: Luke Date: Sun, 27 Apr 2025 18:36:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../snow/compiler/semantic/SemanticError.java | 18 ++++++++- .../jcnc/snow/compiler/semantic/Symbol.java | 16 +++++++- .../snow/compiler/semantic/SymbolKind.java | 17 +++++++- .../snow/compiler/semantic/SymbolTable.java | 39 +++++++++++++++++-- 4 files changed, 84 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/SemanticError.java b/src/main/java/org/jcnc/snow/compiler/semantic/SemanticError.java index e4bf44c..b2e8f27 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/SemanticError.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/SemanticError.java @@ -3,10 +3,26 @@ package org.jcnc.snow.compiler.semantic; import org.jcnc.snow.compiler.parser.ast.base.Node; /** - * 语义错误类,保存 AST 节点和对应的错误信息。 + * 表示语义分析过程中发现的错误。 + *

+ * 每个语义错误包含两个部分: + * 1. 发生错误的 AST(抽象语法树)节点 {@link Node}; + * 2. 错误的详细描述 {@link String}。 + *

+ * + * 该类以 record 形式定义,自动生成构造方法、访问器方法(getters)、equals、hashCode 以及 toString 方法。 */ public record SemanticError(Node node, String message) { + /** + * 返回语义错误的字符串表示。 + *

+ * 格式为:"Semantic error at [节点信息]: [错误信息]"。 + * 方便在日志输出或调试过程中快速定位问题。 + *

+ * + * @return 格式化后的错误信息字符串 + */ @Override public String toString() { return "Semantic error at " + node + ": " + message; diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/Symbol.java b/src/main/java/org/jcnc/snow/compiler/semantic/Symbol.java index 24287f5..bd9dea2 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/Symbol.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/Symbol.java @@ -1,7 +1,21 @@ package org.jcnc.snow.compiler.semantic; /** - * 符号表中的一条记录,包含名称、类型和种类信息。 + * 表示符号表(Symbol Table)中的一条符号记录。 + *

+ * 每条符号记录包含以下三个部分信息: + *

+ *

+ * + * 本类使用 Java 记录类型(record)定义,自动生成构造方法、访问器方法(getters)、equals、hashCode 以及 toString 方法。 + * + * @param name 符号的名称 + * @param type 符号的类型 + * @param kind 符号的种类 */ public record Symbol(String name, Type type, SymbolKind kind) { } diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/SymbolKind.java b/src/main/java/org/jcnc/snow/compiler/semantic/SymbolKind.java index 260aaa4..77ba174 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/SymbolKind.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/SymbolKind.java @@ -1,10 +1,25 @@ package org.jcnc.snow.compiler.semantic; /** - * 符号的种类枚举,用于区分变量、函数和模块等不同符号类型。 + * 表示符号的种类(Symbol Kind)。 + *

+ * 用于在符号表中区分不同类型的符号,例如变量、函数、模块等。 + *

+ * + * 支持的符号种类包括: + * */ public enum SymbolKind { + /** 变量符号,例如局部变量、全局变量等。 */ VARIABLE, + + /** 函数符号,表示一个可调用的功能单元。 */ FUNCTION, + + /** 模块符号,表示一个模块或命名空间。 */ MODULE } diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/SymbolTable.java b/src/main/java/org/jcnc/snow/compiler/semantic/SymbolTable.java index 80bf154..c5b8ae1 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/SymbolTable.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/SymbolTable.java @@ -4,18 +4,40 @@ import java.util.HashMap; import java.util.Map; /** - * 符号表,支持链式作用域查找,通过 parent 引用形成作用域嵌套。 + * 符号表(Symbol Table),用于管理符号(如变量、函数、模块等)及其作用域信息。 + *

+ * 支持链式作用域(Nested Scope)管理: + *

+ *

*/ public class SymbolTable { + /** 父作用域符号表,如果为 null 则表示当前为最外层作用域。 */ private final SymbolTable parent; + + /** 当前作用域中定义的符号集合,按名称索引。 */ private final Map symbols = new HashMap<>(); + /** + * 创建一个新的符号表,并指定其父作用域。 + * + * @param parent 父符号表,若无父作用域则传入 null + */ public SymbolTable(SymbolTable parent) { this.parent = parent; } /** - * 在当前作用域中定义一个符号。如已存在同名符号,则返回 false。 + * 在当前作用域中定义一个新的符号。 + *

+ * 如果当前作用域中已存在同名符号,则定义失败并返回 {@code false}; + * 否则,将符号添加到符号表中并返回 {@code true}。 + *

+ * + * @param symbol 要定义的符号 + * @return 是否定义成功,若名称冲突则返回 {@code false} */ public boolean define(Symbol symbol) { if (symbols.containsKey(symbol.name())) { @@ -26,7 +48,18 @@ public class SymbolTable { } /** - * 查找一个符号,先从当前作用域开始,若未找到则向上查找父作用域。 + * 根据名称查找符号。 + *

+ * 查找顺序为: + *

    + *
  1. 先在当前作用域中查找。
  2. + *
  3. 如果当前作用域未找到,递归向父作用域查找。
  4. + *
  5. 若最终未找到,返回 {@code null}。
  6. + *
+ *

+ * + * @param name 要查找的符号名称 + * @return 找到的符号对象;如果不存在则返回 {@code null} */ public Symbol resolve(String name) { Symbol sym = symbols.get(name);