增加注释

This commit is contained in:
Luke 2025-04-24 22:30:03 +08:00
parent d586c65e22
commit b140eafeb4

View File

@ -11,77 +11,86 @@ import java.util.ArrayList;
import java.util.List;
/**
* FunctionParser 是用于解析函数定义的顶层解析器
* {@code FunctionParser} 是一个顶层语法分析器用于解析函数定义语法结构
* <p>
* 支持的语法结构参数返回类型函数体顺序可变
* 它支持以下组成部分且顺序可灵活排列
* <ul>
* <li>{@code function}函数名声明</li>
* <li>{@code parameter}参数列表支持可选的 {@code declare} 关键字</li>
* <li>{@code return_type}返回类型声明</li>
* <li>{@code body}函数体代码块包含函数内的语句</li>
* </ul>
* 每个部分的顺序是非固定的只要结构合法即可
* <p>
* 示例函数定义语法如下
* <pre>{@code
* function: myFunc
* return_type: int
* module: MathUtils
* function: square_number
* parameter:
* declare a:int
* b:int
* declare number: int
* return_type: int
* body:
* return a + b
* return number * number
* end body
* end function
* end module
* }</pre>
* 本解析器将该结构转换为抽象语法树AST中的 {@code FunctionNode} 节点
*/
public class FunctionParser implements TopLevelParser {
/**
* 解析函数定义包括函数名参数列表返回类型函数体等部分顺序不限
* 解析完整的函数结构构建 FunctionNode 语法树节点
*
* @param ctx 解析上下文
* @return 生成的函数语法树节点
* @param ctx 解析上下文包含 token 流和其他辅助信息
* @return 构造的函数语法树节点
*/
@Override
public FunctionNode parse(ParserContext ctx) {
TokenStream tokens = ctx.getTokens();
// 解析 function: 标识符
// 匹配 function: 起始标签
parseFunctionHeader(tokens);
// 解析函数名
String functionName = parseFunctionName(tokens);
// 初始化各部分容器
// 用于存储参数返回类型和函数体
List<ParameterNode> parameters = new ArrayList<>();
String[] returnType = {null}; // 使用数组模拟引用传参
String[] returnType = {null}; // 模拟引用传参
List<StatementNode> body = new ArrayList<>();
// 解析 parameter / return_type / body 的任意顺序区块
// 解析 parameter / return_type / body顺序任意
parseFlexibleSections(ctx, tokens, parameters, body, type -> returnType[0] = type);
// 匹配函数定义结束
// 匹配函数结尾标签
parseFunctionFooter(tokens);
return new FunctionNode(functionName, parameters, returnType[0], body);
}
/** 匹配 function: 起始标记 */
/** 匹配 function 起始标志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;
}
/**
* 支持顺序无关的函数区块解析逻辑
* 解析函数的可变结构部分parameter, return_type, body顺序不限
*
* @param ctx 解析上下文
* @param tokens token
* @param parameters 参数节点收集容器
* @param body 函数体语句节点容器
* @param returnTypeSetter 设置返回类型 Lambda引用模拟
* @param ctx 上下文
* @param tokens Token
* @param parameters 存储解析后的参数节点
* @param body 存储解析后的语句节点
* @param returnTypeSetter 设置返回类型使用 lambda
*/
private void parseFlexibleSections(ParserContext ctx,
TokenStream tokens,
@ -98,37 +107,43 @@ public class FunctionParser implements TopLevelParser {
tokens.next();
}
// 获取当前关键字
String keyword = tokens.peek().getLexeme();
switch (keyword) {
case "parameter":
if (parsedParam) throw new RuntimeException("重复的“参数”部分");
if (parsedParam) throw new RuntimeException("重复定义 parameter 区块");
parameters.addAll(parseParameters(tokens));
parsedParam = true;
break;
case "return_type":
if (parsedReturn) throw new RuntimeException("重复的'return_type'部分");
if (parsedReturn) throw new RuntimeException("重复定义 return_type 区块");
returnTypeSetter.accept(parseReturnType(tokens));
parsedReturn = true;
break;
case "body":
if (parsedBody) throw new RuntimeException("重复的“body”部分");
if (parsedBody) throw new RuntimeException("重复定义 body 区块");
body.addAll(parseFunctionBody(ctx, tokens));
parsedBody = true;
break;
case "end":
return; // 退出循环进入函数尾部匹配
return; // 完成可变区块的解析继续处理函数结尾
default:
throw new RuntimeException("函数中出现意外部分: " + keyword);
throw new RuntimeException("函数定义中出现未识别的关键字: " + keyword);
}
}
}
/** 解析 parameter: 部分 */
/**
* 解析参数定义区块
*
* @param ts Token
* @return 参数节点列表
*/
private List<ParameterNode> parseParameters(TokenStream ts) {
ts.expect("parameter");
ts.expect(":");
@ -138,16 +153,19 @@ public class FunctionParser implements TopLevelParser {
while (true) {
if (ts.peek().getType() == TokenType.NEWLINE) {
ts.next(); // 忽略空行
ts.next(); // 跳过空行
continue;
}
if ("return_type".equals(ts.peek().getLexeme()) || "body".equals(ts.peek().getLexeme()) || "end".equals(ts.peek().getLexeme())) {
break; // 退出 parameter 区块
String lexeme = ts.peek().getLexeme();
// 如果是下一个区块的起始关键字则退出当前 parameter 区块
if ("return_type".equals(lexeme) || "body".equals(lexeme) || "end".equals(lexeme)) {
break;
}
if ("declare".equals(ts.peek().getLexeme())) {
ts.next(); // 可选 declare
if ("declare".equals(lexeme)) {
ts.next(); // 可选 "declare"
}
String paramName = ts.expectType(TokenType.IDENTIFIER).getLexeme();
@ -161,7 +179,12 @@ public class FunctionParser implements TopLevelParser {
return params;
}
/** 解析 return_type: 部分 */
/**
* 解析返回类型区块
*
* @param ts Token
* @return 返回类型字符串
*/
private String parseReturnType(TokenStream ts) {
ts.expect("return_type");
ts.expect(":");
@ -170,7 +193,13 @@ public class FunctionParser implements TopLevelParser {
return returnType;
}
/** 解析 body: ... end body 部分 */
/**
* 解析函数体 body 区块包括多条语句直到 end body
*
* @param ctx 语法分析上下文
* @param ts Token
* @return 函数体中的语句节点列表
*/
private List<StatementNode> parseFunctionBody(ParserContext ctx, TokenStream ts) {
ts.expect("body");
ts.expect(":");
@ -185,7 +214,7 @@ public class FunctionParser implements TopLevelParser {
}
if ("end".equals(ts.peek().getLexeme())) {
break; // body 结束
break;
}
String keyword = ts.peek().getLexeme();
@ -200,7 +229,11 @@ public class FunctionParser implements TopLevelParser {
return body;
}
/** 匹配函数结束标志 end function */
/**
* 匹配函数定义结束标志end function
*
* @param ts Token
*/
private void parseFunctionFooter(TokenStream ts) {
ts.expect("end");
ts.expect("function");