增加test

This commit is contained in:
Luke 2025-04-28 15:43:54 +08:00
parent 424874bd6e
commit 4ba7f6c2f7
11 changed files with 77 additions and 33 deletions

View File

@ -2,12 +2,16 @@ package org.jcnc.snow.compiler;
import org.jcnc.snow.compiler.lexer.LexerEngine; import org.jcnc.snow.compiler.lexer.LexerEngine;
import org.jcnc.snow.compiler.lexer.token.Token; 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.core.ParserEngine;
import org.jcnc.snow.compiler.parser.ast.ModuleNode; import org.jcnc.snow.compiler.parser.ast.ModuleNode;
import org.jcnc.snow.compiler.parser.context.ParserContext; import org.jcnc.snow.compiler.parser.context.ParserContext;
import org.jcnc.snow.compiler.parser.ast.base.Node; 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.SemanticAnalyzer;
import org.jcnc.snow.compiler.semantic.core.SemanticAnalyzerRunner;
import org.jcnc.snow.compiler.semantic.error.SemanticError; import org.jcnc.snow.compiler.semantic.error.SemanticError;
import org.jcnc.snow.compiler.semantic.utils.SemanticAnalysisReporter;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -15,6 +19,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public class Main { public class Main {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
@ -31,30 +36,9 @@ public class Main {
List<Node> ast = new ParserEngine(ctx).parse(); List<Node> ast = new ParserEngine(ctx).parse();
// 3. 语义分析 // 3. 语义分析
SemanticAnalyzerRunner.runSemanticAnalysis(ast,true);
// 3. 语义分析
// parse() 返回的是顶层 Node 列表我们只关心 ModuleNode
List<ModuleNode> modules = new ArrayList<>();
for (Node n : ast) {
if (n instanceof ModuleNode m) {
modules.add(m);
}
}
SemanticAnalyzer analyzer = new SemanticAnalyzer(true);
List<SemanticError> 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); // System.out.println(source);

View File

@ -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.ExpressionNode;
import org.jcnc.snow.compiler.parser.ast.base.Node; import org.jcnc.snow.compiler.parser.ast.base.Node;
import org.jcnc.snow.compiler.parser.ast.base.StatementNode; import org.jcnc.snow.compiler.parser.ast.base.StatementNode;
import org.jcnc.snow.compiler.parser.util.ASTJsonSerializer; import org.jcnc.snow.compiler.parser.utils.ASTJsonSerializer;
import org.jcnc.snow.compiler.parser.util.JsonFormatter; import org.jcnc.snow.compiler.parser.utils.JsonFormatter;
import java.util.List; import java.util.List;

View File

@ -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.ParserContext;
import org.jcnc.snow.compiler.parser.context.TokenStream; import org.jcnc.snow.compiler.parser.context.TokenStream;
import org.jcnc.snow.compiler.parser.factory.StatementParserFactory; import org.jcnc.snow.compiler.parser.factory.StatementParserFactory;
import org.jcnc.snow.compiler.parser.util.FlexibleSectionParser; import org.jcnc.snow.compiler.parser.utils.FlexibleSectionParser;
import org.jcnc.snow.compiler.parser.util.FlexibleSectionParser.SectionDefinition; import org.jcnc.snow.compiler.parser.utils.FlexibleSectionParser.SectionDefinition;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;

View File

@ -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.context.TokenStream;
import org.jcnc.snow.compiler.parser.expression.PrattExpressionParser; import org.jcnc.snow.compiler.parser.expression.PrattExpressionParser;
import org.jcnc.snow.compiler.parser.factory.StatementParserFactory; import org.jcnc.snow.compiler.parser.factory.StatementParserFactory;
import org.jcnc.snow.compiler.parser.util.FlexibleSectionParser; import org.jcnc.snow.compiler.parser.utils.FlexibleSectionParser;
import org.jcnc.snow.compiler.parser.util.ParserUtils; import org.jcnc.snow.compiler.parser.utils.ParserUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;

View File

@ -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.*;
import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode; import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;

View File

@ -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.lexer.token.TokenType;
import org.jcnc.snow.compiler.parser.context.ParserContext; import org.jcnc.snow.compiler.parser.context.ParserContext;

View File

@ -1,4 +1,4 @@
package org.jcnc.snow.compiler.parser.util; package org.jcnc.snow.compiler.parser.utils;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;

View File

@ -1,4 +1,4 @@
package org.jcnc.snow.compiler.parser.util; package org.jcnc.snow.compiler.parser.utils;
/** /**
* JSON 格式化工具类 * JSON 格式化工具类

View File

@ -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.lexer.token.TokenType;
import org.jcnc.snow.compiler.parser.context.TokenStream; import org.jcnc.snow.compiler.parser.context.TokenStream;

View File

@ -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<Node> ast, boolean verbose) {
List<ModuleNode> modules = ast.stream()
.filter(ModuleNode.class::isInstance)
.map(ModuleNode.class::cast)
.collect(Collectors.toList());
List<SemanticError> errors = new SemanticAnalyzer(verbose).analyze(modules);
SemanticAnalysisReporter.reportAndExitIfNecessary(errors);
}
}

View File

@ -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<SemanticError> errors) {
if (errors != null && !errors.isEmpty()) {
System.err.println("语义分析发现错误:");
for (SemanticError error : errors) {
System.err.println(" " + error);
}
System.exit(1);
} else {
System.out.println("语义分析通过,没有发现错误。");
}
}
}