

                          Example
                        
                       "synchronized" 
                    statement extension

                        


INTRODUCTION
------------

The intention of this example is to demonstrate how to extend
the C++ parser. Thus it will be mainly shown how to extend the
lexical, syntactical, and semantical analysis. Additionally
two ways of manipulating parsed source code will be presented.


THE EXTENSION
-------------

The extension to the C++ parser to realize is a new statement
protecting the enclosed sub-statements from being modified by 
more than one thread. The syntax of the new statement looks as
follows:

  sync_stmt ->   'synchronized' '{' sub-statements '}'
               | 'synchronized' '{'                '}'
           
It may be used for instance like this:

  void Log::write(const std::string &message) {
    std::string entry = getCurrentTime();
    entry += ": "+getUserName();
    entry += ": "+message;
    
    synchronized {
      std::ofstream logfile(m_File, std::ios::app);
      logfile << entry << std::endl;
      logfile.close();
    }
  }

The "synchronized" statement shall not open a new local scope,
i.e. the object "logfile" is to be introduced into the same scope
as the object "entry". Furthermore "synchronized" statements shall
not be nested. Otherwise an error message shall be generated. For
instance the following code:

  synchronized {
    ...
    synchronized {
      ...
    }
  }
  
shall cause the parser to show a message like this:

  file:3: error: synchronized statements cannot be nested
  

REALIZATION
-----------

The protection of the enclosed statements shall be realized using
a pthread's mutex implementation. More precisely, the statement's
head shall be replaced by:

  pthread_mutex_t __mutex_n;
  pthread_mutex_init(&__mutex_n, 0);
  pthread_mutex_lock(&__mutex_n);
  
and its tail by:

  pthread_mutex_unlock(&__mutex_n);
  pthread_mutex_destroy(&__mutex_n);
  
For instance the above code shall be transformed into:

  void Log::write(const std::string &message) {
    std::string entry = getCurrentTime();
    entry += ": "+getUserName();
    entry += ": "+message;
    
    pthread_mutex_t __mutex_1;
    pthread_mutex_init(&__mutex_1, 0);
    pthread_mutex_lock(&__mutex_1);

    std::ofstream logfile(m_File, std::ios::app);
    logfile << entry << std::endl;
    logfile.close();

    pthread_mutex_unlock(&__mutex_1);
    pthread_mutex_destroy(&__mutex_1);
  }

Additionally an include directive for the system header pthread.h 
has to be added to the input file.


IMPLEMENTATION
--------------

The following steps has to be performed to realize this extension:

1. Implement a scanner extension for the "synchronized" keyword. 
   For this purpose a scanner generator description file has to be
   written. The generated scanner has to be added to the C++ scanner
   chain.
   
2. Implement a grammar extension for the "synchronized" statement.
   For this purpose a new syntactical analysis class has to be 
   derived from the C++ syntax class. A new syntactical rule has 
   to be implemented for the "synchronized" statement. Additionally
   a new syntax tree node for the "synchronized" statement is needed
   as well as a new syntax tree builder class supporting the new
   syntax tree node.

3. Implement a semantic analysis extension that is able to decide 
   whether a "synchronized" statement is nested. For this purpose
   a new semantical analysis class has to be derived from the C++
   semantics class. A new semantic state has to be introduced used
   to decide whether a "synchronized" statement is nested or not.

4. Implement a transformer that replaces the "synchronized" statement
   with the pthread function calls. For this purpose a syntax tree
   visitor has to be derived to find all "synchronized" statements
   in the syntax tree. Each "synchronized" statement has to be 
   transformed as described above using special code manipulation
   classes.

5. Implement the main application putting all the components together.
   This includes opening the input file, performing scanning, parsing,
   and transforming in the correct order, and saving the result.
