1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
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.
|