ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/BASS_parse/parse_tree.c
Revision: 118
Committed: Wed Sep 25 22:51:14 2002 UTC (21 years, 9 months ago) by chuckv
Content type: text/plain
File size: 10362 byte(s)
Log Message:
begin the pain that is MPI.

abandon all hope ye who check out this branch..

P.S. we've added consistent BASS error checking

File Contents

# User Rev Content
1 mmeineke 10 #include <stdlib.h>
2     #include <stdio.h>
3    
4     #include "parse_tree.h"
5    
6     void walk_down( struct node_tag* the_node, struct namespc the_namespc );
7     int mol_index; // keeps track of the number of molecules
8     int comp_index; // keeps track of the number of components.
9    
10     /*
11     * This is the parse tree function that is called by the yacc
12     * routine. It passes the global node and namespace to the recursive
13     * walk_down routine to explore the node tree.
14     */
15    
16     void pt_me( struct node_tag* head_node ){
17    
18     struct namespc global_namespc;
19    
20     if( head_node->type != GLOBAL_HEAD ){
21     fprintf( stderr, "Parse tree error: "
22     "The head node was not the global node.\n" );
23     }
24    
25     global_namespc.index = 0;
26     global_namespc.type = GLOBAL_HEAD;
27    
28     mol_index = 0;
29     comp_index = 0;
30 chuckv 118 walk_down( head_node->next_stmt, global_namespc ); // closed global namespace + exit
31    
32 mmeineke 10 }
33    
34     /*
35     * This is the main logic workhorse routine for the node tree
36     * parser. It recursively walks down the node list and calls the
37     * appropriate interface functions acording to the node types. It will
38     * also set the appropriate namespace for the nodes.
39     *
40     * Note: the nodes only know about the namespace of their
41     * current level, the namespace above themselves is hidden.
42     */
43    
44     void walk_down( struct node_tag* the_node, struct namespc the_namespc ){
45    
46     struct namespc current_namespc;
47    
48     if( the_node != NULL ){
49    
50     if( the_node->type == GLOBAL_HEAD ){
51     print_tree_error( the_node, "Too many global regions" );
52     exit(0);
53     }
54    
55     if( the_node->stmt_list != NULL ){
56    
57     // the statement is a block node of some sort
58    
59     switch( the_node->type ){
60    
61     case COMPONENT_HEAD:
62     if( the_namespc.type != GLOBAL_HEAD ){
63     print_tree_error( the_node,
64     "component block is not in the global namespace" );
65     exit(0);
66     }
67     else{
68     init_component( comp_index );
69     current_namespc.index = comp_index;
70     current_namespc.type = COMPONENT_HEAD;
71     walk_down( the_node->stmt_list, current_namespc );
72     comp_index++;
73     }
74     break;
75    
76     case MOLECULE_HEAD:
77     if( the_namespc.type != GLOBAL_HEAD ){
78     print_tree_error( the_node,
79     "Molecule block is not in the global namespace" );
80     exit(0);
81     }
82     else{
83     init_molecule( mol_index );
84     current_namespc.index = mol_index;
85     current_namespc.type = MOLECULE_HEAD;
86     walk_down( the_node->stmt_list, current_namespc );
87     mol_index++;
88     }
89     break;
90    
91     case ATOM_HEAD:
92     if( the_namespc.type != MOLECULE_HEAD ){
93     print_tree_error( the_node,
94     "The atom block is not in a molecule namespace" );
95     exit(0);
96     }
97     else{
98     init_atom( the_node->index );
99     current_namespc.index = the_node->index;
100     current_namespc.type = the_node->type;
101     walk_down( the_node->stmt_list, current_namespc );
102     }
103     break;
104    
105     case BOND_HEAD:
106     if( the_namespc.type != MOLECULE_HEAD ){
107     print_tree_error( the_node,
108     "The bond block is not in a molecule namespace" );
109     exit(0);
110     }
111     else{
112     init_bond( the_node->index );
113     current_namespc.index = the_node->index;
114     current_namespc.type = the_node->type;
115     walk_down( the_node->stmt_list, current_namespc );
116     }
117     break;
118    
119     case BEND_HEAD:
120     if( the_namespc.type != MOLECULE_HEAD ){
121     print_tree_error( the_node,
122     "The bend block is not in a molecule namespace" );
123     exit(0);
124     }
125     else{
126     init_bend( the_node->index );
127     current_namespc.index = the_node->index;
128     current_namespc.type = the_node->type;
129     walk_down( the_node->stmt_list, current_namespc );
130     }
131     break;
132    
133     case TORSION_HEAD:
134     if( the_namespc.type != MOLECULE_HEAD ){
135     print_tree_error( the_node,
136     "The torsion block is not in "
137     "a molecule namespace" );
138     exit(0);
139     }
140     else{
141     init_torsion( the_node->index );
142     current_namespc.index = the_node->index;
143     current_namespc.type = the_node->type;
144     walk_down( the_node->stmt_list, current_namespc );
145     }
146     break;
147    
148     default:
149     print_tree_error( the_node, "Not a valid code block" );
150     exit(0);
151     }
152     }
153    
154     else{
155    
156     // the node is a statement
157    
158     switch( the_node->type ){
159    
160     case MEMBER_STMT:
161     switch( the_namespc.type ){
162     case BOND_HEAD: // fall through
163     case BEND_HEAD: // fall through
164     case TORSION_HEAD: // same for the first three
165     init_members( the_node, the_namespc );
166     break;
167    
168     default:
169     print_tree_error( the_node,
170     "Member statement not in a bond, bend, "
171     "or torsion" );
172     exit(0);
173     break;
174     }
175     break;
176    
177     case CONSTRAINT_STMT:
178     switch( the_namespc.type ){
179     case BOND_HEAD: // fall through
180     case BEND_HEAD: // fall through
181     case TORSION_HEAD: // same for the first three
182     init_constraint( the_node, the_namespc );
183     break;
184    
185     default:
186     print_tree_error( the_node,
187     "Constraint statement not in a bond, bend, "
188     "or torsion" );
189     exit(0);
190     break;
191     }
192     break;
193    
194     case ASSIGNMENT_STMT:
195     init_assignment( the_node, the_namespc );
196     break;
197    
198     case POSITION_STMT:
199     if( the_namespc.type != ATOM_HEAD ){
200     print_tree_error( the_node,
201     "position statement is not located in an "
202     "atom block" );
203     exit(0);
204     }
205    
206     init_position( the_node, the_namespc );
207     break;
208    
209     case ORIENTATION_STMT:
210     if( the_namespc.type != ATOM_HEAD ){
211     print_tree_error( the_node,
212     "orientation statement is not located in an "
213     "atom block" );
214     exit(0);
215     }
216    
217     init_orientation( the_node, the_namespc );
218     break;
219    
220     case START_INDEX_STMT:
221     if( the_namespc.type != COMPONENT_HEAD ){
222     print_tree_error( the_node,
223     "start_index statement is not located in an "
224     "component block" );
225     exit(0);
226     }
227    
228     init_start_index( the_node, the_namespc );
229     break;
230    
231     default:
232     print_tree_error( the_node, "unrecognized statement" );
233     exit(0);
234     break;
235     }
236     }
237    
238     // recurse down to the next node
239    
240     walk_down( the_node->next_stmt, the_namespc );
241     }
242    
243     // send an end of block signal
244     else end_of_block();
245    
246     // we're done
247     }
248    
249    
250    
251     /*
252     * This is a routine utilized by the node parsers to make printing
253     * error messages easy.
254     */
255    
256     void print_tree_error( struct node_tag* err_node, char* err_msg ){
257    
258     switch( err_node->type ){
259    
260     case GLOBAL_HEAD:
261     fprintf( stderr,
262     "Parse tree error: global head node error -> %s\n",
263     err_msg );
264     break;
265    
266     case COMPONENT_HEAD:
267     fprintf( stderr,
268     "Parse tree error: component head node error -> %s\n",
269     err_msg );
270     break;
271    
272     case MOLECULE_HEAD:
273     fprintf( stderr,
274     "Parse tree error: molecule head node error -> %s\n",
275     err_msg );
276     break;
277    
278     case ATOM_HEAD:
279     fprintf( stderr,
280     "Parse tree error: atom head node error [%d] -> %s\n",
281     err_node->index,
282     err_msg );
283     break;
284    
285     case BOND_HEAD:
286     fprintf( stderr,
287     "Parse tree error: bond head node error [%d] -> %s\n",
288     err_node->index,
289     err_msg );
290     break;
291    
292     case BEND_HEAD:
293     fprintf( stderr,
294     "Parse tree error: bend head node error [%d] -> %s\n",
295     err_node->index,
296     err_msg );
297     break;
298    
299     case TORSION_HEAD:
300     fprintf( stderr,
301     "Parse tree error: torsion head node error [%d] -> %s\n",
302     err_node->index,
303     err_msg );
304     break;
305    
306     case MEMBER_STMT:
307     fprintf( stderr,
308     "Parse tree error: member node error => ( %d, %d, %d, %d )\n"
309     " -> %s\n",
310     err_node->the_data.mbr.a,
311     err_node->the_data.mbr.b,
312     err_node->the_data.mbr.c,
313     err_node->the_data.mbr.d,
314     err_msg );
315     break;
316    
317     case CONSTRAINT_STMT:
318     fprintf( stderr,
319     "Parse tree error: constraint node error => ( %lf )\n"
320     " -> %s\n",
321     err_node->the_data.cnstr.constraint_val,
322     err_msg );
323     break;
324    
325     case ASSIGNMENT_STMT:
326     fprintf( stderr,
327     "Parse tree error: assignment node error\n"
328     " => %s = ",
329     err_node->the_data.asmt.identifier );
330    
331     switch( err_node->the_data.asmt.type ){
332    
333     case STR_ASSN:
334     fprintf( stderr,
335     "%s",
336 mmeineke 117 err_node->the_data.asmt.rhs.str_ptr );
337 mmeineke 10 break;
338    
339     case INT_ASSN:
340     fprintf( stderr,
341     "%d",
342 mmeineke 117 err_node->the_data.asmt.rhs.i_val );
343 mmeineke 10 break;
344    
345     case DOUBLE_ASSN:
346     fprintf( stderr,
347     "%lf",
348 mmeineke 117 err_node->the_data.asmt.rhs.d_val );
349 mmeineke 10 break;
350     }
351    
352     fprintf( stderr,
353     "\n"
354     " -> %s\n",
355     err_msg );
356     break;
357    
358     case POSITION_STMT:
359     fprintf( stderr,
360     "Parse tree error: position node error => ( %lf, %lf, %lf )\n"
361     " -> %s\n",
362 mmeineke 117 err_node->the_data.pos.x,
363     err_node->the_data.pos.y,
364     err_node->the_data.pos.z,
365 mmeineke 10 err_msg );
366     break;
367    
368     case ORIENTATION_STMT:
369     fprintf( stderr,
370     "Parse tree error: orientation node error => ( %lf, %lf, %lf )\n"
371     " -> %s\n",
372 mmeineke 117 err_node->the_data.ort.x,
373     err_node->the_data.ort.y,
374     err_node->the_data.ort.z,
375 mmeineke 10 err_msg );
376     break;
377    
378     case START_INDEX_STMT:
379     fprintf( stderr,
380     "Parse tree error: start_index error -> %s\n",
381     err_msg );
382     break;
383    
384    
385     default:
386     fprintf( stderr,
387     "Parse tree error: unknown node type -> %s\n",
388     err_msg );
389     }
390 chuckv 118
391     #ifdef MPI
392     mpiInterfaceExit();
393     #endif
394    
395 mmeineke 10 }
396    
397    
398     /*
399     * recursive walkdown and kill of the node tree
400     * note: looks mighty similar to the walkdown routine.
401     */
402    
403     void kill_tree( struct node_tag* the_node ){
404    
405     // These two are needed to get rid of the integer list
406    
407     struct integer_list_tag* current_il;
408     struct integer_list_tag* temp_il;
409    
410    
411     if( the_node != NULL ){
412    
413     if( the_node->stmt_list != NULL ){
414    
415     // the statement is a block node of some sort
416    
417     kill_tree( the_node->stmt_list );
418     }
419    
420     else{
421    
422     // the node is a statement
423    
424     switch( the_node->type ){
425    
426     case ASSIGNMENT_STMT:
427    
428     if( the_node->the_data.asmt.type == STR_ASSN )
429     free( the_node->the_data.asmt.rhs.str_ptr );
430    
431     free( the_node->the_data.asmt.identifier );
432     break;
433    
434     case START_INDEX_STMT:
435    
436     current_il = the_node->the_data.il_head;
437     while( current_il != NULL ){
438     temp_il = current_il->next;
439     free( current_il );
440     current_il = temp_il;
441     }
442     the_node->the_data.il_head = NULL;
443     break;
444    
445     default:
446     // nothing to do here, everyone else can be freed normally.
447     break;
448     }
449     }
450    
451     // recurse down to the next node
452    
453     kill_tree( the_node->next_stmt );
454     free( the_node );
455     }
456    
457     // we're done
458     }