Как получить исходный текст, используя $text, при этом правило возвращает значение

Итак, у меня есть следующая грамматика:

top_cmd :cmds
        {
            std::cout << $cmds.text << std::endl;
        }
        ;


cmds returns [char* str]
    : cmd+
    {
        str = new char('a');
    }
    ;

Я получаю ошибку компиляции g++:

"str" was not declared in this scope

Если я уберу эту строку

std::cout << $cmds.text << std::endl;

Тогда компиляция в порядке.

Я гуглил, как используется "$text", мне кажется, ожидается, что он будет использовать $ text для переписывания правил. В моем примере функция "cmds" возвращает "char*", когда я удаляю некорректную строку, и некоторую сложную структуру, когда я ее сохраняю.

Я могу думать о следующем обходном пути:

1. do not have lower level rules return anything, but pass variable into lower level rules.
2. use re-write rules

Но и то и другое довольно большое изменение (мой настоящий проект довольно большой), учитывая, сколько у меня времени.

Так есть ли короткий путь? По сути, я не хочу менять грамматику top_cmd и cmds, но я могу получить полный текст соответствия cmds.

Я использую ANTLR3C, но я считаю, что это не зависит от целевого языка.

1 ответ

Решение

Я думаю, что вы должны сделать что-то вроде этого:

top_cmd :cmds
    {
        std::cout << $cmds.text << std::endl;}
    ;


cmds returns [char* str]
: cmd+
  {
      $str = new char('a'); //added $
  }
  ;

$cmds.text вернет текст, соответствующий правилу cmds. Если вы хотите вернуть str, вы должны изменить его на $cmds.str

$ text: текст, который соответствует правилу, или текст, который совпадает с начала правила до момента вычисления выражения $ text. Обратите внимание, что это включает в себя текст для всех токенов, в том числе на скрытых каналах, что вам и нужно, потому что обычно он содержит все пробелы и комментарии. При ссылке на текущее правило этот атрибут доступен в любом действии, включая любые действия исключений.

из окончательной ссылки Antrl

Другие вопросы по тегам