Я пытаюсь создать интерпретатор Pascal с использованием ANTLR, и в настоящее время у меня есть некоторые проблемы с обработкой циклов при обходе дерева AST.Например, для цикла анализируется как:
parametricLoop
: FOR IDENTIFIER ASSIGN start = integerExpression TO end = integerExpression DO
statement
-> ^( PARAMETRIC_LOOP IDENTIFIER $start $end statement )
;
(вариант с DOWNTO игнорируется).Каким образом я могу заставить Уокера повторять выполнение цикла столько раз, сколько необходимо?Я знаю, что я должен использовать input.Mark () и input.Rewind () для этого.Но где именно они должны быть помещены?Мой текущий неправильный вариант выглядит так (целевой язык - C #):
parametricLoop
:
^(
PARAMETRIC_LOOP
IDENTIFIER
start = integerExpression
{
Variable parameter = Members.variable($IDENTIFIER.text);
parameter.value = $start.result;
}
end = integerExpression
{
int end_value = $end.result;
if ((int)parameter.value > end_value) goto EndLoop;
parametric_loop_start = input.Mark();
}
statement
{
parameter.value = (int)parameter.value + 1;
if ((int)parameter.value <= end_value)
input.Rewind(parametric_loop_start);
)
{
EndLoop: ;
}
;
(Надеюсь, все понятно).Условие повторения должно быть проверено перед первым выполнением оператора.Я попытался поиграть с размещением Mark и Rewind в разных блоках кода, включая @init и @after, и даже поместил конечный goto в заголовок цикла, но каждый временной цикл либо повторялся один раз, либо генерировал исключения, такие как встретился неожиданный токен, например ': ='(назначение).Я понятия не имею, как заставить это работать должным образом и не могу найти никакого рабочего примера.Кто-нибудь может предложить решение этой проблемы?