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

# Content
1 #include <stdlib.h>
2 #include <stdio.h>
3
4 #include "parse_tree.h"
5
6 #ifdef IS_MPI
7 #define __is_lex__
8 #include "../headers/mpiInterface.h"
9 #endif
10
11 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 walk_down( head_node->next_stmt, global_namespc ); // closed global namespace + exit
36
37 }
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 //init_start_index( the_node, the_namespc );
234 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 err_node->the_data.asmt.rhs.str_ptr );
342 break;
343
344 case INT_ASSN:
345 fprintf( stderr,
346 "%d",
347 err_node->the_data.asmt.rhs.i_val );
348 break;
349
350 case DOUBLE_ASSN:
351 fprintf( stderr,
352 "%lf",
353 err_node->the_data.asmt.rhs.d_val );
354 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 err_node->the_data.pos.x,
368 err_node->the_data.pos.y,
369 err_node->the_data.pos.z,
370 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 err_node->the_data.ort.x,
378 err_node->the_data.ort.y,
379 err_node->the_data.ort.z,
380 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
396 #ifdef IS_MPI
397 mpiInterfaceExit();
398 #endif
399
400 }
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 }