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
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
lorensen@dwaskill.crd.ge.com (Bill Lorensen) (06/15/89)
I met Steve Johnson about six months ago. Steve is the author of yacc. I complained about the use of external variables in yacc. He mentioned that a prototype file for yyparse exists. Yacc uses it to create the parser, including user code at an indicated location. Sure enough, there is a prototype file in /usr/lib called yaccpar. It appears to be undocumented but I think you can modify this file as the posters have requested. Also, in /usr/lib/lex there are two prototype files, one for c and one for ratfor. I don't know if you can get yacc (or lex) to use your own prototype files via some command line option. Otherwise, your modifications will be used by everyone on the system (dangerous of course). -- Bill Lorensen US Mail:GE Corporate Research and Development P.O. Box 8 Bldg KW Room C207A Schenectady, NY 12301 Office: (518) 387-6744 or 8*833-3874 Fax: (518) 387-6560 or 8*833-6560 E-Mail: lorensen@crd.steinmetz.ge.com
barnett@crdgw1.crd.ge.com (Bruce Barnett) (06/19/89)
In article <LORENSEN.89Jun15071542@dwaskill.crd.ge.com>, lorensen@dwaskill (Bill Lorensen) writes: > >I don't know if you can get yacc (or lex) to use your own prototype >files via some command line option. Otherwise, your modifications will >be used by everyone on the system (dangerous of course). I modified the EASE parser to use some of the routines in the Schreiner/Friedman book "Introduction to Compiler Construction with UNIX". One routine required I modify the yacc parser prototype, to replace the procedure yylex with yyyylex. I did it with the following make rule: y.tab.h parser.c: parser.y @rm -f parser.c yacc -v -d parser.y sed 's/=yylex/=yyyylex/' < y.tab.c >parser.c yyyylex was defined in parser.y, and because of the "=", sed changed the calls to yyyylex and not the procedure itself. -- Bruce G. Barnett <barnett@crdgw1.ge.com> a.k.a. <barnett@[192.35.44.4]> uunet!crdgw1.ge.com!barnett barnett@crdgw1.UUCP
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