在使用GDB进行调试时,如何知道变量在bison中的值?

时间:2016-03-15 12:32:14

标签: c++ gdb bison bisonc++

我正在尝试编写一个可以解析我输入的命令的小编译器。

我尝试解析的命令是:

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的信息。

所以,我想知道在使用GDB时是否有一种方法可以获得$$$1的值。只需输入p $$即可打印其他内容。

2 个答案:

答案 0 :(得分:2)

如果你将bison与C模板一起使用,bison有一个变量yyval和一个yyvsp数组YYSTYPE,我们使用{%union来定义bison parser.y文件中的1}}选项。规则的$$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时

  1. 您可以参考作品的左侧,例如nt1的类型,$$ nt1可以引用yyval.t1 }
  2. RHS上的
  3. $i可以通过以下来引用:yyvsp[i - t].type其中i是要引用的符号的索引,t是符号的总数(终端和非终端)生产。
  4. 因此,例如,$1yyvsp[1-1].t1分别可以引用这两个规则中的yyvsp.[0].t2

答案 1 :(得分:0)

最简单的方法可能是声明与您的规则相同类型的变量($$具有此类型)并分配它。

%union {
  int I;
}
%type<I> rule whatever

rule: whatever {
    int foo = $1;
    // printf("%d", foo);
    $$ = $1;
}

然后,您可以在调试器中查看它,也可以只打印它。

除非安装了标准库调试信息,否则调试器不能进入push_back或其他标准函数。

至于你的问题一般来说,你的obj是规则的本地,由Bison转换为函数,除非你将它存储在其他地方,否则在它之外是不可见的,例如在全球范围内。