Redo Assignment 1, using C++, with the changes specified below.
You will need to define at least the classes symbol and grammar. I recommend that you at least define an additional class rule, either inside the grammar class or with the grammar class as its friend. If you do this, then I will not deduct for having private member functions of rule return mutable values -- presumably the member functions of rule and grammar will use such functions with care.
The return type of the getYields method should be of a new class yields that has a member function size(). You needn't define this class explicitly. If you define it in terms of the "STL" container templates, then you may simply use typedef to define the class (and you will get the size() method for free). You will also need to overload the << operator to accept objects of class yields as its right operand.
The grammar class is to have three different addRule methods for adding rules to the grammar, as in Assignment 1 (but not Assignment 3). Your getYields method should not assume any upper bound on the length of the right-hand size of a rule. It may assume that there are no epsilon productions.
Recall that we are assuming that the program is typically used with small grammars, or small values of n, or both. So you may assume that the cost of copying data is not too high; this may affect your representation. In particular, the classes symbol and grammar should be actual classes rather than types of pointers to classes -- the test function assumes this. For example, they could be defined in terms of the STL container templates. Even though we are assuming that our objects are fairly small, you should still consider using reference variables, and passing parameters by reference when this is possible.
You may use pointer variables in your program if you want. In order to allow for the possibility that calls to a destructor are needed, the test function assumes that a cleanup function has been defined for parameter types grammar and yields. These functions should be defined, and should call any appropriate destructors, although if you don't need destructors then you may well be able to give them empty bodies. Note that these functions are not member functions of the relevant classes. It's always a good idea to document that you don't need an explicit destructor for a class, when that is the case.
As always, you may define any new classes and functions that you find helpful. For example, you may need to overload the << operator to accept objects of other classes besides yields.
Test your classes with the test file A4.cpp, which is available on the class web site. Turn in hard copies of your files (both header and implementation files), a hard copy of the results of your tests, and a diskette containing your files and the results of your test.