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 f438719..cfd244e 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 @@ -1,10 +1,7 @@ package org.jcnc.snow.compiler.parser.module; import org.jcnc.snow.compiler.lexer.token.TokenType; -import org.jcnc.snow.compiler.parser.ast.DeclarationNode; -import org.jcnc.snow.compiler.parser.ast.FunctionNode; -import org.jcnc.snow.compiler.parser.ast.ImportNode; -import org.jcnc.snow.compiler.parser.ast.ModuleNode; +import org.jcnc.snow.compiler.parser.ast.*; import org.jcnc.snow.compiler.parser.ast.base.NodeContext; import org.jcnc.snow.compiler.parser.base.TopLevelParser; import org.jcnc.snow.compiler.parser.context.ParserContext; @@ -12,47 +9,33 @@ import org.jcnc.snow.compiler.parser.context.TokenStream; import org.jcnc.snow.compiler.parser.context.UnexpectedToken; import org.jcnc.snow.compiler.parser.function.FunctionParser; import org.jcnc.snow.compiler.parser.statement.DeclarationStatementParser; +import org.jcnc.snow.compiler.parser.struct.StructParser; import java.util.ArrayList; import java.util.List; /** - * {@code ModuleParser} 负责解析源码中的模块结构,是顶层结构解析器实现之一。 + * {@code ModuleParser} *

- * 模块定义可包含多个导入(import)语句、globals 全局声明和函数定义(function), - * 导入语句可在模块中任意位置出现,且允许模块体中穿插任意数量的空行(空行会被自动忽略,不影响语法结构)。 - *

- * - *

- * 典型模块语法结构: - *

- * module: mymod
- *   import ...
- *   globals:
- *     declare ...
- *   function ...
- *   ...
- * end module
- * 
+ * 顶层结构解析器:负责解析整个源码模块(module ... end module)。 + * *

*/ public class ModuleParser implements TopLevelParser { /** - * 解析一个模块定义块,返回完整的 {@link ModuleNode} 语法树节点。 + * 解析一个完整的模块定义块,返回 AST {@link ModuleNode}。 *

- * 解析过程包括: - *

    - *
  1. 匹配模块声明起始 {@code module: IDENTIFIER}。
  2. - *
  3. 收集模块体内所有 import、globals 和 function 语句,允许穿插空行。
  4. - *
  5. 匹配模块结束 {@code end module}。
  6. - *
- * 若遇到未识别的语句,将抛出 {@link UnexpectedToken} 异常,定位错误位置和原因。 + * 支持空行,允许导入、全局、结构体、函数等多种区块混排。 *

* - * @param ctx 当前解析上下文(包含词法流等状态) - * @return 解析得到的 {@link ModuleNode} 实例 - * @throws UnexpectedToken 当模块体中出现未识别的顶层语句时抛出 + * @param ctx 解析上下文(包含 TokenStream、文件名等信息) + * @return 解析生成的 ModuleNode + * @throws UnexpectedToken 当模块体中遇到不支持的顶层语句时抛出 */ @Override public ModuleNode parse(ParserContext ctx) { @@ -62,37 +45,53 @@ public class ModuleParser implements TopLevelParser { int column = ts.peek().getCol(); String file = ctx.getSourceName(); + // 1) 解析模块声明头部 ts.expect("module"); ts.expect(":"); String name = ts.expectType(TokenType.IDENTIFIER).getLexeme(); ts.expectType(TokenType.NEWLINE); + // 2) 初始化各类节点容器 + List structs = new ArrayList<>(); List imports = new ArrayList<>(); List globals = new ArrayList<>(); List functions = new ArrayList<>(); + // 3) 各子区块的专用解析器 + StructParser structParser = new StructParser(); ImportParser importParser = new ImportParser(); FunctionParser funcParser = new FunctionParser(); DeclarationStatementParser globalsParser = new DeclarationStatementParser(); + // 4) 进入主循环,直到 end module while (true) { // 跳过空行 if (ts.peek().getType() == TokenType.NEWLINE) { ts.next(); continue; } + // 到达模块结尾 if ("end".equals(ts.peek().getLexeme())) { break; } String lex = ts.peek().getLexeme(); switch (lex) { + // 解析 import 语句(可多次出现,支持 import 多个模块) case "import" -> imports.addAll(importParser.parse(ctx)); + + // 解析 struct 结构体定义块 + case "struct" -> structs.add(structParser.parse(ctx)); + + // 解析 function 顶层函数定义 case "function" -> functions.add(funcParser.parse(ctx)); + + // 解析全局变量声明区块 case "globals" -> { ts.expect("globals"); ts.expect(":"); ts.expectType(TokenType.NEWLINE); while (true) { + // 跳过空行 if (ts.peek().getType() == TokenType.NEWLINE) { ts.next(); continue; @@ -100,9 +99,13 @@ public class ModuleParser implements TopLevelParser { String innerLex = ts.peek().getLexeme(); if ("declare".equals(innerLex)) { globals.add(globalsParser.parse(ctx)); - } else if ("function".equals(innerLex) || "import".equals(innerLex) || "end".equals(innerLex)) { + } + // 下一个 function/import/end 开头则结束 globals 区块 + else if ("function".equals(innerLex) || "import".equals(innerLex) || "end".equals(innerLex)) { break; - } else { + } + // 其余标记为非法内容,抛出异常 + else { throw new UnexpectedToken( "globals 区块中不支持的内容: " + innerLex, ts.peek().getLine(), @@ -111,6 +114,7 @@ public class ModuleParser implements TopLevelParser { } } } + // 未知或非法顶层内容 case null, default -> throw new UnexpectedToken( "Unexpected token in module: " + lex, ts.peek().getLine(), @@ -119,9 +123,11 @@ public class ModuleParser implements TopLevelParser { } } + // 5) 匹配模块结尾 "end module" ts.expect("end"); ts.expect("module"); - return new ModuleNode(name, imports, globals, functions, new NodeContext(line, column, file)); + // 6) 构造并返回 ModuleNode + return new ModuleNode(name, imports, globals, structs, functions, new NodeContext(line, column, file)); } }