优化FunctionParser,实现无序
This commit is contained in:
parent
0cecb5797b
commit
d586c65e22
@ -11,17 +11,17 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于解析函数定义块(function),包括函数名、参数列表、返回类型、函数体等。
|
* FunctionParser 是用于解析函数定义的顶层解析器。
|
||||||
* 支持的语法结构示例:
|
* <p>
|
||||||
|
* 支持的语法结构(参数、返回类型、函数体顺序可变):
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* function: myFunc
|
* function: myFunc
|
||||||
|
* return_type: int
|
||||||
* parameter:
|
* parameter:
|
||||||
* declare a:int
|
* declare a:int
|
||||||
* b:int
|
* b:int
|
||||||
* return_type: int
|
|
||||||
* body:
|
* body:
|
||||||
* declare x:int = 10
|
* return a + b
|
||||||
* return x
|
|
||||||
* end body
|
* end body
|
||||||
* end function
|
* end function
|
||||||
* }</pre>
|
* }</pre>
|
||||||
@ -29,87 +29,181 @@ import java.util.List;
|
|||||||
public class FunctionParser implements TopLevelParser {
|
public class FunctionParser implements TopLevelParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析一个函数定义并返回对应的 {@link FunctionNode}。
|
* 解析函数定义,包括函数名、参数列表、返回类型、函数体等部分,顺序不限。
|
||||||
*
|
*
|
||||||
* @param ctx 解析上下文。
|
* @param ctx 解析上下文
|
||||||
* @return 解析生成的函数节点。
|
* @return 生成的函数语法树节点
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public FunctionNode parse(ParserContext ctx) {
|
public FunctionNode parse(ParserContext ctx) {
|
||||||
TokenStream ts = ctx.getTokens();
|
TokenStream tokens = ctx.getTokens();
|
||||||
|
|
||||||
|
// 解析 function: 标识符
|
||||||
|
parseFunctionHeader(tokens);
|
||||||
|
|
||||||
|
// 解析函数名
|
||||||
|
String functionName = parseFunctionName(tokens);
|
||||||
|
|
||||||
|
// 初始化各部分容器
|
||||||
|
List<ParameterNode> parameters = new ArrayList<>();
|
||||||
|
String[] returnType = {null}; // 使用数组模拟引用传参
|
||||||
|
List<StatementNode> 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("function");
|
||||||
ts.expect(":");
|
ts.expect(":");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取函数名称标识符 */
|
||||||
|
private String parseFunctionName(TokenStream ts) {
|
||||||
|
// “function:”后必然是函数名所以可以“expectType”断言
|
||||||
String name = ts.expectType(TokenType.IDENTIFIER).getLexeme();
|
String name = ts.expectType(TokenType.IDENTIFIER).getLexeme();
|
||||||
ts.expectType(TokenType.NEWLINE);
|
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<ParameterNode> parameters,
|
||||||
|
List<StatementNode> body,
|
||||||
|
java.util.function.Consumer<String> 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<ParameterNode> parseParameters(TokenStream ts) {
|
||||||
ts.expect("parameter");
|
ts.expect("parameter");
|
||||||
ts.expect(":");
|
ts.expect(":");
|
||||||
ts.expectType(TokenType.NEWLINE);
|
ts.expectType(TokenType.NEWLINE);
|
||||||
|
|
||||||
List<ParameterNode> params = new ArrayList<>();
|
List<ParameterNode> params = new ArrayList<>();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (ts.peek().getType() == TokenType.NEWLINE) {
|
if (ts.peek().getType() == TokenType.NEWLINE) {
|
||||||
ts.next();
|
ts.next(); // 忽略空行
|
||||||
continue;
|
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())) {
|
if ("declare".equals(ts.peek().getLexeme())) {
|
||||||
ts.next(); // 支持 declare 前缀
|
ts.next(); // 可选 declare
|
||||||
}
|
}
|
||||||
|
|
||||||
String paramName = ts.expectType(TokenType.IDENTIFIER).getLexeme();
|
String paramName = ts.expectType(TokenType.IDENTIFIER).getLexeme();
|
||||||
ts.expect(":");
|
ts.expect(":");
|
||||||
String paramType = ts.expectType(TokenType.TYPE).getLexeme();
|
String paramType = ts.expectType(TokenType.TYPE).getLexeme();
|
||||||
ts.expectType(TokenType.NEWLINE);
|
ts.expectType(TokenType.NEWLINE);
|
||||||
|
|
||||||
params.add(new ParameterNode(paramName, paramType));
|
params.add(new ParameterNode(paramName, paramType));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析返回类型
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 解析 return_type: 部分 */
|
||||||
|
private String parseReturnType(TokenStream ts) {
|
||||||
ts.expect("return_type");
|
ts.expect("return_type");
|
||||||
ts.expect(":");
|
ts.expect(":");
|
||||||
String returnType = ts.expectType(TokenType.TYPE).getLexeme();
|
String returnType = ts.expectType(TokenType.TYPE).getLexeme();
|
||||||
ts.expectType(TokenType.NEWLINE);
|
ts.expectType(TokenType.NEWLINE);
|
||||||
|
return returnType;
|
||||||
|
}
|
||||||
|
|
||||||
// 解析函数体
|
/** 解析 body: ... end body 部分 */
|
||||||
|
private List<StatementNode> parseFunctionBody(ParserContext ctx, TokenStream ts) {
|
||||||
ts.expect("body");
|
ts.expect("body");
|
||||||
ts.expect(":");
|
ts.expect(":");
|
||||||
ts.expectType(TokenType.NEWLINE);
|
ts.expectType(TokenType.NEWLINE);
|
||||||
List<StatementNode> body = new ArrayList<>();
|
|
||||||
parseBody(ctx, body);
|
|
||||||
|
|
||||||
// 解析函数体结束标识
|
List<StatementNode> 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("end");
|
||||||
ts.expect("body");
|
ts.expect("body");
|
||||||
ts.expectType(TokenType.NEWLINE);
|
ts.expectType(TokenType.NEWLINE);
|
||||||
|
|
||||||
// 解析函数定义结束标识
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 匹配函数结束标志 end function */
|
||||||
|
private void parseFunctionFooter(TokenStream ts) {
|
||||||
ts.expect("end");
|
ts.expect("end");
|
||||||
ts.expect("function");
|
ts.expect("function");
|
||||||
ts.expectType(TokenType.NEWLINE);
|
ts.expectType(TokenType.NEWLINE);
|
||||||
|
|
||||||
return new FunctionNode(name, params, returnType, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 辅助方法:从上下文中解析函数体,直到遇到 "end"。
|
|
||||||
*
|
|
||||||
* @param ctx 当前解析上下文。
|
|
||||||
* @param body 存放解析出的语句节点的列表。
|
|
||||||
*/
|
|
||||||
private void parseBody(ParserContext ctx, List<StatementNode> 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
test
7
test
@ -1,12 +1,13 @@
|
|||||||
module: CommonTasks
|
module: CommonTasks
|
||||||
function: add_numbers
|
function: add_numbers
|
||||||
|
body:
|
||||||
|
return num1 + num2
|
||||||
|
end body
|
||||||
parameter:
|
parameter:
|
||||||
declare num1: int
|
declare num1: int
|
||||||
declare num2: int
|
declare num2: int
|
||||||
return_type: int
|
return_type: int
|
||||||
body:
|
|
||||||
return num1 + num2
|
|
||||||
end body
|
|
||||||
end function
|
end function
|
||||||
end module
|
end module
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user