feat: 支持模块成员访问的语义分析
- 实现了跨模块常量和全局变量访问的语义分析- 能根据目标模块的全局符号表返回准确的类型信息- 完全支持跨模块类型推断 - 对非模块成员访问的情况增加了错误处理
This commit is contained in:
parent
439304c86a
commit
f39aece9cf
@ -8,35 +8,42 @@ import org.jcnc.snow.compiler.semantic.analyzers.base.ExpressionAnalyzer;
|
||||
import org.jcnc.snow.compiler.semantic.core.Context;
|
||||
import org.jcnc.snow.compiler.semantic.core.ModuleInfo;
|
||||
import org.jcnc.snow.compiler.semantic.error.SemanticError;
|
||||
import org.jcnc.snow.compiler.semantic.symbol.Symbol;
|
||||
import org.jcnc.snow.compiler.semantic.symbol.SymbolTable;
|
||||
import org.jcnc.snow.compiler.semantic.type.BuiltinType;
|
||||
import org.jcnc.snow.compiler.semantic.type.Type;
|
||||
|
||||
/**
|
||||
* {@code MemberExpressionAnalyzer} – 成员访问表达式的语义分析器。
|
||||
* {@code MemberExpressionAnalyzer} 用于分析模块成员访问表达式的类型和语义。
|
||||
*
|
||||
* <p>
|
||||
* 当前实现仅支持 <code>ModuleName.constOrVar</code> 形式的跨模块常量 /
|
||||
* 全局变量访问,不支持对象成员(如 a.b.c)。
|
||||
* 当前实现支持 <code>ModuleName.constOrVar</code> 形式的跨模块常量/全局变量访问,
|
||||
* 能根据目标模块的全局符号表,返回准确的类型信息,完全支持跨模块类型推断。
|
||||
* <br>
|
||||
* 对于非模块成员的访问(如对象.属性、多级 a.b.c),暂不支持,遇到时将报告语义错误。
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <b>核心特性:</b>
|
||||
* <ul>
|
||||
* <li>示例:ModuleA.a 或 ModuleB.CONST_X</li>
|
||||
* <li>仅检查模块是否存在且已导入,类型降级为 int,后续由 IR 阶段常量折叠</li>
|
||||
* <li>暂不支持复杂的对象/类型成员访问</li>
|
||||
* <li>校验模块是否存在、是否已导入(或自身);</li>
|
||||
* <li>跨模块访问目标模块的全局符号表,查找指定成员符号及其类型;</li>
|
||||
* <li>若成员不存在,报告“模块成员未定义”语义错误;</li>
|
||||
* <li>暂不支持更复杂的对象成员访问,遇到将报“不支持的成员访问对象类型”错误。</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class MemberExpressionAnalyzer implements ExpressionAnalyzer<MemberExpressionNode> {
|
||||
|
||||
/**
|
||||
* 对成员访问表达式执行语义分析。
|
||||
* 语义分析模块成员访问表达式。
|
||||
*
|
||||
* @param ctx 全局语义上下文,包含模块表、错误收集等
|
||||
* @param mi 当前模块信息(含本模块名、已导入模块)
|
||||
* @param fn 当前所在函数节点
|
||||
* @param locals 当前作用域符号表
|
||||
* @param expr 当前要分析的成员表达式(如 ModuleA.a)
|
||||
* @return 分析推断得到的类型(目前恒定降级为 int),如有错误也会记录
|
||||
* @param ctx 全局语义分析上下文,持有所有模块及错误记录
|
||||
* @param mi 当前模块信息(用于判断导入关系)
|
||||
* @param fn 当前函数节点
|
||||
* @param locals 当前局部符号表
|
||||
* @param expr 当前要分析的成员表达式(如 ModuleA.a)
|
||||
* @return 成员表达式的类型;出错时类型降级为 int,并记录语义错误
|
||||
*/
|
||||
@Override
|
||||
public Type analyze(Context ctx,
|
||||
@ -47,29 +54,41 @@ public class MemberExpressionAnalyzer implements ExpressionAnalyzer<MemberExpres
|
||||
|
||||
ctx.log("检查成员访问: " + expr);
|
||||
|
||||
/* ---------- 仅支持 ModuleName.member 形式 ---------- */
|
||||
// -------- 仅支持 ModuleName.member 形式 --------
|
||||
if (expr.object() instanceof IdentifierNode(String mod, NodeContext _)) {
|
||||
|
||||
// 1. 检查模块是否存在、且已在当前模块 import 或为本模块
|
||||
// 1. 校验模块存在且已导入或为本模块自身
|
||||
if (!ctx.getModules().containsKey(mod)
|
||||
|| (!mi.getImports().contains(mod) && !mi.getName().equals(mod))) {
|
||||
ctx.getErrors().add(new SemanticError(expr,
|
||||
"未知或未导入模块: " + mod));
|
||||
ctx.log("错误: 未导入模块 " + mod);
|
||||
return BuiltinType.INT; // 语义降级:默认 int
|
||||
return BuiltinType.INT;
|
||||
}
|
||||
|
||||
// 2. 目前不做类型精确推断。后续可解析目标模块 globals 获取精确类型。
|
||||
// 这里只做语法级校验,类型降级为 INT,由后续阶段折叠。
|
||||
// 2. 查找目标模块的全局符号表,精确返回成员类型
|
||||
ModuleInfo target = ctx.getModules().get(mod);
|
||||
SymbolTable globals = target.getGlobals();
|
||||
if (globals != null) {
|
||||
Symbol sym = globals.resolve(expr.member());
|
||||
if (sym != null) {
|
||||
return sym.type(); // 找到成员,返回其真实类型
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 成员不存在,记录语义错误并类型降级
|
||||
ctx.getErrors().add(new SemanticError(expr,
|
||||
"模块成员未定义: " + mod + "." + expr.member()));
|
||||
ctx.log("错误: 模块成员未定义 " + mod + "." + expr.member());
|
||||
return BuiltinType.INT;
|
||||
}
|
||||
|
||||
/* ---------- 其它对象成员(如 a.b.c)暂不支持 ---------- */
|
||||
// -------- 其它对象成员(如 a.b.c)暂不支持 --------
|
||||
ctx.getErrors().add(new SemanticError(expr,
|
||||
"不支持的成员访问对象类型: "
|
||||
+ expr.object().getClass().getSimpleName()));
|
||||
ctx.log("错误: 不支持的成员访问对象类型 "
|
||||
+ expr.object().getClass().getSimpleName());
|
||||
return BuiltinType.INT; // 语义降级
|
||||
return BuiltinType.INT;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user