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

📄 remsp.c

📁 一个非常好的检索工具
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $Id: remsp.c,v 1.2 1999/11/04 14:02:23 shields Exp $ *//* This software is subject to the terms of the IBM Jikes Compiler License Agreement available at the following URL: http://www.ibm.com/research/jikes. Copyright (C) 1983, 1999, International Business Machines Corporation and others.  All Rights Reserved. You must accept the terms of that agreement to use this software.*/static char hostfile[] = __FILE__;#include "common.h"#include "reduce.h"#include "header.h"#define IS_SP_RHS(symbol)   (sp_rules[symbol] != NIL)#define IS_SP_RULE(rule_no) (rule_list[rule_no] != OMEGA)static int max_sp_state;static struct action_element{    struct action_element *next;    short symbol,          action;} **new_action;static struct action_element *action_element_pool = NULL;static struct update_action_element{    struct update_action_element *next;    short symbol,          action,          state;} **update_action;static struct sp_state_element{    struct sp_state_element *next,                            *link;    struct action_element   *action_root;    struct node             *rule_root,                            *complete_items;    short                    state_number,                             rule_count,                             action_count;} **sp_table;static struct sp_state_element *sp_state_root;static short *sp_rules,             *stack,             *index_of,             *next_rule,             *rule_list,             **sp_action;static BOOLEAN *is_conflict_symbol;static SET_PTR look_ahead;static int top,           symbol_root,           rule_root;/**********************************************************************//*                        ALLOCATE_ACTION_ELEMENT:                    *//**********************************************************************//* This function first tries to recycle an action_element node from a *//* free list. If the list is empty a new node is allocated from       *//* temporary storage.                                                 *//**********************************************************************/static struct action_element* allocate_action_element(void){    struct action_element *p;    p = action_element_pool;    if (p != NULL)        action_element_pool = p -> next;    else    {        p = (struct action_element *)            talloc(sizeof(struct action_element));        if (p == (struct action_element *) NULL)            nospace(__FILE__, __LINE__);    }    return p;}/**********************************************************************//*                          FREE_ACTION_ELEMENTS:                     *//**********************************************************************//* This routine returns a list of action_element structures to the    *//* free list.                                                         *//**********************************************************************/static void free_action_elements(struct action_element *head,                                 struct action_element *tail){    tail -> next = action_element_pool;    action_element_pool = head;    return;}/**********************************************************************//*                             COMPUTE_SP_MAP:                        *//**********************************************************************//* Compute_sp_map is an instantiation of the digraph algorithm. It    *//* is invoked repeatedly by remove_single_productions to:             *//*                                                                    *//*   1) Partially order the right-hand side of all the single         *//*      productions (SP) into a list [A1, A2, A3, ..., An]            *//*      such that if Ai -> Aj then i < j.                             *//*                                                                    *//*   2) As a side effect, it uses the ordering above to order all     *//*      the SP rules.                                                 *//*                                                                    *//**********************************************************************/static void compute_sp_map(int symbol){    int indx;    int i,        lhs_symbol,        rule_no;    stack[++top] = symbol;    indx = top;    index_of[symbol] = indx;/**********************************************************************//* In this instantiation of the digraph algorithm, two symbols (A, B) *//* are related if  A -> B  is a SP and A is the right-hand side of    *//* some other SP rule.                                                *//**********************************************************************/    for (rule_no = sp_rules[symbol];         rule_no != NIL; rule_no = next_rule[rule_no])    {        lhs_symbol = rules[rule_no].lhs;        if (IS_SP_RHS(lhs_symbol))        {            if (index_of[lhs_symbol] == OMEGA)                compute_sp_map(lhs_symbol);            index_of[symbol] = MIN(index_of[symbol],                                   index_of[lhs_symbol]);        }    }/**********************************************************************//* If the index of symbol is the same index it started with then      *//* symbol if the root of a SCC...                                     *//**********************************************************************/    if (index_of[symbol] == indx)    {        /**************************************************************/        /* If symbol is on top of the stack then it is the only       */        /* symbol in its SCC (thus it is not part of a cycle).        */        /* Note that since remove_single_productions is only invoked  */        /* when the input grammar is conflict-free, the graph of      */        /* the single productions will never contain any cycle.       */        /* Thus, this test will always succeed and all single         */        /* productions associated with the symbol being processed     */        /* are added to the list of SP rules here...                  */        /**************************************************************/        if (stack[top] == symbol)        {            for (rule_no = sp_rules[symbol];                 rule_no != NIL; rule_no = next_rule[rule_no])            {                if (rule_root == NIL)                    rule_list[rule_no] = rule_no;                else                {                    rule_list[rule_no] = rule_list[rule_root];                    rule_list[rule_root] = rule_no;                }                rule_root = rule_no;            }        }        /**************************************************************/        /* As all SCC contains exactly one symbol (as explained above)*/        /* this loop will always execute exactly once.                */        /**************************************************************/        do        {            i = stack[top--];            index_of[i] = INFINITY;        } while(i != symbol);    }    return;}/**********************************************************************//*                         COMPUTE_SP_ACTION:                         *//**********************************************************************//* When the parser enters STATE_NO and it is processing SYMBOL, its   *//* next move is ACTION. Given these 3 parameters, compute_sp_action   *//* computes the set of reduce actions that may be executed after      *//* SYMBOL is shifted in STATE_NO.                                     *//*                                                                    *//* NOTE that this algorithm works only for the LALR(1) case. When the *//* transition on SYMBOL is a lookahead-shift, indicating that the     *//* parser requires extra lookahead on a particular symbol, the set of *//* reduce actions for that symbol is calculated as the empty set.     *//**********************************************************************/static void compute_sp_action(short state_no, short symbol, short action){    struct goto_header_type go_to;    struct node *item_ptr;    int item_no,        rule_no,        lhs_symbol,        i,        k;    BOOLEAN end_node;    struct node *p;    go_to = statset[state_no].go_to;    if (sp_action[symbol] == NULL)        sp_action[symbol] = Allocate_short_array(num_terminals + 1);    for ALL_TERMINALS(i) /* initialize sp_action to the empty map */        sp_action[symbol][i] = OMEGA;/**********************************************************************//* Note that before this routine is invoked, the global vector        *//* index_of identifies the index of each symbol in the goto map of    *//* state_no.                                                          *//**********************************************************************/    if (is_conflict_symbol[symbol])             /* do nothing */        ;    else if (action > 0) /* transition action (shift or goto) */    {        for (item_ptr = statset[action].complete_items;             item_ptr != NULL; item_ptr = item_ptr -> next)        {            item_no = item_ptr -> value;            rule_no = item_table[item_no].rule_number;            lhs_symbol = rules[rule_no].lhs;            if (RHS_SIZE(rule_no) == 1 && lhs_symbol != accept_image)            {                if (slr_bit)                {                    ASSIGN_SET(look_ahead, 0, follow, lhs_symbol);                }                else                {                    i = index_of[lhs_symbol];                    k = GOTO_LAPTR(go_to, i);                    if (la_index[k] == OMEGA)                    {                        int stack_top = 0;                        la_traverse(state_no, i, &stack_top);                    }                    ASSIGN_SET(look_ahead, 0, la_set, k);                }                RESET_BIT(look_ahead, empty); /* empty not valid look-ahead */                for ALL_TERMINALS(i)                {                    if (IS_ELEMENT(look_ahead, i))                        sp_action[symbol][i] = rule_no;                }            }        }        /**************************************************************/        /* Remove all lookahead symbols on which conflicts were       */        /* detected from consideration.                               */        /**************************************************************/        for (end_node = ((p = conflict_symbols[action]) == NULL);             ! end_node; end_node = (p == conflict_symbols[action]))        {            p = p -> next;            sp_action[symbol][p -> value] = OMEGA;        }    }    else /* read-reduce action */    {        rule_no = -action;        if (RHS_SIZE(rule_no) == 1)        {            lhs_symbol = rules[rule_no].lhs;            if (slr_bit)            {                ASSIGN_SET(look_ahead, 0, follow, lhs_symbol);            }            else            {                i = index_of[lhs_symbol];                k = GOTO_LAPTR(go_to, i);                if (la_index[k] == OMEGA)                {                    int stack_top = 0;                    la_traverse(state_no, i, &stack_top);                }                ASSIGN_SET(look_ahead, 0, la_set, k);            }            RESET_BIT(look_ahead, empty); /* empty not valid look-ahead */            for ALL_TERMINALS(i)            {                if (IS_ELEMENT(look_ahead, i))                    sp_action[symbol][i] = rule_no;            }

⌨️ 快捷键说明

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