feat: 增加结构体定义解析并优化模块解析逻辑
- 添加 StructParser 解析器,支持结构体定义解析 - 重构 ModuleParser 解析逻辑,提高代码可读性和可维护性 - 优化模块解析流程,支持空行和灵活的语法结构 - 增加异常处理,提升错误提示的准确性和可读性
This commit is contained in:
parent
fea8e14245
commit
17b078b6f3
@ -1,10 +1,7 @@
|
|||||||
package org.jcnc.snow.compiler.parser.module;
|
package org.jcnc.snow.compiler.parser.module;
|
||||||
|
|
||||||
import org.jcnc.snow.compiler.lexer.token.TokenType;
|
import org.jcnc.snow.compiler.lexer.token.TokenType;
|
||||||
import org.jcnc.snow.compiler.parser.ast.DeclarationNode;
|
import org.jcnc.snow.compiler.parser.ast.*;
|
||||||
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.base.NodeContext;
|
import org.jcnc.snow.compiler.parser.ast.base.NodeContext;
|
||||||
import org.jcnc.snow.compiler.parser.base.TopLevelParser;
|
import org.jcnc.snow.compiler.parser.base.TopLevelParser;
|
||||||
import org.jcnc.snow.compiler.parser.context.ParserContext;
|
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.context.UnexpectedToken;
|
||||||
import org.jcnc.snow.compiler.parser.function.FunctionParser;
|
import org.jcnc.snow.compiler.parser.function.FunctionParser;
|
||||||
import org.jcnc.snow.compiler.parser.statement.DeclarationStatementParser;
|
import org.jcnc.snow.compiler.parser.statement.DeclarationStatementParser;
|
||||||
|
import org.jcnc.snow.compiler.parser.struct.StructParser;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code ModuleParser} 负责解析源码中的模块结构,是顶层结构解析器实现之一。
|
* {@code ModuleParser}
|
||||||
* <p>
|
* <p>
|
||||||
* 模块定义可包含多个导入(import)语句、globals 全局声明和函数定义(function),
|
* 顶层结构解析器:负责解析整个源码模块(module ... end module)。
|
||||||
* 导入语句可在模块中任意位置出现,且允许模块体中穿插任意数量的空行(空行会被自动忽略,不影响语法结构)。
|
* <ul>
|
||||||
* </p>
|
* <li>支持模块声明、导入(import)、全局变量(globals)、结构体(struct)、函数(function)等顶层语法。</li>
|
||||||
*
|
* <li>允许模块体中出现任意数量的空行(自动跳过),顺序自由。</li>
|
||||||
* <p>
|
* <li>遇到非法顶层语句或区块会抛出 {@link UnexpectedToken},提示具体位置和原因。</li>
|
||||||
* 典型模块语法结构:
|
* </ul>
|
||||||
* <pre>
|
|
||||||
* module: mymod
|
|
||||||
* import ...
|
|
||||||
* globals:
|
|
||||||
* declare ...
|
|
||||||
* function ...
|
|
||||||
* ...
|
|
||||||
* end module
|
|
||||||
* </pre>
|
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class ModuleParser implements TopLevelParser {
|
public class ModuleParser implements TopLevelParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析一个模块定义块,返回完整的 {@link ModuleNode} 语法树节点。
|
* 解析一个完整的模块定义块,返回 AST {@link ModuleNode}。
|
||||||
* <p>
|
* <p>
|
||||||
* 解析过程包括:
|
* 支持空行,允许导入、全局、结构体、函数等多种区块混排。
|
||||||
* <ol>
|
|
||||||
* <li>匹配模块声明起始 {@code module: IDENTIFIER}。</li>
|
|
||||||
* <li>收集模块体内所有 import、globals 和 function 语句,允许穿插空行。</li>
|
|
||||||
* <li>匹配模块结束 {@code end module}。</li>
|
|
||||||
* </ol>
|
|
||||||
* 若遇到未识别的语句,将抛出 {@link UnexpectedToken} 异常,定位错误位置和原因。
|
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param ctx 当前解析上下文(包含词法流等状态)
|
* @param ctx 解析上下文(包含 TokenStream、文件名等信息)
|
||||||
* @return 解析得到的 {@link ModuleNode} 实例
|
* @return 解析生成的 ModuleNode
|
||||||
* @throws UnexpectedToken 当模块体中出现未识别的顶层语句时抛出
|
* @throws UnexpectedToken 当模块体中遇到不支持的顶层语句时抛出
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ModuleNode parse(ParserContext ctx) {
|
public ModuleNode parse(ParserContext ctx) {
|
||||||
@ -62,37 +45,53 @@ public class ModuleParser implements TopLevelParser {
|
|||||||
int column = ts.peek().getCol();
|
int column = ts.peek().getCol();
|
||||||
String file = ctx.getSourceName();
|
String file = ctx.getSourceName();
|
||||||
|
|
||||||
|
// 1) 解析模块声明头部
|
||||||
ts.expect("module");
|
ts.expect("module");
|
||||||
ts.expect(":");
|
ts.expect(":");
|
||||||
String name = ts.expectType(TokenType.IDENTIFIER).getLexeme();
|
String name = ts.expectType(TokenType.IDENTIFIER).getLexeme();
|
||||||
ts.expectType(TokenType.NEWLINE);
|
ts.expectType(TokenType.NEWLINE);
|
||||||
|
|
||||||
|
// 2) 初始化各类节点容器
|
||||||
|
List<StructNode> structs = new ArrayList<>();
|
||||||
List<ImportNode> imports = new ArrayList<>();
|
List<ImportNode> imports = new ArrayList<>();
|
||||||
List<DeclarationNode> globals = new ArrayList<>();
|
List<DeclarationNode> globals = new ArrayList<>();
|
||||||
List<FunctionNode> functions = new ArrayList<>();
|
List<FunctionNode> functions = new ArrayList<>();
|
||||||
|
|
||||||
|
// 3) 各子区块的专用解析器
|
||||||
|
StructParser structParser = new StructParser();
|
||||||
ImportParser importParser = new ImportParser();
|
ImportParser importParser = new ImportParser();
|
||||||
FunctionParser funcParser = new FunctionParser();
|
FunctionParser funcParser = new FunctionParser();
|
||||||
DeclarationStatementParser globalsParser = new DeclarationStatementParser();
|
DeclarationStatementParser globalsParser = new DeclarationStatementParser();
|
||||||
|
|
||||||
|
// 4) 进入主循环,直到 end module
|
||||||
while (true) {
|
while (true) {
|
||||||
// 跳过空行
|
// 跳过空行
|
||||||
if (ts.peek().getType() == TokenType.NEWLINE) {
|
if (ts.peek().getType() == TokenType.NEWLINE) {
|
||||||
ts.next();
|
ts.next();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// 到达模块结尾
|
||||||
if ("end".equals(ts.peek().getLexeme())) {
|
if ("end".equals(ts.peek().getLexeme())) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
String lex = ts.peek().getLexeme();
|
String lex = ts.peek().getLexeme();
|
||||||
switch (lex) {
|
switch (lex) {
|
||||||
|
// 解析 import 语句(可多次出现,支持 import 多个模块)
|
||||||
case "import" -> imports.addAll(importParser.parse(ctx));
|
case "import" -> imports.addAll(importParser.parse(ctx));
|
||||||
|
|
||||||
|
// 解析 struct 结构体定义块
|
||||||
|
case "struct" -> structs.add(structParser.parse(ctx));
|
||||||
|
|
||||||
|
// 解析 function 顶层函数定义
|
||||||
case "function" -> functions.add(funcParser.parse(ctx));
|
case "function" -> functions.add(funcParser.parse(ctx));
|
||||||
|
|
||||||
|
// 解析全局变量声明区块
|
||||||
case "globals" -> {
|
case "globals" -> {
|
||||||
ts.expect("globals");
|
ts.expect("globals");
|
||||||
ts.expect(":");
|
ts.expect(":");
|
||||||
ts.expectType(TokenType.NEWLINE);
|
ts.expectType(TokenType.NEWLINE);
|
||||||
while (true) {
|
while (true) {
|
||||||
|
// 跳过空行
|
||||||
if (ts.peek().getType() == TokenType.NEWLINE) {
|
if (ts.peek().getType() == TokenType.NEWLINE) {
|
||||||
ts.next();
|
ts.next();
|
||||||
continue;
|
continue;
|
||||||
@ -100,9 +99,13 @@ public class ModuleParser implements TopLevelParser {
|
|||||||
String innerLex = ts.peek().getLexeme();
|
String innerLex = ts.peek().getLexeme();
|
||||||
if ("declare".equals(innerLex)) {
|
if ("declare".equals(innerLex)) {
|
||||||
globals.add(globalsParser.parse(ctx));
|
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;
|
break;
|
||||||
} else {
|
}
|
||||||
|
// 其余标记为非法内容,抛出异常
|
||||||
|
else {
|
||||||
throw new UnexpectedToken(
|
throw new UnexpectedToken(
|
||||||
"globals 区块中不支持的内容: " + innerLex,
|
"globals 区块中不支持的内容: " + innerLex,
|
||||||
ts.peek().getLine(),
|
ts.peek().getLine(),
|
||||||
@ -111,6 +114,7 @@ public class ModuleParser implements TopLevelParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 未知或非法顶层内容
|
||||||
case null, default -> throw new UnexpectedToken(
|
case null, default -> throw new UnexpectedToken(
|
||||||
"Unexpected token in module: " + lex,
|
"Unexpected token in module: " + lex,
|
||||||
ts.peek().getLine(),
|
ts.peek().getLine(),
|
||||||
@ -119,9 +123,11 @@ public class ModuleParser implements TopLevelParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5) 匹配模块结尾 "end module"
|
||||||
ts.expect("end");
|
ts.expect("end");
|
||||||
ts.expect("module");
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user