Я прочитал несколько вещей о циклах в ANTLR, но я до сих пор не понимаю, как на самом деле построить treewalker для циклов. Итак, что я хочу сделать, это проанализировать и выполнить операторы, подобные этим:
int a = 1
while(a < 3) {
int c = 1
a = a + 1
}
Когда я помещаю это в свой парсер, результирующий AST выглядит так:

Теперь я хочу создать treewalker, который сначала проверяет, является ли условие while истинным, затем выполняет операторы или, если оператор не истинен, через некоторое время переходит к оператору. Поэтому, я думаю, мне нужно знать, как получить индекс EOF, чтобы перейти к нему, но я не знаю, как это сделать.
Что я испытал, так это пример кода на этой странице , но кажется, что он больше не работает (вы можете увидеть это в комментариях ниже), и что также беспокоит меня об этом , тот факт, что VARDEF и ASSIGN выполняются до выполнения цикла while, и я не вижу, как это изменить.
Итак, я хочу знать, есть ли у меня правильный подход или есть лучший способ сделать это? Можете ли вы дать мне пример treewalker для моего цикла while, думаю, это было бы очень полезно.
Вот моя текущая попытка для trevealker:
tree grammar SGLTreeWalker;
options {
tokenVocab = SGL;
language = 'CSharp2';
ASTLabelType=CommonTree;
}
@namespace { SGL }
@header {
using System.Collections.Generic;
}
@members{
SGLActions action = new SGLActions();
}
compilationUnit
: mainStatement+ EOF
;
mainStatement
: statement
;
statement
: variableDeclarationList // int a = 1, b = 2, c
| ^(ASSIGN variableAssignment) // a = 4
| whileLoop
;
/* Statements */
whileLoop
: ^('while' expression statement*)
{
int next = input.Index(); // index of node following WHILE
input.Seek($expression.start.startIndex);
Object condition = expression();
while((Boolean) condition) {
input.Seek($statement.start.startIndex);
statement();
input.Seek($expression.start.startIndex);
condition = expression();
}
input.Seek(next);
}
;
variableDeclarationList
: ^(VARDEF variableType variableName expression) {
action.NewLocalVariable($variableType.txt,$variableName.txt,$expression.txt);
}
;
// Only used for the first time declaration of a new variable
variableAssignment
: variableName expression? {
action.AssignVariable($variableName.txt,$expression.txt);
}
;
variableName returns [string txt]
: Identifier {$txt = $Identifier.text;}
;
variableType returns [string txt]
: IntType {$txt = $IntType.text;}
| BooleanType {$txt = $BooleanType.text;}
| StringType {$txt = $StringType.text;}
| FloatType {$txt = $FloatType.text;}
;
/* Expressions */
// start rule for all sorts of expressions
expression returns [string txt]
: ^('+' a=expression b=expression) { $txt = action.Add($a.txt,$b.txt); }
| ^('-' a=expression b=expression) { $txt = action.Sub($a.txt,$b.txt); }
| ^('*' a=expression b=expression) { $txt = action.Mult($a.txt,$b.txt); }
| ^('/' a=expression b=expression) { $txt = action.Div($a.txt,$b.txt); }
| ^('%' a=expression b=expression) { $txt = action.Remainder($a.txt,$b.txt); }
| ^(NEGATE a=expression) { $txt = action.Mult($a.txt,"-1"); }
| ^('<' a=expression b=expression) { $txt = action.ConditionLess($a.txt,$b.txt); }
| ^('<=' a=expression b=expression) { $txt = action.ConditionLessOrEqual($a.txt,$b.txt); }
| ^('>' a=expression b=expression) { $txt = action.ConditionGreater($a.txt,$b.txt); }
| ^('>=' a=expression b=expression) { $txt = action.ConditionGreaterOrEqual($a.txt,$b.txt); }
| ^('!=' a=expression b=expression) { $txt = action.ConditionNotEqual($a.txt,$b.txt); }
| ^('==' a=expression b=expression) { $txt = action.ConditionEqual($a.txt,$b.txt); }
| ^('&&' a=expression b=expression) { $txt = action.ConnectiveAnd($a.txt,$b.txt); }
| ^('||' a=expression b=expression) { $txt = action.ConnectiveOr($a.txt,$b.txt); }
| ^('?' a=expression b=expression c=expression) { $txt = action.ConditionBranch($a.txt,$b.txt,$c.txt); }
| Identifier { $txt = action.GetVariable($Identifier.text); }
| IntegerAtom { $txt = $IntegerAtom.text; }
| BooleanAtom { $txt = $BooleanAtom.text; }
;