所以我正在研究一种允许我解析简单LLVM IR
文件的语法。目前我对GEP指令有问题。例如:
%5 = getelementptr inbounds [2 x i32], [2 x i32]* @values, i64 0, i64 %4
%24 = getelementptr inbounds [8 x [256 x i32]], [8 x [256 x i32]]* @crc_table, i64 0, i64 0, i64 %23
%25 = getelementptr inbounds [8 x [256 x i32]], [8 x [256 x i32]]* @crc_table, i64 0, i64 %20, i64 %23
%26 = getelementptr inbounds [8 x [256 x i32]], [8 x [256 x i32]]* @crc_table, i64 0, i64 %20, i64 3
我想有一个通用的规则,使我能够理解元素的顺序。例如,在第一行中我有number
和register
,但在最后一行中我有number
,register
和number
。
添加…(NUMBER|REGISTER)
……我认为这对我理解订单没有帮助。我想添加一些东西,比如
NOR: (NUMBER|REGISTER)
;
并使用NOR(0)
,NOR(1)
,但我想每次我都要检查它是否是number
或register
。如何处理这个问题?
请注意,LLVM有许多其他指令使用number
和register
,所以我不想每次都检查类型。
我该怎么做?
编辑
谢谢迈克,我这样定义NUMBER
:
NUMBER : ('-')* ([0-9])+
;
和REGISTER
REGISTER : '%'(LETTER|INT|'_'|'.')+
;
如果有用,请忘记我的其他规则,我相信你的建议无论如何都会有用的。到目前为止,我想使用像
这样的东西nor : (NUMBER|REGISTER)
;
我可以对它们进行迭代使用ctx.gep_type().nor().REGISTER() != null
来检查它是寄存器还是数字
将NOR
(词法分析器规则)更改为nor
(解析器规则),您应该能够按照您的建议进行操作;遍历nor
上下文,检查实际存在的类型。
我不知道你可能要涵盖多少变化,所以下面这些替代方案可能是实用的,也可能是不实用的。如果选项非常有限,您还可以这样做:
gepRule:
// whatever goes before the number or registers (I'll abbreviate as "w")
w NUMBER REGISTER # GEP_NR
| w NUMBER REGISTER NUMBER # GEP_NRN
// other alternatives
;
这将为每个选项(在本例中为GEP_NRContext
和GEP_NRNContext
)生成单独的ParserContext类。
基于@arrowd的评论,以及你的评论:许多地方允许数字或寄存器,我怀疑nor
解析器规则可能更实用,但我认为我会显示替代方案,以防每个变化需要处理有点不同。您甚至可以尝试一下这两种方法,看看哪种方法使侦听器/访问者中的代码更易于管理。
注。将NOR
词法分析器规则更改为nor
解析器规则可能已经说明了这一点,但是,在深入研究之前,请确保了解词法分析器和解析器规则之间的区别,以及标记器和解析器如何使用它们。如果你不清楚这一点,ANTLR会显得很混乱。