/[bison]/bison/src/output.c
ViewVC logotype

Diff of /bison/src/output.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.168 by akim, Thu Jun 27 12:08:20 2002 UTC revision 1.169 by hilfinger, Fri Jun 28 02:26:43 2002 UTC
# Line 115  static int nvectors; Line 115  static int nvectors;
115  static int nentries;  static int nentries;
116  static short **froms = NULL;  static short **froms = NULL;
117  static short **tos = NULL;  static short **tos = NULL;
118    static unsigned int **conflict_tos = NULL;
119  static short *tally = NULL;  static short *tally = NULL;
120  static short *width = NULL;  static short *width = NULL;
121  static short *actrow = NULL;  static short *actrow = NULL;
122    static short *conflrow = NULL;
123  static short *state_count = NULL;  static short *state_count = NULL;
124  static short *order = NULL;  static short *order = NULL;
125  static short *base = NULL;  static short *base = NULL;
126  static short *pos = NULL;  static short *pos = NULL;
127    
128    static unsigned int *conflict_table = NULL;
129    static unsigned int *conflict_list = NULL;
130    static int conflict_list_cnt;
131    static int conflict_list_free;
132    
133  /* TABLE_SIZE is the allocated size of both TABLE and CHECK.  /* TABLE_SIZE is the allocated size of both TABLE and CHECK.
134     We start with the original hard-coded value: SHRT_MAX     We start with the original hard-coded value: SHRT_MAX
135     (yes, not USHRT_MAX). */     (yes, not USHRT_MAX). */
# Line 157  table_grow (size_t desired) Line 164  table_grow (size_t desired)
164    
165    table = XREALLOC (table, short, table_size);    table = XREALLOC (table, short, table_size);
166    check = XREALLOC (check, short, table_size);    check = XREALLOC (check, short, table_size);
167      if (glr_parser)
168        conflict_table = XREALLOC (conflict_table, unsigned int, table_size);
169    
170    for (/* Nothing. */; old_size < table_size; ++old_size)    for (/* Nothing. */; old_size < table_size; ++old_size)
171      {      {
# Line 278  prepare_tokens (void) Line 287  prepare_tokens (void)
287    
288  /*-------------------------------------------------------------.  /*-------------------------------------------------------------.
289  | Prepare the muscles related to the rules: rhs, prhs, r1, r2, |  | Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
290  | rline.                                                       |  | rline, dprec, merger                                         |
291  `-------------------------------------------------------------*/  `-------------------------------------------------------------*/
292    
293  static void  static void
# Line 291  prepare_rules (void) Line 300  prepare_rules (void)
300    unsigned int *rline = XMALLOC (unsigned int, nrules + 1);    unsigned int *rline = XMALLOC (unsigned int, nrules + 1);
301    symbol_number_t *r1 = XMALLOC (symbol_number_t, nrules + 1);    symbol_number_t *r1 = XMALLOC (symbol_number_t, nrules + 1);
302    unsigned int *r2 = XMALLOC (unsigned int, nrules + 1);    unsigned int *r2 = XMALLOC (unsigned int, nrules + 1);
303      short *dprec = XMALLOC (short, nrules + 1);
304      short *merger = XMALLOC (short, nrules + 1);
305    
306    for (r = 1; r < nrules + 1; ++r)    for (r = 1; r < nrules + 1; ++r)
307      {      {
# Line 308  prepare_rules (void) Line 319  prepare_rules (void)
319        rhs[i++] = -1;        rhs[i++] = -1;
320        /* Line where rule was defined. */        /* Line where rule was defined. */
321        rline[r] = rules[r].location.first_line;        rline[r] = rules[r].location.first_line;
322          /* Dynamic precedence (GLR) */
323          dprec[r] = rules[r].dprec;
324          /* Merger-function index (GLR) */
325          merger[r] = rules[r].merger;
326      }      }
327    assert (i == nritems);    assert (i == nritems);
328    
# Line 316  prepare_rules (void) Line 331  prepare_rules (void)
331    muscle_insert_unsigned_int_table ("rline", rline, 0, 1, nrules + 1);    muscle_insert_unsigned_int_table ("rline", rline, 0, 1, nrules + 1);
332    muscle_insert_symbol_number_table ("r1", r1, 0, 1, nrules + 1);    muscle_insert_symbol_number_table ("r1", r1, 0, 1, nrules + 1);
333    muscle_insert_unsigned_int_table ("r2", r2, 0, 1, nrules + 1);    muscle_insert_unsigned_int_table ("r2", r2, 0, 1, nrules + 1);
334      muscle_insert_short_table ("dprec", dprec, 0, 1, nrules + 1);
335      muscle_insert_short_table ("merger", merger, 0, 1, nrules + 1);
336    
337    free (rhs);    free (rhs);
338    free (prhs);    free (prhs);
339    free (rline);    free (rline);
340    free (r1);    free (r1);
341    free (r2);    free (r2);
342      free (dprec);
343      free (merger);
344  }  }
345    
346  /*--------------------------------------------.  /*--------------------------------------------.
# Line 341  prepare_states (void) Line 360  prepare_states (void)
360  }  }
361    
362    
363    /*-------------------------------------------------------------------.
364    | For GLR parsers, for each conflicted token in STATE, as indicated  |
365    | by non-zero entries in conflrow, create a list of possible         |
366    | reductions that are alternatives to the shift or reduction         |
367    | currently recorded for that token in STATE.  Store the alternative |
368    | reductions followed by a 0 in conflict_list, updating              |
369    | conflict_list_cnt, and storing an index to the start of the list   |
370    | back into conflrow.                                                |
371    `-------------------------------------------------------------------*/
372    
373    static void
374    conflict_row (state_t *state)
375    {
376      int i, j;
377    
378      if (! glr_parser)
379        return;
380    
381      for (j = 0; j < ntokens; j += 1)
382        if (conflrow[j])
383          {
384            conflrow[j] = conflict_list_cnt;
385    
386            /* find all reductions for token j, and record all that do
387             * not match actrow[j] */
388            for (i = 0; i < state->nlookaheads; i += 1)
389              if (bitset_test (state->lookaheads[i], j)
390                  && actrow[j] != -state->lookaheads_rule[i]->number)
391                {      
392                  assert (conflict_list_free > 0);
393                  conflict_list[conflict_list_cnt]
394                    = state->lookaheads_rule[i]->number;
395                  conflict_list_cnt += 1;
396                  conflict_list_free -= 1;
397                }
398            
399            /* Leave a 0 at the end */
400            assert (conflict_list_free > 0);
401            conflict_list_cnt += 1;
402            conflict_list_free -= 1;
403          }
404    }
405    
406    
407  /*------------------------------------------------------------------.  /*------------------------------------------------------------------.
408  | Decide what to do for each type of token if seen as the lookahead |  | Decide what to do for each type of token if seen as the lookahead |
409  | token in specified state.  The value returned is used as the      |  | token in specified state.  The value returned is used as the      |
# Line 353  prepare_states (void) Line 416  prepare_states (void)
416  | This is where conflicts are resolved.  The loop over lookahead    |  | This is where conflicts are resolved.  The loop over lookahead    |
417  | rules considered lower-numbered rules last, and the last rule     |  | rules considered lower-numbered rules last, and the last rule     |
418  | considered that likes a token gets to handle it.                  |  | considered that likes a token gets to handle it.                  |
419    |                                                                   |
420    | For GLR parsers, also sets conflrow[SYM] to an index into         |
421    | conflict_list iff there is an unresolved conflict (s/r or r/r)    |
422    | with symbol SYM. The default reduction is not used for a symbol   |
423    | that has any such conflicts.                                      |
424  `------------------------------------------------------------------*/  `------------------------------------------------------------------*/
425    
426  static int  static int
# Line 365  action_row (state_t *state) Line 433  action_row (state_t *state)
433    errs *errp = state->errs;    errs *errp = state->errs;
434    /* set nonzero to inhibit having any default reduction */    /* set nonzero to inhibit having any default reduction */
435    int nodefault = 0;    int nodefault = 0;
436      int conflicted = 0;
437    
438    for (i = 0; i < ntokens; i++)    for (i = 0; i < ntokens; i++)
439      actrow[i] = 0;      actrow[i] = conflrow[i] = 0;
440    
441    if (redp->nreds >= 1)    if (redp->nreds >= 1)
442      {      {
# Line 381  action_row (state_t *state) Line 450  action_row (state_t *state)
450            /* and record this rule as the rule to use if that            /* and record this rule as the rule to use if that
451               token follows.  */               token follows.  */
452            if (bitset_test (state->lookaheads[i], j))            if (bitset_test (state->lookaheads[i], j))
453              actrow[j] = -state->lookaheads_rule[i]->number;              {
454                  if (actrow[j] != 0)
455                    conflicted = conflrow[j] = 1;
456                  actrow[j] = -state->lookaheads_rule[i]->number;
457                }
458      }      }
459    
460    /* Now see which tokens are allowed for shifts in this state.  For    /* Now see which tokens are allowed for shifts in this state.  For
# Line 399  action_row (state_t *state) Line 472  action_row (state_t *state)
472        if (ISVAR (symbol))        if (ISVAR (symbol))
473          break;          break;
474    
475          if (actrow[symbol] != 0)
476            conflicted = conflrow[symbol] = 1;
477        actrow[symbol] = shift_state;        actrow[symbol] = shift_state;
478    
479        /* Do not use any default reduction if there is a shift for        /* Do not use any default reduction if there is a shift for
# Line 442  action_row (state_t *state) Line 517  action_row (state_t *state)
517                  }                  }
518              }              }
519    
520            /* actions which match the default are replaced with zero,            /* GLR parsers need space for conflict lists, so we can't
521               which means "use the default" */               default conflicted entries.  For non-conflicted entries
522                 or as long as we are not building a GLR parser,
523                 actions that match the default are replaced with zero,
524                 which means "use the default". */
525    
526            if (max > 0)            if (max > 0)
527              {              {
528                int j;                int j;
529                for (j = 0; j < ntokens; j++)                for (j = 0; j < ntokens; j++)
530                  if (actrow[j] == default_rule)                  if (actrow[j] == default_rule && ! (glr_parser && conflrow[j]))
531                    actrow[j] = 0;                    actrow[j] = 0;
   
               default_rule = -default_rule;  
532              }              }
533              default_rule = -default_rule;
534          }          }
535      }      }
536    
# Line 465  action_row (state_t *state) Line 542  action_row (state_t *state)
542        if (actrow[i] == SHRT_MIN)        if (actrow[i] == SHRT_MIN)
543          actrow[i] = 0;          actrow[i] = 0;
544    
545      if (conflicted)
546        conflict_row (state);
547    
548    return default_rule;    return default_rule;
549  }  }
550    
# Line 477  save_row (int state) Line 557  save_row (int state)
557    short *sp;    short *sp;
558    short *sp1;    short *sp1;
559    short *sp2;    short *sp2;
560      unsigned int *sp3;
561    
562    count = 0;    count = 0;
563    for (i = 0; i < ntokens; i++)    for (i = 0; i < ntokens; i++)
# Line 488  save_row (int state) Line 569  save_row (int state)
569    
570    froms[state] = sp1 = sp = XCALLOC (short, count);    froms[state] = sp1 = sp = XCALLOC (short, count);
571    tos[state] = sp2 = XCALLOC (short, count);    tos[state] = sp2 = XCALLOC (short, count);
572      if (glr_parser)
573        conflict_tos[state] = sp3 = XCALLOC (unsigned int, count);  
574      else
575        conflict_tos[state] = NULL;
576    
577    for (i = 0; i < ntokens; i++)    for (i = 0; i < ntokens; i++)
578      if (actrow[i] != 0)      if (actrow[i] != 0)
579        {        {
580          *sp1++ = i;          *sp1++ = i;
581          *sp2++ = actrow[i];          *sp2++ = actrow[i];
582            if (glr_parser)
583              *sp3++ = conflrow[i];
584        }        }
585    
586    tally[state] = count;    tally[state] = count;
# Line 513  static void Line 600  static void
600  token_actions (void)  token_actions (void)
601  {  {
602    size_t i;    size_t i;
603      int nconflict = conflicts_total_count ();
604    
605    short *yydefact = XCALLOC (short, nstates);    short *yydefact = XCALLOC (short, nstates);
606    
607    actrow = XCALLOC (short, ntokens);    actrow = XCALLOC (short, ntokens);
608    
609      conflrow = XCALLOC (short, ntokens);
610      if (glr_parser)
611        {
612          conflict_list = XCALLOC (unsigned int, 1 + 2 * nconflict);
613          conflict_list_free = 2 * nconflict;
614          conflict_list_cnt = 1;
615        }
616      else
617        conflict_list_free = conflict_list_cnt = 0;
618    
619    for (i = 0; i < nstates; ++i)    for (i = 0; i < nstates; ++i)
620      {      {
621        yydefact[i] = action_row (states[i]);        yydefact[i] = action_row (states[i]);
# Line 525  token_actions (void) Line 625  token_actions (void)
625    muscle_insert_short_table ("defact", yydefact,    muscle_insert_short_table ("defact", yydefact,
626                               yydefact[0], 1, nstates);                               yydefact[0], 1, nstates);
627    XFREE (actrow);    XFREE (actrow);
628      XFREE (conflrow);
629    XFREE (yydefact);    XFREE (yydefact);
630  }  }
631    
# Line 555  actions_output (FILE *out) Line 656  actions_output (FILE *out)
656    fputs ("]])\n\n", out);    fputs ("]])\n\n", out);
657  }  }
658    
659    /*--------------------------------------.
660    | Output the merge functions to OUT.   |
661    `--------------------------------------*/
662    
663    void
664    merger_output (FILE *out)
665    {
666      int n;
667      merger_list* p;
668    
669      fputs ("m4_define([b4_mergers], \n[[", out);
670      for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
671        {
672          if (p->type[0] == '\0')
673            fprintf (out, "  case %d: yyval = %s (*yy0, *yy1); break;\n",
674                     n, p->name);
675          else
676            fprintf (out, "  case %d: yyval.%s = %s (*yy0, *yy1); break;\n",
677                     n, p->type, p->name);
678        }
679      fputs ("]])\n\n", out);
680    }
681    
682  /*---------------------------------------.  /*---------------------------------------.
683  | Output the tokens definition to OOUT.  |  | Output the tokens definition to OOUT.  |
# Line 844  pack_vector (int vector) Line 967  pack_vector (int vector)
967    int loc = 0;    int loc = 0;
968    short *from = froms[i];    short *from = froms[i];
969    short *to = tos[i];    short *to = tos[i];
970      unsigned int *conflict_to = conflict_tos[i];
971    
972    assert (t);    assert (t);
973    
# Line 872  pack_vector (int vector) Line 996  pack_vector (int vector)
996              {              {
997                loc = j + from[k];                loc = j + from[k];
998                table[loc] = to[k];                table[loc] = to[k];
999                  if (glr_parser && conflict_to != NULL)
1000                    conflict_table[loc] = conflict_to[k];
1001                check[loc] = from[k];                check[loc] = from[k];
1002              }              }
1003    
# Line 900  pack_table (void) Line 1026  pack_table (void)
1026    base = XCALLOC (short, nvectors);    base = XCALLOC (short, nvectors);
1027    pos = XCALLOC (short, nentries);    pos = XCALLOC (short, nentries);
1028    table = XCALLOC (short, table_size);    table = XCALLOC (short, table_size);
1029      if (glr_parser)
1030        conflict_table = XCALLOC (unsigned int, table_size);
1031    check = XCALLOC (short, table_size);    check = XCALLOC (short, table_size);
1032    
1033    lowzero = 0;    lowzero = 0;
# Line 928  pack_table (void) Line 1056  pack_table (void)
1056      {      {
1057        XFREE (froms[i]);        XFREE (froms[i]);
1058        XFREE (tos[i]);        XFREE (tos[i]);
1059          XFREE (conflict_tos[i]);
1060      }      }
1061    
1062    XFREE (froms);    XFREE (froms);
1063    XFREE (tos);    XFREE (tos);
1064      XFREE (conflict_tos);
1065    XFREE (pos);    XFREE (pos);
1066  }  }
1067    
1068  /* the following functions output yytable, yycheck  /* the following functions output yytable, yycheck, yyconflp, yyconfl,
1069     and the vectors whose elements index the portion starts */     and the vectors whose elements index the portion starts */
1070    
1071  static void  static void
# Line 962  output_table (void) Line 1092  output_table (void)
1092    
1093    
1094  static void  static void
1095    output_conflicts (void)
1096    {
1097      /* GLR parsing slightly modifies yytable and yycheck
1098         (and thus yypact) so that in states with unresolved conflicts,
1099         the default reduction is not used in the conflicted entries, so
1100         that there is a place to put a conflict pointer.  This means that
1101         yyconflp and yyconfl are nonsense for a non-GLR parser, so we
1102         avoid accidents by not writing them out in that case. */
1103      if (! glr_parser)
1104        return;
1105    
1106      muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
1107                                        conflict_table[0], 1, high+1);
1108      muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
1109                                 conflict_list[0], 1, conflict_list_cnt);
1110    
1111      XFREE (conflict_table);
1112      XFREE (conflict_list);
1113    }
1114    
1115    
1116    static void
1117  output_check (void)  output_check (void)
1118  {  {
1119    muscle_insert_short_table ("check", check,    muscle_insert_short_table ("check", check,
# Line 982  output_actions (void) Line 1134  output_actions (void)
1134    
1135    froms = XCALLOC (short *, nvectors);    froms = XCALLOC (short *, nvectors);
1136    tos = XCALLOC (short *, nvectors);    tos = XCALLOC (short *, nvectors);
1137      conflict_tos = XCALLOC (unsigned int *, nvectors);
1138    tally = XCALLOC (short, nvectors);    tally = XCALLOC (short, nvectors);
1139    width = XCALLOC (short, nvectors);    width = XCALLOC (short, nvectors);
1140    
# Line 999  output_actions (void) Line 1152  output_actions (void)
1152    
1153    output_base ();    output_base ();
1154    output_table ();    output_table ();
1155      output_conflicts ();
1156    
1157    output_check ();    output_check ();
1158    
# Line 1084  output_skeleton (void) Line 1238  output_skeleton (void)
1238    fputs ("m4_init()\n", out);    fputs ("m4_init()\n", out);
1239    
1240    actions_output (out);    actions_output (out);
1241      merger_output (out);
1242    token_definitions_output (out);    token_definitions_output (out);
1243    symbol_destructors_output (out);    symbol_destructors_output (out);
1244    symbol_printers_output (out);    symbol_printers_output (out);
# Line 1140  prepare (void) Line 1295  prepare (void)
1295    
1296    /* Find the right skeleton file.  */    /* Find the right skeleton file.  */
1297    if (!skeleton)    if (!skeleton)
1298      skeleton = "yacc.c";      {
1299          if (glr_parser)
1300            skeleton = "glr.c";
1301          else
1302            skeleton = "yacc.c";
1303        }
1304    
1305    /* Parse the skeleton file and output the needed parsers.  */    /* Parse the skeleton file and output the needed parsers.  */
1306    muscle_insert ("skeleton", skeleton);    muscle_insert ("skeleton", skeleton);

Legend:
Removed from v.1.168  
changed lines
  Added in v.1.169

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26