HELP NEEDED in Project to Make Yacc Identifiers Static
Robert Steven Glickstein
bobg+ at andrew.cmu.edu
Wed Jul 5 12:08:34 AEST 1989
You may recall that, a while ago, I asked the net about the demand that
would exist for a C-program filter which could take the output of Yacc
or Lex and make all global "yy" variables and functions "static". There
was a large demand, and I have now written such a program. This program
does not presently work, and its failure has to do with a deficiency in
the C language. Perhaps one of you bright C wizards out there can
help...?
The original objective for "yyhide":
Change the storage class of all defined identifiers in C source whose
names begin with "yy" or "YY" to static. So for example,
int yyfoo, *yybar;
becomes
static int yyfoo, *yybar;
This didn't work because of the possible degenerate case
int yyfoo, bar;
so yyhide was changed to do this:
static int yyfoo;
int bar;
This also didn't work because of this case:
struct foo {
int a, b;
} yyfoo, yybar;
which became
static struct foo {
int a, b;
} yyfoo;
static struct foo {
int a, b;
} yybar;
(struct foo redefined). So yyhide's solution was to do this:
struct foo {
int a, b;
};
static struct foo yyfoo;
static struct foo yybar;
So far, so good. The next problem was this case:
extern int yyfoo;
/* Arbitrary amount of code */
int yyfoo;
which became
extern int yyfoo;
/* Arbitrary amount of code */
static int yyfoo;
(yyfoo redefined). So yyhide did this:
/* Arbitrary amount of code */
static int yyfoo;
This was fine when yyfoo was an int, but when yyhide changed this
extern struct foo yyfoo;
/* Arbitrary amount of code */
struct foo yyfoo;
to this
/* Arbitrary amount of code */
static struct foo yyfoo;
and something in the /* Arbitrary amount of code */ referred to yyfoo,
the result was "yyfoo undefined". The provisional solution to this (and
the current state of yyhide) was to change
extern SomeRandomType yyfoo;
/* Arbitrary amount of code */
SomeRandomType yyfoo;
to
static SomeRandomType yyfoo;
/* Arbitrary amount of code */
But even this doesn't work because of this case:
extern int *yyfoo;
/* Arbitrary amount of code */
int yybar[] = {1, 2, 3};
/* Arbitrary amount of code */
int *yyfoo = yybar;
which becomes
static int *yyfoo = yybar;
/* Arbitrary amount of code */
static int yybar[] = {1, 2, 3};
/* Arbitrary amount of code */
(yybar undefined [in definition of yyfoo]). The next step in the
development of yyhide seems to be to do a dependency sort on the
variable declarations, but that seems needlessly complicated.
The problem, in effect, is that the Yacc and Lex templates both use
"extern" declarations as a forward-declaration device, and that this
hack does not work when the forwardly declared variable winds up being
static. "Extern" is being overloaded in this sense, and it's kludgy,
but there you have it. There seems to be no way to make a forward
declaration for a static variable. If that's true, then does anyone
have any good ideas? If that's false (you can forwardly declare a
static variable in C), how is it done?
Bob Glickstein
More information about the Comp.lang.c
mailing list