ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/BASS_parse/parse_tree.c
Revision: 160
Committed: Wed Oct 30 22:38:22 2002 UTC (21 years, 8 months ago) by mmeineke
Content type: text/plain
File size: 10511 byte(s)
Log Message:
*** empty log message ***

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