Я пытаюсь написать небольшой компилятор, который может анализировать некоторые команды, которые я печатаю.
Команда, которую я пытаюсь разобрать:
create class something = create class do_something ;
Мой код будет примерно таким:
grammar : my_grammar
{
list<Class1 *> *obj = new list<Class1 *>;
obj->push_back($1);
}
my_grammar : my_definition SEMICOLON
{
report("something detected!");
$$ = $1;
}
my_definition : CREATE CLASS class_name EQU class_expression
{
$5->setClassName(*$3);
$$ = $5;
}
class_expression : CREATE CLASS operand_name
{
$$ = new OperandClass();
$$->setOperationType("createClass");
$$->setOperandName(*$3);
}
Однако, когда я пытаюсь вызвать анализатор где-то еще, я не могу получить Class
Я определил раньше.
Я думаю, должно быть что-то не так с синтаксическим анализатором и отладка с GDB. Но я просто не могу войти в функцию push_back()
я также не могу распечатать информацию obj
правильно.
Итак, мне интересно, есть ли способ, которым я могу получить значение $$
или же $1
при использовании GDB. Просто введите p $$
напечатал бы что-то еще.
Самый простой способ, вероятно, — объявить переменную того же типа, что и ваше правило ($$
имеет этот тип) и назначая его.
%union {
int I;
}
%type<I> rule whatever
rule: whatever {
int foo = $1;
// printf("%d", foo);
$$ = $1;
}
Затем вы можете увидеть его в отладчике или просто распечатать.
Отладчик не может зайти внутрь push_back
или другие стандартные функции, если у вас не установлена стандартная информация об отладке библиотеки.
Что касается вашего вопроса в целом, ваш obj
является локальным по отношению к правилу, которое Bison преобразует в функцию и не видно вне его, если вы не сохраните его где-то еще, например в глобальном.
Если вы используете Bison с шаблонами C, Bison имеет переменную yyval
и массив yyvsp
оба типа YYSTYPE
, который мы определяем с помощью %union
вариант в зубре parser.y
файл. $$
правила дается членом профсоюза yyval
и символы в производстве являются членами в массиве yyvsp
, Например, для союза:
%union {
int t1;
float t2;
}
%type <t1> nt1;
%type <t2> nt2;
%%
input : nt1 | nt2;
nt1 : CONSTANT { $$ = $1; } ;
nt2 : FCONSTANT { $$ = $1 };
%%
int main() { yyparse(); }
при использовании GDB:
nt1
по типу, т.е. $$
за nt1
можно сослаться на yyval.t1
$i
На R.H.S можно отнести: yyvsp[i - t].type
где i — индекс символа, на который делается ссылка, а t — общее количество символов (терминальных и нетерминальных) в производстве. Так, например, $1
в обоих правилах может быть указано yyvsp[1-1].t1
а также yyvsp.[0].t2
соответственно.