Как получить список смешанных типов из контекста правила парсера? - PullRequest
0 голосов
/ 21 июня 2019

Я определил правило синтаксического анализатора, которое может быть списком типа A или типа B:

g4: sectionContent : ( WHITESPACE* ( section | ( LINE_LITERAL NEWLINE ) ) WHITESPACE* )* ;

сгенерированный источник: cpp

  SectionHeaderContext* sectionHeader();

  class  SectionContentContext : public antlr4::ParserRuleContext {
  public:
    SectionContentContext(antlr4::ParserRuleContext *parent, size_t invokingState);
    virtual size_t getRuleIndex() const override;
    std::vector<SectionContext *> section();
    SectionContext* section(size_t i);
    std::vector<antlr4::tree::TerminalNode *> WHITESPACE();
    antlr4::tree::TerminalNode* WHITESPACE(size_t i);
    std::vector<antlr4::tree::TerminalNode *> LINE_LITERAL();
    antlr4::tree::TerminalNode* LINE_LITERAL(size_t i);
    std::vector<antlr4::tree::TerminalNode *> NEWLINE();
    antlr4::tree::TerminalNode* NEWLINE(size_t i);

    virtual antlrcpp::Any accept(antlr4::tree::ParseTreeVisitor *visitor) override;

  };

Вопрос: из сгенерированного источника я вижу, что могу получить список LINE_LITERAL, я также могу получить список SectionContext.Но что, если анализируемый текст представляет собой смешанный список LINE_LITERAL и SectionContext?Разве информация не теряется при разборе?Например,

Для входного документа с:

LINE_LITERAL_1
SectionContext_1
LINE_LITERAL_2
SectionContext_2
LINE_LITERAL_3
SectionContext_3

Информация об относительном заказе между SectionContext_1 и LINE_LITERAL_2 важна.Но используя antlr, я могу получить только список всех LINE_LITERAL и еще один список SectionContext.

1 Ответ

1 голос
/ 22 июня 2019

Все функции, которые вы видите в производном контексте, являются вспомогательными методами. Все они работают в списке детей, в котором токены хранятся в том виде, в котором они были распознаны (в порядке их распознавания). Например, метод section() выполняет итерацию по дочернему списку и собирает все элементы SectionContext. Вместо этого метод section с параметром перебирает дочерний элемент и возвращает i-тое вхождение SectionContext.

Если вы хотите получить дочерние контексты в том порядке, в котором они были распознаны, используйте дочерний список (ParseTree::children в цели C ++).

...