ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libBASS/parse_tree.c
Revision: 957
Committed: Mon Jan 19 16:08:21 2004 UTC (20 years, 7 months ago) by gezelter
Content type: text/plain
File size: 11072 byte(s)
Log Message:
BASS changes to add RigidBodies and LJrcut

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