2

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

我尝试解析的命令是:

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 $$将打印其他内容。

4

2 回答 2

3

如果您在 C 模板中使用 bison,则 bison 有一个变量yyval和一个数组yyvsp,两者都是 type YYSTYPE,我们使用%unionbisonparser.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 时:

  1. 您可以参考产品的左手,例如nt1通过它的类型,即$$fornt1可以参考yyval.t1
  2. $i在 RHS 上可以通过以下方式引用:yyvsp[i - t].type其中 i 是要引用的符号的索引,t 是生产中的符号总数(终端和非终端)。

因此,例如,$1在这两个规则中,可以分别由yyvsp[1-1].t1和引用yyvsp.[0].t2

于 2017-04-25T19:54:27.783 回答
0

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

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

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

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

push_back除非您安装了标准库调试信息,否则调试器无法进入内部或其他标准功能。

至于你的一般问题,你obj是规则的本地,它被 Bison 转换为函数,并且在它之外不可见,除非你将它存储在其他地方,例如在全局中。

于 2016-03-15T13:10:01.197 回答