Reputation: 153
I'm trying to write a small compiler which can parse some commands I type.
The command I try to parse is:
create class something = create class do_something ;
My code would be something like this:
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);
}
However, when I try to call the parser somewhere else, I can't get the Class
I have defined before.
I guess there must be something wrong with the parser and have done some debugging with GDB. But I just can't step in the function push_back()
, neither can I print the information of obj
correctly.
So, I am wondering if there is a way that I can get the value of $$
or $1
while using GDB. Simply type in p $$
would print something else.
Upvotes: 4
Views: 1696
Reputation: 875
If you're using bison with the C templates, bison has a variable yyval
and an array yyvsp
, both of type YYSTYPE
, which we define using the %union
option in the bison parser.y
file. The $$
of a rule is given by the union member of yyval
, and the symbols in the production are members in the array yyvsp
. For example, for the union:
%union {
int t1;
float t2;
}
%type <t1> nt1;
%type <t2> nt2;
%%
input : nt1 | nt2;
nt1 : CONSTANT { $$ = $1; } ;
nt2 : FCONSTANT { $$ = $1 };
%%
int main() { yyparse(); }
while using gdb:
nt1
by it's type, i.e $$
for nt1
can be referred to by yyval.t1
$i
on the R.H.S can be referred to by: yyvsp[i - t].type
where i is the index of the symbol to be referenced, and t is the total number of symbols(terminal and non-terminals) in production. So, for example, $1
in both rules can be referred to by yyvsp[1-1].t1
and yyvsp.[0].t2
, respectively.
Upvotes: 5
Reputation: 797
The simplest way is probably declaring a variable of the same type as your rule ($$
has this type) and assigning it.
%union {
int I;
}
%type<I> rule whatever
rule: whatever {
int foo = $1;
// printf("%d", foo);
$$ = $1;
}
You can then either see it in the debugger or just printf it.
The debugger cannot go inside push_back
or other standard functions unless you have standard library debugging information installed.
As for your question in general, your obj
is local to the rule, which gets transformed to the function by Bison, and is not visible outside it unless you store it somewhere else, e.g. in a global.
Upvotes: 0