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

📄 mkfirst.c

📁 一个非常好的检索工具
💻 C
📖 第 1 页 / 共 5 页
字号:
        nospace(__FILE__, __LINE__);    if (read_reduce_bit)    {        for ALL_RULES(rule_no)        {            int j;            j = RHS_SIZE(rule_no);            if (rules[rule_no].lhs != accept_image && j > 0)            {                struct node *p;                item_no = first_item_of[rule_no] + j;                p = Allocate_node();                p -> value = item_no;                p -> next = NULL;                adequate_item[rule_no] = p;            }            else                adequate_item[rule_no] = NULL;        }    }    /***************************************************************/    /* Construct the CLITEMS map. Each element of CLITEMS points   */    /* to a circular linked list of items.                         */    /***************************************************************/    clitems = (struct node **)              calloc(num_non_terminals, sizeof(struct node *));    if (clitems == NULL)        nospace(__FILE__, __LINE__);    clitems -= (num_terminals + 1);    for ALL_NON_TERMINALS(nt)    {        clitems[nt] = NULL;        for (end_node = ((rule_no = lhs_rule[nt]) == NIL);             ! end_node;             end_node = (rule_no == lhs_rule[nt]))        {            struct node *p;            rule_no = next_rule[rule_no];            p = Allocate_node();            p -> value = first_item_of[rule_no];            if (clitems[nt] == NULL)                p -> next = p;            else            {                p -> next = clitems[nt] -> next;                clitems[nt] -> next = p;            }            clitems[nt] = p;        }    }    /***************************************************************/    /* If LALR_LEVEL > 1, we need to calculate RMPSELF, a set that */    /* identifies the nonterminals that can right-most produce     */    /* themselves. In order to compute RMPSELF, the map PRODUCES   */    /* must be constructed which identifies for each nonterminal   */    /* the set of nonterminals that it can right-most produce.     */    /***************************************************************/    if (lalr_level > 1)    {        produces = (SET_PTR)                   calloc(num_non_terminals,                          non_term_set_size * sizeof(BOOLEAN_CELL));        if (produces == NULL)            nospace(__FILE__, __LINE__);        produces -= ((num_terminals + 1) * non_term_set_size);        direct_produces = (struct node **)                          calloc(num_non_terminals, sizeof(struct node *));        if (direct_produces == NULL)            nospace(__FILE__, __LINE__);        direct_produces -= (num_terminals + 1);        for ALL_NON_TERMINALS(nt)        {            struct node *p,                        *q;            for (end_node = ((p = clitems[nt]) == NULL);                 ! end_node; end_node = (p == clitems[nt]))            {                p = p -> next;                item_no = p -> value;                symbol = item_table[item_no].symbol;                if (symbol IS_A_NON_TERMINAL)                {                    i = item_table[item_no].suffix_index;                    if (IS_IN_SET(first, i, empty) &&                        (! IS_IN_NTSET(produces, nt,                                       symbol - num_terminals)))                    {                        NTSET_BIT_IN(produces, nt,                                     symbol - num_terminals);                        q = Allocate_node();                        q -> value = symbol;                        q -> next = direct_produces[nt];                        direct_produces[nt] = q;                    }                }            }        }        /************************************************************/        /* Complete the construction of the RIGHT_MOST_PRODUCES map */        /* for non-terminals using the digraph algorithm.           */        /************************************************************/        for ALL_NON_TERMINALS(nt)            index_of[nt] = OMEGA;        top = 0;        for ALL_NON_TERMINALS(nt)        {            if (index_of[nt] == OMEGA)                compute_produces(nt);        }        init_rmpself(produces);        produces += ((num_terminals + 1) * non_term_set_size);        ffree(produces);        direct_produces += (num_terminals + 1);        ffree(direct_produces);    }    /***************************************************************/    /* Construct the FOLLOW map if                                 */    /*   1) an SLR table is requested                              */    /*   2) if we have to print the FOLLOW map                     */    /*   3) Error-maps are requested                               */    /*   4) There are more than one starting symbol.               */    /***************************************************************/    if (slr_bit || follow_bit || error_maps_bit ||        next_rule[lhs_rule[accept_image]] != lhs_rule[accept_image])    {        follow = (SET_PTR)                 calloc(num_non_terminals,                        term_set_size * sizeof(BOOLEAN_CELL));        if (follow == NULL)            nospace(__FILE__, __LINE__);        follow -= ((num_terminals + 1) * term_set_size);        SET_BIT_IN(follow, accept_image, eoft_image);        for ALL_NON_TERMINALS(i) /* Initialize INDEX_OF to OMEGA */            index_of[i] = OMEGA;        index_of[accept_image] = INFINITY;  /* mark computed */        top = 0;        for ALL_NON_TERMINALS(nt)        {            if (index_of[nt] == OMEGA) /* not yet computed ? */                compute_follow(nt);        }    /***************************************************************/    /*  Initialize FIRST for suffixes that can follow each starting*/    /* non-terminal ( except the main symbol) with the FOLLOW set */    /* of the non-terminal in question.                            */    /***************************************************************/        rule_no = lhs_rule[accept_image];        if (next_rule[rule_no] != rule_no)        {            rule_no = next_rule[rule_no];   /* first rule */            top = item_table[first_item_of[rule_no]].suffix_index;            for (i = top + 1; i <= num_first_sets; i++)            {                rule_no = next_rule[rule_no];                item_no = first_item_of[rule_no];                symbol = item_table[item_no].symbol;                if (symbol IS_A_NON_TERMINAL)                {                   ASSIGN_SET(first, i, follow, symbol);                }            }        }    }    /***************************************************************/    /* If WARNINGS option is turned on, the unreachable symbols in */    /* the grammar are printed.                                    */    /***************************************************************/    if (warnings_bit)        print_unreachables();    /***************************************************************/    /* If a Cross_Reference listing is requested, it is generated  */    /* here.                                                       */    /***************************************************************/    if (xref_bit)        print_xref();    /***************************************************************/    /* If a listing of the FIRST map is requested, it is generated */    /* here.                                                       */    /***************************************************************/    if (first_bit)        print_nt_first();    /****************************************************************/    /* If a listing of the FOLLOW map is requested, it is generated */    /* here.                                                        */    /***************************************************************/    if (follow_bit)        print_follow_map();    /***************************************************************/    /* Free allocated arrays.                                      */    /***************************************************************/    nt_first += ((num_terminals + 1) * term_set_size);    ffree(nt_first);    nt_list += (num_terminals + 1);    ffree(nt_list);    ffree(first_table);    ffree(first_element);    nt_items += (num_terminals + 1);    ffree(nt_items);    ffree(next_item);    ffree(stack);    index_of += (num_terminals + 1);    ffree(index_of);    lhs_rule += (num_terminals + 1);    ffree(lhs_rule);    ffree(next_rule);    ffree(first_item_of);    return;}/*****************************************************************************//*                           NO_RULES_PRODUCED:                              *//*****************************************************************************/static void no_rules_produced(void){    char line[PRINT_LINE_SIZE + 1],         tok[SYMBOL_SIZE + 1];    int nt_root,        nt_last,        symbol;    /*************************************************************/    /* Build a list of all non-terminals that do not produce any */    /* rules.                                                    */    /*************************************************************/    nt_root = NIL;    for ALL_NON_TERMINALS(symbol)    {        if (lhs_rule[symbol] == NIL)        {            if (nt_root == NIL)                nt_root = symbol;            else                nt_list[nt_last] = symbol;            nt_last = symbol;        }    }    /*************************************************************/    /* If the list of non-terminals that do not produce any rules*/    /* is not empty, signal error and stop.                      */    /*************************************************************/    if (nt_root != NIL)    {        PR_HEADING;        nt_list[nt_last] = NIL;        if (nt_list[nt_root] == NIL)        {            PRNTERR("The following Non-terminal does not produce any rules: ");        }        else        {            PRNTERR("The following Non-terminals do not produce any rules: ");        }        strcpy(line, "        ");        for (symbol = nt_root; symbol != NIL; symbol = nt_list[symbol])        {            restore_symbol(tok, RETRIEVE_STRING(symbol));            if (strlen(line) + strlen(tok) > PRINT_LINE_SIZE)            {                PRNT(line);                print_large_token(line, tok, "    ", LEN);            }            else                strcat(line, tok);            strcat(line,BLANK);        }        PRNT(line);        exit(12);    }}/*****************************************************************************//*                            COMPUTE_CLOSURE:                               *//*****************************************************************************//*  This function computes the closure of a non-terminal LHS_SYMBOL passed   *//* to it as an argument using the digraph algorithm.                         *//*  The closure of a non-terminal A is the set of all non-terminals Bi that  *//* can directly or indirectly start a string generated by A.                 *//* I.e., A *::= Bi X where X is an arbitrary string.                         *//*****************************************************************************/static void compute_closure(int lhs_symbol){    int indx;    short *nont_list;    int symbol,        rule_no,        nt_root,        i;    struct node *p,                *q;    BOOLEAN end_node;    nont_list = Allocate_short_array(num_non_terminals);    nont_list -= (num_terminals + 1); /* Temporary direct        */                                      /* access set for closure. */    stack[++top] = lhs_symbol;    indx = top;    index_of[lhs_symbol] = indx;    for ALL_NON_TERMINALS(i)        nont_list[i] = OMEGA;    nont_list[lhs_symbol] = NIL;    nt_root = lhs_symbol;    closure[lhs_symbol] = NULL; /* Permanent closure set. Linked list */    for (end_node = ((rule_no = lhs_rule[lhs_symbol]) == NIL);         ! end_node;          /* Iterate over all rules of LHS_SYMBOL */         end_node = (rule_no == lhs_rule[lhs_symbol]))    {        rule_no = next_rule[rule_no];        symbol = (RHS_SIZE(rule_no) == 0 ? empty                                         : rhs_sym[rules[rule_no].rhs]);        if (symbol IS_A_NON_TERMINAL)        {            if (nont_list[symbol] == OMEGA)            {                if (index_of[symbol] == OMEGA) /* if first time seen */                    compute_closure(symbol);                index_of[lhs_symbol] = MIN(index_of[lhs_symbol],                                           index_of[symbol]);                nont_list[symbol] = nt_root;                nt_root = symbol;                /* add closure[symbol] to closure of LHS_SYMBOL.  */

⌨️ 快捷键说明

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