ANTLR4数组实现:如何获取初始化时的数组元素
解决ANTLR4中数组初始化元素的获取与存储问题
我来帮你搞定这个数组初始化的问题!咱们一步步来,先补全语法规则,再通过ANTLR的监听器机制提取元素并存入你的HashMap。
第一步:完善语法规则
你的array_init规则还没完成,得让它能匹配多个用逗号分隔的整数。修改后的语法片段如下:
/* PARSER RULES */ declare_var : INTEGER ID '[' (INT)? ']' (ASSIGN '{' array_init '}')? SCOL ; array_init : INT (',' INT)* ; // 匹配1个或多个用逗号分隔的整数 /* 补充必要的词法规则 */ INTEGER : 'int'; ASSIGN : '='; SCOL : ';'; INT : [0-9]+; ID : [a-zA-Z_][a-zA-Z0-9_]*; WS : [ \t\r\n]+ -> skip; // 忽略空白字符
这样语法就能正确识别{1, 2}、{5, 8, 10}这类初始化列表了。
第二步:通过Listener提取元素并存入HashMap
ANTLR的Listener机制是处理语法树节点的常用方式,咱们写一个自定义Listener,重写enterDeclare_var方法来处理数组初始化逻辑:
public class GaleugListener extends GaleugParserNewBaseListener { public Map<Integer, Value> array_memory = new HashMap<>(); @Override public void enterDeclare_var(GaleugParserNew.Declare_varContext ctx) { // 检查是否存在数组初始化部分 if (ctx.array_init() != null) { GaleugParserNew.Array_initContext arrayCtx = ctx.array_init(); // 获取所有INT节点 List<GaleugParserNew.INTContext> intNodes = arrayCtx.INT(); // 遍历元素,按索引顺序存入HashMap for (int i = 0; i < intNodes.size(); i++) { int numValue = Integer.parseInt(intNodes.get(i).getText()); // 假设Value是你的自定义值类型,这里替换成你实际的构造逻辑 array_memory.put(i, new Value(numValue)); } } } }
如果你的Value类有特殊的构造方式,直接调整对应的代码即可。
第三步:使用Listener处理输入
最后,在解析代码时用上这个Listener就行:
public class Main { public static void main(String[] args) throws IOException { String input = "int array[] = {1, 2};"; GaleugLexerNew lexer = new GaleugLexerNew(CharStreams.fromString(input)); CommonTokenStream tokens = new CommonTokenStream(lexer); GaleugParserNew parser = new GaleugParserNew(tokens); GaleugListener listener = new GaleugListener(); ParseTreeWalker.DEFAULT.walk(listener, parser.declare_var()); // 测试输出HashMap中的内容 listener.array_memory.forEach((index, value) -> System.out.printf("array[%d] = %s%n", index, value) ); } }
这样就能把数组的每个元素按索引正确存入array_memory了。如果后续需要支持更复杂的初始化(比如嵌套数组、表达式初始化),只需要扩展语法规则和对应的处理逻辑就行。
内容的提问来源于stack exchange,提问作者blah
相关产品推荐
相关产品推荐

