我正在尝试编写一个可以解析我输入的命令的小编译器。
我尝试解析的命令是:
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 $$
即可打印其他内容。
答案 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时:
nt1
的类型,$$
nt1
可以引用yyval.t1
} $i
可以通过以下来引用:yyvsp[i - t].type
其中i是要引用的符号的索引,t是符号的总数(终端和非终端)生产。 因此,例如,$1
和yyvsp[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转换为函数,除非你将它存储在其他地方,否则在它之外是不可见的,例如在全球范围内。