使用 GDB 调试时如何知道 bison 中变量的值?
How can I know the value of a variable in bison while debugging with GDB?
我正在尝试编写一个小型编译器,它可以解析我键入的一些命令。
我尝试解析的命令是:
create class something = create class do_something ;
我的代码应该是这样的:
grammar : my_grammar
{
list<Class1 *> *obj = new list<Class1 *>;
obj->push_back();
}
my_grammar : my_definition SEMICOLON
{
report("something detected!");
$$ = ;
}
my_definition : CREATE CLASS class_name EQU class_expression
{
->setClassName(*);
$$ = ;
}
class_expression : CREATE CLASS operand_name
{
$$ = new OperandClass();
$$->setOperationType("createClass");
$$->setOperandName(*);
}
但是,当我尝试在其他地方调用解析器时,我无法获得我之前定义的Class
。
我猜一定是解析器出了问题,用GDB调试了一下。但是我就是进不了函数push_back()
,也不能正确打印obj
的信息。
所以,我想知道是否有一种方法可以在使用 GDB 时获取 $$
或 </code> 的值。只需输入 <code>p $$
即可打印其他内容。
最简单的方法可能是声明一个与您的规则类型相同的变量($$
具有此类型)并分配它。
%union {
int I;
}
%type<I> rule whatever
rule: whatever {
int foo = ;
// printf("%d", foo);
$$ = ;
}
然后您可以在调试器中看到它或者只是打印它。
调试器无法进入 push_back
或其他标准函数,除非您安装了标准库调试信息。
至于你的一般问题,你的 obj
是规则的本地问题,它被 Bison 转换为函数,并且在它之外不可见,除非你将它存储在其他地方,例如在全球范围内。
如果您将 bison 与 C 模板一起使用,bison 有一个变量 yyval
和一个数组 yyvsp
,都是 YYSTYPE
类型,我们使用 [= bison parser.y
文件中的 14=] 选项。规则的$$
由yyval
的并集成员给出,产生式中的符号是数组yyvsp
中的成员。例如,对于联合:
%union {
int t1;
float t2;
}
%type <t1> nt1;
%type <t2> nt2;
%%
input : nt1 | nt2;
nt1 : CONSTANT { $$ = ; } ;
nt2 : FCONSTANT { $$ = };
%%
int main() { yyparse(); }
使用 gdb 时:
- 你可以引用左手的产生式,例如
nt1
的类型,即nt1
的$$
可以用yyval.t1
R.H.S上的$i
可以这样引用:yyvsp[i - t].type
其中i是要引用的符号的索引,t是符号的总数(终端和非终端)在生产中。
因此,例如,两个规则中的</code>可以分别被<code>yyvsp[1-1].t1
和yyvsp.[0].t2
引用。
我正在尝试编写一个小型编译器,它可以解析我键入的一些命令。
我尝试解析的命令是:
create class something = create class do_something ;
我的代码应该是这样的:
grammar : my_grammar
{
list<Class1 *> *obj = new list<Class1 *>;
obj->push_back();
}
my_grammar : my_definition SEMICOLON
{
report("something detected!");
$$ = ;
}
my_definition : CREATE CLASS class_name EQU class_expression
{
->setClassName(*);
$$ = ;
}
class_expression : CREATE CLASS operand_name
{
$$ = new OperandClass();
$$->setOperationType("createClass");
$$->setOperandName(*);
}
但是,当我尝试在其他地方调用解析器时,我无法获得我之前定义的Class
。
我猜一定是解析器出了问题,用GDB调试了一下。但是我就是进不了函数push_back()
,也不能正确打印obj
的信息。
所以,我想知道是否有一种方法可以在使用 GDB 时获取 $$
或 </code> 的值。只需输入 <code>p $$
即可打印其他内容。
最简单的方法可能是声明一个与您的规则类型相同的变量($$
具有此类型)并分配它。
%union {
int I;
}
%type<I> rule whatever
rule: whatever {
int foo = ;
// printf("%d", foo);
$$ = ;
}
然后您可以在调试器中看到它或者只是打印它。
调试器无法进入 push_back
或其他标准函数,除非您安装了标准库调试信息。
至于你的一般问题,你的 obj
是规则的本地问题,它被 Bison 转换为函数,并且在它之外不可见,除非你将它存储在其他地方,例如在全球范围内。
如果您将 bison 与 C 模板一起使用,bison 有一个变量 yyval
和一个数组 yyvsp
,都是 YYSTYPE
类型,我们使用 [= bison parser.y
文件中的 14=] 选项。规则的$$
由yyval
的并集成员给出,产生式中的符号是数组yyvsp
中的成员。例如,对于联合:
%union {
int t1;
float t2;
}
%type <t1> nt1;
%type <t2> nt2;
%%
input : nt1 | nt2;
nt1 : CONSTANT { $$ = ; } ;
nt2 : FCONSTANT { $$ = };
%%
int main() { yyparse(); }
使用 gdb 时:
- 你可以引用左手的产生式,例如
nt1
的类型,即nt1
的$$
可以用yyval.t1
R.H.S上的 $i
可以这样引用:yyvsp[i - t].type
其中i是要引用的符号的索引,t是符号的总数(终端和非终端)在生产中。
因此,例如,两个规则中的</code>可以分别被<code>yyvsp[1-1].t1
和yyvsp.[0].t2
引用。