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



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

例如:

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

但是,在这种情况下,生成的代码仅考虑最后一个表达式 (4 * 6(。

代码链接: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:我强烈建议使用听众或访问者,而不是在整个语法中进行操作。它们使语法非常难以阅读。

最新更新