(root)/
bison-3.8.2/
src/
symlist.c
       1  /* Lists of symbols for Bison
       2  
       3     Copyright (C) 2002, 2005-2007, 2009-2015, 2018-2021 Free Software
       4     Foundation, Inc.
       5  
       6     This file is part of Bison, the GNU Compiler Compiler.
       7  
       8     This program is free software: you can redistribute it and/or modify
       9     it under the terms of the GNU General Public License as published by
      10     the Free Software Foundation, either version 3 of the License, or
      11     (at your option) any later version.
      12  
      13     This program is distributed in the hope that it will be useful,
      14     but WITHOUT ANY WARRANTY; without even the implied warranty of
      15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16     GNU General Public License for more details.
      17  
      18     You should have received a copy of the GNU General Public License
      19     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      20  
      21  #include <config.h>
      22  #include "system.h"
      23  
      24  #include "symlist.h"
      25  
      26  /*--------------------------------------.
      27  | Create a list containing SYM at LOC.  |
      28  `--------------------------------------*/
      29  
      30  symbol_list *
      31  symbol_list_sym_new (symbol *sym, location loc)
      32  {
      33    symbol_list *res = xmalloc (sizeof *res);
      34  
      35    res->content_type = SYMLIST_SYMBOL;
      36    res->content.sym = sym;
      37    res->sym_loc = loc;
      38    res->named_ref = NULL;
      39  
      40    res->midrule = NULL;
      41    res->midrule_parent_rule = NULL;
      42    res->midrule_parent_rhs_index = 0;
      43  
      44    /* Members used for LHS only.  */
      45    res->rhs_loc = empty_loc;
      46    res->ruleprec = NULL;
      47    res->percent_empty_loc = empty_loc;
      48    code_props_none_init (&res->action_props);
      49    res->dprec = 0;
      50    res->dprec_loc = empty_loc;
      51    res->merger = 0;
      52    res->merger_declaration_loc = empty_loc;
      53    res->expected_sr_conflicts = -1;
      54    res->expected_rr_conflicts = -1;
      55  
      56    res->next = NULL;
      57  
      58    return res;
      59  }
      60  
      61  
      62  /*--------------------------------------------.
      63  | Create a list containing TYPE_NAME at LOC.  |
      64  `--------------------------------------------*/
      65  
      66  symbol_list *
      67  symbol_list_type_new (uniqstr type_name, location loc)
      68  {
      69    symbol_list *res = xmalloc (sizeof *res);
      70  
      71    res->content_type = SYMLIST_TYPE;
      72    res->content.sem_type = xmalloc (sizeof (semantic_type));
      73    res->content.sem_type->tag = type_name;
      74    res->content.sem_type->location = loc;
      75    res->content.sem_type->status = undeclared;
      76  
      77    res->sym_loc = loc;
      78    res->named_ref = NULL;
      79    res->next = NULL;
      80  
      81    return res;
      82  }
      83  
      84  
      85  symbol_list *
      86  symbol_list_type_set (symbol_list *syms, uniqstr type_name)
      87  {
      88    for (symbol_list *l = syms; l; l = l->next)
      89      symbol_type_set (l->content.sym, type_name, l->sym_loc);
      90    return syms;
      91  }
      92  
      93  
      94  symbol_list *
      95  symbol_list_find_symbol (symbol_list *l, const symbol *sym)
      96  {
      97    for (/* Nothing. */; l && l->content.sym; l = l->next)
      98      if (l->content.sym == sym)
      99        return l;
     100    return NULL;
     101  }
     102  
     103  
     104  /*-----------------------------------------------------------------------.
     105  | Print this list, for which every content_type must be SYMLIST_SYMBOL.  |
     106  `-----------------------------------------------------------------------*/
     107  
     108  void
     109  symbol_list_syms_print (const symbol_list *l, FILE *out)
     110  {
     111    fputc ('[', out);
     112    char const *sep = "";
     113    for (/* Nothing. */; l && l->content.sym; l = l->next)
     114      {
     115        fputs (sep, out);
     116        fputs (l->content_type == SYMLIST_SYMBOL ? "symbol{"
     117               : l->content_type == SYMLIST_TYPE ? "type{"
     118               : "invalid content_type{",
     119               out);
     120        if (l->content_type == SYMLIST_SYMBOL)
     121          symbol_print (l->content.sym, out);
     122        fputs (l->action_props.is_value_used ? " (used)" : " (unused)", out);
     123        putc ('}', out);
     124        sep = ", ";
     125      }
     126    fputc (']', out);
     127  }
     128  
     129  
     130  /*---------------------------.
     131  | Prepend NODE to the LIST.  |
     132  `---------------------------*/
     133  
     134  symbol_list *
     135  symbol_list_prepend (symbol_list *list, symbol_list *node)
     136  {
     137    node->next = list;
     138    return node;
     139  }
     140  
     141  
     142  symbol_list *
     143  symbol_list_last (symbol_list *list)
     144  {
     145    if (!list)
     146      return NULL;
     147    symbol_list *next = list;
     148    while (next->next)
     149      next = next->next;
     150    return next;
     151  }
     152  
     153  symbol_list *
     154  symbol_list_append (symbol_list *list, symbol_list *node)
     155  {
     156    if (list)
     157      symbol_list_last (list)->next = node;
     158    else
     159      list = node;
     160    return list;
     161  }
     162  
     163  
     164  
     165  /*-----------------------------------------------.
     166  | Free the LIST, but not the items it contains.  |
     167  `-----------------------------------------------*/
     168  
     169  void
     170  symbol_list_free (symbol_list *list)
     171  {
     172    for (symbol_list *next; list; list = next)
     173      {
     174        next = list->next;
     175        named_ref_free (list->named_ref);
     176        if (list->content_type == SYMLIST_TYPE)
     177          free (list->content.sem_type);
     178        free (list);
     179      }
     180  }
     181  
     182  
     183  /*--------------------.
     184  | Return its length.  |
     185  `--------------------*/
     186  
     187  int
     188  symbol_list_length (symbol_list const *l)
     189  {
     190    int res = 0;
     191    for (/* Nothing. */;
     192         l && !(l->content_type == SYMLIST_SYMBOL && l->content.sym == NULL);
     193         l = l->next)
     194      ++res;
     195    return res;
     196  }
     197  
     198  
     199  /*------------------------------.
     200  | Get item N in symbol list L.  |
     201  `------------------------------*/
     202  
     203  symbol_list *
     204  symbol_list_n_get (symbol_list *l, int n)
     205  {
     206    aver (0 <= n);
     207    for (int i = 0; i < n; ++i)
     208      {
     209        l = l->next;
     210        aver (l);
     211      }
     212    aver (l->content_type == SYMLIST_SYMBOL);
     213    aver (l->content.sym);
     214    return l;
     215  }
     216  
     217  /*--------------------------------------------------------------.
     218  | Get the data type (alternative in the union) of the value for |
     219  | symbol N in symbol list L.                                    |
     220  `--------------------------------------------------------------*/
     221  
     222  uniqstr
     223  symbol_list_n_type_name_get (symbol_list *l, int n)
     224  {
     225    return symbol_list_n_get (l, n)->content.sym->content->type_name;
     226  }
     227  
     228  bool
     229  symbol_list_null (symbol_list *node)
     230  {
     231    return (!node
     232            || (node->content_type == SYMLIST_SYMBOL && !node->content.sym));
     233  }
     234  
     235  void
     236  symbol_list_code_props_set (symbol_list *node, code_props_type kind,
     237                              code_props const *cprops)
     238  {
     239    switch (node->content_type)
     240      {
     241      case SYMLIST_SYMBOL:
     242        symbol_code_props_set (node->content.sym, kind, cprops);
     243        if (node->content.sym->content->status == undeclared)
     244          node->content.sym->content->status = used;
     245        break;
     246      case SYMLIST_TYPE:
     247        semantic_type_code_props_set
     248          (semantic_type_get (node->content.sem_type->tag,
     249                              &node->content.sem_type->location),
     250           kind, cprops);
     251        if (node->content.sem_type->status == undeclared)
     252          node->content.sem_type->status = used;
     253        break;
     254      }
     255  }