ANTLR4 генерирует код для последнего выражения, введенного в фигурные скобки - PullRequest
0 голосов
/ 11 апреля 2019

Я строю язык, который в основном используется для целей расчета.Это небольшой язык с синтаксисом, подобным 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* в двух разных правилах.Я не уверен, как еще справиться с этой проблемой.Вся помощь очень ценится.

Спасибо

1 Ответ

0 голосов
/ 11 апреля 2019

В любом случае, похоже, ваша проблема в том, что действие $instruction в block относится только к последней инструкции, поскольку блок находится за пределами *, поэтому действие запускается только один раз.

Вы можете либо переместить действие в *, как вы это делали в правиле calcul, либо вы можете поместить все инструкции в список с помощью instructions+=instruction*, а затем использовать $instructions в действии (или лучше: слушатель или посетитель).

PS: я настоятельно рекомендую использовать слушателя или посетителя вместо того, чтобы выполнять действия по всей вашей грамматике. Они делают грамматику очень трудной для чтения.

...