修复loop错误

This commit is contained in:
Luke 2025-04-25 16:47:10 +08:00
parent ba6c036122
commit b18d53e4ba
2 changed files with 31 additions and 46 deletions

View File

@ -1,6 +1,5 @@
package org.jcnc.snow.compiler.parser.statement; package org.jcnc.snow.compiler.parser.statement;
import org.jcnc.snow.compiler.lexer.token.Token;
import org.jcnc.snow.compiler.lexer.token.TokenType; import org.jcnc.snow.compiler.lexer.token.TokenType;
import org.jcnc.snow.compiler.parser.ast.AssignmentNode; import org.jcnc.snow.compiler.parser.ast.AssignmentNode;
import org.jcnc.snow.compiler.parser.ast.ExpressionNode; import org.jcnc.snow.compiler.parser.ast.ExpressionNode;
@ -19,7 +18,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* 用于解析 loop 语句块支持下结构 * 用于解析 loop 语句块支持下结构
* <pre>{@code * <pre>{@code
* loop: * loop:
* initializer: * initializer:
@ -33,6 +32,7 @@ import java.util.Map;
* end body * end body
* end loop * end loop
* }</pre> * }</pre>
* 使用 FlexibleSectionParser 解析各区块并统一入口出口处理
*/ */
public class LoopStatementParser implements StatementParser { public class LoopStatementParser implements StatementParser {
@ -40,73 +40,58 @@ public class LoopStatementParser implements StatementParser {
public LoopNode parse(ParserContext ctx) { public LoopNode parse(ParserContext ctx) {
TokenStream ts = ctx.getTokens(); TokenStream ts = ctx.getTokens();
// 匹配 loop: // 匹配 loop: 开头
ParserUtils.matchHeader(ts, "loop"); ParserUtils.matchHeader(ts, "loop");
ParserUtils.skipNewlines(ts); // 各区块中间值容器模拟引用
// 用于保存各区块内容
final StatementNode[] initializer = new StatementNode[1]; final StatementNode[] initializer = new StatementNode[1];
final ExpressionNode[] condition = new ExpressionNode[1]; final ExpressionNode[] condition = new ExpressionNode[1];
final AssignmentNode[] update = new AssignmentNode[1]; final AssignmentNode[] update = new AssignmentNode[1];
final List<StatementNode> body = new ArrayList<>(); final List<StatementNode> body = new ArrayList<>();
// 建区块定义 map // 造区块定义
Map<String, FlexibleSectionParser.SectionDefinition> sections = new HashMap<>(); Map<String, FlexibleSectionParser.SectionDefinition> sections = new HashMap<>();
// initializer 区块 // initializer 区块解析初始化语句
sections.put("initializer", new FlexibleSectionParser.SectionDefinition( sections.put("initializer", new FlexibleSectionParser.SectionDefinition(
ts1 -> ts1.peek().getLexeme().equals("initializer"), ts1 -> ts1.peek().getLexeme().equals("initializer"),
(ctx1, ts1) -> { (ctx1, ts1) -> {
ts1.expect("initializer"); ParserUtils.matchHeader(ts1, "initializer");
ts1.expect(":");
ts1.expectType(TokenType.NEWLINE);
ParserUtils.skipNewlines(ts);
initializer[0] = StatementParserFactory.get(ts1.peek().getLexeme()).parse(ctx1); initializer[0] = StatementParserFactory.get(ts1.peek().getLexeme()).parse(ctx1);
ParserUtils.skipNewlines(ts); ParserUtils.skipNewlines(ts1);
} }
)); ));
// condition 区块 // condition 区块解析布尔条件表达式
sections.put("condition", new FlexibleSectionParser.SectionDefinition( sections.put("condition", new FlexibleSectionParser.SectionDefinition(
ts1 -> ts1.peek().getLexeme().equals("condition"), ts1 -> ts1.peek().getLexeme().equals("condition"),
(ctx1, ts1) -> { (ctx1, ts1) -> {
ts1.expect("condition"); ParserUtils.matchHeader(ts1, "condition");
ts1.expect(":");
ts1.expectType(TokenType.NEWLINE);
ParserUtils.skipNewlines(ts);
condition[0] = new PrattExpressionParser().parse(ctx1); condition[0] = new PrattExpressionParser().parse(ctx1);
ts1.expectType(TokenType.NEWLINE); ts1.expectType(TokenType.NEWLINE);
ParserUtils.skipNewlines(ts); ParserUtils.skipNewlines(ts1);
} }
)); ));
// update 区块 // update 区块解析变量赋值表达式
sections.put("update", new FlexibleSectionParser.SectionDefinition( sections.put("update", new FlexibleSectionParser.SectionDefinition(
ts1 -> ts1.peek().getLexeme().equals("update"), ts1 -> ts1.peek().getLexeme().equals("update"),
(ctx1, ts1) -> { (ctx1, ts1) -> {
ts1.expect("update"); ParserUtils.matchHeader(ts1, "update");
ts1.expect(":");
ts1.expectType(TokenType.NEWLINE);
ParserUtils.skipNewlines(ts);
String varName = ts1.expectType(TokenType.IDENTIFIER).getLexeme(); String varName = ts1.expectType(TokenType.IDENTIFIER).getLexeme();
ts1.expect("="); ts1.expect("=");
ExpressionNode updateExpr = new PrattExpressionParser().parse(ctx1); ExpressionNode expr = new PrattExpressionParser().parse(ctx1);
ts1.expectType(TokenType.NEWLINE); ts1.expectType(TokenType.NEWLINE);
update[0] = new AssignmentNode(varName, updateExpr); update[0] = new AssignmentNode(varName, expr);
ParserUtils.skipNewlines(ts); ParserUtils.skipNewlines(ts1);
} }
)); ));
// body 区块 // body 区块解析语句块
sections.put("body", new FlexibleSectionParser.SectionDefinition( sections.put("body", new FlexibleSectionParser.SectionDefinition(
ts1 -> ts1.peek().getLexeme().equals("body"), ts1 -> ts1.peek().getLexeme().equals("body"),
(ctx1, ts1) -> { (ctx1, ts1) -> {
ts1.expect("body"); ParserUtils.matchHeader(ts1, "body");
ts1.expect(":");
ts1.expectType(TokenType.NEWLINE);
ParserUtils.skipNewlines(ts);
while (!(ts1.peek().getLexeme().equals("end") && while (!(ts1.peek().getLexeme().equals("end") &&
ts1.peek(1).getLexeme().equals("body"))) { ts1.peek(1).getLexeme().equals("body"))) {
@ -114,24 +99,23 @@ public class LoopStatementParser implements StatementParser {
? ts1.peek().getLexeme() ? ts1.peek().getLexeme()
: ""; : "";
body.add(StatementParserFactory.get(keyword).parse(ctx1)); body.add(StatementParserFactory.get(keyword).parse(ctx1));
ParserUtils.skipNewlines(ts); ParserUtils.skipNewlines(ts1);
} }
ts1.expect("end"); ts1.expect("end");
ts1.expect("body"); ts1.expect("body");
ts1.expectType(TokenType.NEWLINE); ts1.expectType(TokenType.NEWLINE);
ParserUtils.skipNewlines(ts); ParserUtils.skipNewlines(ts1);
} }
)); ));
// 使用 FlexibleSectionParser 解析 loop 部分 // 使用 FlexibleSectionParser 解析所有结构部分
FlexibleSectionParser.parse(ctx, ts, sections); FlexibleSectionParser.parse(ctx, ts, sections);
// 匹配 loop 结束 // 匹配 end loop
ParserUtils.matchFooter(ts, "loop"); ParserUtils.matchFooter(ts, "loop");
// 构造并返回 LoopNode 抽象语法树节点
return new LoopNode(initializer[0], condition[0], update[0], body); return new LoopNode(initializer[0], condition[0], update[0], body);
} }
} }

View File

@ -4,15 +4,16 @@ import org.jcnc.snow.compiler.lexer.token.TokenType;
import org.jcnc.snow.compiler.parser.context.TokenStream; import org.jcnc.snow.compiler.parser.context.TokenStream;
/** /**
* 常用的语法解析工具类 * 语法结构通用辅助工具类
* 提供常用的结构匹配和容错功能
*/ */
public class ParserUtils { public class ParserUtils {
/** /**
* 匹配开头部分 `loop:``function:` * 匹配形如 "keyword:" 的语法结构头部并跳过换行
* *
* @param ts Token * @param ts Token
* @param keyword 关键词 * @param keyword 结构标识关键字 "loop", "function"
*/ */
public static void matchHeader(TokenStream ts, String keyword) { public static void matchHeader(TokenStream ts, String keyword) {
ts.expect(keyword); ts.expect(keyword);
@ -22,10 +23,10 @@ public class ParserUtils {
} }
/** /**
* 匹配结尾部分 `end loop``end function` * 匹配形如 "end keyword" 的语法结构结尾
* *
* @param ts Token * @param ts Token
* @param keyword 关键词 * @param keyword 结构标识关键字 "loop", "function"
*/ */
public static void matchFooter(TokenStream ts, String keyword) { public static void matchFooter(TokenStream ts, String keyword) {
ts.expect("end"); ts.expect("end");
@ -34,7 +35,7 @@ public class ParserUtils {
} }
/** /**
* 跳过多余换行 * 跳过连续的换行符常用于容错与美化语法结构
* *
* @param ts Token * @param ts Token
*/ */