⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 remsp.c

📁 一个非常好的检索工具
💻 C
📖 第 1 页 / 共 5 页
字号:
        /* If the two states are compatible merge them into the map   */        /* sp_action[SYMBOL]. (Note that this effectively destroys    */        /* the original map.) Also, keep track of whether or not an   */        /* actual merging action was necessary with the boolean       */        /* variable no_overwrite.                                     */        /**************************************************************/                if (actionp == NULL) /* compatible states */                {                    no_overwrite = TRUE;                    for (actionp = state -> action_root;                         actionp != NULL;                         action_tail = actionp, actionp = actionp -> next)                    {                        if (sp_action[symbol][actionp -> symbol] == OMEGA)                        {                            sp_action[symbol][actionp -> symbol] =                                                         actionp -> action;                            no_overwrite = FALSE;                        }                    }            /**********************************************************/            /* If the item was not previously associated with this    */            /* state, add it.                                         */            /**********************************************************/                    for (p = state -> complete_items;                         p != NULL; p = p -> next)                    {                        if (p -> value == item_no)                            break;                    }                    if (p == NULL)                    {                        p = Allocate_node();                        p -> value = item_no;                        p -> next = state -> complete_items;                        state -> complete_items = p;                    }            /**********************************************************/            /* If the two maps are identical (there was no merging),  */            /* return the state number otherwise, free the old map    */            /* and break out of the search loop.                      */            /**********************************************************/                    if (no_overwrite &&                        state -> action_count == sp_action_count)                        return state -> state_number;                    free_action_elements(state -> action_root, action_tail);                    break; /* for (state = sp_table[hash_address]; ... */                }            }        }    }    /******************************************************************/    /* If we did not find a compatible state, construct a new one.    */    /* Add it to the list of state and add it to the hash table.      */    /******************************************************************/    if (state == NULL)    {        state = (struct sp_state_element *)                talloc(sizeof(struct sp_state_element));        if (state == NULL)            nospace(__FILE__, __LINE__);        state -> next = sp_state_root;        sp_state_root = state;        state -> link = sp_table[hash_address];        sp_table[hash_address] = state;        max_sp_state++;        state -> state_number = max_sp_state;        state -> rule_count = sp_rule_count;        p = Allocate_node();        p -> value = item_no;        p -> next = NULL;        state -> complete_items = p;        state -> rule_root = NULL;        for (rule_no = rule_head;             rule_no != NIL; rule_no = next_rule[rule_no])        {            p = Allocate_node();            p -> value = rule_no;            p -> next = state -> rule_root;            state -> rule_root = p;        }    }    /******************************************************************/    /* If the state is new or had its reduce map merged with another  */    /* map, we update the reduce map here.                            */    /******************************************************************/    state -> action_count = sp_action_count;    state -> action_root = NULL;    for ALL_TERMINALS(i)    {        struct action_element *actionp;        if (sp_action[symbol][i] != OMEGA)        {            actionp = allocate_action_element();            actionp -> symbol = i;            actionp -> action = sp_action[symbol][i];            actionp -> next = state -> action_root;            state -> action_root = actionp;        }    }    return state -> state_number;}/*****************************************************************************//*                       REMOVE_SINGLE_PRODUCTIONS:                          *//*****************************************************************************//* This program is invoked to remove as many single production actions as    *//* possible for a conflict-free automaton.                                   *//*****************************************************************************/void remove_single_productions(void){    struct goto_header_type go_to;    struct shift_header_type sh;    struct reduce_header_type red;    struct sp_state_element *state;    struct node             *p,                            *rule_tail;    int rule_head,        sp_rule_count,        sp_action_count,        rule_no,        state_no,        symbol,        lhs_symbol,        action,        item_no,        i,        j;    BOOLEAN end_node;    short *symbol_list,          *shift_transition,          *rule_count;    short shift_table[SHIFT_TABLE_SIZE];    struct new_shift_element    {        short link,              shift_number;    } *new_shift;    /******************************************************************/    /* Set up a a pool of temporary space.                            */    /******************************************************************/    reset_temporary_space();    /******************************************************************/    /* Allocate all other necessary temporary objects.                */    /******************************************************************/    sp_rules = Allocate_short_array(num_symbols + 1);    stack = Allocate_short_array(num_symbols + 1);    index_of = Allocate_short_array(num_symbols + 1);    next_rule = Allocate_short_array(num_rules + 1);    rule_list = Allocate_short_array(num_rules + 1);    symbol_list = Allocate_short_array(num_symbols + 1);    shift_transition = Allocate_short_array(num_symbols + 1);    rule_count = Allocate_short_array(num_rules + 1);    new_shift = (struct new_shift_element *)                calloc(max_la_state + 1,                       sizeof(struct new_shift_element));    if (new_shift == NULL)        nospace(__FILE__, __LINE__);    look_ahead = (SET_PTR)                 calloc(1, term_set_size * sizeof(BOOLEAN_CELL));    if (look_ahead == NULL)        nospace(__FILE__, __LINE__);    sp_action = (short **)                calloc(num_symbols + 1, sizeof(short *));    if (sp_action == NULL)        nospace(__FILE__, __LINE__);    is_conflict_symbol = (BOOLEAN *)                         calloc(num_symbols + 1, sizeof(BOOLEAN));    if (is_conflict_symbol == NULL)        nospace(__FILE__, __LINE__);    sp_table = (struct sp_state_element **)               calloc(STATE_TABLE_SIZE,                      sizeof(struct sp_state_element *));    if (sp_table == NULL)        nospace(__FILE__, __LINE__);    new_action = (struct action_element **)                 calloc(num_states + 1, sizeof(struct action_element *));    if (new_action == NULL)        nospace(__FILE__, __LINE__);    update_action = (struct update_action_element **)                    calloc(num_states + 1,                           sizeof(struct update_action_element *));    if (update_action == NULL)        nospace(__FILE__, __LINE__);    /******************************************************************/    /* Initialize all relevant sets and maps to the empty set.        */    /******************************************************************/    rule_root = NIL;    symbol_root = NIL;    for ALL_RULES(i)        rule_list[i] = OMEGA;    for ALL_SYMBOLS(i)    {        symbol_list[i] = OMEGA;        sp_rules[i]    = NIL;        sp_action[i]   = NULL;    }    /******************************************************************/    /* Construct a set of all symbols used in the right-hand side of  */    /* single production in symbol_list. The variable symbol_root     */    /* points to the root of the list. Also, construct a mapping from */    /* each symbol into the set of single productions of which it is  */    /* the right-hand side. sp_rules is the base of that map and the  */    /* relevant sets are stored in the vector next_rule.              */    /******************************************************************/    for ALL_RULES(rule_no)    {        if (rules[rule_no].sp)        {            i = rhs_sym[rules[rule_no].rhs];            next_rule[rule_no] = sp_rules[i];            sp_rules[i] = rule_no;            if (symbol_list[i] == OMEGA)            {                symbol_list[i] = symbol_root;                symbol_root = i;            }        }    }    /******************************************************************/    /* Initialize the index_of vector and clear the stack (top).      */    /* Next, iterate over the list of right-hand side symbols used in */    /* single productions and invoke compute_sp_map to partially      */    /* order these symbols (based on the ::= (or ->) relationship) as */    /* well as their associated rules. (See compute_sp_map for detail)*/    /* As the list of rules is constructed as a circular list to keep */    /* it in proper order, it is turned into a linear list here.      */    /******************************************************************/    for (i = symbol_root; i != NIL; i = symbol_list[i])        index_of[i] = OMEGA;    top = 0;    for (i = symbol_root; i != NIL; i = symbol_list[i])    {        if (index_of[i] == OMEGA)            compute_sp_map(i);    }    if (rule_root != NIL) /* make rule_list non-circular */    {        rule_no = rule_root;        rule_root = rule_list[rule_no];        rule_list[rule_no] = NIL;    }    /******************************************************************/    /* Clear out all the sets in sp_rules and using the new revised   */    /* list of SP rules mark the new set of right-hand side symbols.  */    /* Note this code is important for consistency in case we are     */    /* removing single productions in an automaton containing         */    /* conflicts. If an automaton does not contain any conflict, the  */    /* new set of SP rules is always the same as the initial set.     */    /******************************************************************/    for (i = symbol_root; i != NIL; i = symbol_list[i])        sp_rules[i] = NIL;    top = 0;    for (rule_no = rule_root;         rule_no != NIL; rule_no = rule_list[rule_no])    {        top++;        i = rhs_sym[rules[rule_no].rhs];        sp_rules[i] = OMEGA;    }    /******************************************************************/    /* Initialize the base of the hash table for the new SP states.   */    /* Initialize the root pointer for the list of new states.        */    /* Initialize max_sp_state to num_states. It will be incremented  */    /* each time a new state is constructed.                          */    /* Initialize the update_action table.                            */    /* Initialize the is_conflict_symbol array for non_terminals.     */    /* Since nonterminals are not used as lookahead symbols, they are */    /* never involved in conflicts.                                   */    /* Initialize the set/list (symbol_root, symbol_list) to the      */    /* empty set/list.                                                */    /******************************************************************/    for (i = 0; i < STATE_TABLE_SIZE; i++)        sp_table[i] = NULL;    sp_state_root = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -