Copyright © 1998-99, Compiler Resources, Inc. New Features in Revision 2.3
The Current Model
Yacc++ parser objects have always been fully re-entrant and thread-safe. You can have multiple parser objects of the same -or- of different classes within an application. Multiple parser objects can be active concurrently within a process and paused and resumed.
New at Revision 2.3
The addition of parser memento objects extends the Yacc++ model further. Now you can save and restore the state of your parser object to and from a file. This enables use across processes -or- across different invocations of the same application.
Sometimes it may be useful to capture the state of a parser and restore that state at a later point in time. The object-oriented pattern for doing this is called the memento pattern. A separate object, the parser memento object, is created when the parser state is to be stored. The parser memento object can then be used to restore the state of the parser object. For more information on the memento pattern:
Design Patterns -- Elements of Reusable Software Gamma, Helm, Johnson, Vlissides, Memento Pattern, page 283
This feature is for use in applications where tokens are fed directly to the parser. A small extract from the tutorial on the memento feature is shown below:
Writing Your Grammar
To use mementos, add the MEMENTO parser class construct to your grammar. This instructs yxx to generate a parser memento class in addition to the parser class. Yacc++ will also write out memento specific member functions to the parser class. See yy_mypsr.h and yy_mypsr.cxx to view the code Yacc++ generates as a result of the inclusion of the MEMENTO clause.
class mementob; . . . // Instruct yxx to generate a parser memento class parser :: memento ; . . .
Saving a Parser Memento to a File
Yacc++ parser memento objects provide binary access functions that allow their contents to be saved and restored. Example mementob uses the binary access functions to save the contents of a parser memento object to a file and to restore it from the file.
This example is the same as mementoa except it saves and restores the parser memento object to a file. The code is located in yy_mainb.cxx. The italicized code below is specific to reading and writing the file. Note the use of yy_sizeof_data() and yy_data_ptr(). These are member functions in the base MEMENTO class in the Language Objects Library. See yy_memen.h.
// When it is time, save the parser to a file using the memento yy_saved_parser = new yy_psr_mementob_memento_obj(*yy_parser); sizeof_data = yy_saved_parser->yy_sizeof_data(); file = fopen("parser.mem", "wb"); fwrite(&sizeof_data, sizeof(sizeof_data), 1, file); fwrite(yy_saved_parser->yy_data_ptr(), sizeof_data, 1, file); fclose(file); delete yy_saved_parser; // Later, restore the parser from the memento file using the memento yy_saved_parser = new yy_psr_mementob_memento_obj; file = fopen("parser.mem", "rb"); fread(&sizeof_data, sizeof(sizeof_data), 1, file); yy_saved_parser->yy_sizeof_data() = sizeof_data; fread(yy_saved_parser->yy_data_ptr(), sizeof_data, 1, file); fclose(file); yy_parser = new yy_psr_dflt_obj(*yy_saved_parser);
There were several limitations with UNION in Revision 2.x that are now fixed in Revision 2.3. The following are now working as a result of the overhaul:
The reference object that encapsulates the UNION as well as how
parser objects interact with it were changed to provide the support.
On-line Documentation
We have had many requests for on-line documentation. It is a big job that is in progress. At Revision 2.3, the following is available in *.html format:
The following new warnings were added to Revision 2.3:
You do not want to create AST objects for parser non-terminals that are declared REMOVE because it will cause a runtime memory leak.
If you have an existing grammar with action code that used the public parser member functions, you do not need to make changes.
If you have an existing grammar with action code that accessed the internal data members directly, the code may no longer compile. You need to change the code to use the public interface defined in the base parser object. See yy_psr.h.
INTERNAL DATA MEMBER (Previously) PUBLIC MEMBER FUNCTION yy_psr_err_value yy_psr_error() yy_psr_done yy_psr_is_done()
Revision 2.3 has member function interfaces to provide access to the internal parser stack. Change your grammar to:
yy_psr_left_pop(); // pops last entry : equivalent to --yy_psr_left; yy_psr_left_pop(2); // pops last 2 entries // removes number of entries starting at index // thus, if number = 3: removes index, index+1, index+2 yy_psr_last_remove(index, number);
See yy_psr.h and yy_psrsk.h.
Last updated on January 25, 1999. To send email to Compiler Resources, Inc.
Return to Yacc++ Home Page |
---|