From: mcgrant@rascals.stanford.edu (Michael C. Grant)
Subject: Re: yacc and C++
Organization: Information Systems Laboratory, Stanford University
Date: 9 Nov 92 12:52:19

In article <1992Nov9.013842.28215@cs.brown.edu>
hm@cs.brown.edu (Harry Mamaysky) writes:

   So, does any one have a better way of using YACC with C++?
   Does a better way exist?
   Does a (free) YACC like tool exist for C++? If so, where?
   Please respond either by email or to comp.lang.c++. If any one out
   there has a nicer solution, I am most eager to hear about it.
   Harry.
   hm@cs.brown.edu

Well, here's a hack that I put together so that 1) yacc uses new instead
of malloc, and 2) I can use a class for the YYSTYPE (and overload operator=
for example). It's not modified at all for speed, just for correctness.

I've only tried this patch on the yacc++ included with the Sun Sparcstation.

To use the (context) patch, put the file in yaccpar.diff, name your file
with a .Y (instead of .y) suffix, and add the following suffix entry
to your Makefile:

.Y.o:
        yacc++ -d $(YFLAGS) $*.Y
        rm -f $*.tab.H
        mv y.tab.h $*.tab.H
        patch y.tab.c yaccpar.diff -o $*.tab.C
        rm -f y.tab.c
        $(CCC) $(CFLAGS) $(YCFLAGS) -c -o $*.o $*.tab.C

This also simulates the bison naming scheme; i.e. if my file is parse.Y
then the output is parse.tab.H and parse.tab.C.

I have no idea if this is a near-optimal solution but it worked for me
and took me very little time to do.

Nobody is allowed to sue me or get ticked off at me if this doesn't
work for them. So caveat emptor.

Mike

*** /usr/lang/SC1.0/yaccpar	Wed Feb 13 23:22:42 1991
--- yaccpar.C	Thu Oct 29 00:21:14 1992
***************
*** 26,33 ****
  	goto yynewstate;\
  }
  #define YYRECOVERING()	(!!yyerrflag)
- #define YYCOPY(to, from, type) \
- 	(type *) memcpy(to, (char *) from, yynewmax * sizeof(type))
  #ifndef YYDEBUG
  #	define YYDEBUG	1	/* make debugging available */
  #endif
--- 26,31 ----
***************
*** 38,47 ****
  ** if you have function redefined error messages here.
  */
  
- #ifdef __cplusplus
  EXTERN_FUNCTION ( extern int printf,    (const char*, DOTDOTDOT) );
  EXTERN_FUNCTION ( extern void *memcpy,  (void *, const void *, int) );
- #endif
  
  
  /*
--- 36,43 ----
***************
*** 57,64 ****
  /*
  ** static variables used by the parser
  */
! static YYSTYPE yy_yyv[YYMAXDEPTH], *yyv = yy_yyv;	/* value stack */
! static int yy_yys[YYMAXDEPTH], *yys = yy_yys;	/* state stack */
  
  static YYSTYPE *yypv;			/* top of value stack */
  static int *yyps;			/* top of state stack */
--- 53,60 ----
  /*
  ** static variables used by the parser
  */
! static YYSTYPE* yyv = new YYSTYPE [YYMAXDEPTH]; /* value stack */
! static int*     yys = new int     [YYMAXDEPTH]; /* state stack */
  
  static YYSTYPE *yypv;			/* top of value stack */
  static int *yyps;			/* top of state stack */
***************
*** 66,72 ****
  static int yystate;			/* current state */
  static int yytmp;			/* extra var (lasts between blocks) */
  
- #if defined(__cplusplus) || defined(__STDC__) || defined(lint)
  static int __yaccpar_lint_hack__ = 0;   
  				/* if you change the value from 0 to
  				something else, make sure you know
--- 62,67 ----
***************
*** 73,79 ****
  				what to do with yyerrlab reference.
  				This is a hack - to make sure C++ and
  				lint are happy with the 4.1 yacc code. */
- #endif
  
  int yynerrs;			/* number of errors */
  
--- 68,73 ----
***************
*** 102,108 ****
  	yyerrflag = 0;
  	yychar = -1;
  
- #if defined(__cplusplus) || defined(__STDC__) || defined(lint)
  /*
     Note that the following can never be executed but simply to please
     lint and C++
--- 96,101 ----
***************
*** 112,118 ****
  		case 1: goto yyerrlab;
  		case 2: goto yynewstate;
  	}
- #endif
  
  	{
  		register YYSTYPE *yy_pv;	/* top of value stack */
--- 105,110 ----
***************
*** 179,219 ****
  		if ( ++yy_ps >= &yys[ yymaxdepth ] )	/* room on stack? */
  		{
                          /*
!                         ** reallocate and recover.  Note that pointers
                          ** have to be reset, or bad things will happen
                          */ 
                          int yyps_index = (yy_ps - yys);
                          int yypv_index = (yy_pv - yyv);
                          int yypvt_index = (yypvt - yyv);
!                         int yynewmax;
  
! 			yynewmax = yymaxdepth + YYMAXDEPTH;
! 			if (yymaxdepth == YYMAXDEPTH)	/* first time growth */
! 			{
! 				YYSTYPE *newyyv = (YYSTYPE*)malloc(yynewmax*sizeof(YYSTYPE));
! 				int *newyys = (int*)malloc(yynewmax*sizeof(int));
! 				if (newyys != 0 && newyyv != 0)
! 				{
! 					yys = YYCOPY(newyys, yys, int);
! 					yyv = YYCOPY(newyyv, yyv, YYSTYPE);
! 				}
! 				else
! 					yynewmax = 0;	/* failed */
! 			}
! 			else				/* not first time */
! 			{
! 				yyv = (YYSTYPE*)realloc((char*)yyv,
!                                 	yynewmax * sizeof(YYSTYPE));
! 				yys = (int*)realloc((char*)yys,
! 					yynewmax * sizeof(int));
! 				if (yys == 0 || yyv == 0)
! 					yynewmax = 0;	/* failed */
! 			}
! 			if (yynewmax <= yymaxdepth)	/* tables not expanded */
! 			{
! 				yyerror( "yacc stack overflow" );
! 				YYABORT;
! 			}
  			yymaxdepth = yynewmax;
  
                          yy_ps = yys + yyps_index;
--- 171,192 ----
  		if ( ++yy_ps >= &yys[ yymaxdepth ] )	/* room on stack? */
  		{
                          /*
!                         ** grow the stack. Note that pointers
                          ** have to be reset, or bad things will happen
                          */ 
                          int yyps_index = (yy_ps - yys);
                          int yypv_index = (yy_pv - yyv);
                          int yypvt_index = (yypvt - yyv);
!                         int yynewmax = yymaxdepth + YYMAXDEPTH;
  
!                         YYSTYPE* newyyv = new YYSTYPE [yynewmax];
!                         int*     newyys = new int     [yynewmax];
!                         for ( register int k = 0 ; k < yymaxdepth ; k++ ) {
!                                 newyyv[k] = yyv[k];
!                                 newyys[k] = yys[k];
!                         }
!                         delete [] yys; yys = newyys;
!                         delete [] yyv; yyv = newyyv;
  			yymaxdepth = yynewmax;
  
                          yy_ps = yys + yyps_index;

Newsgroups: comp.lang.c++,comp.std.c++