ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libBASS/parse_tree.c
Revision: 998
Committed: Thu Jan 29 23:01:17 2004 UTC (20 years, 5 months ago) by gezelter
Content type: text/plain
File size: 10871 byte(s)
Log Message:
member list fixes for rigid bodies

File Contents

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