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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
Persistence State Service
-------------------------
The Persistent State Service (PSS) provides a standard way to
persistently save the state of objects in a datastore. A datastore is
an entity that manages data like a database or a set of files. For
TAO's implementation of PSS, the datastore is a normal file, for now.
The PSS defines two ways to define the datastore schema and
the interfaces to the storage object instances in the datastore. One
way is to use the Persistent State Definition Language (PSDL). PSDL
language is a superset to the IDL language and introduces four new
constructs: storagehome, storagetype, abstract storagehome and
abstract storagetype. A PSDL file (which is similar to an IDL file)
contain the definitions which describe the interface to the
datastore. This psdl interface and the datastore is visible only to
the server which saves the state of objects. The clients to this
server do not idea about how the server saves the state of the
objects and hence have no idea about the psdl interface or the
datastore.
The PSS implementation provides a compiler tool to process
the psdl file and generates stubs (I will use the name 'stub' just for
the lack of any other name.. though this stub is not the same as the
normal stub that is generated by the IDL compiler).
PSDL Compiler
=============
TAO's implementation of the PSS provides psdl_tao as the
compiler to
Design
======
The Input file (of format pidl) is first parsed with the
yacc-lex parser. The TAO_PSDL_Interpreter has a method (build_tree)
which helps construct an expression tree representing nodes from the
tokens returned by the Yacc generated parser. In addition, based on
the grammar set in PSDL.yy, any syntax errors are checked by the yacc
parser. Using the '-b' (build-tree) option, you can print out the
generated parse-tree for debugging purposes. All the classes in
PSDL_Node help build the parse tree.
(@@ To-do: I should be adding an option to the executable so that the
parse tree can be printed out when the option is set.)
Along with the basic parsing, we build the symbol
table. The TAO_PSDL_Scope class is the base class which helps add each
type (like interface, exceptions etc) to the symbol table.
The symbol table is constructed using the ACE hash maps.
We use two kinds of hash-maps...one maps the identifier to a
structure (Node_Info) which has information about the identifier
(identifier_type, module_name & interface_name (module and interfaces
to which this identifier belongs). This is used in cases where in the
identifier doesnt have some members in itself.. constant declarations,
typedefs, exceptions with no members etc.
Unlike a simple declaration or a typedef, types like
interfaces have member declarations which come with their scope. For
example, an interface has its own set of declarations, methods,
interfaces etc. For such types, we will have a class derived from
base TAO_PDSL_Scope. [In the case of interfaces, it is
TAO_PSDL_Interface_Scope.] The second hash map is to
map the identifier and the instance of the identifier's
type... i.e. say the identifier is of type interface, this hash-map
has a mapping between the identifier and the pointer to the instance
of TAO_PSDL_Interface_Scope. [All the TAO_PSDL_*_Scope classes fall in
this category.]
In this phase, along with building the symbol table, we also
do the semantic checking. Semantic checking includes checking if an
identifier that is declared before is now being redeclared.
Identifiers are case-sensitive and case-insensitive too...
ie. for ex: You cannot have CosNaming and cosnaming.
After the symbol tables are built, the next step is to
generate code in to the stubs. The classes TAO_PSDL_*_Visitor generates
this code. TAO_PSDL_Node_Visitor is the base class and the derived
classes override the necessary methods. So, if you want to generate
for some other type in future, we need to have another of
TAO_PSDL_*_Visitor class and override the necessary virtual method.
Implementation files of the stubs (idlC.cpp)
=================================
The generation of the header and implementation files
for the stubs can be done in a single pass. The implementation files
mainly involves the '<<' and '>>' operator support. These operators
support will be mainly useful while marshalling and demarshalling the
data types.
Status in a summary.
=======
1. Can parse any psdl file.
2. Does syntax checking.
3. Can build parse tree for most but not all of the types.
4. Builds ASTs for the basic types which includes typedefs,
interfaces, structs, modules, exceptions, constant declarations.
5. Generate the code that goes into the header file for the same types
listed above.
Files and Description
=====================
PSDL.yy Yacc file which has the PSDL grammar.
PSDL_y.cpp
PSDL_y.h Yacc generated files.
PSDL_l.cpp Lex generated file.
PSDL_Node.h
PSDL_Node.cpp Each node in the parse tree is derived from
the base type TAO_PSDL_Node. The classes in
this file provide the interface for the
different types. Each class will have accessor
methods to access the private members and an
accept method to invoke the corresponding
visitor method. (We are applying the visitor
pattern here.)
PSDL_Scope.h
PSDL_Scope.cpp
PSDL_*_Scope.* The classes in these files are useful for
building the AST. TAO_PSDL_Scope is the base
class and there are classes for each type
(which has members in it, ex: interface)
which needs to be added to the AST which
derive from TAO_PSDL_Scope.
PSDL_Node_Visitor.h
PSDL_Node_Visitor.cpp
PSDL_*_Visitor.* TAO_PSDL_Node_Visitor acts as a base class
useful for generating code into
stubs. TAO_PDSL_Node_Visitor derives from
TAO_PSDL_Scope_Visitor. The sub-classes (for
the different types) which
need to override the basic functionality of
the visitor methods in TAO_PSDL_Node_Visitor
derive from it and override accordingly. The
derived classes methods are invoked from the base class as needed
making use of the factory pattern (TAO_PSDL_Visitor_Factory).
To-Do
====
1. The visitor classes should generate the code into a file and not to
stdout as I am doing now.
2. Support for comments , pragmas etc. Right now, if you have
comments or pragmas, its going to fail.
Test
====
% ./psdl_tao < trial_idl.idl
Things to do
============
1. Have a test to include all the existing types. Should check the
generated code and check if it is the right thing. - 2 days
2. Work on the stubs.
. Redirect the output to a file rather than to stdout.
. Work on the implementation files (*C.cpp). This will be based on
ACE Reliable Multicast framework.
ps: Bala told last friday that ACE Reliable Multicast Framework
has several bugs. So, this might end up taking longer. FYI,
- 2 weeks.
3. Have a test/example for the total framework. 1 week- 10 days
- Have an application which is going to use the PSS framework.. have a server etc.
4. Additional Documentation as needed including
. Steps for modifying the existing services to use PSS. 1 week.
5. Include support for all the types in PSDL language in all the
stages which includes mainly
. Building the parse tree
. While building ASTs
. Generating the stubs.
6. Extend the tests to include all the new types.
IMR
===
1. Test
2. Documentation abt the differences between old and new IMR.
3. How to update/migrate to the new IMR.
4. Code review. 2 days
5. modift 2 days.
MInor things
============
1. Print out the Caps of the names
#if !defined (_TRIAL_INTERFACE___PTR_CH_)
instead of
#if !defined (__trial_interface___PTR_CH_)
2. Check out TAO_NAMESPACE_STORAGE_CLASS and static nad extern storage classes before _tc_*
Notes on how to proceed
=======================
1. Serialize the data using TAO_OutputCDR.
The implementation files should have the '<<' and '>>' methods.
2. There needs to be another executable or library which would be
actually saving the state of objects to the database. Since RMCast is
not working right now, we can save the data to a file and retrieve
from it.
Example
=======
1. Have a mini naming idl which just has the bind and find functions
support.
There can be just a server.cpp which will bind information.
2. Have a psdl interface which has a
sequence of struct (name,
stringified_ior).
When a bind is done, it has to be going through the helper
classes and inserted into a hash_map and saved to the file. And when
find is invoked, it has to be read from the file and demarshalled.
|