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

📄 resolve.c

📁 一个非常好的检索工具
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $Id: resolve.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"/***********************************************************************//* VISITED is a structure used to mark state-symbol pairs that have    *//* been visited in the process of computing follow-sources for a       *//* given action in conflict.                                           *//* The field MAP is an array indexable by the states 1..NUM_STATES;    *//* each element of which points to a set (list) of symbols. Thus, for  *//* a given state S, and for all symbol X in the list MAP[S], [S,X]     *//* has been visited. For efficiency, the fields LIST and ROOT are used *//* to store the set (list) of indexed elements of MAP that are not     *//* NULL.                                                               *//* See routines MARK_VISITED, WAS_VISITED, CLEAR_VISITED,              *//*              INIT_LALRK_PROCESS, EXIT_PROCESS                       *//***********************************************************************/static struct visited_element{    struct node **map;    short        *list,                  root;} visited;/***********************************************************************//* Given a set of actions that are in conflict on a given symbol, the  *//* structure SOURCES_ELEMENT is used to store a mapping from each      *//* such action into a set of configurations that can be reached        *//* following execution of the action in question up to the point where *//* the automaton is about to shift the conflict symbol.                *//* The field CONFIGS is an array indexable by actions which are        *//* encoded as follows:                                                 *//*    1. shift-reduce  [-NUM_RULES..-1]                                *//*    2. reduce        [0..NUM_RULES]                                  *//*    3. shift         [NUM_RULES+1..NUM_STATES+1].                    *//* Each element of CONFIGS points to a set (sorted list) of            *//* configurations.  For efficiency, the fields LIST and ROOT are used  *//* to store the set (list) of indexed elements of CONFIGS that are not *//* NULL.                                                               *//* See routines ALLOCATE_SOURCES, FREE_SOURCES, CLEAR_SOURCES,         *//*              ADD_CONFIGS, UNION_CONFIG_SETS.                        *//* See STATE_TO_RESOLVE_CONFLICTS for an explanation of STACK_SEEN.    *//*                                                                     *//* A configuration is a stack of states that represents a certain path *//* in the automaton. The stack is implemented as a list of             *//* STACK_ELEMENT nodes linked through the field PREVIOUS.              *//* A set/list of configurations is linked through the field NEXT.      *//* When attempting to resolve conflicts we try to make sure that the   *//* set of configurations associated with each action is unique. This   *//* is achieved by throwing these configurations into a set and making  *//* sure that there are no duplicates. The field LINK is used for that  *//* purpose (see routine STACK_WAS_SEEN). The field STATE_NUMBER is     *//* obviously used to store the number of a state in the automaton. The *//* field SIZE holds index of the node within the stack. Thus, for the  *//* first element of the stack this field represents the number of      *//* elements in the stack; for the last element, this field holds the   *//* value 1.                                                            *//* See routines ALLOCATE_STACK_ELEMENT, FREE_STACK_ELEMENT,            *//*              ADD_DANGLING_STACK, FREE_DANGLING_STACK.               *//***********************************************************************/static struct sources_element{    struct stack_element **configs,                         **stack_seen;    short                 *list,                           root;} sources;struct stack_element{    struct stack_element *previous,                         *next,                         *link;    short                 state_number,                          size;};static struct stack_element *stack_pool = NULL,                            *dangling_stacks = NULL;/***********************************************************************//* The structure STATE_ELEMENT is used to construct lookahead states.  *//* LA_STATE_ROOT point to a list of lookahead states using the LINK    *//* field. The field NEXT_SHIFT is used to hash the new shift maps      *//* associated with lookahead states. The field IN_STATE identifies the *//* state that shifted into the lookahead state in question. The field  *//* SYMBOL identifies the symbol on shift the transition was made into  *//* the lookahead state in question.  The remaining fields are          *//* self-explanatory.                                                   *//***********************************************************************/struct state_element{    struct state_element      *link,                              *next_shift;    struct reduce_header_type  reduce;    struct shift_header_type   shift;    short                      in_state,                               symbol,                               state_number,                               shift_number;};static struct state_element *la_state_root = NULL;/***********************************************************************//* The structures SR_CONFLICT_ELEMENT and RR_CONFLICT_ELEMENT are used *//* th store conflict information. CONFLICT_ELEMENT_POOL is used to     *//* keep track of a pool conflict element structures (SR or RR) that    *//* are available for allocation.                                       *//* See routines ALLOCATE_CONFLICT_ELEMENT and FREE_CONFLICT_ELEMENTS.  *//***********************************************************************/struct sr_conflict_element{    struct sr_conflict_element *next;    short                       state_number,                                item,                                symbol;};static struct sr_conflict_element *sr_conflict_root;struct rr_conflict_element{    struct rr_conflict_element *next;    short                       symbol,                                item1,                                item2;};static struct rr_conflict_element *rr_conflict_root;static void *conflict_element_pool = NULL;/***********************************************************************//* NT_ITEMS and ITEM_LIST are used to construct a mapping from each    *//* nonterminal into the set of items of which the nonterminal in       *//* question is the dot symbol. See CONFLICTS_INITIALIZATION.           *//***********************************************************************/static short *nt_items  = NULL,             *item_list = NULL;/***********************************************************************//* LALR_VISITED is used to keep track of (state, nonterminal) pairs    *//* that are visited in tracing the path of a lalr conflict.SLR_VISITED *//* is similarly used to keep track of nonterminal symbols that are     *//* visited in tracing the path of an slr conflict. SYMBOL_SEEN is used *//* to keep track of nonterminal symbols that are visited in tracing a  *//* path to the start state (root).                                     *//*                                                                     *//* CYCLIC is a boolean vector used to identify states that can enter   *//* a cycle of transitions on nullable nonterminals.                    *//* As the computation of CYCLIC requires a modified version of the     *//* digraph algorithm, the variables STACK, INDEX_OF and TOP are used   *//* for that algorithm.                                                 *//*                                                                     *//* RMPSELF is a boolean vector that indicates whether or not a given   *//* non-terminal can right-most produce itself. It is only constructed  *//* when LALR_LEVEL > 1.                                                *//***********************************************************************/static BOOLEAN *lalr_visited,               *slr_visited,               *symbol_seen,               *cyclic,               *rmpself;static short *stack,             *index_of,              top;static struct state_element **shift_table;/*******************************************************************//*                     ALLOCATE_CONFLICT_ELEMENT:                  *//*******************************************************************//* This function allocates a conflict_element (sr or rr) structure *//* & returns a pointer to it. If there are nodes in the free pool, *//* one of them is returned. Otherwise, a new node is allocated     *//* from the temporary storage pool.                                *//*******************************************************************/static void *allocate_conflict_element(void){    void *p;    p = conflict_element_pool;    if (p != NULL)        conflict_element_pool = ((struct sr_conflict_element *) p) -> next;    else    {        p = (void *) talloc(MAX(sizeof(struct sr_conflict_element),                            sizeof(struct rr_conflict_element)));        if (p == NULL)            nospace(__FILE__, __LINE__);    }    return p;}/**********************************************************************//*                         FREE_CONFLICT_ELEMENTS:                    *//**********************************************************************//* This routine returns a list of conflict_element (sr/rr)structures  *//* to the free pool.                                                  *//**********************************************************************/static void free_conflict_elements(void *head, void *tail){    ((struct sr_conflict_element *) tail) -> next =             (struct sr_conflict_element *) conflict_element_pool;    conflict_element_pool = head;    return;}/*******************************************************************//*                      ALLOCATE_STACK_ELEMENT:                    *//*******************************************************************//* This function allocates a stack_element structure and returns a *//* pointer to it. If there are nodes in the free pool, one of them *//* is returned. Otherwise, a new node is allocated from the        *//* temporary storage pool.                                         *//*******************************************************************/static struct stack_element *allocate_stack_element(void){    struct stack_element *p;    p = stack_pool;    if (p != NULL)        stack_pool = p -> next;    else    {        p = (struct stack_element *)            talloc(sizeof(struct stack_element));        if (p == NULL)            nospace(__FILE__, __LINE__);    }    return p;}/**********************************************************************//*                           FREE_STACK_ELEMENTS:                     *//**********************************************************************//* This routine returns a list of stack_element structures to the     *//* free pool.                                                         *//**********************************************************************/static void free_stack_elements(struct stack_element *head,                                struct stack_element *tail){    tail -> next = stack_pool;    stack_pool = head;    return;}/***************************************************************************//*                        ADD_DANGLING_STACK_ELEMENT:                      *//***************************************************************************//* When an allocated stack_element structure is not directly associated    *//* with an action, it is added to a circular list of dangling stack_element*//* nodes so that its space can be reclaimed.                               *//***************************************************************************/static void add_dangling_stack_element(struct stack_element *s){    if (dangling_stacks == NULL)        s -> next = s;    else    {        s -> next = dangling_stacks -> next;        dangling_stacks -> next = s;    }    dangling_stacks = s;    return;}/***************************************************************************//*                       FREE_DANGLING_STACK_ELEMENTS:                     *//***************************************************************************//* This function is invoked to free up all dangling stack_element nodes    *//* and reset the dangling stack list.                                      *//* Recall that the dangling stack list is circular.                        *//***************************************************************************/static void free_dangling_stack_elements(void){    struct stack_element *tail;    if (dangling_stacks != NULL)    {        tail = dangling_stacks;        free_stack_elements(dangling_stacks -> next, tail);        dangling_stacks = NULL;    }    return;}/***************************************************************************//*                              ALLOCATE_SOURCES:                          *//***************************************************************************//* This function allocates and initializes a SOURCE_ELEMENT map.           *//* See definition of SOURCE_ELEMENT above.                                 *//***************************************************************************/static struct sources_element allocate_sources(void){    struct sources_element sources;    sources.configs = (struct stack_element **)                      calloc(num_rules + num_rules + num_states + 1,                             sizeof(struct stack_element *));    if (sources.configs == NULL)        nospace(__FILE__, __LINE__);    sources.configs += num_rules;    sources.stack_seen = (struct stack_element **)

⌨️ 快捷键说明

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