ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/BASS_parse/parse_tree.c
Revision: 10
Committed: Tue Jul 9 18:40:59 2002 UTC (22 years ago) by mmeineke
Content type: text/plain
Original Path: branches/mmeineke/mdtools/BASS_parse/parse_tree.c
File size: 10067 byte(s)
Log Message:
everything you need to make libmdtools

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