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

# 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 gezelter 988
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 mmeineke 675
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 mmeineke 377
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 gezelter 988 case MEMBERS_STMT:
206 mmeineke 377 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 gezelter 988 "Members statement not in a bond, bend, "
216 mmeineke 377 "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 gezelter 957 if( the_namespc.type != ATOM_HEAD && the_namespc.type != RIGIDBODY_HEAD){
243 mmeineke 377 print_tree_error( the_node,
244     "position statement is not located in an "
245 gezelter 957 "atom or rigidBody block" );
246 mmeineke 377 }
247    
248     init_position( the_node, the_namespc );
249     break;
250    
251     case ORIENTATION_STMT:
252 gezelter 957 if( the_namespc.type != ATOM_HEAD && the_namespc.type != RIGIDBODY_HEAD){
253 mmeineke 377 print_tree_error( the_node,
254     "orientation statement is not located in an "
255 gezelter 957 "atom or rigidBody block" );
256 mmeineke 377 }
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 gezelter 957 case RIGIDBODY_HEAD:
308     sprintf( painCave.errMsg,
309     "Parse tree error: rigidBody head node error -> %s\n",
310     err_msg );
311     break;
312    
313 mmeineke 377 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 gezelter 988
334     case ZCONSTRAINT_HEAD:
335 mmeineke 377 sprintf( painCave.errMsg,
336 gezelter 988 "Parse tree error: Zconstraint head node error [%d] -> %s\n",
337 mmeineke 377 err_node->index,
338     err_msg );
339     break;
340 gezelter 988
341     case MEMBER_HEAD:
342 mmeineke 675 sprintf( painCave.errMsg,
343 gezelter 988 "Parse tree error: member head node error [%d] -> %s\n",
344 mmeineke 675 err_node->index,
345     err_msg );
346     break;
347    
348 gezelter 988 case MEMBERS_STMT:
349 mmeineke 377 sprintf( painCave.errMsg,
350 gezelter 988 "Parse tree error: members node error => ( %d, %d, %d, %d )\n"
351 mmeineke 377 " -> %s\n",
352 gezelter 988 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 mmeineke 377 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     }