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

# Content
1 #include <stdlib.h>
2 #include <stdio.h>
3
4 #include "parse_tree.h"
5 #include "../headers/simError.h"
6
7 #ifdef IS_MPI
8 #define __is_lex__
9 #include "../headers/mpiBASS.h"
10 #endif
11
12 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 sprintf( painCave.errMsg,
28 "Parse tree error: The head node was not the global node.\n" );
29 painCave.isFatal = 1;
30 simError();
31 }
32
33 global_namespc.index = 0;
34 global_namespc.type = GLOBAL_HEAD;
35
36 mol_index = 0;
37 comp_index = 0;
38 walk_down( head_node->next_stmt, global_namespc ); // closed global namespace + exit
39
40 }
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 //init_start_index( the_node, the_namespc );
224 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 sprintf( painCave.errMsg,
256 "Parse tree error: global head node error -> %s\n",
257 err_msg );
258 break;
259
260 case COMPONENT_HEAD:
261 sprintf( painCave.errMsg,
262 "Parse tree error: component head node error -> %s\n",
263 err_msg );
264 break;
265
266 case MOLECULE_HEAD:
267 sprintf( painCave.errMsg,
268 "Parse tree error: molecule head node error -> %s\n",
269 err_msg );
270 break;
271
272 case ATOM_HEAD:
273 sprintf( painCave.errMsg,
274 "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 sprintf( painCave.errMsg,
281 "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 sprintf( painCave.errMsg,
288 "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 sprintf( painCave.errMsg,
295 "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 sprintf( painCave.errMsg,
302 "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 sprintf( painCave.errMsg,
313 "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 sprintf( painCave.errMsg,
321 "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 sprintf( painCave.errMsg,
329 "%s",
330 err_node->the_data.asmt.rhs.str_ptr );
331 break;
332
333 case INT_ASSN:
334 sprintf( painCave.errMsg,
335 "%d",
336 err_node->the_data.asmt.rhs.i_val );
337 break;
338
339 case DOUBLE_ASSN:
340 sprintf( painCave.errMsg,
341 "%lf",
342 err_node->the_data.asmt.rhs.d_val );
343 break;
344 }
345
346 sprintf( painCave.errMsg,
347 "\n"
348 " -> %s\n",
349 err_msg );
350 break;
351
352 case POSITION_STMT:
353 sprintf( painCave.errMsg,
354 "Parse tree error: position node error => ( %lf, %lf, %lf )\n"
355 " -> %s\n",
356 err_node->the_data.pos.x,
357 err_node->the_data.pos.y,
358 err_node->the_data.pos.z,
359 err_msg );
360 break;
361
362 case ORIENTATION_STMT:
363 sprintf( painCave.errMsg,
364 "Parse tree error: orientation node error => ( %lf, %lf, %lf )\n"
365 " -> %s\n",
366 err_node->the_data.ort.x,
367 err_node->the_data.ort.y,
368 err_node->the_data.ort.z,
369 err_msg );
370 break;
371
372 case START_INDEX_STMT:
373 sprintf( painCave.errMsg,
374 "Parse tree error: start_index error -> %s\n",
375 err_msg );
376 break;
377
378
379 default:
380 sprintf( painCave.errMsg,
381 "Parse tree error: unknown node type -> %s\n",
382 err_msg );
383 }
384
385 painCave.isFatal = 1;
386 simError();
387 }
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 }