Как получить исходный текст, используя $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. Обратите внимание, что это включает в себя текст для всех токенов, в том числе на скрытых каналах, что вам и нужно, потому что обычно он содержит все пробелы и комментарии. При ссылке на текущее правило этот атрибут доступен в любом действии, включая любые действия исключений.