Hiding Yacc vars

Peter Rowell peter at thirdi.UUCP
Thu Jun 15 07:36:57 AEST 1989


In article <YYZLi4u00Vsn07D0gR at andrew.cmu.edu> bobg+ at 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 at thirdi.UUCP
Third Eye Software, Inc.		(415) 321-0967
Menlo Park, CA  94025   	"There are already enough names." Lao Tze



More information about the Comp.unix.questions mailing list