ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/BASS_parse/parse_tree.c
Revision: 170
Committed: Mon Nov 11 15:16:09 2002 UTC (21 years, 7 months ago) by mmeineke
Content type: text/plain
File size: 10623 byte(s)
Log Message:
continuing to refine the error checking in the BASS processing

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