diff --git a/src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java b/src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java
index 8d6de5d..13883ec 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java
@@ -11,17 +11,17 @@ import java.util.ArrayList;
import java.util.List;
/**
- * 用于解析函数定义块(function),包括函数名、参数列表、返回类型、函数体等。
- * 支持的语法结构示例:
+ * FunctionParser 是用于解析函数定义的顶层解析器。
+ *
+ * 支持的语法结构(参数、返回类型、函数体顺序可变):
*
{@code
* function: myFunc
+ * return_type: int
* parameter:
* declare a:int
* b:int
- * return_type: int
* body:
- * declare x:int = 10
- * return x
+ * return a + b
* end body
* end function
* }
@@ -29,87 +29,181 @@ import java.util.List;
public class FunctionParser implements TopLevelParser {
/**
- * 解析一个函数定义并返回对应的 {@link FunctionNode}。
+ * 解析函数定义,包括函数名、参数列表、返回类型、函数体等部分,顺序不限。
*
- * @param ctx 解析上下文。
- * @return 解析生成的函数节点。
+ * @param ctx 解析上下文
+ * @return 生成的函数语法树节点
*/
@Override
public FunctionNode parse(ParserContext ctx) {
- TokenStream ts = ctx.getTokens();
+ TokenStream tokens = ctx.getTokens();
+
+ // 解析 function: 标识符
+ parseFunctionHeader(tokens);
+
+ // 解析函数名
+ String functionName = parseFunctionName(tokens);
+
+ // 初始化各部分容器
+ List parameters = new ArrayList<>();
+ String[] returnType = {null}; // 使用数组模拟引用传参
+ List body = new ArrayList<>();
+
+ // 解析 parameter / return_type / body 的任意顺序区块
+ parseFlexibleSections(ctx, tokens, parameters, body, type -> returnType[0] = type);
+
+ // 匹配函数定义结束
+ parseFunctionFooter(tokens);
+
+ return new FunctionNode(functionName, parameters, returnType[0], body);
+ }
+
+ /** 匹配 function: 起始标记 */
+ private void parseFunctionHeader(TokenStream ts) {
ts.expect("function");
ts.expect(":");
+
+
+ }
+
+ /** 获取函数名称标识符 */
+ private String parseFunctionName(TokenStream ts) {
+ // “function:”后必然是函数名所以可以“expectType”断言
String name = ts.expectType(TokenType.IDENTIFIER).getLexeme();
ts.expectType(TokenType.NEWLINE);
+ return name;
+ }
- // 解析参数列表
+ /**
+ * 支持顺序无关的函数区块解析逻辑。
+ *
+ * @param ctx 解析上下文
+ * @param tokens token 流
+ * @param parameters 参数节点收集容器
+ * @param body 函数体语句节点容器
+ * @param returnTypeSetter 设置返回类型的 Lambda(引用模拟)
+ */
+ private void parseFlexibleSections(ParserContext ctx,
+ TokenStream tokens,
+ List parameters,
+ List body,
+ java.util.function.Consumer returnTypeSetter) {
+ boolean parsedParam = false;
+ boolean parsedReturn = false;
+ boolean parsedBody = false;
+
+ while (true) {
+ // 跳过空行
+ while (tokens.peek().getType() == TokenType.NEWLINE) {
+ tokens.next();
+ }
+
+ String keyword = tokens.peek().getLexeme();
+
+ switch (keyword) {
+ case "parameter":
+ if (parsedParam) throw new RuntimeException("重复的“参数”部分。");
+ parameters.addAll(parseParameters(tokens));
+ parsedParam = true;
+ break;
+
+ case "return_type":
+ if (parsedReturn) throw new RuntimeException("重复的'return_type'部分。");
+ returnTypeSetter.accept(parseReturnType(tokens));
+ parsedReturn = true;
+ break;
+
+ case "body":
+ if (parsedBody) throw new RuntimeException("重复的“body”部分。");
+ body.addAll(parseFunctionBody(ctx, tokens));
+ parsedBody = true;
+ break;
+
+ case "end":
+ return; // 退出循环,进入函数尾部匹配
+
+ default:
+ throw new RuntimeException("函数中出现意外部分: " + keyword);
+ }
+ }
+ }
+
+ /** 解析 parameter: 部分 */
+ private List parseParameters(TokenStream ts) {
ts.expect("parameter");
ts.expect(":");
ts.expectType(TokenType.NEWLINE);
+
List params = new ArrayList<>();
+
while (true) {
if (ts.peek().getType() == TokenType.NEWLINE) {
- ts.next();
+ ts.next(); // 忽略空行
continue;
}
- if ("return_type".equals(ts.peek().getLexeme())) {
- break;
+
+ if ("return_type".equals(ts.peek().getLexeme()) || "body".equals(ts.peek().getLexeme()) || "end".equals(ts.peek().getLexeme())) {
+ break; // 退出 parameter 区块
}
+
if ("declare".equals(ts.peek().getLexeme())) {
- ts.next(); // 支持 declare 前缀
+ ts.next(); // 可选 declare
}
+
String paramName = ts.expectType(TokenType.IDENTIFIER).getLexeme();
ts.expect(":");
String paramType = ts.expectType(TokenType.TYPE).getLexeme();
ts.expectType(TokenType.NEWLINE);
+
params.add(new ParameterNode(paramName, paramType));
}
- // 解析返回类型
+ return params;
+ }
+
+ /** 解析 return_type: 部分 */
+ private String parseReturnType(TokenStream ts) {
ts.expect("return_type");
ts.expect(":");
String returnType = ts.expectType(TokenType.TYPE).getLexeme();
ts.expectType(TokenType.NEWLINE);
+ return returnType;
+ }
- // 解析函数体
+ /** 解析 body: ... end body 部分 */
+ private List parseFunctionBody(ParserContext ctx, TokenStream ts) {
ts.expect("body");
ts.expect(":");
ts.expectType(TokenType.NEWLINE);
- List body = new ArrayList<>();
- parseBody(ctx, body);
- // 解析函数体结束标识
+ List body = new ArrayList<>();
+
+ while (true) {
+ if (ts.peek().getType() == TokenType.NEWLINE) {
+ ts.next(); // 跳过空行
+ continue;
+ }
+
+ if ("end".equals(ts.peek().getLexeme())) {
+ break; // body 结束
+ }
+
+ String keyword = ts.peek().getLexeme();
+ StatementNode statement = StatementParserFactory.get(keyword).parse(ctx);
+ body.add(statement);
+ }
+
ts.expect("end");
ts.expect("body");
ts.expectType(TokenType.NEWLINE);
- // 解析函数定义结束标识
+ return body;
+ }
+
+ /** 匹配函数结束标志 end function */
+ private void parseFunctionFooter(TokenStream ts) {
ts.expect("end");
ts.expect("function");
ts.expectType(TokenType.NEWLINE);
-
- return new FunctionNode(name, params, returnType, body);
- }
-
- /**
- * 辅助方法:从上下文中解析函数体,直到遇到 "end"。
- *
- * @param ctx 当前解析上下文。
- * @param body 存放解析出的语句节点的列表。
- */
- private void parseBody(ParserContext ctx, List body) {
- TokenStream ts = ctx.getTokens();
- while (true) {
- if (ts.peek().getType() == TokenType.NEWLINE) {
- ts.next();
- continue;
- }
- if ("end".equals(ts.peek().getLexeme())) {
- break;
- }
- String key = ts.peek().getLexeme();
- StatementNode stmt = StatementParserFactory.get(key).parse(ctx);
- body.add(stmt);
- }
}
}
diff --git a/test b/test
index 1185bf0..d7319c6 100644
--- a/test
+++ b/test
@@ -1,12 +1,13 @@
module: CommonTasks
function: add_numbers
+ body:
+ return num1 + num2
+ end body
parameter:
declare num1: int
declare num2: int
return_type: int
- body:
- return num1 + num2
- end body
+
end function
end module