修复注释
This commit is contained in:
parent
98ceb4faa8
commit
59dbafb2b6
@ -7,6 +7,7 @@ import org.jcnc.snow.compiler.ir.core.IRFunction;
|
||||
import org.jcnc.snow.compiler.ir.core.IRProgram;
|
||||
import org.jcnc.snow.compiler.lexer.core.LexerEngine;
|
||||
import org.jcnc.snow.compiler.lexer.token.Token;
|
||||
import org.jcnc.snow.compiler.lexer.utils.TokenPrinter;
|
||||
import org.jcnc.snow.compiler.parser.ast.base.Node;
|
||||
import org.jcnc.snow.compiler.parser.context.ParserContext;
|
||||
import org.jcnc.snow.compiler.parser.core.ParserEngine;
|
||||
@ -48,9 +49,9 @@ public class SnowCompiler {
|
||||
List<Node> ast = new ParserEngine(ctx).parse();
|
||||
|
||||
// System.out.println(source);
|
||||
// TokenPrinter.print(tokens); // 打印 Token 列表
|
||||
TokenPrinter.print(tokens); // 打印 Token 列表
|
||||
ASTPrinter.print(ast); // 打印 AST
|
||||
// ASTPrinter.printJson(ast); // 打印JSON AST
|
||||
ASTPrinter.printJson(ast); // 打印JSON AST
|
||||
/* 3. 语义分析 */
|
||||
SemanticAnalyzerRunner.runSemanticAnalysis(ast, false);
|
||||
|
||||
|
||||
@ -10,23 +10,18 @@ import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* 通用的解析器,用于解析结构化的内容部分,完全解耦合关键字和语法。
|
||||
* <p>
|
||||
* {@code FlexibleSectionParser} 提供了一个灵活的机制来解析可变的语法块。每个语法块的解析逻辑通过外部提供,
|
||||
* 该类仅负责按顺序解析不同的区块,直到遇到结束标记。它完全解耦了具体的语法关键字和解析逻辑。
|
||||
* </p>
|
||||
* <p>
|
||||
* 使用此类可以解析如函数定义中的多个部分(如参数、返回类型、函数体等),而无需在解析器中硬编码这些结构。
|
||||
* </p>
|
||||
*
|
||||
* FlexibleSectionParser 提供了一个灵活的机制来解析可变的语法块。每个语法块的解析逻辑通过外部提供,
|
||||
* 该类仅负责按顺序解析不同的区块,直到遇到结束标记,同时能够跳过并收集注释供后续使用。
|
||||
*
|
||||
* 使用此类可以解析如函数定义中的多个部分(如参数、返回类型、函数体等),而无需在解析器中硬编码这些结构,
|
||||
* 并且保留注释信息以便 IDE 或工具链进行注释跳转、重构等操作。
|
||||
*/
|
||||
public class FlexibleSectionParser {
|
||||
|
||||
/**
|
||||
* 解析一系列的可变区块,解析顺序和具体内容由外部定义。
|
||||
* <p>
|
||||
* 该方法接受一个包含区块定义的映射,每个区块定义包含一个条件(Predicate<TokenStream>)
|
||||
* 和一个解析器(BiConsumer<ParserContext, TokenStream>)。
|
||||
* 条件用于判断当前是否应解析该区块,解析器则执行解析逻辑。
|
||||
* </p>
|
||||
* 在解析过程中会跳过并收集注释,以及跳过空行。
|
||||
*
|
||||
* @param ctx 当前的解析上下文,包含语法分析所需的所有信息(如作用域、错误处理等)
|
||||
* @param tokens 当前的词法 token 流,用于逐个查看或消耗 token
|
||||
@ -36,66 +31,63 @@ public class FlexibleSectionParser {
|
||||
TokenStream tokens,
|
||||
Map<String, SectionDefinition> sectionDefinitions) {
|
||||
|
||||
// 跳过最开始的空行,避免误判开始关键字
|
||||
while (tokens.peek().getType() == TokenType.NEWLINE) {
|
||||
tokens.next();
|
||||
}
|
||||
// 在开始解析之前,跳过并收集所有紧邻开头的注释和空行
|
||||
skipCommentsAndNewlines(tokens);
|
||||
|
||||
// 主循环:逐个处理区块,直到遇到 "end" 为止
|
||||
while (true) {
|
||||
// 获取当前 token 的字面量(通常是关键字字符串)
|
||||
// 在每次解析前,跳过并收集注释和空行
|
||||
skipCommentsAndNewlines(tokens);
|
||||
|
||||
String keyword = tokens.peek().getLexeme();
|
||||
|
||||
// 尝试在映射中找到对应该关键字的区块定义
|
||||
SectionDefinition definition = sectionDefinitions.get(keyword);
|
||||
if ("end".equals(keyword)) {
|
||||
// 遇到 'end' 则终止解析
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果找到了定义且其条件满足当前 token 流
|
||||
SectionDefinition definition = sectionDefinitions.get(keyword);
|
||||
if (definition != null && definition.condition().test(tokens)) {
|
||||
// 执行该区块的解析逻辑
|
||||
definition.parser().accept(ctx, tokens);
|
||||
} else if ("end".equals(keyword)) {
|
||||
// 如果遇到 "end",表示所有区块结束,退出循环
|
||||
break;
|
||||
} else {
|
||||
// 如果关键字无法识别,或不满足条件,则抛出异常
|
||||
// 无法识别该关键字或条件不满足则报错
|
||||
throw new RuntimeException("未识别的关键字或条件不满足: " + keyword);
|
||||
}
|
||||
|
||||
// 每次解析完成后,继续跳过空行,准备进入下一个区块的判断
|
||||
while (tokens.peek().getType() == TokenType.NEWLINE) {
|
||||
tokens.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳过所有连续的注释行和空行。
|
||||
*
|
||||
* @param tokens 词法流
|
||||
*/
|
||||
private static void skipCommentsAndNewlines(TokenStream tokens) {
|
||||
while (true) {
|
||||
TokenType type = tokens.peek().getType();
|
||||
if (type == TokenType.COMMENT || type == TokenType.NEWLINE) {
|
||||
tokens.next();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 区块定义类:表示一个语法区块的匹配条件和解析逻辑。
|
||||
* <p>
|
||||
* 每个区块由两个部分组成:
|
||||
* - 条件:用于判断当前 token 流是否应进入该区块的解析。
|
||||
* - 解析器:具体的解析逻辑,通常是消费若干 token 并更新解析上下文。
|
||||
* </p>
|
||||
*
|
||||
* @param condition 匹配条件,返回 true 表示此区块应被解析
|
||||
* @param parser 实际解析逻辑
|
||||
*/
|
||||
public record SectionDefinition(Predicate<TokenStream> condition, BiConsumer<ParserContext, TokenStream> parser) {
|
||||
|
||||
/**
|
||||
* 获取条件判断函数。
|
||||
*
|
||||
* @return 一个用于判断是否进入该区块的 Predicate
|
||||
*/
|
||||
public record SectionDefinition(Predicate<TokenStream> condition,
|
||||
BiConsumer<ParserContext, TokenStream> parser) {
|
||||
@Override
|
||||
public Predicate<TokenStream> condition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取解析器函数。
|
||||
*
|
||||
* @return 一个解析该区块的 BiConsumer 函数
|
||||
*/
|
||||
@Override
|
||||
public BiConsumer<ParserContext, TokenStream> parser() {
|
||||
return parser;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user