Как выполнить итерацию в python посетителя antlr

#antlr4

#antlr4

Вопрос:

Я пытаюсь создавать объекты, используя посетителей цели python. Для следующего грамматического правила:

 prog : stat  ;
 

У меня есть этот код посетителя для создания соответствующих объектов:

 def visitProg(self, ctx:ExprParser.ProgContext):
    stat_list = []
    for s in ctx.stat():
        stat_list.append(self.visit(s))
    node = ObjProg(stat_list)
    return node
 

Приведенный выше код работает нормально. Однако, когда я меняю правило на это:

 prog : s1=stat (',' s2=stat)* ;
 

каким должен быть соответствующий код посетителя? Я пытался написать это так, но я получаю ошибки компиляции:

 def visitProg(self, ctx:ExprParser.ProgContext):
    stat_list = []
    stat_list.append(self.visit(ctx.s1))
    for s in ctx.s2:
        stat_list.append(self.visit(s))
    node = ObjProg(stat_list)
    return node
 

Ответ №1:

В правиле:

 prog : s1=stat (',' s2=stat)* ;
 

оба s1 и s2 являются одиночными stat контекстами. Таким образом, код for s in ctx.s2 неверен.

Если вы используете = оператор:

 prog : stats =stat (',' stats =stat)* ;
 

тогда вы могли бы сделать:

 def visitProg(self, ctx:ExprParser.ProgContext):
    stat_list = []
    for s in ctx.stats:
        stat_list.append(self.visit(s))
    return ObjProg(stat_list)
 

И если есть необходимость отделить первый stat от других, вы могли бы сделать это:

 prog : first_stat=stat (',' stats =stat)* ;
 

а затем что-то вроде этого:

 def visitProg(self, ctx:ExprParser.ProgContext):
    stat_list = [self.visit(ctx.first_stat)]
    for s in ctx.stats:
        stat_list.append(self.visit(s))
    return ObjProg(stat_list)
 

Возможно, вам нужно проверить ctx.stats is None , я не уверен.

Комментарии:

1. Спасибо. Я внес небольшое редактирование в ваш ответ, чтобы разделить s1 и s2.

2. Но нет необходимости создавать 2 списка ( s1 и s2 ). Кроме того, s1 всегда будет только один элемент, нет смысла создавать из него = список.