ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libBASS/parse_tree.c
Revision: 854
Committed: Thu Nov 6 19:24:31 2003 UTC (20 years, 8 months ago) by mmeineke
Content type: text/plain
File size: 10411 byte(s)
Log Message:
fixed the includes in the Make.dep

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     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 mmeineke 675
153     case ZCONSTRAINT_HEAD:
154     if( the_namespc.type != GLOBAL_HEAD ){
155     print_tree_error( the_node,
156     "The Zconstraint block is not in "
157     "the global namespace" );
158     }
159     else{
160     init_zconstraint( the_node->index );
161     current_namespc.index = the_node->index;
162     current_namespc.type = the_node->type;
163     walk_down( the_node->stmt_list, current_namespc );
164     }
165     break;
166 mmeineke 377
167     default:
168     print_tree_error( the_node, "Not a valid code block" );
169     }
170     }
171    
172     else{
173    
174     // the node is a statement
175    
176     switch( the_node->type ){
177    
178     case MEMBER_STMT:
179     switch( the_namespc.type ){
180     case BOND_HEAD: // fall through
181     case BEND_HEAD: // fall through
182     case TORSION_HEAD: // same for the first three
183     init_members( the_node, the_namespc );
184     break;
185    
186     default:
187     print_tree_error( the_node,
188     "Member statement not in a bond, bend, "
189     "or torsion" );
190     break;
191     }
192     break;
193    
194     case CONSTRAINT_STMT:
195     switch( the_namespc.type ){
196     case BOND_HEAD: // fall through
197     case BEND_HEAD: // fall through
198     case TORSION_HEAD: // same for the first three
199     init_constraint( the_node, the_namespc );
200     break;
201    
202     default:
203     print_tree_error( the_node,
204     "Constraint statement not in a bond, bend, "
205     "or torsion" );
206     break;
207     }
208     break;
209    
210     case ASSIGNMENT_STMT:
211     init_assignment( the_node, the_namespc );
212     break;
213    
214     case POSITION_STMT:
215     if( the_namespc.type != ATOM_HEAD ){
216     print_tree_error( the_node,
217     "position statement is not located in an "
218     "atom block" );
219     }
220    
221     init_position( the_node, the_namespc );
222     break;
223    
224     case ORIENTATION_STMT:
225     if( the_namespc.type != ATOM_HEAD ){
226     print_tree_error( the_node,
227     "orientation statement is not located in an "
228     "atom block" );
229     }
230    
231     init_orientation( the_node, the_namespc );
232     break;
233    
234     default:
235     print_tree_error( the_node, "unrecognized statement" );
236     break;
237     }
238     }
239    
240     // recurse down to the next node
241    
242     walk_down( the_node->next_stmt, the_namespc );
243     }
244    
245     // send an end of block signal
246     else end_of_block();
247    
248     // we're done
249     }
250    
251    
252    
253     /*
254     * This is a routine utilized by the node parsers to make printing
255     * error messages easy.
256     */
257    
258     void print_tree_error( struct node_tag* err_node, char* err_msg ){
259    
260     switch( err_node->type ){
261    
262     case GLOBAL_HEAD:
263     sprintf( painCave.errMsg,
264     "Parse tree error: global head node error -> %s\n",
265     err_msg );
266     break;
267    
268     case COMPONENT_HEAD:
269     sprintf( painCave.errMsg,
270     "Parse tree error: component head node error -> %s\n",
271     err_msg );
272     break;
273    
274     case MOLECULE_HEAD:
275     sprintf( painCave.errMsg,
276     "Parse tree error: molecule head node error -> %s\n",
277     err_msg );
278     break;
279    
280     case ATOM_HEAD:
281     sprintf( painCave.errMsg,
282     "Parse tree error: atom head node error [%d] -> %s\n",
283     err_node->index,
284     err_msg );
285     break;
286    
287     case BOND_HEAD:
288     sprintf( painCave.errMsg,
289     "Parse tree error: bond head node error [%d] -> %s\n",
290     err_node->index,
291     err_msg );
292     break;
293    
294     case BEND_HEAD:
295     sprintf( painCave.errMsg,
296     "Parse tree error: bend head node error [%d] -> %s\n",
297     err_node->index,
298     err_msg );
299     break;
300    
301     case TORSION_HEAD:
302     sprintf( painCave.errMsg,
303     "Parse tree error: torsion head node error [%d] -> %s\n",
304     err_node->index,
305     err_msg );
306     break;
307 mmeineke 675
308     case ZCONSTRAINT_HEAD:
309     sprintf( painCave.errMsg,
310     "Parse tree error: Zconstraint head node error [%d] -> %s\n",
311     err_node->index,
312     err_msg );
313     break;
314    
315 mmeineke 377 case MEMBER_STMT:
316     sprintf( painCave.errMsg,
317     "Parse tree error: member node error => ( %d, %d, %d, %d )\n"
318     " -> %s\n",
319     err_node->the_data.mbr.a,
320     err_node->the_data.mbr.b,
321     err_node->the_data.mbr.c,
322     err_node->the_data.mbr.d,
323     err_msg );
324     break;
325    
326     case CONSTRAINT_STMT:
327     sprintf( painCave.errMsg,
328     "Parse tree error: constraint node error => ( %lf )\n"
329     " -> %s\n",
330     err_node->the_data.cnstr.constraint_val,
331     err_msg );
332     break;
333    
334     case ASSIGNMENT_STMT:
335     sprintf( painCave.errMsg,
336     "Parse tree error: assignment node error\n"
337     " => %s = ",
338     err_node->the_data.asmt.identifier );
339    
340     switch( err_node->the_data.asmt.type ){
341    
342     case STR_ASSN:
343     sprintf( painCave.errMsg,
344     "%s",
345     err_node->the_data.asmt.rhs.str_ptr );
346     break;
347    
348     case INT_ASSN:
349     sprintf( painCave.errMsg,
350     "%d",
351     err_node->the_data.asmt.rhs.i_val );
352     break;
353    
354     case DOUBLE_ASSN:
355     sprintf( painCave.errMsg,
356     "%lf",
357     err_node->the_data.asmt.rhs.d_val );
358     break;
359     }
360    
361     sprintf( painCave.errMsg,
362     "\n"
363     " -> %s\n",
364     err_msg );
365     break;
366    
367     case POSITION_STMT:
368     sprintf( painCave.errMsg,
369     "Parse tree error: position node error => ( %lf, %lf, %lf )\n"
370     " -> %s\n",
371     err_node->the_data.pos.x,
372     err_node->the_data.pos.y,
373     err_node->the_data.pos.z,
374     err_msg );
375     break;
376    
377     case ORIENTATION_STMT:
378     sprintf( painCave.errMsg,
379     "Parse tree error: orientation node error => ( %lf, %lf, %lf )\n"
380     " -> %s\n",
381     err_node->the_data.ort.x,
382     err_node->the_data.ort.y,
383     err_node->the_data.ort.z,
384     err_msg );
385     break;
386    
387     default:
388     sprintf( painCave.errMsg,
389     "Parse tree error: unknown node type -> %s\n",
390     err_msg );
391     }
392    
393     painCave.isFatal = 1;
394     simError();
395     #ifdef IS_MPI
396     mpiInterfaceExit();
397     #endif //is_mpi
398    
399     }
400    
401    
402     /*
403     * recursive walkdown and kill of the node tree
404     * note: looks mighty similar to the walkdown routine.
405     */
406    
407     void kill_tree( struct node_tag* the_node ){
408    
409    
410     if( the_node != NULL ){
411    
412     if( the_node->stmt_list != NULL ){
413    
414     // the statement is a block node of some sort
415    
416     kill_tree( the_node->stmt_list );
417     }
418    
419     else{
420    
421     // the node is a statement
422    
423     switch( the_node->type ){
424    
425     case ASSIGNMENT_STMT:
426    
427     if( the_node->the_data.asmt.type == STR_ASSN )
428     free( the_node->the_data.asmt.rhs.str_ptr );
429    
430     free( the_node->the_data.asmt.identifier );
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     }