diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ParserEngine.java b/src/main/java/org/jcnc/snow/compiler/parser/ParserEngine.java index b2605a2..581265c 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/ParserEngine.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/ParserEngine.java @@ -15,6 +15,7 @@ import java.util.List; * 同时自动跳过空行(NEWLINE)以增强容错性。 */ public class ParserEngine { + // 解析上下文对象,包含 TokenStream 及相关辅助功能 private final ParserContext ctx; /** @@ -33,25 +34,32 @@ public class ParserEngine { */ public List parse() { List nodes = new ArrayList<>(); - TokenStream ts = ctx.getTokens(); + TokenStream ts = ctx.getTokens(); // 获取 Token 流 - while (ts.isAtEnd()) { - // 跳过空行 + // 循环解析直到文件结束 + while (!ts.isAtEnd()) { + // 跳过空行,增加语法容错能力 if (ts.peek().getType() == TokenType.NEWLINE) { - ts.next(); + ts.next(); // 消耗空行 continue; } - // 根据当前关键字分发顶层解析器 + // 获取当前标记(如 module, import, function) String lex = ts.peek().getLexeme(); + + // 通过工厂方法获得对应的顶层解析器 TopLevelParser parser = TopLevelParserFactory.get(lex); + + // 如果找不到对应解析器,说明语法结构非法或暂不支持 if (parser == null) { throw new IllegalStateException("意外的顶级标记: " + lex); } + // 使用解析器解析该顶层结构,添加到结果列表中 nodes.add(parser.parse(ctx)); } + // 返回构建的 AST 节点集合 return nodes; } } diff --git a/src/main/java/org/jcnc/snow/compiler/parser/TopLevelParser.java b/src/main/java/org/jcnc/snow/compiler/parser/TopLevelParser.java index 63c4e0a..ca70923 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/TopLevelParser.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/TopLevelParser.java @@ -4,16 +4,20 @@ import org.jcnc.snow.compiler.parser.ast.Node; import org.jcnc.snow.compiler.parser.context.ParserContext; /** - * 顶层结构解析器接口,用于解析模块级别的语法结构,如 {@code module}、{@code import} 等。 - * 所有顶层解析器应实现该接口。 + * 顶层结构解析器接口,用于解析模块级别的语法结构,如 {@code module}、{@code import}、{@code function} 等。 + * 所有顶层解析器应实现该接口,并从 {@link ParserContext} 中读取 TokenStream 来构造 AST 节点。 + *

+ * 该接口由 {@link org.jcnc.snow.compiler.parser.factory.TopLevelParserFactory} 根据当前关键字动态调度。 */ public interface TopLevelParser { /** * 从解析上下文中解析一个顶层语法结构。 + * 每个实现应从 TokenStream 中消费对应的 token,并返回构建后的 AST 节点。 * - * @param ctx 当前解析上下文。 - * @return 表示顶层结构的 AST 节点。 + * @param ctx 当前解析上下文,包含 Token 流与状态信息。 + * @return 表示顶层结构的 AST 节点,不应为 null。 + * @throws IllegalStateException 如果遇到非法语法结构。 */ Node parse(ParserContext ctx); } diff --git a/src/main/java/org/jcnc/snow/compiler/parser/factory/TopLevelParserFactory.java b/src/main/java/org/jcnc/snow/compiler/parser/factory/TopLevelParserFactory.java index 99b7d35..0b9efa9 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/factory/TopLevelParserFactory.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/factory/TopLevelParserFactory.java @@ -9,15 +9,20 @@ import java.util.HashMap; /** * 顶层解析器工厂类,用于根据文件开头的关键字(如 {@code module})分发对应的顶层结构解析器。 * 每种顶层结构(模块、导入等)应有一个专门的 {@link TopLevelParser} 实现类。 + * + *

该类采用静态注册机制,在类加载时将所有支持的关键字及其解析器实例注册到内部映射表中。 + * 外部通过 {@link #get(String)} 方法获取对应的解析器。

+ * + *

用于 {@link org.jcnc.snow.compiler.parser.ParserEngine} 中,根据关键字动态解析不同语法块。

*/ public class TopLevelParserFactory { + // 存储关键字 -> 解析器 实例的映射关系 private static final Map registry = new HashMap<>(); static { - // 注册模块解析器 + // 注册模块解析器,关键字 "module" 映射到 ModuleParser 实例 registry.put("module", new ModuleParser()); - // import、package 在此添加注册项 } /** diff --git a/src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java b/src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java index 5a8a018..40f9346 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java @@ -34,43 +34,58 @@ public class ModuleParser implements TopLevelParser { @Override public ModuleNode parse(ParserContext ctx) { TokenStream ts = ctx.getTokens(); + + // 期望以 "module" 开头 ts.expect("module"); ts.expect(":"); + + // 读取模块名称(标识符) String name = ts.expectType(TokenType.IDENTIFIER).getLexeme(); + + // 模块声明后的换行 ts.expectType(TokenType.NEWLINE); + // 初始化导入列表与函数列表 List imports = new ArrayList<>(); List functions = new ArrayList<>(); + + // 创建导入语句和函数解析器 ImportParser importParser = new ImportParser(); FunctionParser funcParser = new FunctionParser(); - // 解析模块体:包含 import 和 function 语句 + // 解析模块主体内容(支持多个 import 和 function 语句) while (true) { - // 跳过空行 + // 跳过空行(多个空行不会导致错误) 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" 结尾 ts.expect("end"); ts.expect("module"); ts.expectType(TokenType.NEWLINE); + // 返回构建完成的模块语法树节点 return new ModuleNode(name, imports, functions); } }