ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/BASS_parse/parse_tree.c
Revision: 163
Committed: Tue Nov 5 22:04:42 2002 UTC (21 years, 8 months ago) by mmeineke
Content type: text/plain
File size: 10569 byte(s)
Log Message:
adding simError into the mpiBASS Event loop

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