ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libBASS/parse_tree.c
Revision: 378
Committed: Fri Mar 21 17:42:12 2003 UTC (21 years, 3 months ago) by mmeineke
Content type: text/plain
File size: 10601 byte(s)
Log Message:
This commit was generated by cvs2svn to compensate for changes in r377,
which included commits to RCS files with non-trunk default branches.

File Contents

# User Rev Content
1 mmeineke 377 #include <stdlib.h>
2     #include <stdio.h>
3    
4     #include <parse_tree.h>
5     #include <simError.h>
6    
7     #ifdef IS_MPI
8     #define __is_lex__
9     #include <mpiBASS.h>
10     #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     if( the_namespc.type != MOLECULE_HEAD ){
102     print_tree_error( the_node,
103     "The atom block is not in a molecule 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 BOND_HEAD:
114     if( the_namespc.type != MOLECULE_HEAD ){
115     print_tree_error( the_node,
116     "The bond block is not in a molecule namespace" );
117     }
118     else{
119     init_bond( the_node->index );
120     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 BEND_HEAD:
127     if( the_namespc.type != MOLECULE_HEAD ){
128     print_tree_error( the_node,
129     "The bend block is not in a molecule namespace" );
130     }
131     else{
132     init_bend( 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 TORSION_HEAD:
140     if( the_namespc.type != MOLECULE_HEAD ){
141     print_tree_error( the_node,
142     "The torsion block is not in "
143     "a molecule namespace" );
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     }
156     }
157    
158     else{
159    
160     // the node is a statement
161    
162     switch( the_node->type ){
163    
164     case MEMBER_STMT:
165     switch( the_namespc.type ){
166     case BOND_HEAD: // fall through
167     case BEND_HEAD: // fall through
168     case TORSION_HEAD: // same for the first three
169     init_members( the_node, the_namespc );
170     break;
171    
172     default:
173     print_tree_error( the_node,
174     "Member statement not in a bond, bend, "
175     "or torsion" );
176     break;
177     }
178     break;
179    
180     case CONSTRAINT_STMT:
181     switch( the_namespc.type ){
182     case BOND_HEAD: // fall through
183     case BEND_HEAD: // fall through
184     case TORSION_HEAD: // same for the first three
185     init_constraint( the_node, the_namespc );
186     break;
187    
188     default:
189     print_tree_error( the_node,
190     "Constraint statement not in a bond, bend, "
191     "or torsion" );
192     break;
193     }
194     break;
195    
196     case ASSIGNMENT_STMT:
197     init_assignment( the_node, the_namespc );
198     break;
199    
200     case POSITION_STMT:
201     if( the_namespc.type != ATOM_HEAD ){
202     print_tree_error( the_node,
203     "position statement is not located in an "
204     "atom block" );
205     }
206    
207     init_position( the_node, the_namespc );
208     break;
209    
210     case ORIENTATION_STMT:
211     if( the_namespc.type != ATOM_HEAD ){
212     print_tree_error( the_node,
213     "orientation statement is not located in an "
214     "atom block" );
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     }
226    
227     //init_start_index( the_node, the_namespc );
228     break;
229    
230     default:
231     print_tree_error( the_node, "unrecognized statement" );
232     break;
233     }
234     }
235    
236     // recurse down to the next node
237    
238     walk_down( the_node->next_stmt, the_namespc );
239     }
240    
241     // send an end of block signal
242     else end_of_block();
243    
244     // we're done
245     }
246    
247    
248    
249     /*
250     * This is a routine utilized by the node parsers to make printing
251     * error messages easy.
252     */
253    
254     void print_tree_error( struct node_tag* err_node, char* err_msg ){
255    
256     switch( err_node->type ){
257    
258     case GLOBAL_HEAD:
259     sprintf( painCave.errMsg,
260     "Parse tree error: global head node error -> %s\n",
261     err_msg );
262     break;
263    
264     case COMPONENT_HEAD:
265     sprintf( painCave.errMsg,
266     "Parse tree error: component head node error -> %s\n",
267     err_msg );
268     break;
269    
270     case MOLECULE_HEAD:
271     sprintf( painCave.errMsg,
272     "Parse tree error: molecule head node error -> %s\n",
273     err_msg );
274     break;
275    
276     case ATOM_HEAD:
277     sprintf( painCave.errMsg,
278     "Parse tree error: atom head node error [%d] -> %s\n",
279     err_node->index,
280     err_msg );
281     break;
282    
283     case BOND_HEAD:
284     sprintf( painCave.errMsg,
285     "Parse tree error: bond head node error [%d] -> %s\n",
286     err_node->index,
287     err_msg );
288     break;
289    
290     case BEND_HEAD:
291     sprintf( painCave.errMsg,
292     "Parse tree error: bend head node error [%d] -> %s\n",
293     err_node->index,
294     err_msg );
295     break;
296    
297     case TORSION_HEAD:
298     sprintf( painCave.errMsg,
299     "Parse tree error: torsion head node error [%d] -> %s\n",
300     err_node->index,
301     err_msg );
302     break;
303    
304     case MEMBER_STMT:
305     sprintf( painCave.errMsg,
306     "Parse tree error: member node error => ( %d, %d, %d, %d )\n"
307     " -> %s\n",
308     err_node->the_data.mbr.a,
309     err_node->the_data.mbr.b,
310     err_node->the_data.mbr.c,
311     err_node->the_data.mbr.d,
312     err_msg );
313     break;
314    
315     case CONSTRAINT_STMT:
316     sprintf( painCave.errMsg,
317     "Parse tree error: constraint node error => ( %lf )\n"
318     " -> %s\n",
319     err_node->the_data.cnstr.constraint_val,
320     err_msg );
321     break;
322    
323     case ASSIGNMENT_STMT:
324     sprintf( painCave.errMsg,
325     "Parse tree error: assignment node error\n"
326     " => %s = ",
327     err_node->the_data.asmt.identifier );
328    
329     switch( err_node->the_data.asmt.type ){
330    
331     case STR_ASSN:
332     sprintf( painCave.errMsg,
333     "%s",
334     err_node->the_data.asmt.rhs.str_ptr );
335     break;
336    
337     case INT_ASSN:
338     sprintf( painCave.errMsg,
339     "%d",
340     err_node->the_data.asmt.rhs.i_val );
341     break;
342    
343     case DOUBLE_ASSN:
344     sprintf( painCave.errMsg,
345     "%lf",
346     err_node->the_data.asmt.rhs.d_val );
347     break;
348     }
349    
350     sprintf( painCave.errMsg,
351     "\n"
352     " -> %s\n",
353     err_msg );
354     break;
355    
356     case POSITION_STMT:
357     sprintf( painCave.errMsg,
358     "Parse tree error: position node error => ( %lf, %lf, %lf )\n"
359     " -> %s\n",
360     err_node->the_data.pos.x,
361     err_node->the_data.pos.y,
362     err_node->the_data.pos.z,
363     err_msg );
364     break;
365    
366     case ORIENTATION_STMT:
367     sprintf( painCave.errMsg,
368     "Parse tree error: orientation node error => ( %lf, %lf, %lf )\n"
369     " -> %s\n",
370     err_node->the_data.ort.x,
371     err_node->the_data.ort.y,
372     err_node->the_data.ort.z,
373     err_msg );
374     break;
375    
376     case START_INDEX_STMT:
377     sprintf( painCave.errMsg,
378     "Parse tree error: start_index error -> %s\n",
379     err_msg );
380     break;
381    
382    
383     default:
384     sprintf( painCave.errMsg,
385     "Parse tree error: unknown node type -> %s\n",
386     err_msg );
387     }
388    
389     painCave.isFatal = 1;
390     simError();
391     #ifdef IS_MPI
392     mpiInterfaceExit();
393     #endif //is_mpi
394    
395     }
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     }