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 a48bdb0..8827fb2 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 @@ -11,6 +11,7 @@ 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 java.util.ArrayList; import java.util.HashMap; @@ -40,10 +41,9 @@ public class LoopStatementParser implements StatementParser { TokenStream ts = ctx.getTokens(); // 匹配 loop: - ts.expect("loop"); - ts.expect(":"); - ts.expectType(TokenType.NEWLINE); - skipNewlines(ts); + ParserUtils.matchHeader(ts, "loop"); + + ParserUtils.skipNewlines(ts); // 用于保存各区块内容 final StatementNode[] initializer = new StatementNode[1]; @@ -61,9 +61,9 @@ public class LoopStatementParser implements StatementParser { ts1.expect("initializer"); ts1.expect(":"); ts1.expectType(TokenType.NEWLINE); - skipNewlines(ts1); + ParserUtils.skipNewlines(ts); initializer[0] = StatementParserFactory.get(ts1.peek().getLexeme()).parse(ctx1); - skipNewlines(ts1); + ParserUtils.skipNewlines(ts); } )); @@ -74,10 +74,10 @@ public class LoopStatementParser implements StatementParser { ts1.expect("condition"); ts1.expect(":"); ts1.expectType(TokenType.NEWLINE); - skipNewlines(ts1); + ParserUtils.skipNewlines(ts); condition[0] = new PrattExpressionParser().parse(ctx1); ts1.expectType(TokenType.NEWLINE); - skipNewlines(ts1); + ParserUtils.skipNewlines(ts); } )); @@ -88,14 +88,14 @@ public class LoopStatementParser implements StatementParser { ts1.expect("update"); ts1.expect(":"); ts1.expectType(TokenType.NEWLINE); - skipNewlines(ts1); + ParserUtils.skipNewlines(ts); String varName = ts1.expectType(TokenType.IDENTIFIER).getLexeme(); ts1.expect("="); ExpressionNode updateExpr = new PrattExpressionParser().parse(ctx1); ts1.expectType(TokenType.NEWLINE); update[0] = new AssignmentNode(varName, updateExpr); - skipNewlines(ts1); + ParserUtils.skipNewlines(ts); } )); @@ -106,7 +106,7 @@ public class LoopStatementParser implements StatementParser { ts1.expect("body"); ts1.expect(":"); ts1.expectType(TokenType.NEWLINE); - skipNewlines(ts1); + ParserUtils.skipNewlines(ts); while (!(ts1.peek().getLexeme().equals("end") && ts1.peek(1).getLexeme().equals("body"))) { @@ -114,13 +114,13 @@ public class LoopStatementParser implements StatementParser { ? ts1.peek().getLexeme() : ""; body.add(StatementParserFactory.get(keyword).parse(ctx1)); - skipNewlines(ts1); + ParserUtils.skipNewlines(ts); } ts1.expect("end"); ts1.expect("body"); ts1.expectType(TokenType.NEWLINE); - skipNewlines(ts1); + ParserUtils.skipNewlines(ts); } )); @@ -128,16 +128,10 @@ public class LoopStatementParser implements StatementParser { FlexibleSectionParser.parse(ctx, ts, sections); // 匹配 loop 结束 - ts.expect("end"); - ts.expect("loop"); - ts.expectType(TokenType.NEWLINE); + ParserUtils.matchFooter(ts, "loop"); + return new LoopNode(initializer[0], condition[0], update[0], body); } - - private void skipNewlines(TokenStream ts) { - while (ts.peek().getType() == TokenType.NEWLINE) { - ts.next(); - } - } + } diff --git a/src/main/java/org/jcnc/snow/compiler/parser/util/ParserUtils.java b/src/main/java/org/jcnc/snow/compiler/parser/util/ParserUtils.java new file mode 100644 index 0000000..676e9cf --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/parser/util/ParserUtils.java @@ -0,0 +1,46 @@ +package org.jcnc.snow.compiler.parser.util; + +import org.jcnc.snow.compiler.lexer.token.TokenType; +import org.jcnc.snow.compiler.parser.context.TokenStream; + +/** + * 常用的语法解析工具类。 + */ +public class ParserUtils { + + /** + * 匹配开头部分,如 `loop:`、`function:` + * + * @param ts Token 流 + * @param keyword 关键词 + */ + public static void matchHeader(TokenStream ts, String keyword) { + ts.expect(keyword); + ts.expect(":"); + ts.expectType(TokenType.NEWLINE); + skipNewlines(ts); + } + + /** + * 匹配结尾部分,如 `end loop`、`end function` + * + * @param ts Token 流 + * @param keyword 关键词 + */ + public static void matchFooter(TokenStream ts, String keyword) { + ts.expect("end"); + ts.expect(keyword); + ts.expectType(TokenType.NEWLINE); + } + + /** + * 跳过多余换行 + * + * @param ts Token 流 + */ + public static void skipNewlines(TokenStream ts) { + while (ts.peek().getType() == TokenType.NEWLINE) { + ts.next(); + } + } +}