ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/BASS_parse/parse_tree.c
Revision: 163
Committed: Tue Nov 5 22:04:42 2002 UTC (21 years, 8 months ago) by mmeineke
Content type: text/plain
File size: 10569 byte(s)
Log Message:
adding simError into the mpiBASS Event loop

File Contents

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