Xref: utzoo comp.unix.questions:14285 comp.lang.c:19369 Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!ucbvax!hplabs!pyramid!thirdi!peter From: peter@thirdi.UUCP (Peter Rowell) Newsgroups: comp.unix.questions,comp.lang.c Subject: Re: Hiding Yacc vars Message-ID: <463@thirdi.UUCP> Date: 14 Jun 89 21:36:57 GMT References: Reply-To: peter@thirdi.UUCP (Peter Rowell) Organization: Third Eye Software, Menlo Park, CA Lines: 59 In article 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