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

📄 remsp.c

📁 一个非常好的检索工具
💻 C
📖 第 1 页 / 共 5 页
字号:
            if (SHIFT_ACTION(sh, i) > num_states)                SHIFT_ACTION(sh, i) += (max_sp_state - num_states);        }    }    for (state_no = num_states + 1; state_no <= max_la_state; state_no++)    {        if (lastats[state_no].in_state > num_states)            lastats[state_no].in_state += (max_sp_state - num_states);    }    lastats -= (max_sp_state - num_states);    max_la_state += (max_sp_state - num_states);    SHORT_CHECK(max_la_state);    /******************************************************************/    /* We now permanently construct all the new SP states.            */    /******************************************************************/    for (state = sp_state_root; state != NULL; state = state -> next)    {        struct action_element *actionp;        int default_rule,            reduce_size;        state_no = state -> state_number;        /**************************************************************/        /* These states are identified as special SP states since     */        /* they have no kernel items. They also have no goto and      */        /* shift actions.                                             */        /**************************************************************/        statset[state_no].kernel_items = NULL;        statset[state_no].complete_items = state -> complete_items;        statset[state_no].go_to.size = 0;        statset[state_no].go_to.map = NULL;        statset[state_no].shift_number = 0;        /**************************************************************/        /* Count the number of actions defined on each rule in the    */        /* range of the reduce map.                                   */        /**************************************************************/        for (p = state -> rule_root; p != NULL; p = p -> next)            rule_count[p -> value] = 0;        for (actionp = state -> action_root;             actionp != NULL; actionp = actionp -> next)            rule_count[actionp -> action]++;        /**************************************************************/        /* Count the total number of reduce actions in the reduce map */        /* and calculate the default.                                 */        /**************************************************************/        reduce_size = 0;        sp_rule_count = 0;        for (p = state -> rule_root; p != NULL; rule_tail = p, p = p -> next)        {            reduce_size += rule_count[p -> value];            if (rule_count[p -> value] > sp_rule_count)            {                sp_rule_count = rule_count[p -> value];                default_rule = p -> value;            }        }        free_nodes(state -> rule_root, rule_tail);        /**************************************************************/        /* Construct a permanent reduce map for this SP state.        */        /**************************************************************/        num_reductions += reduce_size;        red = Allocate_reduce_map(reduce_size);        reduce[state_no] = red;        REDUCE_SYMBOL(red, 0)  = DEFAULT_SYMBOL;        REDUCE_RULE_NO(red, 0) = default_rule;        for (actionp = state -> action_root;             actionp != NULL; actionp = actionp -> next)        {            REDUCE_SYMBOL(red, reduce_size)  = actionp -> symbol;            REDUCE_RULE_NO(red, reduce_size) = actionp -> action;            reduce_size--;        }    }    /******************************************************************/    /* We are now ready to update some old actions and add new ones.  */    /* This may require that we create new shift maps.  We            */    /* initialize top to 0 so we can use it as an index to allocate   */    /* elements from new_shift. We also initialize all the elements   */    /* of shift_table to NIL. Shift_table will be used as the base of */    /* a hash table for the new shift maps.                           */    /******************************************************************/    top = 0;    for (i = 0; i <= SHIFT_TABLE_UBOUND; i++)        shift_table[i] = NIL;    /******************************************************************/    /* At most, the shift array contains 1..num_states elements. As,  */    /* each of these elements might be (theoretically) replaced by a  */    /* new one, we need to double its size.                           */    /******************************************************************/    shift = (struct shift_header_type *)            realloc(shift,               2 * (num_states + 1) * sizeof(struct shift_header_type));    if (shift == NULL)        nospace(__FILE__, __LINE__);    /******************************************************************/    /* For each state with updates or new actions, take appropriate   */    /* actions.                                                       */    /******************************************************************/    for ALL_STATES(state_no)    {        BOOLEAN any_shift_action;        /**************************************************************/        /* Update reduce actions for final items of single productions*/        /* that are in non-final states.                              */        /**************************************************************/        if (update_action[state_no] != NULL)        {            struct update_action_element *p;            red = reduce[state_no];            for (i = 1; i <= red.size; i++)                index_of[REDUCE_SYMBOL(red, i)] = i;            for (p = update_action[state_no]; p != NULL; p = p -> next)                REDUCE_RULE_NO(red, index_of[p -> symbol]) = p -> action;        }        /**************************************************************/        /* Update initial automaton with transitions into new SP      */        /* states.                                                    */        /**************************************************************/        if (new_action[state_no] != NULL)        {            struct action_element *p;            /**********************************************************/            /* Mark the index of each symbol on which there is a      */            /* transition and copy the shift map into the vector      */            /* shift_transition.                                      */            /**********************************************************/            go_to = statset[state_no].go_to;            for (i = 1; i <= go_to.size; i++)                index_of[GOTO_SYMBOL(go_to, i)] = i;            sh = shift[statset[state_no].shift_number];            for (i = 1; i <= sh.size; i++)            {                index_of[SHIFT_SYMBOL(sh, i)] = i;                shift_transition[SHIFT_SYMBOL(sh, i)] = SHIFT_ACTION(sh, i);            }            /**********************************************************/            /* Iterate over the new action and update the goto map    */            /* directly for goto actions but update shift_transition  */            /* for shift actions. Also, keep track as to whether or   */            /* not there were any shift transitions at all...         */            /**********************************************************/            any_shift_action = FALSE;            for (p = new_action[state_no]; p != NULL; p = p -> next)            {                if (p -> symbol IS_A_NON_TERMINAL)                {                    if (GOTO_ACTION(go_to, index_of[p -> symbol]) < 0 &&                        p -> action > 0)                    {                        num_goto_reduces--;                        num_gotos++;                    }                    GOTO_ACTION(go_to, index_of[p -> symbol]) = p -> action;                }                else                {                    if (SHIFT_ACTION(sh, index_of[p -> symbol]) < 0 &&                        p -> action > 0)                    {                        num_shift_reduces--;                        num_shifts++;                    }                    shift_transition[p -> symbol] = p -> action;                    any_shift_action = TRUE;                }            }            /**********************************************************/            /* If there were any shift actions, a new shift map may   */            /* have been created. Hash shift_transition into the      */            /* shift hash table.                                      */            /**********************************************************/            if (any_shift_action)            {                struct shift_header_type sh2;                unsigned long hash_address;                hash_address = sh.size;                for (i = 1; i <= sh.size; i++) /* Compute Hash location */                    hash_address += SHIFT_SYMBOL(sh, i);                hash_address %= SHIFT_TABLE_SIZE;            /**************************************************************/            /* Search HASH_ADDRESS location for shift map that matches    */            /* the shift map in shift_transition.  If a match is found    */            /* we leave the loop prematurely, the search index j is not   */            /* NIL, and it identifies the shift map in the hash table     */            /* that matched the shift_transition.                         */            /**************************************************************/                for (j = shift_table[hash_address];                     j != NIL; j = new_shift[j].link)                {                    sh2 = shift[new_shift[j].shift_number];                    if (sh.size == sh2.size)                    {                        for (i = 1; i <= sh.size; i++)                            if (SHIFT_ACTION(sh2, i) !=                                shift_transition[SHIFT_SYMBOL(sh2, i)])                                    break;                        if (i > sh.size)                            break; /* for (j = shift_table[ ... */                    }                }            /**************************************************************/            /* If j == NIL, the map at hand had not yet being inserted in */            /* the table, it is inserted.  Otherwise, we have a match,    */            /* and STATE_NO is reset to share the shift map previously    */            /* inserted that matches its shift map.                       */            /**************************************************************/                if (j == NIL)                {                    sh2 = Allocate_shift_map(sh.size);                    for (i = 1; i <= sh.size; i++)                    {                        symbol = SHIFT_SYMBOL(sh, i);                        SHIFT_SYMBOL(sh2, i) = symbol;                        SHIFT_ACTION(sh2, i) = shift_transition[symbol];                    }                    num_shift_maps++;                    shift[num_shift_maps] = sh2;                    statset[state_no].shift_number = num_shift_maps;                    top++;                    new_shift[top].shift_number = num_shift_maps;                    new_shift[top].link = shift_table[hash_address];                    shift_table[hash_address] = top;                }                else                {                    statset[state_no].shift_number =                           new_shift[j].shift_number;                }            }        }    }    /******************************************************************/    /* Free all nodes used in the construction of the conflict_symbols*/    /* map as this map is no longer useful and its size is based on   */    /* the base value of num_states.                                  */    /******************************************************************/    for ALL_STATES(state_no)    {        if (conflict_symbols[state_no] != NULL)        {            p = conflict_symbols[state_no] -> next;            free_nodes(p, conflict_symbols[state_no]);        }    }    /******************************************************************/    /* All updates have now been made, adjust the number of regular   */    /* states to include the new SP states.                           */    /******************************************************************/    num_states = max_sp_state;    /******************************************************************/    /* Free all temporary space allocated earlier.                    */    /******************************************************************/    ffree(sp_rules);    ffree(stack);    ffree(index_of);    ffree(next_rule);    ffree(rule_list);    ffree(symbol_list);    ffree(shift_transition);    ffree(rule_count);    ffree(new_shift);    ffree(look_ahead);    for ALL_SYMBOLS(i)    {        if (sp_action[i] != NULL)        {            ffree(sp_action[i]);        }    }    ffree(sp_action);    ffree(is_conflict_symbol);    ffree(sp_table);    ffree(new_action);    ffree(update_action);    return;}

⌨️ 快捷键说明

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