ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libBASS/parse_tree.c
Revision: 1156
Committed: Tue May 11 20:07:56 2004 UTC (20 years, 1 month ago) by gezelter
Content type: text/plain
File size: 11282 byte(s)
Log Message:
bugfix for cutoffGroup

File Contents

# Content
1 #include <stdlib.h>
2 #include <stdio.h>
3
4 #include "parse_tree.h"
5 #include "simError.h"
6
7 #ifdef IS_MPI
8 #define __is_lex__
9 #include "mpiBASS.h"
10 #endif
11
12 void walk_down( struct node_tag* the_node, struct namespc the_namespc );
13 int mol_index; // keeps track of the number of molecules
14 int comp_index; // keeps track of the number of components.
15
16 /*
17 * This is the parse tree function that is called by the yacc
18 * routine. It passes the global node and namespace to the recursive
19 * walk_down routine to explore the node tree.
20 */
21
22 void pt_me( struct node_tag* head_node ){
23
24 struct namespc global_namespc;
25
26 if( head_node->type != GLOBAL_HEAD ){
27 sprintf( painCave.errMsg,
28 "Parse tree error: The head node was not the global node.\n" );
29 painCave.isFatal = 1;
30 simError();
31 #ifdef IS_MPI
32 mpiInterfaceExit();
33 #endif //is_mpi
34 }
35
36 global_namespc.index = 0;
37 global_namespc.type = GLOBAL_HEAD;
38
39 mol_index = 0;
40 comp_index = 0;
41 walk_down( head_node->next_stmt, global_namespc );
42 // closed global namespace and exit
43
44 }
45
46 /*
47 * This is the main logic workhorse routine for the node tree
48 * parser. It recursively walks down the node list and calls the
49 * appropriate interface functions acording to the node types. It will
50 * also set the appropriate namespace for the nodes.
51 *
52 * Note: the nodes only know about the namespace of their
53 * current level, the namespace above themselves is hidden.
54 */
55
56 void walk_down( struct node_tag* the_node, struct namespc the_namespc ){
57
58 struct namespc current_namespc;
59
60 if( the_node != NULL ){
61
62 if( the_node->type == GLOBAL_HEAD ){
63 print_tree_error( the_node, "Too many global regions" );
64 }
65
66 if( the_node->stmt_list != NULL ){
67
68 // the statement is a block node of some sort
69
70 switch( the_node->type ){
71
72 case COMPONENT_HEAD:
73 if( the_namespc.type != GLOBAL_HEAD ){
74 print_tree_error( the_node,
75 "component block is not in the global namespace" );
76 }
77 else{
78 init_component( comp_index );
79 current_namespc.index = comp_index;
80 current_namespc.type = COMPONENT_HEAD;
81 walk_down( the_node->stmt_list, current_namespc );
82 comp_index++;
83 }
84 break;
85
86 case MOLECULE_HEAD:
87 if( the_namespc.type != GLOBAL_HEAD ){
88 print_tree_error( the_node,
89 "Molecule block is not in the global namespace" );
90 }
91 else{
92 init_molecule( mol_index );
93 current_namespc.index = mol_index;
94 current_namespc.type = MOLECULE_HEAD;
95 walk_down( the_node->stmt_list, current_namespc );
96 mol_index++;
97 }
98 break;
99
100 case ATOM_HEAD:
101 if( the_namespc.type != MOLECULE_HEAD ){
102 print_tree_error( the_node,
103 "The atom block is not in a molecule namespace" );
104 }
105 else{
106 init_atom( the_node->index );
107 current_namespc.index = the_node->index;
108 current_namespc.type = the_node->type;
109 walk_down( the_node->stmt_list, current_namespc );
110 }
111 break;
112
113 case RIGIDBODY_HEAD:
114 if( the_namespc.type != MOLECULE_HEAD ){
115 print_tree_error( the_node,
116 "The RigidBody block is not in a Molecule namespace" );
117 }
118 else{
119 init_rigidbody( the_node->index );
120 current_namespc.index = the_node->index;
121 current_namespc.type = the_node->type;
122 walk_down( the_node->stmt_list, current_namespc );
123 }
124 break;
125
126 case CUTOFFGROUP_HEAD:
127 if( the_namespc.type != MOLECULE_HEAD ){
128 print_tree_error( the_node,
129 "The CutoffGroup block is not in a Molecule namespace" );
130 }
131 else{
132 init_cutoffgroup( the_node->index );
133 current_namespc.index = the_node->index;
134 current_namespc.type = the_node->type;
135 walk_down( the_node->stmt_list, current_namespc );
136 }
137 break;
138
139 case BOND_HEAD:
140 if( the_namespc.type != MOLECULE_HEAD ){
141 print_tree_error( the_node,
142 "The bond block is not in a molecule namespace" );
143 }
144 else{
145 init_bond( the_node->index );
146 current_namespc.index = the_node->index;
147 current_namespc.type = the_node->type;
148 walk_down( the_node->stmt_list, current_namespc );
149 }
150 break;
151
152 case BEND_HEAD:
153 if( the_namespc.type != MOLECULE_HEAD ){
154 print_tree_error( the_node,
155 "The bend block is not in a molecule namespace" );
156 }
157 else{
158 init_bend( the_node->index );
159 current_namespc.index = the_node->index;
160 current_namespc.type = the_node->type;
161 walk_down( the_node->stmt_list, current_namespc );
162 }
163 break;
164
165 case TORSION_HEAD:
166 if( the_namespc.type != MOLECULE_HEAD ){
167 print_tree_error( the_node,
168 "The torsion block is not in "
169 "a molecule namespace" );
170 }
171 else{
172 init_torsion( the_node->index );
173 current_namespc.index = the_node->index;
174 current_namespc.type = the_node->type;
175 walk_down( the_node->stmt_list, current_namespc );
176 }
177 break;
178
179 case ZCONSTRAINT_HEAD:
180 if( the_namespc.type != GLOBAL_HEAD ){
181 print_tree_error( the_node,
182 "The Zconstraint block is not in "
183 "the global namespace" );
184 }
185 else{
186 init_zconstraint( the_node->index );
187 current_namespc.index = the_node->index;
188 current_namespc.type = the_node->type;
189 walk_down( the_node->stmt_list, current_namespc );
190 }
191 break;
192
193 default:
194 print_tree_error( the_node, "Not a valid code block" );
195 }
196 }
197
198 else{
199
200 // the node is a statement
201
202 switch( the_node->type ){
203
204 case MEMBERS_STMT:
205 switch( the_namespc.type ){
206 case BOND_HEAD: // fall through
207 case BEND_HEAD: // fall through
208 case TORSION_HEAD:
209 case RIGIDBODY_HEAD:
210 case CUTOFFGROUP_HEAD: // same for the first four
211 init_members( the_node, the_namespc );
212 break;
213
214 default:
215 print_tree_error( the_node,
216 "Members statement not in a bond, bend, "
217 "torsion, RigidBody, or CutoffGroup" );
218 break;
219 }
220 break;
221
222 case CONSTRAINT_STMT:
223 switch( the_namespc.type ){
224 case BOND_HEAD: // fall through
225 case BEND_HEAD: // fall through
226 case TORSION_HEAD: // same for the first three
227 init_constraint( the_node, the_namespc );
228 break;
229
230 default:
231 print_tree_error( the_node,
232 "Constraint statement not in a bond, bend, "
233 "or torsion" );
234 break;
235 }
236 break;
237
238 case ASSIGNMENT_STMT:
239 init_assignment( the_node, the_namespc );
240 break;
241
242 case POSITION_STMT:
243 if( the_namespc.type != ATOM_HEAD ){
244 print_tree_error( the_node,
245 "position statement is not located in an "
246 "atom block" );
247 }
248
249 init_position( the_node, the_namespc );
250 break;
251
252 case ORIENTATION_STMT:
253 if( the_namespc.type != ATOM_HEAD ){
254 print_tree_error( the_node,
255 "orientation statement is not located in an "
256 "atom block" );
257 }
258
259 init_orientation( the_node, the_namespc );
260 break;
261
262 default:
263 print_tree_error( the_node, "unrecognized statement" );
264 break;
265 }
266 }
267
268 // recurse down to the next node
269
270 walk_down( the_node->next_stmt, the_namespc );
271 }
272
273 // send an end of block signal
274 else end_of_block();
275
276 // we're done
277 }
278
279
280
281 /*
282 * This is a routine utilized by the node parsers to make printing
283 * error messages easy.
284 */
285
286 void print_tree_error( struct node_tag* err_node, char* err_msg ){
287
288 switch( err_node->type ){
289
290 case GLOBAL_HEAD:
291 sprintf( painCave.errMsg,
292 "Parse tree error: global head node error -> %s\n",
293 err_msg );
294 break;
295
296 case COMPONENT_HEAD:
297 sprintf( painCave.errMsg,
298 "Parse tree error: component head node error -> %s\n",
299 err_msg );
300 break;
301
302 case MOLECULE_HEAD:
303 sprintf( painCave.errMsg,
304 "Parse tree error: molecule head node error -> %s\n",
305 err_msg );
306 break;
307
308 case RIGIDBODY_HEAD:
309 sprintf( painCave.errMsg,
310 "Parse tree error: rigidBody head node error -> %s\n",
311 err_msg );
312 break;
313
314 case CUTOFFGROUP_HEAD:
315 sprintf( painCave.errMsg,
316 "Parse tree error: CutoffGroup head node error -> %s\n",
317 err_msg );
318 break;
319
320 case ATOM_HEAD:
321 sprintf( painCave.errMsg,
322 "Parse tree error: atom head node error [%d] -> %s\n",
323 err_node->index,
324 err_msg );
325 break;
326
327 case BOND_HEAD:
328 sprintf( painCave.errMsg,
329 "Parse tree error: bond head node error [%d] -> %s\n",
330 err_node->index,
331 err_msg );
332 break;
333
334 case BEND_HEAD:
335 sprintf( painCave.errMsg,
336 "Parse tree error: bend head node error [%d] -> %s\n",
337 err_node->index,
338 err_msg );
339 break;
340
341 case ZCONSTRAINT_HEAD:
342 sprintf( painCave.errMsg,
343 "Parse tree error: Zconstraint head node error [%d] -> %s\n",
344 err_node->index,
345 err_msg );
346 break;
347
348 case MEMBERS_STMT:
349 sprintf( painCave.errMsg,
350 "Parse tree error: members node error (nMembers = %d)\n"
351 " -> %s\n",
352 err_node->the_data.mbrs.nMembers,
353 err_msg );
354 break;
355
356 case CONSTRAINT_STMT:
357 sprintf( painCave.errMsg,
358 "Parse tree error: constraint node error => ( %lf )\n"
359 " -> %s\n",
360 err_node->the_data.cnstr.constraint_val,
361 err_msg );
362 break;
363
364 case ASSIGNMENT_STMT:
365 sprintf( painCave.errMsg,
366 "Parse tree error: assignment node error\n"
367 " => %s = ",
368 err_node->the_data.asmt.identifier );
369
370 switch( err_node->the_data.asmt.type ){
371
372 case STR_ASSN:
373 sprintf( painCave.errMsg,
374 "%s",
375 err_node->the_data.asmt.rhs.str_ptr );
376 break;
377
378 case INT_ASSN:
379 sprintf( painCave.errMsg,
380 "%d",
381 err_node->the_data.asmt.rhs.i_val );
382 break;
383
384 case DOUBLE_ASSN:
385 sprintf( painCave.errMsg,
386 "%lf",
387 err_node->the_data.asmt.rhs.d_val );
388 break;
389 }
390
391 sprintf( painCave.errMsg,
392 "\n"
393 " -> %s\n",
394 err_msg );
395 break;
396
397 case POSITION_STMT:
398 sprintf( painCave.errMsg,
399 "Parse tree error: position node error => ( %lf, %lf, %lf )\n"
400 " -> %s\n",
401 err_node->the_data.pos.x,
402 err_node->the_data.pos.y,
403 err_node->the_data.pos.z,
404 err_msg );
405 break;
406
407 case ORIENTATION_STMT:
408 sprintf( painCave.errMsg,
409 "Parse tree error: orientation node error => ( %lf, %lf, %lf )\n"
410 " -> %s\n",
411 err_node->the_data.ort.phi,
412 err_node->the_data.ort.theta,
413 err_node->the_data.ort.psi,
414 err_msg );
415 break;
416
417 default:
418 sprintf( painCave.errMsg,
419 "Parse tree error: unknown node type -> %s\n",
420 err_msg );
421 }
422
423 painCave.isFatal = 1;
424 simError();
425 #ifdef IS_MPI
426 mpiInterfaceExit();
427 #endif //is_mpi
428
429 }
430
431
432 /*
433 * recursive walkdown and kill of the node tree
434 * note: looks mighty similar to the walkdown routine.
435 */
436
437 void kill_tree( struct node_tag* the_node ){
438
439
440 if( the_node != NULL ){
441
442 if( the_node->stmt_list != NULL ){
443
444 // the statement is a block node of some sort
445
446 kill_tree( the_node->stmt_list );
447 }
448
449 else{
450
451 // the node is a statement
452
453 switch( the_node->type ){
454
455 case ASSIGNMENT_STMT:
456
457 if( the_node->the_data.asmt.type == STR_ASSN )
458 free( the_node->the_data.asmt.rhs.str_ptr );
459
460 free( the_node->the_data.asmt.identifier );
461 break;
462
463 default:
464 // nothing to do here, everyone else can be freed normally.
465 break;
466 }
467 }
468
469 // recurse down to the next node
470
471 kill_tree( the_node->next_stmt );
472 free( the_node );
473 }
474
475 // we're done
476 }