From a64209c2116987c2f2a34c74cba7c92e2e8470ac Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 25 Jun 2025 14:39:18 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E8=AF=AD=E4=B9=89=E5=88=86?= =?UTF-8?q?=E6=9E=90=E6=94=AF=E6=8C=81=E5=B8=83=E5=B0=94=E5=80=BC=E6=AF=94?= =?UTF-8?q?=E8=BE=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../expression/BinaryExpressionAnalyzer.java | 60 +++++++++---------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/BinaryExpressionAnalyzer.java b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/BinaryExpressionAnalyzer.java index 2bc22de..c14b83b 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/BinaryExpressionAnalyzer.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/BinaryExpressionAnalyzer.java @@ -11,79 +11,75 @@ import org.jcnc.snow.compiler.semantic.type.BuiltinType; import org.jcnc.snow.compiler.semantic.type.Type; /** - * {@code BinaryExpressionAnalyzer} 是一个用于分析二元表达式的语义分析器。 + * {@code BinaryExpressionAnalyzer} 负责对二元表达式做语义分析并返回其类型。 *

- * 支持的特性包括: - *

- * 对于不支持的运算符或不兼容的类型组合,将记录语义错误,并默认返回 {@code BuiltinType.INT} 以保持分析过程的连续性。 + * 支持特性: + * 1. 字符串拼接「+」 + * 2. 数值运算与自动宽化 + * 3. 比较 / 关系运算 + * 4. 布尔值比较(== / !=) *

- * 实现类遵循 {@code ExpressionAnalyzer} 接口规范。 + * 如遇不支持的运算符或不兼容的类型组合,将记录语义错误, + * 并以 {@code int} 作为回退类型,保持后续分析不中断。 */ public class BinaryExpressionAnalyzer implements ExpressionAnalyzer { - /** - * 分析给定的二元表达式节点,返回其表达式类型。 - * - * @param ctx 当前语义分析上下文,用于访问日志记录、错误收集、注册表等服务。 - * @param mi 当前模块信息,包含模块级别的符号与类型定义。 - * @param fn 当前正在分析的函数节点。 - * @param locals 当前函数作用域内的符号表,用于变量查找。 - * @param bin 要分析的二元表达式节点。 - * @return 分析后推断出的表达式类型。 - */ @Override public Type analyze(Context ctx, ModuleInfo mi, FunctionNode fn, SymbolTable locals, BinaryExpressionNode bin) { + ctx.log("检查二元表达式: " + bin.operator()); - // 获取左侧表达式类型 - Type left = ctx.getRegistry().getExpressionAnalyzer(bin.left()) + /* ----------- 先递归分析左右子表达式类型 ----------- */ + Type left = ctx.getRegistry() + .getExpressionAnalyzer(bin.left()) .analyze(ctx, mi, fn, locals, bin.left()); - // 获取右侧表达式类型 - Type right = ctx.getRegistry().getExpressionAnalyzer(bin.right()) + Type right = ctx.getRegistry() + .getExpressionAnalyzer(bin.right()) .analyze(ctx, mi, fn, locals, bin.right()); String op = bin.operator(); - // 情况 1:字符串拼接(+ 操作符且任一操作数为字符串类型) + /* ----------- 情况 1:字符串拼接 ----------- */ if (op.equals("+") && (left == BuiltinType.STRING || right == BuiltinType.STRING)) { return BuiltinType.STRING; } - // 情况 2:数值类型运算或比较 + /* ----------- 情况 1.5:布尔值比较 ----------- */ + if (("==".equals(op) || "!=".equals(op)) && + left == BuiltinType.BOOLEAN && + right == BuiltinType.BOOLEAN) { + return BuiltinType.BOOLEAN; + } + + /* ----------- 情况 2:数值运算 / 比较 ----------- */ if ("+-*/%".contains(op) || ("<<=>>===!=").contains(op)) { if (left.isNumeric() && right.isNumeric()) { - // 自动宽化到更宽的数值类型(如 int + float => float) + // 自动数值宽化(如 int + float → float) Type wide = Type.widen(left, right); - if (wide == null) wide = BuiltinType.INT; // 容错降级为 int + if (wide == null) wide = BuiltinType.INT; // 容错降级 - // 若为比较运算符,统一返回 boolean 类型作为布尔值表示 + // 比较运算统一返回 boolean if ("< <= > >= == !=".contains(op)) { return BuiltinType.BOOLEAN; } - return wide; } } - // 情况 3:不支持的类型组合,记录语义错误 + /* ----------- 情况 3:不支持的类型组合 ----------- */ ctx.getErrors().add(new SemanticError( bin, String.format("运算符 '%s' 不支持类型: %s 和 %s", op, left, right) )); ctx.log("错误: 运算符 '" + op + "' 不支持类型: " + left + ", " + right); - // 错误情况下默认返回 int 类型,以保证语义分析不中断 + // 回退类型 return BuiltinType.INT; } }