functions = new ArrayList<>();
- // 创建导入语句和函数解析器
+ // 创建 import 与 function 的子解析器
ImportParser importParser = new ImportParser();
FunctionParser funcParser = new FunctionParser();
- // 解析模块主体内容(支持多个 import 和 function 语句)
+ // 进入模块主体内容解析循环
while (true) {
- // 跳过空行(多个空行不会导致错误)
+ // 跳过所有空行(即连续的 NEWLINE)
if (ts.peek().getType() == TokenType.NEWLINE) {
ts.next();
continue;
}
- // 模块体结束判断:遇到 "end" 关键字
+ // 若遇到 "end",则表明模块定义结束
if ("end".equals(ts.peek().getLexeme())) {
break;
}
- // 判断当前行的语法元素,调用相应解析器
+ // 根据当前行首关键字决定解析器的选择
String lex = ts.peek().getLexeme();
if ("import".equals(lex)) {
- // 添加解析后的导入语句节点
+ // 调用导入语句解析器,解析多个模块导入节点
imports.addAll(importParser.parse(ctx));
} else if ("function".equals(lex)) {
- // 添加解析后的函数节点
+ // 调用函数定义解析器,解析单个函数结构
functions.add(funcParser.parse(ctx));
} else {
- // 非法语法,抛出异常提示位置与原因
+ // 遇到无法识别的语句开头,抛出异常并提供详细提示
throw new IllegalStateException("Unexpected token in module: " + lex);
}
}
- // 解析模块结尾结构,确保以 "end module" 结尾
+ // 确保模块体以 "end module" 结束
ts.expect("end");
ts.expect("module");
ts.expectType(TokenType.NEWLINE);
- // 返回构建完成的模块语法树节点
+ // 构建并返回完整的模块语法树节点
return new ModuleNode(name, imports, functions);
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/DeclarationStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/DeclarationStatementParser.java
index 7ec9fe6..b99d09c 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/statement/DeclarationStatementParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/DeclarationStatementParser.java
@@ -7,47 +7,68 @@ import org.jcnc.snow.compiler.parser.context.ParserContext;
import org.jcnc.snow.compiler.parser.expression.PrattExpressionParser;
/**
- * 解析变量声明语句的解析器。
- * 支持语法格式:
+ * {@code DeclarationStatementParser} 类负责解析变量声明语句,是语句级解析器的一部分。
+ *
+ * 本解析器支持以下两种形式的声明语法:
*
{@code
- * declare name:type
- * declare name:type = expression
+ * declare myVar:Integer
+ * declare myVar:Integer = 42 + 3
* }
- * 每条语句必须以换行(NEWLINE)结束。
+ * 其中:
+ *
+ * - {@code myVar} 为变量名(必须为标识符类型);
+ * - {@code Integer} 为类型标注(必须为类型标记);
+ * - 可选的初始化表达式由 {@link PrattExpressionParser} 解析;
+ * - 每条声明语句必须以换行符({@code NEWLINE})结束。
+ *
+ * 若语法不满足上述结构,将在解析过程中抛出异常。
*/
public class DeclarationStatementParser implements StatementParser {
/**
- * 解析一条 declare 声明语句。
+ * 解析一条 {@code declare} 声明语句,并返回对应的抽象语法树节点 {@link DeclarationNode}。
+ *
+ * 解析流程如下:
+ *
+ * - 匹配关键字 {@code declare};
+ * - 读取变量名称(标识符类型);
+ * - 读取类型标注(在冒号后,要求为 {@code TYPE} 类型);
+ * - 若存在 {@code =},则继续解析其后的表达式作为初始化值;
+ * - 最终必须匹配 {@code NEWLINE} 表示语句结束。
+ *
+ * 若遇到非法语法结构,将触发异常并中断解析过程。
*
- * @param ctx 当前解析上下文。
- * @return 构造好的 {@link DeclarationNode} AST 节点。
+ * @param ctx 当前语法解析上下文,包含词法流、错误信息等。
+ * @return 返回一个 {@link DeclarationNode} 节点,表示解析完成的声明语法结构。
*/
@Override
public DeclarationNode parse(ParserContext ctx) {
+ // 声明语句必须以 "declare" 开头
ctx.getTokens().expect("declare");
- // 获取变量名
+ // 获取变量名称(标识符)
String name = ctx.getTokens()
.expectType(TokenType.IDENTIFIER)
.getLexeme();
+ // 类型标注的冒号分隔符
ctx.getTokens().expect(":");
- // 获取变量类型
+ // 获取变量类型(类型标识符)
String type = ctx.getTokens()
.expectType(TokenType.TYPE)
.getLexeme();
- // 可选初始化表达式
+ // 可选的初始化表达式,若存在 "=",则解析等号右侧表达式
ExpressionNode init = null;
if (ctx.getTokens().match("=")) {
init = new PrattExpressionParser().parse(ctx);
}
- // 声明语句必须以 NEWLINE 结束
+ // 声明语句必须以换行符结尾
ctx.getTokens().expectType(TokenType.NEWLINE);
+ // 返回构建好的声明语法树节点
return new DeclarationNode(name, type, init);
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java
index 37eb095..dd9df94 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java
@@ -10,46 +10,61 @@ import org.jcnc.snow.compiler.parser.context.TokenStream;
import org.jcnc.snow.compiler.parser.expression.PrattExpressionParser;
/**
- * 表达式语句解析器:将赋值表达式或任意表达式作为语句进行解析。
- * 支持的形式包括:
- *
- * identifier = expression
- * expression
- *
- * 两者都必须以换行(NEWLINE)结尾。
+ * {@code ExpressionStatementParser} 负责解析通用表达式语句,包括赋值语句和单一表达式语句。
+ *
+ * 支持的语法结构如下:
+ *
{@code
+ * x = 1 + 2 // 赋值语句
+ * doSomething() // 函数调用等普通表达式语句
+ * }
+ *
+ * - 若以标识符开头,且后接等号 {@code =},则视为赋值语句,解析为 {@link AssignmentNode}。
+ * - 否则视为普通表达式,解析为 {@link ExpressionStatementNode}。
+ * - 所有表达式语句必须以换行符 {@code NEWLINE} 结束。
+ *
+ * 不允许以关键字或空行作为表达式的起始,若遇到非法开头,将抛出解析异常。
*/
public class ExpressionStatementParser implements StatementParser {
/**
- * 解析一个表达式语句,可能是赋值语句或普通表达式。
+ * 解析一个表达式语句,根据上下文决定其为赋值或一般表达式。
+ *
+ * 具体逻辑如下:
+ *
+ * - 若当前行为标识符后接等号,则作为赋值处理。
+ * - 否则解析整个表达式作为单独语句。
+ * - 所有语句都必须以换行符结束。
+ * - 若表达式以关键字或空行开头,将立即抛出异常,避免非法解析。
+ *
*
- * @param ctx 当前的解析上下文。
- * @return 表达式语句节点或赋值语句节点。
+ * @param ctx 当前解析上下文,提供词法流与状态信息。
+ * @return 返回 {@link AssignmentNode} 或 {@link ExpressionStatementNode} 表示的语法节点。
+ * @throws IllegalStateException 若表达式起始为关键字或语法非法。
*/
@Override
public StatementNode parse(ParserContext ctx) {
TokenStream ts = ctx.getTokens();
- // 空行或非法起始符号,提前退出(安全防护)
+ // 快速检查:若遇空行或关键字开头,不可作为表达式语句
if (ts.peek().getType() == TokenType.NEWLINE || ts.peek().getType() == TokenType.KEYWORD) {
throw new IllegalStateException("Cannot parse expression starting with keyword: " + ts.peek().getLexeme());
}
- // 判断是否是赋值语句(形如:identifier = expr)
+ // 处理赋值语句:格式为 identifier = expression
if (ts.peek().getType() == TokenType.IDENTIFIER
&& ts.peek(1).getLexeme().equals("=")) {
- String varName = ts.next().getLexeme(); // consume identifier
- ts.expect("="); // consume '='
- ExpressionNode value = new PrattExpressionParser().parse(ctx);
- ts.expectType(TokenType.NEWLINE);
- return new AssignmentNode(varName, value);
+ String varName = ts.next().getLexeme(); // 消耗标识符
+ ts.expect("="); // 消耗等号
+ ExpressionNode value = new PrattExpressionParser().parse(ctx); // 解析表达式
+ ts.expectType(TokenType.NEWLINE); // 语句必须以换行符结束
+ return new AssignmentNode(varName, value); // 返回赋值节点
}
- // 普通表达式语句(如函数调用)
+ // 处理普通表达式语句,如函数调用、字面量、运算表达式等
ExpressionNode expr = new PrattExpressionParser().parse(ctx);
- ts.expectType(TokenType.NEWLINE);
- return new ExpressionStatementNode(expr);
+ ts.expectType(TokenType.NEWLINE); // 语句必须以换行符结束
+ return new ExpressionStatementNode(expr); // 返回表达式语句节点
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/IfStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/IfStatementParser.java
index 7c42555..f0e2498 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/statement/IfStatementParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/IfStatementParser.java
@@ -12,75 +12,96 @@ import java.util.ArrayList;
import java.util.List;
/**
- * 解析 if 语句:
+ * {@code IfStatementParser} 类负责解析 if 条件语句,是语句级解析器中的条件分支处理器。
*
- * 支持格式:
+ * 本解析器支持以下结构的条件语法:
+ *
{@code
* if then
- *
+ *
* [else
- * ]
+ * ]
* end if
+ * }
+ * 其中:
+ *
+ * - {@code } 为任意可解析的布尔或数值表达式,使用 {@link PrattExpressionParser} 解析;
+ * - {@code } 与 {@code } 可包含多条语句,自动跳过空行;
+ * - {@code else} 分支为可选,若存在,必须紧跟换行与语句;
+ * - {@code end if} 为终止标识,表示整个 if 语句块的结束。
+ *
+ * 所有语句的实际解析由 {@link StatementParserFactory} 根据关键词动态分派处理。
*/
public class IfStatementParser implements StatementParser {
+ /**
+ * 解析一条完整的 if 条件语句,返回语法树中对应的 {@link IfNode} 节点。
+ *
+ * 本方法支持 then 分支和可选的 else 分支,并确保以 {@code end if} 正确结尾。
+ * 在解析过程中自动跳过空行;遇到未知关键字或不符合预期的 token 时会抛出异常。
+ *
+ * @param ctx 当前的语法解析上下文,包含 token 流和语义环境。
+ * @return 构造完成的 {@link IfNode},包含条件表达式、then 分支和 else 分支语句列表。
+ * @throws IllegalStateException 若语法结构不完整或存在非法 token。
+ */
@Override
public IfNode parse(ParserContext ctx) {
- var ts = ctx.getTokens(); // 获取 Token 流管理器
+ var ts = ctx.getTokens(); // 获取 token 流引用
- ts.expect("if"); // 消费 "if" 关键字
+ // 消耗起始关键字 "if"
+ ts.expect("if");
- // 使用 Pratt 解析器解析布尔表达式或其他条件表达式
+ // 使用 Pratt 算法解析 if 条件表达式
var condition = new PrattExpressionParser().parse(ctx);
- // 消费 "then" 关键字和随后的换行符
+ // 条件表达式后必须紧跟 "then" 和换行
ts.expect("then");
ts.expectType(TokenType.NEWLINE);
- // 准备容器存储 then 和 else 分支的语句
+ // 初始化 then 和 else 分支语句列表
List thenBranch = new ArrayList<>();
List elseBranch = new ArrayList<>();
- // -------------------
- // 解析 THEN 分支语句
- // -------------------
+ // -------------------------
+ // 解析 THEN 分支语句块
+ // -------------------------
while (true) {
Token peek = ts.peek();
- // 忽略空行
+ // 跳过空行
if (peek.getType() == TokenType.NEWLINE) {
ts.next();
continue;
}
- // 检测是否进入 else 或 end,跳出 then 区块
+ // 遇到 else 或 end 表示 then 分支结束
if (peek.getType() == TokenType.KEYWORD &&
(peek.getLexeme().equals("else") || peek.getLexeme().equals("end"))) {
break;
}
- // 提取关键词,交由 StatementParserFactory 派发对应解析器
+ // 获取当前语句的关键字,调用工厂获取对应解析器
String keyword = peek.getType() == TokenType.KEYWORD ? peek.getLexeme() : "";
StatementNode stmt = StatementParserFactory.get(keyword).parse(ctx);
thenBranch.add(stmt);
}
- // -------------------
- // 解析 ELSE 分支语句
- // -------------------
+ // -------------------------
+ // 解析 ELSE 分支语句块(可选)
+ // -------------------------
if (ts.peek().getLexeme().equals("else")) {
- ts.next(); // 消费 "else"
- ts.expectType(TokenType.NEWLINE); // 消费换行
+ ts.next(); // 消耗 "else"
+ ts.expectType(TokenType.NEWLINE); // 消耗换行符
while (true) {
Token peek = ts.peek();
- // 忽略空行
+ // 跳过空行
if (peek.getType() == TokenType.NEWLINE) {
ts.next();
continue;
}
- // "end" 关键字表示 else 块结束
+ // "end" 表示 else 分支结束
if (peek.getType() == TokenType.KEYWORD && peek.getLexeme().equals("end")) {
break;
}
@@ -91,12 +112,14 @@ public class IfStatementParser implements StatementParser {
}
}
- // 统一消费 "end if" 和其后的换行
+ // -------------------------
+ // 统一结束处理:end if
+ // -------------------------
ts.expect("end");
ts.expect("if");
ts.expectType(TokenType.NEWLINE);
- // 构造 AST 节点,返回 IfNode 包含条件、then 分支、else 分支
+ // 构建并返回 IfNode,包含条件、then 分支和 else 分支
return new IfNode(condition, thenBranch, elseBranch);
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java
index b54c26f..583b5c9 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java
@@ -18,7 +18,9 @@ import java.util.List;
import java.util.Map;
/**
- * 用于解析 loop 语句块,支持如下结构:
+ * {@code LoopStatementParser} 类负责解析自定义结构化的 {@code loop} 语句块。
+ *
+ * 该语法结构参考了传统的 for-loop,并将其拆解为命名的语义区块:
*
{@code
* loop:
* initializer:
@@ -28,31 +30,53 @@ import java.util.Map;
* update:
* i = i + 1
* body:
- * ...语句...
+ * print(i)
* end body
* end loop
* }
- * 使用 FlexibleSectionParser 解析各区块,并统一入口出口处理。
+ *
+ * 各区块说明:
+ *
+ * - {@code initializer}:初始化语句,通常为变量声明。
+ * - {@code condition}:循环判断条件,必须为布尔或数值表达式。
+ * - {@code update}:每轮执行后更新逻辑,通常为赋值语句。
+ * - {@code body}:主执行语句块,支持任意多条语句。
+ *
+ * 本类依赖 {@link FlexibleSectionParser} 实现各区块的统一处理,确保结构明确、可扩展。
*/
public class LoopStatementParser implements StatementParser {
+ /**
+ * 解析 {@code loop} 语句块,构建出对应的 {@link LoopNode} 抽象语法树节点。
+ *
+ * 本方法会按顺序检查各个命名区块(可乱序书写),并分别绑定其对应语义解析器:
+ *
+ * - 通过 {@link ParserUtils#matchHeader} 匹配区块开头;
+ * - 通过 {@link FlexibleSectionParser} 派发区块逻辑;
+ * - 通过 {@link StatementParserFactory} 调用实际语句解析;
+ * - 最后以 {@code end loop} 表示结构终止。
+ *
+ *
+ * @param ctx 当前解析上下文。
+ * @return {@link LoopNode},包含初始化、条件、更新与循环体等信息。
+ */
@Override
public LoopNode parse(ParserContext ctx) {
TokenStream ts = ctx.getTokens();
- // 匹配 loop: 开头
+ // 匹配 loop: 起始语法
ParserUtils.matchHeader(ts, "loop");
- // 各区块中间值容器(模拟引用)
+ // 使用数组模拟引用以便在 lambda 中写入(Java 不支持闭包内修改局部变量)
final StatementNode[] initializer = new StatementNode[1];
final ExpressionNode[] condition = new ExpressionNode[1];
final AssignmentNode[] update = new AssignmentNode[1];
final List body = new ArrayList<>();
- // 构造区块定义
+ // 定义各命名区块的识别与处理逻辑
Map sections = new HashMap<>();
- // initializer 区块:解析初始化语句
+ // initializer 区块:仅支持一条语句,通常为 declare
sections.put("initializer", new FlexibleSectionParser.SectionDefinition(
ts1 -> ts1.peek().getLexeme().equals("initializer"),
(ctx1, ts1) -> {
@@ -62,7 +86,7 @@ public class LoopStatementParser implements StatementParser {
}
));
- // condition 区块:解析布尔条件表达式
+ // condition 区块:支持任意可解析为布尔的表达式
sections.put("condition", new FlexibleSectionParser.SectionDefinition(
ts1 -> ts1.peek().getLexeme().equals("condition"),
(ctx1, ts1) -> {
@@ -73,7 +97,7 @@ public class LoopStatementParser implements StatementParser {
}
));
- // update 区块:解析变量赋值表达式
+ // update 区块:目前仅支持单一变量赋值语句
sections.put("update", new FlexibleSectionParser.SectionDefinition(
ts1 -> ts1.peek().getLexeme().equals("update"),
(ctx1, ts1) -> {
@@ -87,14 +111,14 @@ public class LoopStatementParser implements StatementParser {
}
));
- // body 区块:解析语句块
+ // body 区块:支持多条语句,直到遇到 end body
sections.put("body", new FlexibleSectionParser.SectionDefinition(
ts1 -> ts1.peek().getLexeme().equals("body"),
(ctx1, ts1) -> {
ParserUtils.matchHeader(ts1, "body");
while (!(ts1.peek().getLexeme().equals("end") &&
- ts1.peek(1).getLexeme().equals("body"))) {
+ ts1.peek(1).getLexeme().equals("body"))) {
String keyword = ts1.peek().getType() == TokenType.KEYWORD
? ts1.peek().getLexeme()
: "";
@@ -109,13 +133,13 @@ public class LoopStatementParser implements StatementParser {
}
));
- // 使用 FlexibleSectionParser 解析所有结构部分
+ // 使用通用区块解析器处理各命名结构块
FlexibleSectionParser.parse(ctx, ts, sections);
- // 匹配 end loop
+ // 解析结尾的 end loop 标记
ParserUtils.matchFooter(ts, "loop");
- // 构造并返回 LoopNode 抽象语法树节点
+ // 返回构造完成的 LoopNode
return new LoopNode(initializer[0], condition[0], update[0], body);
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/ReturnStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/ReturnStatementParser.java
index b90ebbb..8a6a6a2 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/statement/ReturnStatementParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/ReturnStatementParser.java
@@ -7,35 +7,48 @@ import org.jcnc.snow.compiler.parser.context.ParserContext;
import org.jcnc.snow.compiler.parser.expression.PrattExpressionParser;
/**
- * 用于解析 return 语句。
- * 支持有无返回值两种形式:
+ * {@code ReturnStatementParser} 负责解析 return 语句,是语句级解析器的一部分。
+ *
+ * 支持以下两种 return 语句形式:
*
{@code
- * return
- * return expression
+ * return // 无返回值
+ * return expression // 带返回值
* }
- * 语句必须以换行符(NEWLINE)结束。
+ * 所有 return 语句都必须以换行符({@code NEWLINE})结束,返回值表达式(若存在)由 {@link PrattExpressionParser} 负责解析。
+ * 若语法结构不满足要求,将在解析过程中抛出异常。
*/
public class ReturnStatementParser implements StatementParser {
/**
- * 解析 return 语句并构建 {@link ReturnNode}。
+ * 解析一条 return 语句,并返回对应的 {@link ReturnNode} 抽象语法树节点。
+ *
+ * 解析逻辑如下:
+ *
+ * - 匹配起始关键字 {@code return}。
+ * - 判断其后是否为 {@code NEWLINE},若否则表示存在返回值表达式。
+ * - 使用 {@link PrattExpressionParser} 解析返回值表达式(若存在)。
+ * - 最后匹配换行符,标志语句结束。
+ *
*
- * @param ctx 当前解析上下文。
- * @return 表示 return 语句的 AST 节点。
+ * @param ctx 当前解析上下文,包含词法流与语法状态。
+ * @return 构造完成的 {@link ReturnNode},表示 return 语句的语法树节点。
*/
@Override
public ReturnNode parse(ParserContext ctx) {
+ // 消耗 "return" 关键字
ctx.getTokens().expect("return");
ExpressionNode expr = null;
- // 如果不是换行,说明有返回值
+ // 如果下一 token 不是换行符,说明存在返回值表达式
if (ctx.getTokens().peek().getType() != TokenType.NEWLINE) {
expr = new PrattExpressionParser().parse(ctx);
}
+ // return 语句必须以换行符结束
ctx.getTokens().expectType(TokenType.NEWLINE);
+ // 构建并返回 ReturnNode(可能为空表达式)
return new ReturnNode(expr);
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/StatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/StatementParser.java
index bc60558..edcc075 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/statement/StatementParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/StatementParser.java
@@ -4,16 +4,23 @@ import org.jcnc.snow.compiler.parser.context.ParserContext;
import org.jcnc.snow.compiler.parser.ast.base.StatementNode;
/**
- * 语句解析器接口,用于将解析上下文中的 Token 转换为 {@link StatementNode}。
- * 各类语句(如声明、赋值、条件、循环、返回等)均应实现该接口。
+ * {@code StatementParser} 是所有语句解析器的通用接口。
+ *
+ * 其职责是从给定的 {@link ParserContext} 中读取并分析当前语句,构造并返回相应的抽象语法树节点。
+ * 所有语句类型(如变量声明、赋值语句、控制结构、函数返回等)应提供对应的实现类。
+ *
+ *
+ * 通常,此接口的实现由 {@code StatementParserFactory} 根据当前关键字动态派发,用于解析模块体、
+ * 条件分支、循环体或其他语句块中的单条语句。
*/
public interface StatementParser {
/**
- * 从给定的解析上下文中解析出一个语句节点。
+ * 解析一条语句,将其从词法表示转换为结构化语法树节点。
*
- * @param ctx 当前的解析上下文。
- * @return 表示语句的 AST 节点。
+ * @param ctx 当前的解析上下文,提供 token 流、状态与符号环境等。
+ * @return 表示该语句的 AST 节点,类型为 {@link StatementNode} 或其子类。
+ * @throws IllegalStateException 若语法非法或结构不完整。
*/
StatementNode parse(ParserContext ctx);
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java b/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java
index 470c53e..df36075 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java
@@ -7,19 +7,32 @@ import org.jcnc.snow.compiler.parser.ast.base.Node;
import java.util.*;
/**
- * ASTJsonSerializer 工具类
+ * {@code ASTJsonSerializer} 是抽象语法树(AST)序列化工具类。
*
- * 将编译器生成的 AST(抽象语法树)节点列表转换为通用的 Map/List 结构
- * 并借助 JSONParser.toJson(Object) 方法序列化为 JSON 字符串。
+ * 该工具可将编译器内部构建的 AST 节点对象转换为通用的 {@code Map} 和 {@code List} 结构,
+ * 并可借助 {@code JSONParser.toJson(Object)} 方法将其序列化为 JSON 字符串,用于调试、
+ * 可视化或跨语言数据传输。
*
- * 支持的节点类型包括:ModuleNode、FunctionNode、DeclarationNode、
- * AssignmentNode、IfNode、LoopNode、ReturnNode、ExpressionStatementNode
- * 以及各种 ExpressionNode(如 BinaryExpressionNode、IdentifierNode 等)。
+ * 支持的节点类型包括:
+ *
+ * - {@link ModuleNode}
+ * - {@link FunctionNode}
+ * - {@link DeclarationNode}
+ * - {@link AssignmentNode}
+ * - {@link IfNode}
+ * - {@link LoopNode}
+ * - {@link ReturnNode}
+ * - {@link ExpressionStatementNode}
+ * - 各类 {@link ExpressionNode} 子类型,如 {@code BinaryExpressionNode}, {@code IdentifierNode} 等
+ *
*/
public class ASTJsonSerializer {
/**
- * 快速创建一个 LinkedHashMap,并写入 type 字段
+ * 创建包含 {@code type} 字段的节点 Map,用于标识节点类型。
+ *
+ * @param type 节点类型字符串。
+ * @return 一个初始化后的 Map 实例。
*/
private static Map newNodeMap(String type) {
Map m = new LinkedHashMap<>();
@@ -28,7 +41,11 @@ public class ASTJsonSerializer {
}
/**
- * 用于构建表达式节点的 Map
+ * 构建表达式节点的 Map 表示,支持动态键值对传参。
+ *
+ * @param type 表达式类型。
+ * @param kv 可变参数(key-value 键值对)。
+ * @return 表示表达式节点的 Map。
*/
private static Map exprMap(String type, Object... kv) {
Map m = new LinkedHashMap<>();
@@ -40,10 +57,10 @@ public class ASTJsonSerializer {
}
/**
- * 将 AST 根节点列表序列化为 JSON 字符串。
+ * 将 AST 根节点列表转换为 JSON 字符串。
*
- * @param ast 表示抽象语法树根节点的 List
- * @return 对应的 JSON 格式字符串
+ * @param ast 表示顶层语法树结构的节点列表。
+ * @return 对应的 JSON 字符串表示形式。
*/
public static String toJsonString(List ast) {
List