ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/BASS_parse/parse_tree.c
Revision: 133
Committed: Fri Oct 11 15:09:01 2002 UTC (21 years, 8 months ago) by chuckv
Content type: text/plain
File size: 10445 byte(s)
Log Message:
Clean up with icc debug flags...

File Contents

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