ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/BASS_parse/parse_tree.c
Revision: 11
Committed: Tue Jul 9 18:40:59 2002 UTC (22 years ago) by mmeineke
Content type: text/plain
File size: 10067 byte(s)
Log Message:
This commit was generated by cvs2svn to compensate for changes in r10, which
included commits to RCS files with non-trunk default branches.

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