ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libBASS/parse_tree.c
Revision: 1153
Committed: Tue May 11 04:21:52 2004 UTC (20 years, 2 months ago) by gezelter
Content type: text/plain
File size: 11285 byte(s)
Log Message:
BASS changes for adding CutoffGroups to molecules.  Also restructured
the plethora of cutoff radii into one cutoffRadius and one
switchingRadius.  Also removed the useMolecularCutoffs keyword

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 1153 if( the_namespc.type != MOLECULE_HEAD ){
102 gezelter 957 print_tree_error( the_node,
103 gezelter 1153 "The atom block is not in a molecule namespace" );
104 gezelter 957 }
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 1153 "The RigidBody 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 gezelter 1153
126     case CUTOFFGROUP_HEAD:
127     if( the_namespc.type != CUTOFFGROUP_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 mmeineke 377
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 mmeineke 675
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 mmeineke 377
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 gezelter 988 case MEMBERS_STMT:
205 mmeineke 377 switch( the_namespc.type ){
206     case BOND_HEAD: // fall through
207     case BEND_HEAD: // fall through
208 gezelter 1153 case TORSION_HEAD:
209 gezelter 998 case RIGIDBODY_HEAD:
210 gezelter 1153 case CUTOFFGROUP_HEAD: // same for the first four
211 mmeineke 377 init_members( the_node, the_namespc );
212     break;
213    
214     default:
215     print_tree_error( the_node,
216 gezelter 988 "Members statement not in a bond, bend, "
217 gezelter 1153 "torsion, RigidBody, or CutoffGroup" );
218 mmeineke 377 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 gezelter 1153 if( the_namespc.type != ATOM_HEAD ){
244 mmeineke 377 print_tree_error( the_node,
245     "position statement is not located in an "
246 gezelter 1153 "atom block" );
247 mmeineke 377 }
248    
249     init_position( the_node, the_namespc );
250     break;
251    
252     case ORIENTATION_STMT:
253 gezelter 1153 if( the_namespc.type != ATOM_HEAD ){
254 mmeineke 377 print_tree_error( the_node,
255     "orientation statement is not located in an "
256 gezelter 1153 "atom block" );
257 mmeineke 377 }
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 gezelter 957 case RIGIDBODY_HEAD:
309     sprintf( painCave.errMsg,
310     "Parse tree error: rigidBody head node error -> %s\n",
311     err_msg );
312     break;
313 gezelter 1153
314     case CUTOFFGROUP_HEAD:
315     sprintf( painCave.errMsg,
316     "Parse tree error: CutoffGroup head node error -> %s\n",
317     err_msg );
318     break;
319 gezelter 957
320 mmeineke 377 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 gezelter 988
341     case ZCONSTRAINT_HEAD:
342 mmeineke 377 sprintf( painCave.errMsg,
343 gezelter 988 "Parse tree error: Zconstraint head node error [%d] -> %s\n",
344 mmeineke 377 err_node->index,
345     err_msg );
346     break;
347 gezelter 988
348     case MEMBERS_STMT:
349 mmeineke 377 sprintf( painCave.errMsg,
350 gezelter 998 "Parse tree error: members node error (nMembers = %d)\n"
351 mmeineke 377 " -> %s\n",
352 gezelter 998 err_node->the_data.mbrs.nMembers,
353 mmeineke 377 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 gezelter 998 err_node->the_data.ort.phi,
412     err_node->the_data.ort.theta,
413     err_node->the_data.ort.psi,
414 mmeineke 377 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     }