ANTLR4 为花括号中输入的最后一个表达式生成代码

ANTLR4 generating code for the last expression entered in curly braces

我正在构建一种主要用于计算目的的语言。它是一种具有类似 C 语法但功能极其有限的小型语言。在过去的几天里,我一直在尝试生成封装在大括号中的代码,但是每当我在大括号中输入 expressions 时,生成的代码总是针对最后输入的表达式。它应该在 while 循环中工作。

例如:

while( true )
{
    // some expressions (not using any variables for simplicity)
    5 + 9;
    8 - 10;
    4 * 6;
}

然而,生成的代码只考虑了本例中的最后一个表达式 (4 * 6)。

link 代码: https://codeshare.io/GL0xRk

还有,处理花括号的代码片段和一些其他相关代码:

calcul returns [String code]
@init
{
$code = new String();
}
@after
{
System.out.print($code);
for( int i = 0; i < getvarg_count(); ++i )
{
    System.out.println("POP");
}
System.out.println("HALT");
}
: (decl
{
// declaration
$code += $decl.code;
})*
NEWLINE*
{
$code += "";
}
(instruction
{
// instruction, eg. x = 5; 7 * 4;
$code += $instruction.code;
System.err.println("instruction found");
})*
;

whileStat returns [String code]
: WHILE '(' condition ')' NEWLINE* block
{
int cur_label = nextLabel();
$code = "LABEL " + cur_label + "\n";
$code += $condition.code;
$code += "JUMPF " + (cur_label + 1) + "\n";
$code += $block.code;
$code += "JUMP " + cur_label + "\n";
$code += "LABEL " + (cur_label + 1) + "\n";
}
;

block returns [String code]
@init
{
$code = new String();
}
: '{' instruction* '}' NEWLINE*
{
System.err.println("block found");
$code += $instruction.code;
System.err.println("curly braces for while found");
}
;

编译代码生成:

while(true)
{
 5+9;
 8-10;
 4*6;
}
block found
curly braces for while found
instruction found
LABEL 0
PUSHI 1
JUMPF 1
PUSHI 4
PUSHI 6
MUL
POP
JUMP 0
LABEL 1
HALT

我感觉 $code 总是被重新初始化。或者可能是因为我在两个不同的规则中有 instruction*。我不确定如何处理这个问题。非常感谢所有帮助。

谢谢

无论如何,看起来你的问题是 block 的动作中的 $instruction 只引用最后一条指令,因为该块在 * 之外,所以动作只得到 运行 一次。

您可以像在 calcul 规则中那样将操作移动到 * 内,或者您可以将所有指令放入带有 instructions+=instruction* 的列表中,然后使用 $instructions 在行动中(或更好:听众或访客)。

PS:我强烈建议使用侦听器或访问器,而不是在整个语法中使用操作。它们使语法很难阅读。