From: kanze@us-es.sel.de (James Kanze)
Subject: Re: Need Yacc & Lex retargeted to C++
Organization: SEL
	<1992Nov16.201658.2862@lsil.com>
Date: 18 Nov 92 12:09:46

In article <1992Nov16.201658.2862@lsil.com>, Ameesh Desai writes:

|> In article 21091@murdoch.acc.Virginia.EDU,
|> cgh6m@darwin.clas.Virginia.EDU (Craig G. Hocker) writes:

|> >This seems to be a topic of some interest, so I will mention a 
|> >C++ Parser Class Kit I came across by accident yesterday while
|> >downloading another file. Nobody has mentioned it.
|> >
|> >anonymous ftp to  export.lcs.mit.edu
|> >
|> >    contrib/yacc.shar.Z
|> >
|> >
|> >warning: it's a beta version, but the author does seem to be actively
|> >soliciting people to modify and send him enhancements.
|> >
|> >I can't comment on it, since I haven't tried to do anything with it
|> >yet.

|> The implementation seems to encapsulate only the global yacc variables
|> within a C++ class. In effect providing a C++ "wrapper" to yacc calls
|> and vars.

|> The problem with yacc is not its variables. Its making yacc understand
|> C++ class definations. You should ideally be able to write stuff
|> like...

|> %{

|> class A {   // some C++ class
|> ...
|> public:
|> 	A();		// see note below ...
|> 			//  this would cause problems with yacc
|> };

|> %}

|> %union
|> {
|> int ival;
|> float fval;
|> char *sval
|> A aclass; 		// make this work !
|> }

|> %type <aclass> rule_that_returns_a_class

|> ....
|> %%

|> The fact that a class contains a ctor/dtor should not prevent it from
|> being returned. The current yacc implementation depends on union for
|> declaring the return type, and C++ will not allow a class with a
|> ctor/dtor to be part of the union !

	Nota bene: my comments here concern the classical yacc, and
	not the C++ Parser Class Kit, which I haven't seen.

Actually, there is no rule in yacc that says that the semantic values
have to be declared as a union.  This is just a facility that was
offered, as it corresponds to the most typical case in C.  The actual
type of the semantic value can be anything.

In an object oriented approach, one would probably want a polymorphic
type, rather than a union.  In C++, this implies a (possibly
intelligent) reference or pointer.

There is another point to consider, however.  The code generated by
the traditional yacc maintains these values on a stack, implemented as
a simple C-style array.  This means that if you declare the type as a
class (intelligent reference or pointer), you must provide a default
constructor, which will be called for every element in the array
before parsing starts.  You must also provide an assignment operator.
In addition, none of the elements will be destructed before the end of
parsing, which could result in the locking up of ressourses.

For these reasons, until now, I have always declared the semantic type
to be a C pointer to the base class of all of my semantic values.  The
scanner will construct the actuall desired class (with "new"); it is
up to the individual actions to destruct (with "delete") the
individual values.  (This requires some understanding of what's going
on to do it at the right moment, but isn't really that hard.)

It shouldn't be to difficult, however, to modify the parser to use a
real class (a container type generated from a template?) to implement
the semantic stack.  If this is done, there should be no problem using
intelligent references (the envelope classes in Coplien) as the
semantic values.  (Warning: I have not actually tried this yet.  I'm
just thinking out loud.)
--
James Kanze			GABI Software, Sarl.
email: kanze@us-es.sel.de	8 rue du Faisan
				67000 Strasbourg
				France