如何获取MVEL编译后ASTNode节点的完整信息及左右子节点
你预期的实现逻辑是完全可行的,MVEL的ASTNode本身支持直接获取左右子节点,如果需要完整遍历整棵AST树,可以参考以下实现方案:
1. 基础左右子节点访问
你写的调用逻辑本身没有问题:
ASTNode left = node.getLeftNode(); ASTNode right = node.getRightNode();
对于二元操作节点(比如算术运算、逻辑判断、赋值等),两个方法会分别返回对应的左右子节点;如果是一元操作节点(比如取反、类型强转),getRightNode()会返回null,仅需处理左节点即可。
2. 全量AST树遍历实现
如果需要访问所有层级的节点,可以通过递归的方式实现全量遍历,注意部分特殊节点(方法调用、集合字面量等)除了左右子节点外还有额外的子节点集合,需要单独处理:
import org.mvel2.ast.*; import java.util.List; import java.util.Map; public void traverseAST(ASTNode node) { if (node == null) { return; } // 此处添加自定义的节点信息处理逻辑 // 示例:打印节点类型、节点名称、所在表达式行号 System.out.printf("节点类型:%s,节点内容:%s,行号:%d%n", node.getClass().getSimpleName(), node.getName(), node.getLineNumber()); // 递归遍历左右子节点 traverseAST(node.getLeftNode()); traverseAST(node.getRightNode()); // 处理特殊节点的额外子节点 if (node instanceof MethodCallNode) { // 处理方法调用的参数节点 List<ASTNode> params = ((MethodCallNode) node).getParameters(); for (ASTNode param : params) { traverseAST(param); } } else if (node instanceof ListLiteralNode) { // 处理列表字面量的元素节点 List<ASTNode> items = ((ListLiteralNode) node).getItems(); for (ASTNode item : items) { traverseAST(item); } } else if (node instanceof MapLiteralNode) { // 处理Map字面量的键值对节点 Map<ASTNode, ASTNode> entries = ((MapLiteralNode) node).getEntries(); for (Map.Entry<ASTNode, ASTNode> entry : entries.entrySet()) { traverseAST(entry.getKey()); traverseAST(entry.getValue()); } } else if (node instanceof FunctionNode) { // 处理自定义函数的代码块节点 traverseAST(((FunctionNode) node).getBlock()); } }
3. 其他常用节点信息获取
你可以通过ASTNode提供的内置方法获取更多节点属性:
getLiteralValue():获取字面量节点(数字、字符串、布尔常量等)对应的实际值getOperator():获取操作符节点对应的操作符枚举值isLiteral():判断当前节点是否为字面量节点getFields():获取节点关联的字段属性信息
内容的提问来源于stack exchange,提问作者Mike Zhou
相关产品推荐
相关产品推荐

