|
List Info
Thread: initial-action question
|
|
| initial-action question |
  United States |
2008-02-11 02:17:02 |
I would like to declare some variables that are local to
yyparse. I
am building a linked list of structures, and I need to make
sure I
have values for all the structure members before I add a new
node to
the list. Since I wrote the parser to be a pure parser,
global
variables, are not an option. Something like
%initial-action {int x;
int y; int z;} doesn't work, since the initial action code
is
enclosed in braces and the variables x,y,z,etc. do not exist
outside
the braces. If I use %parse-param{variables_t variables;},
where
variables_t is a structure containing x,y,z, I get what I
want, but
since I don't need x,y,z after yyparse returns, this seems
like an
inefficient way to do things. Is there a better way to do
this?
There must be a "standard" way this is
done---temporarily saving all
the previously parsed values until all the required values
are
available. Any help would be very appreciated. Thanks.
_______________________________________________
help-bison gnu.org http
://lists.gnu.org/mailman/listinfo/help-bison
|
|
| Re: initial-action question |
  Germany |
2008-02-11 04:03:52 |
> I would like to declare some variables that are local
to yyparse.
To the best of my knowledge, you would need to modify the
skeleton file.
When I wanted to do this, I determined that it was not
possible otherwise.
I may be wrong, but I don't think this has changed with more
recent
versions.
> I
> am building a linked list of structures, and I need to
make sure I
> have values for all the structure members before I add
a new node to
> the list. Since I wrote the parser to be a pure
parser, global
> variables, are not an option.
Why not? I'm not recommending this, but you can certainly
declare global
variables and make them accessible to `yyparse' in the
ordinary way (i.e.,
by using `extern' declarations, if necessary). If you're
using threads,
you will, of course, have to protect these variables with
mutexes, which
would reduce concurrency. That's why I recommend against
doing this.
> Something like %initial-action {int x;
> int y; int z;} doesn't work, since the initial action
code is
> enclosed in braces and the variables x,y,z,etc. do not
exist outside
> the braces. If I use %parse-param{variables_t
variables;}, where
> variables_t is a structure containing x,y,z, I get what
I want, but
> since I don't need x,y,z after yyparse returns, this
seems like an
> inefficient way to do things. Is there a better way to
do this?
> There must be a "standard" way this is
done---temporarily saving all
> the previously parsed values until all the required
values are
> available. Any help would be very appreciated.
Thanks.
I recommend declaring a `struct' or `class' type for use as
the parameter
to `yyparse'. You can put anything you want into it, not
just these
variables. If you're worried about the memory, you can
declare this
object in such a way that it will be on the stack and
disappear in the
fullness of time. Otherwise, you could allocate memory for
it on the heap
and free it when you're done with it. However, the cost of
doing this
with respect to time might outweigh the real or imaginary
advantage of not
declaring it statically.
Unless you're working on a system where every clock cycle
and every byte
of memory counts, I wouldn't worry about a few integers, or
even a few
larger objects.
I allocate the (very large) object that I pass as the
parameter to
`yyparse' (and `yylex') on the heap and free the memory when
I'm done with
it.
Laurence Finston
_______________________________________________
help-bison gnu.org http
://lists.gnu.org/mailman/listinfo/help-bison
|
|
| Re: initial-action question |
  Sweden |
2008-02-11 06:28:58 |
On 11 Feb 2008, at 09:17, Aaron Jackson wrote:
> I would like to declare some variables that are local
to yyparse.
> I am building a linked list of structures, and I need
to make sure
> I have values for all the structure members before I
add a new node
> to the list. Since I wrote the parser to be a pure
parser, global
> variables, are not an option. Something like
%initial-action {int
> x; int y; int z;} doesn't work, since the initial
action code is
> enclosed in braces and the variables x,y,z,etc. do not
exist
> outside the braces.
If that happens, it is probably a bug.
> If I use %parse-param{variables_t variables;}, where
variables_t
> is a structure containing x,y,z, I get what I want, but
since I
> don't need x,y,z after yyparse returns, this seems like
an
> inefficient way to do things. Is there a better way to
do this?
There is a command %define or something that lets you
defining a M4
macor that can be put into the skeleton file.
> There must be a "standard" way this is
done---temporarily saving
> all the previously parsed values until all the required
values are
> available.
Not really: the origin is in impure parsers for rather
standard
situations.
Hans Aberg
_______________________________________________
help-bison gnu.org http
://lists.gnu.org/mailman/listinfo/help-bison
|
|
| Re: initial-action question |
  United States |
