ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libBASS/parse_tree.c
Revision: 988
Committed: Tue Jan 27 19:37:48 2004 UTC (20 years, 5 months ago) by gezelter
Content type: text/plain
File size: 11444 byte(s)
Log Message:
More BASS changes to do new rigidBody scheme

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 && the_namespc.type != RIGIDBODY_HEAD ){
102 print_tree_error( the_node,
103 "The atom block is not in a molecule or rigidBody 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 rigid body 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 BOND_HEAD:
127 if( the_namespc.type != MOLECULE_HEAD ){
128 print_tree_error( the_node,
129 "The bond block is not in a molecule namespace" );
130 }
131 else{
132 init_bond( 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 BEND_HEAD:
140 if( the_namespc.type != MOLECULE_HEAD ){
141 print_tree_error( the_node,
142 "The bend block is not in a molecule namespace" );
143 }
144 else{
145 init_bend( 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 TORSION_HEAD:
153 if( the_namespc.type != MOLECULE_HEAD ){
154 print_tree_error( the_node,
155 "The torsion block is not in "
156 "a molecule namespace" );
157 }
158 else{
159 init_torsion( the_node->index );
160 current_namespc.index = the_node->index;
161 current_namespc.type = the_node->type;
162 walk_down( the_node->stmt_list, current_namespc );
163 }
164 break;
165
166 case MEMBER_HEAD:
167 if( the_namespc.type != RIGIDBODY_HEAD ){
168 print_tree_error( the_node,
169 "The Member block is not in "
170 "a rigidBody namespace" );
171 }
172 else{
173 init_member( the_node->index );
174 current_namespc.index = the_node->index;
175 current_namespc.type = the_node->type;
176 walk_down( the_node->stmt_list, current_namespc );
177 }
178 break;
179
180 case ZCONSTRAINT_HEAD:
181 if( the_namespc.type != GLOBAL_HEAD ){
182 print_tree_error( the_node,
183 "The Zconstraint block is not in "
184 "the global namespace" );
185 }
186 else{
187 init_zconstraint( the_node->index );
188 current_namespc.index = the_node->index;
189 current_namespc.type = the_node->type;
190 walk_down( the_node->stmt_list, current_namespc );
191 }
192 break;
193
194 default:
195 print_tree_error( the_node, "Not a valid code block" );
196 }
197 }
198
199 else{
200
201 // the node is a statement
202
203 switch( the_node->type ){
204
205 case MEMBERS_STMT:
206 switch( the_namespc.type ){
207 case BOND_HEAD: // fall through
208 case BEND_HEAD: // fall through
209 case TORSION_HEAD: // same for the first three
210 init_members( the_node, the_namespc );
211 break;
212
213 default:
214 print_tree_error( the_node,
215 "Members statement not in a bond, bend, "
216 "or torsion" );
217 break;
218 }
219 break;
220
221 case CONSTRAINT_STMT:
222 switch( the_namespc.type ){
223 case BOND_HEAD: // fall through
224 case BEND_HEAD: // fall through
225 case TORSION_HEAD: // same for the first three
226 init_constraint( the_node, the_namespc );
227 break;
228
229 default:
230 print_tree_error( the_node,
231 "Constraint statement not in a bond, bend, "
232 "or torsion" );
233 break;
234 }
235 break;
236
237 case ASSIGNMENT_STMT:
238 init_assignment( the_node, the_namespc );
239 break;
240
241 case POSITION_STMT:
242 if( the_namespc.type != ATOM_HEAD && the_namespc.type != RIGIDBODY_HEAD){
243 print_tree_error( the_node,
244 "position statement is not located in an "
245 "atom or rigidBody block" );
246 }
247
248 init_position( the_node, the_namespc );
249 break;
250
251 case ORIENTATION_STMT:
252 if( the_namespc.type != ATOM_HEAD && the_namespc.type != RIGIDBODY_HEAD){
253 print_tree_error( the_node,
254 "orientation statement is not located in an "
255 "atom or rigidBody block" );
256 }
257
258 init_orientation( the_node, the_namespc );
259 break;
260
261 default:
262 print_tree_error( the_node, "unrecognized statement" );
263 break;
264 }
265 }
266
267 // recurse down to the next node
268
269 walk_down( the_node->next_stmt, the_namespc );
270 }
271
272 // send an end of block signal
273 else end_of_block();
274
275 // we're done
276 }
277
278
279
280 /*
281 * This is a routine utilized by the node parsers to make printing
282 * error messages easy.
283 */
284
285 void print_tree_error( struct node_tag* err_node, char* err_msg ){
286
287 switch( err_node->type ){
288
289 case GLOBAL_HEAD:
290 sprintf( painCave.errMsg,
291 "Parse tree error: global head node error -> %s\n",
292 err_msg );
293 break;
294
295 case COMPONENT_HEAD:
296 sprintf( painCave.errMsg,
297 "Parse tree error: component head node error -> %s\n",
298 err_msg );
299 break;
300
301 case MOLECULE_HEAD:
302 sprintf( painCave.errMsg,
303 "Parse tree error: molecule head node error -> %s\n",
304 err_msg );
305 break;
306
307 case RIGIDBODY_HEAD:
308 sprintf( painCave.errMsg,
309 "Parse tree error: rigidBody head node error -> %s\n",
310 err_msg );
311 break;
312
313 case ATOM_HEAD:
314 sprintf( painCave.errMsg,
315 "Parse tree error: atom head node error [%d] -> %s\n",
316 err_node->index,
317 err_msg );
318 break;
319
320 case BOND_HEAD:
321 sprintf( painCave.errMsg,
322 "Parse tree error: bond head node error [%d] -> %s\n",
323 err_node->index,
324 err_msg );
325 break;
326
327 case BEND_HEAD:
328 sprintf( painCave.errMsg,
329 "Parse tree error: bend head node error [%d] -> %s\n",
330 err_node->index,
331 err_msg );
332 break;
333
334 case ZCONSTRAINT_HEAD:
335 sprintf( painCave.errMsg,
336 "Parse tree error: Zconstraint head node error [%d] -> %s\n",
337 err_node->index,
338 err_msg );
339 break;
340
341 case MEMBER_HEAD:
342 sprintf( painCave.errMsg,
343 "Parse tree error: member 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 => ( %d, %d, %d, %d )\n"
351 " -> %s\n",
352 err_node->the_data.mbrs.a,
353 err_node->the_data.mbrs.b,
354 err_node->the_data.mbrs.c,
355 err_node->the_data.mbrs.d,
356 err_msg );
357 break;
358
359 case CONSTRAINT_STMT:
360 sprintf( painCave.errMsg,
361 "Parse tree error: constraint node error => ( %lf )\n"
362 " -> %s\n",
363 err_node->the_data.cnstr.constraint_val,
364 err_msg );
365 break;
366
367 case ASSIGNMENT_STMT:
368 sprintf( painCave.errMsg,
369 "Parse tree error: assignment node error\n"
370 " => %s = ",
371 err_node->the_data.asmt.identifier );
372
373 switch( err_node->the_data.asmt.type ){
374
375 case STR_ASSN:
376 sprintf( painCave.errMsg,
377 "%s",
378 err_node->the_data.asmt.rhs.str_ptr );
379 break;
380
381 case INT_ASSN:
382 sprintf( painCave.errMsg,
383 "%d",
384 err_node->the_data.asmt.rhs.i_val );
385 break;
386
387 case DOUBLE_ASSN:
388 sprintf( painCave.errMsg,
389 "%lf",
390 err_node->the_data.asmt.rhs.d_val );
391 break;
392 }
393
394 sprintf( painCave.errMsg,
395 "\n"
396 " -> %s\n",
397 err_msg );
398 break;
399
400 case POSITION_STMT:
401 sprintf( painCave.errMsg,
402 "Parse tree error: position node error => ( %lf, %lf, %lf )\n"
403 " -> %s\n",
404 err_node->the_data.pos.x,
405 err_node->the_data.pos.y,
406 err_node->the_data.pos.z,
407 err_msg );
408 break;
409
410 case ORIENTATION_STMT:
411 sprintf( painCave.errMsg,
412 "Parse tree error: orientation node error => ( %lf, %lf, %lf )\n"
413 " -> %s\n",
414 err_node->the_data.ort.x,
415 err_node->the_data.ort.y,
416 err_node->the_data.ort.z,
417 err_msg );
418 break;
419
420 default:
421 sprintf( painCave.errMsg,
422 "Parse tree error: unknown node type -> %s\n",
423 err_msg );
424 }
425
426 painCave.isFatal = 1;
427 simError();
428 #ifdef IS_MPI
429 mpiInterfaceExit();
430 #endif //is_mpi
431
432 }
433
434
435 /*
436 * recursive walkdown and kill of the node tree
437 * note: looks mighty similar to the walkdown routine.
438 */
439
440 void kill_tree( struct node_tag* the_node ){
441
442
443 if( the_node != NULL ){
444
445 if( the_node->stmt_list != NULL ){
446
447 // the statement is a block node of some sort
448
449 kill_tree( the_node->stmt_list );
450 }
451
452 else{
453
454 // the node is a statement
455
456 switch( the_node->type ){
457
458 case ASSIGNMENT_STMT:
459
460 if( the_node->the_data.asmt.type == STR_ASSN )
461 free( the_node->the_data.asmt.rhs.str_ptr );
462
463 free( the_node->the_data.asmt.identifier );
464 break;
465
466 default:
467 // nothing to do here, everyone else can be freed normally.
468 break;
469 }
470 }
471
472 // recurse down to the next node
473
474 kill_tree( the_node->next_stmt );
475 free( the_node );
476 }
477
478 // we're done
479 }