bobg+@andrew.cmu.edu (Robert Steven Glickstein) (06/14/89)
I'm sure some of you have encountered this problem before. Both Yacc and Lex make all of their identifiers external, when in fact they should be static. This becomes a major problem when you have large software projects in which zillions of libraries are linked together, any two of which might define yyparse, yytext, yylength, etc., leading to a name conflict. The kludgy solution that we've been using at the ITC has been to run lex.yy.c and y.tab.c through sed, changing all instances of "yy" to "fooyy". The right solution (short of hacking Yacc and Lex themselves) is to run the output files through a postprocessor to make all the "yy"-something declarations static. This postprocessor would optionally preserve the external-ness of yylex and yyparse, but it would be able to rename them to something the programmer specified. (I call this an option because another behavior would be to leave yylex and yyparse static, and provide interface routines in the files foo.l and bar.y to get at the parser and tokenizer.) Anyway, does such a postprocessor exist? If not, I plan to write one; how much interest do you folks have in seeing it written? Gratefully, Bob Glickstein Information Technology Center Carnegie Mellon University Pittsburgh, PA
swh@hpcupt1.HP.COM (Steve Harrold) (06/14/89)
Re: Hiding yacc, et al If such a post-processor existed I would indeed use it. But, as you've already discovered, the "sed" route is already available. Both methods are "post-processors". Additionally, for those implementations of lex and yacc that rely on the -ll and -ly switches for library routines, you'll have to find some way of renaming these vendor supplied external routines.
peter@thirdi.UUCP (Peter Rowell) (06/15/89)
In article <YYZLi4u00Vsn07D0gR@andrew.cmu.edu> bobg+@andrew.cmu.edu (Robert Steven Glickstein) writes: >I'm sure some of you have encountered this problem before. Both Yacc >and Lex make all of their identifiers external, when in fact they should >be static. I agree. The global/static variable problem can be solved (portably, I believe) by putting the following rule in your makefile. 1. After yacc has created y.tab.c, we create the target .c file by putting a bunch of static definitions at the front of the file. Then when the real McCoy is seen, the compiler considers it to be a *static* declaration, not a *global* declaration. 2. The grep is used to remove those nasty line number directives put out to help the compiler to tell you the line the problem is on, but which make working with almost any debugger pure hell. 3. The sed replaces the references to YYSTYPE, yyparse, yylex, and yylval with names that are specific to the grammar. E.g. cgram.y would define cgram_TYPE, cgram_parse, cgram_lex, and cgram_lval. Don't forget that if you change the name of yylval in the grammar, you must change it in the .h file created (if any). This could have been done by just renaming *everything* starting with "yy" to "$*_", but I like to have a few true globals as possible. If your yylex is contained in the grammar file, you can add the following to the static file: static int yylex(); static YYSTYPE yylval; and then you need only to rename yyparse(); ==== rule for your makefile ==== # Since the following creates the .c file, it will work fine with # any ".c.o" rule you may have. .y.c: yacc -d $*.y @cat yacc.static > $*.c # creates the target .c @grep -v "^#.*line" y.tab.c |\ sed -e 's/yyparse/$*_parse/'\ -e 's/yylex/$*_lex/'\ -e 's/yylval/$*_lval/'\ -e 's/YYSTYPE/$*_TYPE/'\ >> $*.c # appends to the target .c @sed -e 's/yylval/$*_lval/'\ -e 's/YYSTYPE/$*_TYPE/'\ y.tab.h > $*.yacc.h # process and save the defines @rm y.tab.c y.tab.h ===== "yacc.static" contains: ===== static YYSTYPE yyv[]; static int yychar; static int yynerrs; static short yyerrflag; ---------------------------------------------------------------------- Peter Rowell peter@thirdi.UUCP Third Eye Software, Inc. (415) 321-0967 Menlo Park, CA 94025 "There are already enough names." Lao Tze
bobg+@andrew.cmu.edu (Robert Steven Glickstein) (07/22/89)
> Excerpts from ext.nn.comp.unix.questions: 13-Jun-89 Hiding Yacc vars > Robert S. Glickstein@and (1274) > I'm sure some of you have encountered this problem before. Both Yacc > and Lex make all of their identifiers external, when in fact they should > be static. This becomes a major problem when you have large software > projects in which zillions of libraries are linked together, any two of > which might define yyparse, yytext, yylength, etc., leading to a name > conflict. > [...] > The right solution (short of hacking Yacc and Lex > themselves) is to run the output files through a postprocessor to make > all the "yy"-something declarations static. [...] > Anyway, does such a postprocessor exist? If not, I plan to write one; > how much interest do you folks have in seeing it written? Well, I've written the above-described postprocessor, and it works like a charm. It's called yyhide, and for those of you who are drooling at the thought of getting your hands on it, it will be available in the Andrew system distributed with X11R4. I couldn't have written this program without the help of several netters, who assisted with Yacc problems and various semantic questions. Thanks to them, and let's hope that someday soon, better versions of Yacc and Lex will become available which will make yyhide obsolete. _______________________________ Bob Glickstein, System Designer Information Technology Center room 220 Carnegie Mellon University Pittsburgh, PA 15213-3890 (412) 268-6743 Mail to: bobg+@andrew.cmu.edu UUCP: ...!harvard!andrew.cmu.edu!bobg 101 USES FOR A DEAD MICROPROCESSOR (1) Scarecrow for centipedes (2) Dead cat brush (3) Hair barrettes (4) Cleats (5) Self-piercing earrings (6) Fungus trellis (7) False eyelashes (8) Prosthetic dog claws . . . (99) Window garden harrow (pulled behind Tonka tractors) (100) Killer velcro (101) Currency