/* l2xisdcl.c LTX2X declaration analysis */ /* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */ /* This code is partly based on algorithms presented by Ronald Mak in */ /* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */ #include #include "l2xicmon.h" #include "l2xierr.h" #include "l2xiscan.h" #include "l2xisymt.h" #include "l2xiidbg.h" /* EXTERNALS */ extern int line_number; extern TOKEN_CODE token; /* GLOBALS */ char buffer[MAX_PRINT_LINE_LENGTH]; char *defn_names[] = { #define dfntc(a, b) b, #include "l2xidftc.h" #undef dfntc }; char *form_names[] = { #define fotc(a, b, c, d) d, #define sotc(a, b, c, d) #define sftc(a, b, c, d) d, #include "l2xisftc.h" #undef fotc #undef sotc #undef sftc }; /* ANALYSIS */ /***************************************************************************/ /* analyze_const_defn(idp) Analyze a constant definition */ analyze_const_defn(idp) SYMTAB_NODE_PTR idp; /* constant id */ { char *bp; if (DEBUG < Danalyze) return; /* the name */ sprintf(buffer, ">> id = %s\n", idp->name); debug_print(buffer); sprintf(buffer, ">> address = %d\n", idp); /* definition and value */ sprintf(buffer, ">> defn = %s, value = ", defn_names[idp->defn.key]); bp = buffer + strlen(buffer); if ((idp->typep == integer_typep) || (idp->typep->form == ENUM_FORM)) sprintf(bp, "%d\n", idp->defn.info.constant.value.integer); else if (idp->typep == real_typep) sprintf(bp, "%g\n", idp->defn.info.constant.value.real); else if (idp->typep->form == ARRAY_FORM) /* ????????????????????????? */ sprintf(bp, "'%s'\n", idp->defn.info.constant.value.stringp); else if (idp->typep->form == STRING_FORM) sprintf(bp, "'%s'\n", idp->defn.info.constant.value.stringp); debug_print(buffer); /* and type. careful as an enum type will get into an infinite loop */ if (idp->typep->form != ENUM_FORM) analyze_type(idp->typep, FALSE); } /* end analyze_const_defn */ /***************************************************************************/ /***************************************************************************/ /* analyze_type_defn(idp) Analyze a type definition */ analyze_type_defn(idp) SYMTAB_NODE_PTR idp; /* id */ { char *bp; if (DEBUG < Danalyze) return; /* the type's name, definition ... */ sprintf(buffer, ">>id = %s\n", idp->name); debug_print(buffer); sprintf(buffer, ">> address = %d\n", idp); debug_print(buffer); sprintf(buffer, ">> defn = %s\n", defn_names[idp->defn.key]); /* print_line(buffer); */ debug_print(buffer); /* and type */ analyze_type(idp->typep, TRUE); } /* end analyze_type_defn */ /***************************************************************************/ /***************************************************************************/ /* analyze_type(tp, verbose_flag) Analyze a type definition */ analyze_type(tp, verbose_flag) TYPE_STRUCT_PTR tp; /* pointer to type structure */ BOOLEAN verbose_flag; /* TRUE for verbose analysis */ { char *bp; if (DEBUG < Danalyze) return; if (tp == NULL) return; /* the form, byte size (and name) */ sprintf(buffer, ">> form = %s, size = %d bytes, type id = ", form_names[tp->form], tp->size); bp = buffer + strlen(buffer); if (tp->type_idp != NULL) sprintf(bp, "%s\n", tp->type_idp->name); else { sprintf(bp, "\n"); verbose_flag = TRUE; } debug_print(buffer); /* do the appropriate analysus */ switch (tp->form) { case ENUM_FORM: { analyze_enum_type(tp, verbose_flag); break; } case SUBRANGE_FORM: { analyze_subrange_type(tp, verbose_flag); break; } case ARRAY_FORM: { analyze_array_type(tp, verbose_flag); break; } case STRING_FORM: { verbose_flag = TRUE; analyze_string_type(tp, verbose_flag); break; } case BOUND_FORM: { analyze_bound_type(tp, verbose_flag); break; } case ENTITY_FORM: { analyze_entity_type(tp, verbose_flag); break; } case BAG_FORM: case LIST_FORM: case SET_FORM: { analyze_bls_type(tp, verbose_flag); break; } default: { break; } } /* end switch */ } /* end analyze_type */ /***************************************************************************/ /***************************************************************************/ /* analyze_enum_type(tp, verbose_flag) Analyze an enumeration type */ analyze_enum_type(tp, verbose_flag) TYPE_STRUCT_PTR tp; /* pointer to type structure */ BOOLEAN verbose_flag; /* TRUE for verbose analysis */ { SYMTAB_NODE_PTR idp; /* id */ if (DEBUG < Danalyze) return; if (!verbose_flag) return; /* loop to analyze each enum constant as a constant defn */ debug_print(">> -- Enum Constants --\n"); for (idp = tp->info.enumeration.const_idp; idp != NULL; idp = idp->next) { analyze_const_defn(idp); } } /* end analyze_enum_type */ /***************************************************************************/ /***************************************************************************/ /* analyze_subrange_type(tp, verbose_flag) Analyze a subrange type */ analyze_subrange_type(tp, verbose_flag) TYPE_STRUCT_PTR tp; /* pointer to type structure */ BOOLEAN verbose_flag; /* TRUE for verbose analysis */ { SYMTAB_NODE_PTR idp; /* id */ if (DEBUG < Danalyze) return; if (!verbose_flag) return; sprintf(buffer, ">> min value = %d, max value = %d\n", tp->info.subrange.min, tp->info.subrange.max); debug_print(buffer); debug_print(">> -- Range Type -- \n"); analyze_type(tp->info.subrange.range_typep, FALSE); } /* end analyze_subrange_type */ /***************************************************************************/ /***************************************************************************/ /* analyze_bound_type(tp, verbose_flag) Analyze a bound type */ analyze_bound_type(tp, verbose_flag) TYPE_STRUCT_PTR tp; /* pointer to type structure */ BOOLEAN verbose_flag; /* TRUE for verbose analysis */ { SYMTAB_NODE_PTR idp; /* id */ if (DEBUG < Danalyze) return; if (!verbose_flag) return; sprintf(buffer, ">> min value = %d, max value = %d\n", tp->info.bound.min, tp->info.bound.max); debug_print(buffer); debug_print(">> -- Bound Type -- \n"); analyze_type(tp->info.bound.bound_typep, FALSE); } /* end analyze_bound_type */ /***************************************************************************/ /***************************************************************************/ /* analyze_array_type(tp, verbose_flag) Analyze an array type */ analyze_array_type(tp, verbose_flag) TYPE_STRUCT_PTR tp; /* pointer to type structure */ BOOLEAN verbose_flag; /* TRUE for verbose analysis */ { SYMTAB_NODE_PTR idp; /* id */ if (DEBUG < Danalyze) return; if (!verbose_flag) return; sprintf(buffer, ">> element count = %d\n", tp->info.array.elmt_count); debug_print(buffer); sprintf(buffer, ">> index limits = %d to %d\n", tp->info.array.min_index, tp->info.array.max_index); debug_print(buffer); debug_print(">> -- INDEX TYPE -- \n"); analyze_type(tp->info.array.index_typep, FALSE); debug_print(">> -- ELEMENT TYPE -- \n"); analyze_type(tp->info.array.elmt_typep, FALSE); } /* end analyze_array_type */ /***************************************************************************/ /***************************************************************************/ /* analyze_bls_type(tp, verbose_flag) Analyze a bag, etc type */ analyze_bls_type(tp, verbose_flag) TYPE_STRUCT_PTR tp; /* pointer to type structure */ BOOLEAN verbose_flag; /* TRUE for verbose analysis */ { SYMTAB_NODE_PTR idp; /* id */ if (DEBUG < Danalyze) return; if (!verbose_flag) return; sprintf(buffer, ">> element count = %d\n", tp->info.dynagg.elmt_count); debug_print(buffer); sprintf(buffer, ">> index limits = %d to %d\n", tp->info.dynagg.min_index, tp->info.dynagg.max_index); debug_print(buffer); debug_print(">> -- INDEX TYPE -- \n"); analyze_type(tp->info.dynagg.index_typep, FALSE); debug_print(">> -- ELEMENT TYPE -- \n"); analyze_type(tp->info.dynagg.elmt_typep, FALSE); } /* end analyze_bls_type */ /***************************************************************************/ /***************************************************************************/ /* analyze_string_type(tp, verbose_flag) Analyze a string type */ analyze_string_type(tp, verbose_flag) TYPE_STRUCT_PTR tp; /* pointer to type structure */ BOOLEAN verbose_flag; /* TRUE for verbose analysis */ { SYMTAB_NODE_PTR idp; /* id */ if (DEBUG < Danalyze) return; if (!verbose_flag) return; sprintf(buffer, ">> maximum length = %d\n", tp->info.string.max_length); debug_print(buffer); sprintf(buffer, ">> length = %d\n", tp->info.string.length); debug_print(buffer); return; } /* end analyze_string_type */ /***************************************************************************/ /***************************************************************************/ /* analyze_entity_type(tp, verbose_flag) Analyze an entity type */ analyze_entity_type(tp, verbose_flag) TYPE_STRUCT_PTR tp; /* pointer to type structure */ BOOLEAN verbose_flag; /* TRUE for verbose analysis */ { SYMTAB_NODE_PTR idp; /* id */ if (DEBUG < Danalyze) return; if (!verbose_flag) return; /* loop to analyze each attribute as a variable decl */ debug_print(">> -- Attributes -- \n"); for (idp = tp->info.entity.attribute_symtab; idp != NULL; idp = idp->next) { analyze_var_decl(idp); } } /* end analyze_entity_type */ /***************************************************************************/ /***************************************************************************/ /* analyze_var_decl(idp) Analyze a variable declaration */ analyze_var_decl(idp) SYMTAB_NODE_PTR idp; /* id */ { if (DEBUG < Danalyze) return; /* the name, definition and offset */ sprintf(buffer, ">> id = %s\n", idp->name); debug_print(buffer); sprintf(buffer, ">> address = %d\n", idp); debug_print(buffer); sprintf(buffer, ">> defn = %s, offset = %d\n", defn_names[idp->defn.key], idp->defn.info.data.offset); /* print_line(buffer); */ debug_print(buffer); /* and type */ analyze_type(idp->typep, FALSE); } /* end analyze_var_decl */ /***************************************************************************/ /***************************************************************************/ /* analyze_block(code_segment) a dummy procedure */ analyze_block(code_segment) char *code_segment; { return; } /* end analyze_block */ /***************************************************************************/ /***************************************************************************/ /* analyze_routine_header(rtn_idp) a dummy procedure */ analyze_routine_header(rtn_idp) SYMTAB_NODE_PTR rtn_idp; { return; } /* end analyze_routine_header */ /***************************************************************************/ /***************************************************************************/