2008-02-11 11:33:25 |
Thanks for the response.
On Feb 11, 2008, at 5:03 AM, lfinsto1 gwdg.de wrote:
>> I would like to declare some variables that are
local to yyparse.
>
> To the best of my knowledge, you would need to modify
the skeleton
> file.
> When I wanted to do this, I determined that it was not
possible
> otherwise.
> I may be wrong, but I don't think this has changed with
more recent
> versions.
I wanted to avoid this since I want my .y code to be
portable.
>
>> I
>> am building a linked list of structures, and I need
to make sure I
>> have values for all the structure members before I
add a new node to
>> the list. Since I wrote the parser to be a pure
parser, global
>> variables, are not an option.
>
> Why not? I'm not recommending this, but you can
certainly declare
> global
> variables and make them accessible to `yyparse' in the
ordinary way
> (i.e.,
> by using `extern' declarations, if necessary). If
you're using
> threads,
> you will, of course, have to protect these variables
with mutexes,
> which
> would reduce concurrency. That's why I recommend
against doing this.
OK, I think I worded my email a bit too strong. I would
prefer not
to use global variables for the reasons you mentioned.
>
>> Something like %initial-action {int x;
>> int y; int z;} doesn't work, since the initial
action code is
>> enclosed in braces and the variables x,y,z,etc. do
not exist outside
>> the braces. If I use %parse-param{variables_t
variables;}, where
>> variables_t is a structure containing x,y,z, I get
what I want, but
>> since I don't need x,y,z after yyparse returns,
this seems like an
>> inefficient way to do things. Is there a better
way to do this?
>> There must be a "standard" way this is
done---temporarily saving all
>> the previously parsed values until all the required
values are
>> available. Any help would be very appreciated.
Thanks.
>
> I recommend declaring a `struct' or `class' type for
use as the
> parameter
> to `yyparse'. You can put anything you want into it,
not just these
> variables. If you're worried about the memory, you
can declare this
> object in such a way that it will be on the stack and
disappear in the
> fullness of time. Otherwise, you could allocate memory
for it on
> the heap
> and free it when you're done with it. However, the
cost of doing this
> with respect to time might outweigh the real or
imaginary advantage
> of not
> declaring it statically.
>
> Unless you're working on a system where every clock
cycle and every
> byte
> of memory counts, I wouldn't worry about a few
integers, or even a few
> larger objects.
>
> I allocate the (very large) object that I pass as the
parameter to
> `yyparse' (and `yylex') on the heap and free the memory
when I'm
> done with
> it.
I ended up using a structure with all the variables I
needed, but it
just doesn't seem personally satisfying to me. It just
seems cleaner
if I could declare variables that are local to yyparse, that
way, the
function calling yyparse doesn't have to know what's going
on in the
background.
_______________________________________________
help-bison gnu.org http
://lists.gnu.org/mailman/listinfo/help-bison
|
|
| Re: initial-action question |
  United States |
2008-02-11 11:47:39 |
On Mon, 11 Feb 2008, Aaron Jackson wrote:
> I would like to declare some variables that are local
to yyparse.
> If I use %parse-param{variables_t variables;},
> where variables_t is a structure containing x,y,z, I
get what I want, but
> since I don't need x,y,z after yyparse returns, this
seems like an inefficient
> way to do things.
I see two advantages of the %parse-param approach that, in
my mind,
outweigh the disadvantage of writing a few extra lines of
code.
First, Bison can easily make the %parse-param variables
accessible to all
parser functions including Bison-generated internal
functions that the
user doesn't normally invoke directly.
Second, for push parsing, the main parser function is
invoked multiple
times, so state variables cannot be local to it.
You may argue that these advantages are irrelevant to your
use case. I
feel it's better not to customize Bison's interfaces
perfectly for every
possible use case. Instead, I think we need to balance such
customization
with simple generalizations for the Bison project as a
whole.
You might consider wrapping yyparse in your own function
that allocates
your %parse-param variables on the stack.
_______________________________________________
help-bison gnu.org http
://lists.gnu.org/mailman/listinfo/help-bison
|
|
| Re: initial-action question |
  Germany |
2008-02-12 06:10:52 |
Aaron Jackson wrote:
> Thanks for the response.
You're welcome.
> On Feb 11, 2008, at 5:03 AM, lfinsto1 gwdg.de
wrote:
>
>> To the best of my knowledge, you would need to
modify the skeleton
file. [...]
> I wanted to avoid this since I want my .y code to be
portable.
It would be. You'd just have to include it in your
distribution and
account for this in your `make' rules and/or explain to
users anything
special they'd need to do. To the best of my knowledge,
Bison uses to m4
to copy the skeleton file and inserts the parser rules and
the
corresponding actions in the appropriate places. However, I
don't think
it's necessary or desirable in this case. (I've never
modified the
skeleton file myself.)
> I ended up using a structure with all the variables I
needed, but it
just > doesn't seem personally satisfying to me.
> It just seems cleaner
> if I could declare variables that are local to yyparse,
that way, the
function calling yyparse doesn't have to know what's going
on in the
background.
I didn't know about Bison's internal functions, which Joel
Denny explained
in his message, making it impossible, or at least
impracticable, for users
to declare local variables in `yyparse'.
>From the point of view of programming philosophy, I
don't see anything not
clean about using the parameter. The place where you store
your values is
just a region of memory. I don't see any significant
difference between
letting it be popped from the stack when `yyparse' returns
to its caller
or freeing it after it returns. It will probably be cheaper
to let it be
popped from the stack, but not so much that I would choose
to program in a
way that would be less clear and understandable.
If you're really worried about the caller of `yyparse'
having access to
the contents of the object passed as a parameter, you could
use C++ and
make them private data members. You wouldn't necessarily
have to generate
a C++ parser. I generate a C parser and compile with g++.
On the other
hand, if you're using C, you're already using a language
that doesn't
support data hiding that much anyway, so I wouldn't worry
too much about
it. After all, the caller of `yyparse' isn't going to
access this data by
itself --- it's under your control. (I'm not very
"object-oriented".)
It can also be very useful to have a structure that
represents the state
of a parse and which continues to exist after `yyparse' has
returned.
Laurence
_______________________________________________
help-bison gnu.org http
://lists.gnu.org/mailman/listinfo/help-bison
|
|
[1-6]
|
|