[comp.unix.internals] two

leland@cs (12/07/90)

I have an application that requires two discrete uses of both lex and
yacc.  Since both lex and yacc have hardcoded names (all with the 'yy'
prefix) for a whole bunch of global symbols, there is an immediate
problem:  somehow the two sets must be hidden from each other and
distinguished for any other code that accesses them.

I've tried this kludge:  create a header file that re-#define's all the
names 'yyfoo' in lex/yacc set #1 to be named, say, set1yyfoo, and all
those in set #2 to be named set2yyfoo.  This has worked for me in the
past, but won't in this particular instance because the generated
code includes calls to yyless() and yywrap(), which are in the LEX
library (-ll), the contents of which I cannot rename.  So that doesn't
work.

I've also investigated GNU's replacements for these programs, flex and
bison.  I haven't gotten to the bison documentation yet, but a
quick look at the flex man page implies that these programs still
have the hardcoded global symbol names.  Flex eliminates the need
for the external library, however, so this may solve my problem.  But
it's still a horrible kludge, and it would require that others to whom
I distribute the software maintain flex and/or bison.  I'm looking
for something better.

I may be able to use some special loader options to 'hide' the yy*
symbols when compiling the object modules that contain them, but
the procedure for doing is not obvious nor it is standardized across
loader versions.

Has anybody listening gotten into this before?  Can you offer any
suggestions?  Thanks for whatever you may know.

It is difficult to accept that, considering how long these programs have
been around, none of the implementers ever thought to make these globals
static or to add a command-line option to rename them.

Leland Woodbury
-- 
ARPANET/INTERNET: leland@cs.columbia.edu
	  USENET: ...!columbia!cs.columbia.edu!leland
	  BITNET: leland%cs.columbia.edu@cuvmb
	  USMAIL: Columbia Univ., 457 CS, 500 W. 120 St., NYC 10027-6699

tom@flood.com (Tom Chatt) (12/10/90)

I have an several occasions used more than one lex/yacc thing
in one executable. I used a kludge that is similar in concept
to yours, but perhaps a bit more reliable. Rather than creating
a header file to redefine all of the yy_symbols to something
else (which requires you to know all of the yy_symbols), I would
run a "sed" on the generated code to do a global replace on the
"yy" prefix. For example, to make two separate yaccs:
	    yacc zzparse.y
	    sed -e s/yy/zz/g y.tab.c > zzparse.c
	    yacc xxparse.y
	    sed -e s/yy/xx/g y.tab.c > xxparse.c
If you are willing to follow some fairly reasonable naming
conventions with regard to your lex and yacc source files, the
above sort of filtering can be implemented in a couple of
general ".y.o" and ".l.o" rules in your makefile. This solves
the general case, rather than having to deal (e.g., create a
header file) for each specific case, which is surely tedious.

With regard to using calls out of the lex library (which are not
available for you to rename -- not easily, anyway), I believe that
most of the calls in the lex (and yacc) libraries provide "default
action" routines which a user may want to customize. (This explains
why the implementers did *not* make these routines static globals.
It would have defeated the purpose.) For instance, the lex library
even provides a "main()" routine, so that you could create a lex
executable without having to provide your own "main()". Of course,
providing your own "main()" is not precluded. Likewise for "yywrap()",
and (if I remember right) everything else in there. It is possible
(and not even hard) to create a lex source which does not need any
of these default routines, by providing your own versions. Your
own versions may perform the same default actions, but this gives
you the opportunity to do your global rename on the prefixes.

I can provide more specific info if you e-mail me (though I'm out
of the office a lot recently and can't guarantee quick turnaround).
Good luck.

-- 
Tom Chatt                        \   Don't take offense, take action.
Internet: tom@flood.com           \    Speak up. When we remain silent,
UUCP: ...!uunet!flood!tom        / \     we oppress ourselves.