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

File Contents

# Content
1 #include <stdlib.h>
2 #include <stdio.h>
3
4 #include "parse_tree.h"
5
6 void walk_down( struct node_tag* the_node, struct namespc the_namespc );
7 int mol_index; // keeps track of the number of molecules
8 int comp_index; // keeps track of the number of components.
9
10 /*
11 * This is the parse tree function that is called by the yacc
12 * routine. It passes the global node and namespace to the recursive
13 * walk_down routine to explore the node tree.
14 */
15
16 void pt_me( struct node_tag* head_node ){
17
18 struct namespc global_namespc;
19
20 if( head_node->type != GLOBAL_HEAD ){
21 fprintf( stderr, "Parse tree error: "
22 "The head node was not the global node.\n" );
23 }
24
25 global_namespc.index = 0;
26 global_namespc.type = GLOBAL_HEAD;
27
28 mol_index = 0;
29 comp_index = 0;
30 walk_down( head_node->next_stmt, global_namespc ); // closed global namespace + exit
31
32 }
33
34 /*
35 * This is the main logic workhorse routine for the node tree
36 * parser. It recursively walks down the node list and calls the
37 * appropriate interface functions acording to the node types. It will
38 * also set the appropriate namespace for the nodes.
39 *
40 * Note: the nodes only know about the namespace of their
41 * current level, the namespace above themselves is hidden.
42 */
43
44 void walk_down( struct node_tag* the_node, struct namespc the_namespc ){
45
46 struct namespc current_namespc;
47
48 if( the_node != NULL ){
49
50 if( the_node->type == GLOBAL_HEAD ){
51 print_tree_error( the_node, "Too many global regions" );
52 exit(0);
53 }
54
55 if( the_node->stmt_list != NULL ){
56
57 // the statement is a block node of some sort
58
59 switch( the_node->type ){
60
61 case COMPONENT_HEAD:
62 if( the_namespc.type != GLOBAL_HEAD ){
63 print_tree_error( the_node,
64 "component block is not in the global namespace" );
65 exit(0);
66 }
67 else{
68 init_component( comp_index );
69 current_namespc.index = comp_index;
70 current_namespc.type = COMPONENT_HEAD;
71 walk_down( the_node->stmt_list, current_namespc );
72 comp_index++;
73 }
74 break;
75
76 case MOLECULE_HEAD:
77 if( the_namespc.type != GLOBAL_HEAD ){
78 print_tree_error( the_node,
79 "Molecule block is not in the global namespace" );
80 exit(0);
81 }
82 else{
83 init_molecule( mol_index );
84 current_namespc.index = mol_index;
85 current_namespc.type = MOLECULE_HEAD;
86 walk_down( the_node->stmt_list, current_namespc );
87 mol_index++;
88 }
89 break;
90
91 case ATOM_HEAD:
92 if( the_namespc.type != MOLECULE_HEAD ){
93 print_tree_error( the_node,
94 "The atom block is not in a molecule namespace" );
95 exit(0);
96 }
97 else{
98 init_atom( the_node->index );
99 current_namespc.index = the_node->index;
100 current_namespc.type = the_node->type;
101 walk_down( the_node->stmt_list, current_namespc );
102 }
103 break;
104
105 case BOND_HEAD:
106 if( the_namespc.type != MOLECULE_HEAD ){
107 print_tree_error( the_node,
108 "The bond block is not in a molecule namespace" );
109 exit(0);
110 }
111 else{
112 init_bond( the_node->index );
113 current_namespc.index = the_node->index;
114 current_namespc.type = the_node->type;
115 walk_down( the_node->stmt_list, current_namespc );
116 }
117 break;
118
119 case BEND_HEAD:
120 if( the_namespc.type != MOLECULE_HEAD ){
121 print_tree_error( the_node,
122 "The bend block is not in a molecule namespace" );
123 exit(0);
124 }
125 else{
126 init_bend( the_node->index );
127 current_namespc.index = the_node->index;
128 current_namespc.type = the_node->type;
129 walk_down( the_node->stmt_list, current_namespc );
130 }
131 break;
132
133 case TORSION_HEAD:
134 if( the_namespc.type != MOLECULE_HEAD ){
135 print_tree_error( the_node,
136 "The torsion block is not in "
137 "a molecule namespace" );
138 exit(0);
139 }
140 else{
141 init_torsion( the_node->index );
142 current_namespc.index = the_node->index;
143 current_namespc.type = the_node->type;
144 walk_down( the_node->stmt_list, current_namespc );
145 }
146 break;
147
148 default:
149 print_tree_error( the_node, "Not a valid code block" );
150 exit(0);
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 exit(0);
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 exit(0);
190 break;
191 }
192 break;
193
194 case ASSIGNMENT_STMT:
195 init_assignment( the_node, the_namespc );
196 break;
197
198 case POSITION_STMT:
199 if( the_namespc.type != ATOM_HEAD ){
200 print_tree_error( the_node,
201 "position statement is not located in an "
202 "atom block" );
203 exit(0);
204 }
205
206 init_position( the_node, the_namespc );
207 break;
208
209 case ORIENTATION_STMT:
210 if( the_namespc.type != ATOM_HEAD ){
211 print_tree_error( the_node,
212 "orientation statement is not located in an "
213 "atom block" );
214 exit(0);
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 exit(0);
226 }
227
228 init_start_index( the_node, the_namespc );
229 break;
230
231 default:
232 print_tree_error( the_node, "unrecognized statement" );
233 exit(0);
234 break;
235 }
236 }
237
238 // recurse down to the next node
239
240 walk_down( the_node->next_stmt, the_namespc );
241 }
242
243 // send an end of block signal
244 else end_of_block();
245
246 // we're done
247 }
248
249
250
251 /*
252 * This is a routine utilized by the node parsers to make printing
253 * error messages easy.
254 */
255
256 void print_tree_error( struct node_tag* err_node, char* err_msg ){
257
258 switch( err_node->type ){
259
260 case GLOBAL_HEAD:
261 fprintf( stderr,
262 "Parse tree error: global head node error -> %s\n",
263 err_msg );
264 break;
265
266 case COMPONENT_HEAD:
267 fprintf( stderr,
268 "Parse tree error: component head node error -> %s\n",
269 err_msg );
270 break;
271
272 case MOLECULE_HEAD:
273 fprintf( stderr,
274 "Parse tree error: molecule head node error -> %s\n",
275 err_msg );
276 break;
277
278 case ATOM_HEAD:
279 fprintf( stderr,
280 "Parse tree error: atom head node error [%d] -> %s\n",
281 err_node->index,
282 err_msg );
283 break;
284
285 case BOND_HEAD:
286 fprintf( stderr,
287 "Parse tree error: bond head node error [%d] -> %s\n",
288 err_node->index,
289 err_msg );
290 break;
291
292 case BEND_HEAD:
293 fprintf( stderr,
294 "Parse tree error: bend head node error [%d] -> %s\n",
295 err_node->index,
296 err_msg );
297 break;
298
299 case TORSION_HEAD:
300 fprintf( stderr,
301 "Parse tree error: torsion head node error [%d] -> %s\n",
302 err_node->index,
303 err_msg );
304 break;
305
306 case MEMBER_STMT:
307 fprintf( stderr,
308 "Parse tree error: member node error => ( %d, %d, %d, %d )\n"
309 " -> %s\n",
310 err_node->the_data.mbr.a,
311 err_node->the_data.mbr.b,
312 err_node->the_data.mbr.c,
313 err_node->the_data.mbr.d,
314 err_msg );
315 break;
316
317 case CONSTRAINT_STMT:
318 fprintf( stderr,
319 "Parse tree error: constraint node error => ( %lf )\n"
320 " -> %s\n",
321 err_node->the_data.cnstr.constraint_val,
322 err_msg );
323 break;
324
325 case ASSIGNMENT_STMT:
326 fprintf( stderr,
327 "Parse tree error: assignment node error\n"
328 " => %s = ",
329 err_node->the_data.asmt.identifier );
330
331 switch( err_node->the_data.asmt.type ){
332
333 case STR_ASSN:
334 fprintf( stderr,
335 "%s",
336 err_node->the_data.asmt.rhs.str_ptr );
337 break;
338
339 case INT_ASSN:
340 fprintf( stderr,
341 "%d",
342 err_node->the_data.asmt.rhs.i_val );
343 break;
344
345 case DOUBLE_ASSN:
346 fprintf( stderr,
347 "%lf",
348 err_node->the_data.asmt.rhs.d_val );
349 break;
350 }
351
352 fprintf( stderr,
353 "\n"
354 " -> %s\n",
355 err_msg );
356 break;
357
358 case POSITION_STMT:
359 fprintf( stderr,
360 "Parse tree error: position node error => ( %lf, %lf, %lf )\n"
361 " -> %s\n",
362 err_node->the_data.pos.x,
363 err_node->the_data.pos.y,
364 err_node->the_data.pos.z,
365 err_msg );
366 break;
367
368 case ORIENTATION_STMT:
369 fprintf( stderr,
370 "Parse tree error: orientation node error => ( %lf, %lf, %lf )\n"
371 " -> %s\n",
372 err_node->the_data.ort.x,
373 err_node->the_data.ort.y,
374 err_node->the_data.ort.z,
375 err_msg );
376 break;
377
378 case START_INDEX_STMT:
379 fprintf( stderr,
380 "Parse tree error: start_index error -> %s\n",
381 err_msg );
382 break;
383
384
385 default:
386 fprintf( stderr,
387 "Parse tree error: unknown node type -> %s\n",
388 err_msg );
389 }
390
391 #ifdef IS_MPI
392 mpiInterfaceExit();
393 #endif
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 }