如何以足够通用的方式解析 LLVM GEP 指令?

How to parse LLVM GEP instruction in a generic enough way?

所以我正在研究一种允许我解析简单 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 但在最后一行我有 numberregisternumber.

添加规则... (NUMBER|REGISTER) ...我认为这不会帮助我理解顺序。我想添加类似

的内容
NOR: (NUMBER|REGISTER)
    ;

并使用 NOR(0)NOR(1) 但我认为每次我都必须检查它是 number 还是 register。如何解决这个问题?

请注意,LLVM 还有许多使用 numberregister 的其他指令,所以我不想每次都检查类型。

我该怎么做?

编辑

谢谢迈克, 我这样定义 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
   ;

这将为每个备选方案生成单独的 ParserContext 类(在本例中为 GEP_NRContextGEP_NRNContext)。

根据@arrowd 的评论,以及你的评论:许多地方允许数字或寄存器,我怀疑 nor 解析器规则可能更实用,但我想我会展示替代方案以防万一每个变体都需要以不同的方式处理。您甚至可能想同时尝试一下,看看哪个能让您的 listeners/visitors 中的代码更易于管理。

p.s。将 NOR 词法分析器规则更改为 nor 解析器规则,可能已经说明了这一点,但是,在您深入了解 make sure 之前,您了解其中的区别词法分析器和解析器规则之间的关系,以及分词器和解析器如何使用它们。如果你的想法不是很清楚,ANTLR 会显得很混乱。