diff --git a/src/main/java/org/jcnc/snow/compiler/Main.java b/src/main/java/org/jcnc/snow/compiler/Main.java index d72325e..5571248 100644 --- a/src/main/java/org/jcnc/snow/compiler/Main.java +++ b/src/main/java/org/jcnc/snow/compiler/Main.java @@ -2,12 +2,16 @@ package org.jcnc.snow.compiler; import org.jcnc.snow.compiler.lexer.LexerEngine; import org.jcnc.snow.compiler.lexer.token.Token; +import org.jcnc.snow.compiler.lexer.utils.TokenPrinter; import org.jcnc.snow.compiler.parser.core.ParserEngine; import org.jcnc.snow.compiler.parser.ast.ModuleNode; import org.jcnc.snow.compiler.parser.context.ParserContext; import org.jcnc.snow.compiler.parser.ast.base.Node; +import org.jcnc.snow.compiler.parser.function.ASTPrinter; import org.jcnc.snow.compiler.semantic.core.SemanticAnalyzer; +import org.jcnc.snow.compiler.semantic.core.SemanticAnalyzerRunner; import org.jcnc.snow.compiler.semantic.error.SemanticError; +import org.jcnc.snow.compiler.semantic.utils.SemanticAnalysisReporter; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -15,6 +19,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; public class Main { public static void main(String[] args) throws IOException { @@ -31,30 +36,9 @@ public class Main { List ast = new ParserEngine(ctx).parse(); // 3. 语义分析 + SemanticAnalyzerRunner.runSemanticAnalysis(ast,true); - // 3. 语义分析 - // parse() 返回的是顶层 Node 列表,我们只关心 ModuleNode - List modules = new ArrayList<>(); - for (Node n : ast) { - if (n instanceof ModuleNode m) { - modules.add(m); - } - } - SemanticAnalyzer analyzer = new SemanticAnalyzer(true); - List errors = analyzer.analyze(modules); - - if (!errors.isEmpty()) { - System.err.println("语义分析发现错误:"); - for (SemanticError e : errors) { - System.err.println(" " + e); - } - // 遇到错误直接退出 - System.exit(1); - } else { - // 无错误时也打印一条成功信息 - System.out.println("语义分析通过,没有发现错误。"); - } // 打印 // System.out.println(source); diff --git a/src/main/java/org/jcnc/snow/compiler/parser/function/ASTPrinter.java b/src/main/java/org/jcnc/snow/compiler/parser/function/ASTPrinter.java index ead038e..27ce0fa 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/function/ASTPrinter.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/function/ASTPrinter.java @@ -4,8 +4,8 @@ import org.jcnc.snow.compiler.parser.ast.*; import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode; import org.jcnc.snow.compiler.parser.ast.base.Node; import org.jcnc.snow.compiler.parser.ast.base.StatementNode; -import org.jcnc.snow.compiler.parser.util.ASTJsonSerializer; -import org.jcnc.snow.compiler.parser.util.JsonFormatter; +import org.jcnc.snow.compiler.parser.utils.ASTJsonSerializer; +import org.jcnc.snow.compiler.parser.utils.JsonFormatter; import java.util.List; diff --git a/src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java b/src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java index 342f287..f142b5a 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java @@ -8,8 +8,8 @@ import org.jcnc.snow.compiler.parser.ast.base.StatementNode; import org.jcnc.snow.compiler.parser.context.ParserContext; import org.jcnc.snow.compiler.parser.context.TokenStream; import org.jcnc.snow.compiler.parser.factory.StatementParserFactory; -import org.jcnc.snow.compiler.parser.util.FlexibleSectionParser; -import org.jcnc.snow.compiler.parser.util.FlexibleSectionParser.SectionDefinition; +import org.jcnc.snow.compiler.parser.utils.FlexibleSectionParser; +import org.jcnc.snow.compiler.parser.utils.FlexibleSectionParser.SectionDefinition; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java index bb00165..b54c26f 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java @@ -9,8 +9,8 @@ import org.jcnc.snow.compiler.parser.context.ParserContext; import org.jcnc.snow.compiler.parser.context.TokenStream; import org.jcnc.snow.compiler.parser.expression.PrattExpressionParser; import org.jcnc.snow.compiler.parser.factory.StatementParserFactory; -import org.jcnc.snow.compiler.parser.util.FlexibleSectionParser; -import org.jcnc.snow.compiler.parser.util.ParserUtils; +import org.jcnc.snow.compiler.parser.utils.FlexibleSectionParser; +import org.jcnc.snow.compiler.parser.utils.ParserUtils; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/main/java/org/jcnc/snow/compiler/parser/util/ASTJsonSerializer.java b/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java similarity index 99% rename from src/main/java/org/jcnc/snow/compiler/parser/util/ASTJsonSerializer.java rename to src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java index 1b3c023..470c53e 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/util/ASTJsonSerializer.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java @@ -1,4 +1,4 @@ -package org.jcnc.snow.compiler.parser.util; +package org.jcnc.snow.compiler.parser.utils; import org.jcnc.snow.compiler.parser.ast.*; import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode; diff --git a/src/main/java/org/jcnc/snow/compiler/parser/util/FlexibleSectionParser.java b/src/main/java/org/jcnc/snow/compiler/parser/utils/FlexibleSectionParser.java similarity index 98% rename from src/main/java/org/jcnc/snow/compiler/parser/util/FlexibleSectionParser.java rename to src/main/java/org/jcnc/snow/compiler/parser/utils/FlexibleSectionParser.java index b99614e..b11a40e 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/util/FlexibleSectionParser.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/utils/FlexibleSectionParser.java @@ -1,4 +1,4 @@ -package org.jcnc.snow.compiler.parser.util; +package org.jcnc.snow.compiler.parser.utils; import org.jcnc.snow.compiler.lexer.token.TokenType; import org.jcnc.snow.compiler.parser.context.ParserContext; diff --git a/src/main/java/org/jcnc/snow/compiler/parser/util/JSONParser.java b/src/main/java/org/jcnc/snow/compiler/parser/utils/JSONParser.java similarity index 99% rename from src/main/java/org/jcnc/snow/compiler/parser/util/JSONParser.java rename to src/main/java/org/jcnc/snow/compiler/parser/utils/JSONParser.java index 9a52939..70330e0 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/util/JSONParser.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/utils/JSONParser.java @@ -1,4 +1,4 @@ -package org.jcnc.snow.compiler.parser.util; +package org.jcnc.snow.compiler.parser.utils; import java.util.*; import java.util.Map.Entry; diff --git a/src/main/java/org/jcnc/snow/compiler/parser/util/JsonFormatter.java b/src/main/java/org/jcnc/snow/compiler/parser/utils/JsonFormatter.java similarity index 98% rename from src/main/java/org/jcnc/snow/compiler/parser/util/JsonFormatter.java rename to src/main/java/org/jcnc/snow/compiler/parser/utils/JsonFormatter.java index 498f8ae..9ee8744 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/util/JsonFormatter.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/utils/JsonFormatter.java @@ -1,4 +1,4 @@ -package org.jcnc.snow.compiler.parser.util; +package org.jcnc.snow.compiler.parser.utils; /** * JSON 格式化工具类。 diff --git a/src/main/java/org/jcnc/snow/compiler/parser/util/ParserUtils.java b/src/main/java/org/jcnc/snow/compiler/parser/utils/ParserUtils.java similarity index 96% rename from src/main/java/org/jcnc/snow/compiler/parser/util/ParserUtils.java rename to src/main/java/org/jcnc/snow/compiler/parser/utils/ParserUtils.java index 7d24dc3..48c485b 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/util/ParserUtils.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/utils/ParserUtils.java @@ -1,4 +1,4 @@ -package org.jcnc.snow.compiler.parser.util; +package org.jcnc.snow.compiler.parser.utils; import org.jcnc.snow.compiler.lexer.token.TokenType; import org.jcnc.snow.compiler.parser.context.TokenStream; diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/core/SemanticAnalyzerRunner.java b/src/main/java/org/jcnc/snow/compiler/semantic/core/SemanticAnalyzerRunner.java new file mode 100644 index 0000000..904838b --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/semantic/core/SemanticAnalyzerRunner.java @@ -0,0 +1,31 @@ +package org.jcnc.snow.compiler.semantic.core; + +import org.jcnc.snow.compiler.parser.ast.ModuleNode; +import org.jcnc.snow.compiler.parser.ast.base.Node; +import org.jcnc.snow.compiler.semantic.error.SemanticError; +import org.jcnc.snow.compiler.semantic.utils.SemanticAnalysisReporter; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 语义分析统一入口,封装模块筛选、分析器调用、错误报告。 + */ +public class SemanticAnalyzerRunner { + /** + * 对给定 AST 执行语义分析,并在有错误时终止程序。 + * + * @param ast AST 根节点列表 + * @param verbose 是否启用详细日志输出 + */ + public static void runSemanticAnalysis(List ast, boolean verbose) { + List modules = ast.stream() + .filter(ModuleNode.class::isInstance) + .map(ModuleNode.class::cast) + .collect(Collectors.toList()); + + List errors = new SemanticAnalyzer(verbose).analyze(modules); + + SemanticAnalysisReporter.reportAndExitIfNecessary(errors); + } +} diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/utils/SemanticAnalysisReporter.java b/src/main/java/org/jcnc/snow/compiler/semantic/utils/SemanticAnalysisReporter.java new file mode 100644 index 0000000..697da7a --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/semantic/utils/SemanticAnalysisReporter.java @@ -0,0 +1,29 @@ +package org.jcnc.snow.compiler.semantic.utils; + +import org.jcnc.snow.compiler.semantic.error.SemanticError; + +import java.util.List; + +/** + * 用于统一处理语义分析结果的输出与终止逻辑。 + */ +public final class SemanticAnalysisReporter { + /** + * 根据语义错误列表打印分析结果。 + * 如果存在错误,则打印错误详情并退出程序; + * 如果无错误,则打印成功信息。 + * + * @param errors 语义分析过程中收集到的错误列表 + */ + public static void reportAndExitIfNecessary(List errors) { + if (errors != null && !errors.isEmpty()) { + System.err.println("语义分析发现错误:"); + for (SemanticError error : errors) { + System.err.println(" " + error); + } + System.exit(1); + } else { + System.out.println("语义分析通过,没有发现错误。"); + } + } +}