修复loop错误
This commit is contained in:
parent
ba6c036122
commit
b18d53e4ba
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 流
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user