Coverage Report

Created: 2026-01-17 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/flex/src/gen.c
Line
Count
Source
1
/* gen - actual generation (writing) of flex scanners */
2
3
/*  Copyright (c) 1990 The Regents of the University of California. */
4
/*  All rights reserved. */
5
6
/*  This code is derived from software contributed to Berkeley by */
7
/*  Vern Paxson. */
8
9
/*  The United States Government has rights in this work pursuant */
10
/*  to contract no. DE-AC03-76SF00098 between the United States */
11
/*  Department of Energy and the University of California. */
12
13
/*  This file is part of flex. */
14
15
/*  Redistribution and use in source and binary forms, with or without */
16
/*  modification, are permitted provided that the following conditions */
17
/*  are met: */
18
19
/*  1. Redistributions of source code must retain the above copyright */
20
/*     notice, this list of conditions and the following disclaimer. */
21
/*  2. Redistributions in binary form must reproduce the above copyright */
22
/*     notice, this list of conditions and the following disclaimer in the */
23
/*     documentation and/or other materials provided with the distribution. */
24
25
/*  Neither the name of the University nor the names of its contributors */
26
/*  may be used to endorse or promote products derived from this software */
27
/*  without specific prior written permission. */
28
29
/*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
30
/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
31
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
32
/*  PURPOSE. */
33
34
#include "flexdef.h"
35
#include "tables.h"
36
37
/* These typedefs are only used for computing footprint sizes,
38
 * You need to make sure they match reality in the skeleton file to
39
 * get accurate numbers, but they don't otherwise matter.
40
 */
41
typedef char YY_CHAR;
42
struct yy_trans_info {int32_t yy_verify; int32_t yy_nxt;};
43
44
/* declare functions that have forward references */
45
46
static void genecs(void);
47
48
struct packtype_t *optimize_pack(size_t sz)
49
0
{
50
  /* FIXME: There's a 32-bit assumption lurking here */
51
0
  static struct packtype_t out;
52
0
  if (sz == 0) {
53
0
    out.name  = ctrl.long_align ? "M4_HOOK_INT32" : "M4_HOOK_INT16";
54
0
    out.width = ctrl.long_align ? 32 : 16;
55
0
  } else {
56
0
    out.name = (ctrl.long_align || sz >= INT16_MAX) ? "M4_HOOK_INT32" : "M4_HOOK_INT16";
57
0
    out.width = (ctrl.long_align || sz >= INT16_MAX) ? 32 : 16;
58
0
  }
59
0
  return &out;
60
0
}
61
62
/* Almost everything is done in terms of arrays starting at 1, so provide
63
 * a null entry for the zero element of all C arrays.  (The exception
64
 * to this is that the fast table representation generally uses the
65
 * 0 elements of its arrays, too.)
66
 */
67
68
/** Make the table for possible eol matches.
69
 *  @return the newly allocated rule_can_match_eol table
70
 */
71
static struct yytbl_data *mkeoltbl (void)
72
0
{
73
0
  int     i;
74
0
  flex_int8_t *tdata = 0;
75
0
  struct yytbl_data *tbl;
76
77
0
  tbl = calloc(1, sizeof (struct yytbl_data));
78
0
  yytbl_data_init (tbl, YYTD_ID_RULE_CAN_MATCH_EOL);
79
0
  tbl->td_flags = YYTD_DATA8;
80
0
  tbl->td_lolen = (flex_uint32_t) (num_rules + 1);
81
0
  tbl->td_data = tdata =
82
0
    calloc(tbl->td_lolen, sizeof (flex_int8_t));
83
84
0
  for (i = 1; i <= num_rules; i++)
85
0
    tdata[i] = rule_has_nl[i] ? 1 : 0;
86
87
0
  return tbl;
88
0
}
89
90
/* Generate the table for possible eol matches. */
91
static void geneoltbl (void)
92
0
{
93
0
  int     i;
94
0
  struct packtype_t *ptype = optimize_pack(num_rules);
95
96
0
  outn ("m4_ifdef( [[M4_MODE_YYLINENO]],[[");
97
0
  out_str ("m4_define([[M4_HOOK_EOLTABLE_TYPE]], [[%s]])\n", ptype->name);
98
0
  out_dec ("m4_define([[M4_HOOK_EOLTABLE_SIZE]], [[%d]])", num_rules + 1);
99
0
  outn ("m4_define([[M4_HOOK_EOLTABLE_BODY]], [[m4_dnl");
100
101
0
  if (gentables) {
102
0
    for (i = 1; i <= num_rules; i++) {
103
0
      out_dec ("%d, ", rule_has_nl[i] ? 1 : 0);
104
      /* format nicely, 20 numbers per line. */
105
0
      if ((i % 20) == 19)
106
0
        out ("\n    ");
107
0
    }
108
0
  }
109
0
  footprint += num_rules * ptype->width;
110
0
  outn ("]])");
111
0
  outn ("]])");
112
0
}
113
114
115
/** mkctbl - make full speed compressed transition table
116
 * This is an array of structs; each struct a pair of integers.
117
 * You should call mkssltbl() immediately after this.
118
 * Then, I think, mkecstbl(). Arrrg.
119
 * @return the newly allocated trans table
120
 */
121
122
static struct yytbl_data *mkctbl (void)
123
0
{
124
0
  int i;
125
0
  struct yytbl_data *tbl = 0;
126
0
  flex_int32_t *tdata = 0, curr = 0;
127
0
  int     end_of_buffer_action = num_rules + 1;
128
129
0
  struct packtype_t *ptype = optimize_pack(tblend + 2 + 1);
130
0
  out_str ("m4_define([[M4_HOOK_MKCTBL_TYPE]], [[%s]])", ptype->name);
131
132
0
  tbl = calloc(1, sizeof (struct yytbl_data));
133
0
  yytbl_data_init (tbl, YYTD_ID_TRANSITION);
134
0
  tbl->td_flags = YYTD_DATA32 | YYTD_STRUCT;
135
0
  tbl->td_hilen = 0;
136
0
  tbl->td_lolen = (flex_uint32_t) (tblend + 2 + 1); /* number of structs */
137
138
0
  tbl->td_data = tdata =
139
0
    calloc(tbl->td_lolen * 2, sizeof (flex_int32_t));
140
141
  /* We want the transition to be represented as the offset to the
142
   * next state, not the actual state number, which is what it currently
143
   * is.  The offset is base[nxt[i]] - (base of current state)].  That's
144
   * just the difference between the starting points of the two involved
145
   * states (to - from).
146
   *
147
   * First, though, we need to find some way to put in our end-of-buffer
148
   * flags and states.  We do this by making a state with absolutely no
149
   * transitions.  We put it at the end of the table.
150
   */
151
152
  /* We need to have room in nxt/chk for two more slots: One for the
153
   * action and one for the end-of-buffer transition.  We now *assume*
154
   * that we're guaranteed the only character we'll try to index this
155
   * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure
156
   * there's room for jam entries for other characters.
157
   */
158
159
0
  while (tblend + 2 >= current_max_xpairs)
160
0
    expand_nxt_chk ();
161
162
0
  while (lastdfa + 1 >= current_max_dfas)
163
0
    increase_max_dfas ();
164
165
0
  base[lastdfa + 1] = tblend + 2;
166
0
  nxt[tblend + 1] = end_of_buffer_action;
167
0
  chk[tblend + 1] = numecs + 1;
168
0
  chk[tblend + 2] = 1;  /* anything but EOB */
169
170
  /* So that "make test" won't show arb. differences. */
171
0
  nxt[tblend + 2] = 0;
172
173
  /* Make sure every state has an end-of-buffer transition and an
174
   * action #.
175
   */
176
0
  for (i = 0; i <= lastdfa; ++i) {
177
0
    int     anum = dfaacc[i].dfaacc_state;
178
0
    int     offset = base[i];
179
180
0
    chk[offset] = EOB_POSITION;
181
0
    chk[offset - 1] = ACTION_POSITION;
182
0
    nxt[offset - 1] = anum; /* action number */
183
0
  }
184
185
0
  for (i = 0; i <= tblend; ++i) {
186
0
    if (chk[i] == EOB_POSITION) {
187
0
      tdata[curr++] = 0;
188
0
      tdata[curr++] = base[lastdfa + 1] - i;
189
0
    }
190
191
0
    else if (chk[i] == ACTION_POSITION) {
192
0
      tdata[curr++] = 0;
193
0
      tdata[curr++] = nxt[i];
194
0
    }
195
196
0
    else if (chk[i] > numecs || chk[i] == 0) {
197
0
      tdata[curr++] = 0;
198
0
      tdata[curr++] = 0;
199
0
    }
200
0
    else {   /* verify, transition */
201
202
0
      tdata[curr++] = chk[i];
203
0
      tdata[curr++] = base[nxt[i]] - (i - chk[i]);
204
0
    }
205
0
  }
206
207
  /* Here's the final, end-of-buffer state. */
208
0
  tdata[curr++] = chk[tblend + 1];
209
0
  tdata[curr++] = nxt[tblend + 1];
210
211
0
  tdata[curr++] = chk[tblend + 2];
212
0
  tdata[curr++] = nxt[tblend + 2];
213
214
0
  return tbl;
215
0
}
216
217
218
/** Make start_state_list table.
219
 *  @return the newly allocated start_state_list table
220
 */
221
static struct yytbl_data *mkssltbl (void)
222
0
{
223
0
  struct yytbl_data *tbl = 0;
224
0
  flex_int32_t *tdata = 0;
225
0
  flex_int32_t i;
226
227
0
  tbl = calloc(1, sizeof (struct yytbl_data));
228
0
  yytbl_data_init (tbl, YYTD_ID_START_STATE_LIST);
229
0
  tbl->td_flags = YYTD_DATA32 | YYTD_PTRANS;
230
0
  tbl->td_hilen = 0;
231
0
  tbl->td_lolen = (flex_uint32_t) (lastsc * 2 + 1);
232
233
0
  tbl->td_data = tdata =
234
0
    calloc(tbl->td_lolen, sizeof (flex_int32_t));
235
236
0
  for (i = 0; i <= lastsc * 2; ++i)
237
0
    tdata[i] = base[i];
238
239
0
  return tbl;
240
0
}
241
242
243
244
/* genctbl - generates full speed compressed transition table */
245
246
static void genctbl(void)
247
0
{
248
0
  int i;
249
0
  int     end_of_buffer_action = num_rules + 1;
250
251
  /* Table of verify for transition and offset to next state. */
252
0
  out_dec ("m4_define([[M4_HOOK_TRANSTABLE_SIZE]], [[%d]])", tblend + 2 + 1);
253
0
  outn ("m4_define([[M4_HOOK_TRANSTABLE_BODY]], [[m4_dnl");
254
255
  /* We want the transition to be represented as the offset to the
256
   * next state, not the actual state number, which is what it currently
257
   * is.  The offset is base[nxt[i]] - (base of current state)].  That's
258
   * just the difference between the starting points of the two involved
259
   * states (to - from).
260
   *
261
   * First, though, we need to find some way to put in our end-of-buffer
262
   * flags and states.  We do this by making a state with absolutely no
263
   * transitions.  We put it at the end of the table.
264
   */
265
266
  /* We need to have room in nxt/chk for two more slots: One for the
267
   * action and one for the end-of-buffer transition.  We now *assume*
268
   * that we're guaranteed the only character we'll try to index this
269
   * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure
270
   * there's room for jam entries for other characters.
271
   */
272
273
0
  while (tblend + 2 >= current_max_xpairs)
274
0
    expand_nxt_chk ();
275
276
0
  while (lastdfa + 1 >= current_max_dfas)
277
0
    increase_max_dfas ();
278
279
0
  base[lastdfa + 1] = tblend + 2;
280
0
  nxt[tblend + 1] = end_of_buffer_action;
281
0
  chk[tblend + 1] = numecs + 1;
282
0
  chk[tblend + 2] = 1;  /* anything but EOB */
283
284
  /* So that "make test" won't show arb. differences. */
285
0
  nxt[tblend + 2] = 0;
286
287
  /* Make sure every state has an end-of-buffer transition and an
288
   * action #.
289
   */
290
0
  for (i = 0; i <= lastdfa; ++i) {
291
0
    int     anum = dfaacc[i].dfaacc_state;
292
0
    int     offset = base[i];
293
294
0
    chk[offset] = EOB_POSITION;
295
0
    chk[offset - 1] = ACTION_POSITION;
296
0
    nxt[offset - 1] = anum; /* action number */
297
0
  }
298
299
0
  for (i = 0; i <= tblend; ++i) {
300
0
    if (chk[i] == EOB_POSITION)
301
0
      transition_struct_out (0, base[lastdfa + 1] - i);
302
303
0
    else if (chk[i] == ACTION_POSITION)
304
0
      transition_struct_out (0, nxt[i]);
305
306
0
    else if (chk[i] > numecs || chk[i] == 0)
307
0
      transition_struct_out (0, 0); /* unused slot */
308
309
0
    else    /* verify, transition */
310
0
      transition_struct_out (chk[i],
311
0
                 base[nxt[i]] - (i -
312
0
                     chk[i]));
313
0
  }
314
315
316
  /* Here's the final, end-of-buffer state. */
317
0
  transition_struct_out (chk[tblend + 1], nxt[tblend + 1]);
318
0
  transition_struct_out (chk[tblend + 2], nxt[tblend + 2]);
319
320
0
  outn ("]])");
321
0
  footprint += sizeof(struct yy_trans_info) * (tblend + 2 + 1);
322
323
0
  out_dec ("m4_define([[M4_HOOK_STARTTABLE_SIZE]], [[%d]])", lastsc * 2 + 1);
324
0
  if (gentables) {
325
0
    outn ("m4_define([[M4_HOOK_STARTTABLE_BODY]], [[m4_dnl");
326
0
    for (i = 0; i <= lastsc * 2; ++i)
327
0
      out_dec ("M4_HOOK_STATE_ENTRY_FORMAT(%d)", base[i]);
328
329
0
    dataend (NULL);
330
0
    outn("]])");
331
0
    footprint +=  sizeof(struct yy_trans_info *) * (lastsc * 2 + 1);
332
0
  }
333
334
0
  if (ctrl.useecs)
335
0
    genecs ();
336
0
}
337
338
339
/* mkecstbl - Make equivalence-class tables.  */
340
341
static struct yytbl_data *mkecstbl (void)
342
0
{
343
0
  int i;
344
0
  struct yytbl_data *tbl = 0;
345
0
  flex_int32_t *tdata = 0;
346
347
0
  tbl = calloc(1, sizeof (struct yytbl_data));
348
0
  yytbl_data_init (tbl, YYTD_ID_EC);
349
0
  tbl->td_flags |= YYTD_DATA32;
350
0
  tbl->td_hilen = 0;
351
0
  tbl->td_lolen = (flex_uint32_t) ctrl.csize;
352
353
0
  tbl->td_data = tdata =
354
0
    calloc(tbl->td_lolen, sizeof (flex_int32_t));
355
356
0
  for (i = 1; i < ctrl.csize; ++i) {
357
0
    ecgroup[i] = ABS (ecgroup[i]);
358
0
    tdata[i] = ecgroup[i];
359
0
  }
360
361
0
  return tbl;
362
0
}
363
364
/* Generate equivalence-class tables. */
365
366
static void genecs(void)
367
0
{
368
0
  int ch, row;
369
0
  int     numrows;
370
371
0
  out_dec ("m4_define([[M4_HOOK_ECSTABLE_SIZE]], [[%d]])", ctrl.csize);
372
0
  outn ("m4_define([[M4_HOOK_ECSTABLE_BODY]], [[m4_dnl");
373
374
0
  for (ch = 1; ch < ctrl.csize; ++ch) {
375
0
    ecgroup[ch] = ABS (ecgroup[ch]);
376
0
    mkdata (ecgroup[ch]);
377
0
  }
378
379
0
  dataend (NULL);
380
0
  outn("]])");
381
0
  footprint += sizeof(YY_CHAR) * ctrl.csize;
382
383
0
  if (env.trace) {
384
0
    fputs (_("\n\nEquivalence Classes:\n\n"), stderr);
385
386
    /* Print in 8 columns */
387
0
    numrows = ctrl.csize / 8;
388
389
0
    for (row = 0; row < numrows; ++row) {
390
0
      for (ch = row; ch < ctrl.csize; ch += numrows) {
391
0
        fprintf (stderr, "%4s = %-2d",
392
0
           readable_form (ch), ecgroup[ch]);
393
394
0
        putc (' ', stderr);
395
0
      }
396
397
0
      putc ('\n', stderr);
398
0
    }
399
0
  }
400
0
}
401
402
/* mkftbl - make the full table and return the struct .
403
 * you should call mkecstbl() after this.
404
 */
405
406
static struct yytbl_data *mkftbl(void)
407
0
{
408
0
  int i;
409
0
  int     end_of_buffer_action = num_rules + 1;
410
0
  struct yytbl_data *tbl;
411
0
  flex_int32_t *tdata = 0;
412
413
0
  tbl = calloc(1, sizeof (struct yytbl_data));
414
0
  yytbl_data_init (tbl, YYTD_ID_ACCEPT);
415
0
  tbl->td_flags |= YYTD_DATA32;
416
0
  tbl->td_hilen = 0;  /* it's a one-dimensional array */
417
0
  tbl->td_lolen = (flex_uint32_t) (lastdfa + 1);
418
419
0
  tbl->td_data = tdata =
420
0
    calloc(tbl->td_lolen, sizeof (flex_int32_t));
421
422
0
  dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
423
424
0
  for (i = 1; i <= lastdfa; ++i) {
425
0
    int anum = dfaacc[i].dfaacc_state;
426
427
0
    tdata[i] = anum;
428
429
0
    if (env.trace && anum)
430
0
      fprintf (stderr, _("state # %d accepts: [%d]\n"),
431
0
         i, anum);
432
0
  }
433
434
0
  return tbl;
435
0
}
436
437
438
/* genftbl - generate full transition table */
439
440
static void genftbl(void)
441
0
{
442
0
  int i;
443
0
  int     end_of_buffer_action = num_rules + 1;
444
0
  struct packtype_t *ptype = optimize_pack(num_rules + 1);
445
446
0
  dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
447
448
0
  outn ("m4_define([[M4_HOOK_NEED_ACCEPT]], 1)");
449
0
  out_str ("m4_define([[M4_HOOK_ACCEPT_TYPE]], [[%s]])", ptype->name);
450
0
  out_dec ("m4_define([[M4_HOOK_ACCEPT_SIZE]], [[%d]])", lastdfa + 1);
451
0
  outn ("m4_define([[M4_HOOK_ACCEPT_BODY]], [[m4_dnl");
452
453
0
  for (i = 1; i <= lastdfa; ++i) {
454
0
    int anum = dfaacc[i].dfaacc_state;
455
456
0
    mkdata (anum);
457
458
0
    if (env.trace && anum)
459
0
      fprintf (stderr, _("state # %d accepts: [%d]\n"),
460
0
         i, anum);
461
0
  }
462
463
0
  dataend (NULL);
464
0
  outn("]])");
465
0
  footprint += (lastdfa + 1) * ptype->width;
466
467
0
  if (ctrl.useecs)
468
0
    genecs ();
469
470
  /* Don't have to dump the actual full table entries - they were
471
   * created on-the-fly.
472
   */
473
0
}
474
475
/* gentabs - generate data statements for the transition tables */
476
477
static void gentabs(void)
478
0
{
479
0
  int     sz, i, j, k, *accset, nacc, *acc_array, total_states;
480
0
  int     end_of_buffer_action = num_rules + 1;
481
0
  struct yytbl_data *yyacc_tbl = 0, *yymeta_tbl = 0, *yybase_tbl = 0,
482
0
      *yydef_tbl = 0, *yynxt_tbl = 0, *yychk_tbl = 0, *yyacclist_tbl=0;
483
0
  flex_int32_t *yyacc_data = 0, *yybase_data = 0, *yydef_data = 0,
484
0
      *yynxt_data = 0, *yychk_data = 0, *yyacclist_data=0;
485
0
  flex_int32_t yybase_curr = 0, yyacclist_curr=0,yyacc_curr=0;
486
0
  struct packtype_t *ptype;
487
488
0
  acc_array = allocate_integer_array (current_max_dfas);
489
0
  nummt = 0;
490
491
  /* The compressed table format jams by entering the "jam state",
492
   * losing information about the previous state in the process.
493
   * In order to recover the previous state, we effectively need
494
   * to keep backing-up information.
495
   */
496
0
  ++num_backing_up;
497
498
0
  if (reject) {
499
    /* Write out accepting list and pointer list.
500
501
     * First we generate the "yy_acclist" array.  In the process,
502
     * we compute the indices that will go into the "yy_accept"
503
     * array, and save the indices in the dfaacc array.
504
     */
505
0
    int     EOB_accepting_list[2];
506
507
    /* Set up accepting structures for the End Of Buffer state. */
508
0
    EOB_accepting_list[0] = 0;
509
0
    EOB_accepting_list[1] = end_of_buffer_action;
510
0
    accsiz[end_of_buffer_state] = 1;
511
0
    dfaacc[end_of_buffer_state].dfaacc_set =
512
0
        EOB_accepting_list;
513
514
0
    sz = MAX (numas, 1) + 1;
515
0
    ptype = optimize_pack(sz);
516
0
    out_str ("m4_define([[M4_HOOK_ACCLIST_TYPE]], [[%s]])", ptype->name);
517
0
    out_dec ("m4_define([[M4_HOOK_ACCLIST_SIZE]], [[%d]])", sz);
518
0
    outn ("m4_define([[M4_HOOK_ACCLIST_BODY]], [[m4_dnl");
519
520
0
    yyacclist_tbl = calloc(1,sizeof(struct yytbl_data));
521
0
    yytbl_data_init (yyacclist_tbl, YYTD_ID_ACCLIST);
522
0
    yyacclist_tbl->td_lolen  = (flex_uint32_t) (MAX(numas,1) + 1);
523
0
    yyacclist_tbl->td_data = yyacclist_data =
524
0
        calloc(yyacclist_tbl->td_lolen, sizeof (flex_int32_t));
525
0
    yyacclist_curr = 1;
526
527
0
    j = 1;    /* index into "yy_acclist" array */
528
529
0
    for (i = 1; i <= lastdfa; ++i) {
530
0
      acc_array[i] = j;
531
532
0
      if (accsiz[i] != 0) {
533
0
        accset = dfaacc[i].dfaacc_set;
534
0
        nacc = accsiz[i];
535
536
0
        if (env.trace)
537
0
          fprintf (stderr,
538
0
             _("state # %d accepts: "),
539
0
             i);
540
541
0
        for (k = 1; k <= nacc; ++k) {
542
0
          int     accnum = accset[k];
543
544
0
          ++j;
545
546
0
          if (variable_trailing_context_rules
547
0
              && !(accnum &
548
0
             YY_TRAILING_HEAD_MASK)
549
0
              && accnum > 0
550
0
              && accnum <= num_rules
551
0
              && rule_type[accnum] ==
552
0
              RULE_VARIABLE) {
553
            /* Special hack to flag
554
             * accepting number as part
555
             * of trailing context rule.
556
             */
557
0
            accnum |= YY_TRAILING_MASK;
558
0
          }
559
560
0
          mkdata (accnum);
561
0
          yyacclist_data[yyacclist_curr++] = accnum;
562
563
0
          if (env.trace) {
564
0
            fprintf (stderr, "[%d]",
565
0
               accset[k]);
566
567
0
            if (k < nacc)
568
0
              fputs (", ",
569
0
                     stderr);
570
0
            else
571
0
              putc ('\n',
572
0
                    stderr);
573
0
          }
574
0
        }
575
0
      }
576
0
    }
577
578
    /* add accepting number for the "jam" state */
579
0
    acc_array[i] = j;
580
581
0
    dataend (NULL);
582
0
    outn("]])");
583
0
    footprint += sz * ptype->width;
584
0
    if (tablesext) {
585
0
      yytbl_data_compress (yyacclist_tbl);
586
0
      if (yytbl_data_fwrite (&tableswr, yyacclist_tbl) < 0)
587
0
        flexerror (_("Could not write yyacclist_tbl"));
588
0
      yytbl_data_destroy (yyacclist_tbl);
589
0
      yyacclist_tbl = NULL;
590
0
    }
591
0
  }
592
593
0
  else {
594
0
    dfaacc[end_of_buffer_state].dfaacc_state =
595
0
        end_of_buffer_action;
596
597
0
    for (i = 1; i <= lastdfa; ++i)
598
0
      acc_array[i] = dfaacc[i].dfaacc_state;
599
600
    /* add accepting number for jam state */
601
0
    acc_array[i] = 0;
602
0
  }
603
604
  /* Begin generating yy_accept */
605
606
  /* Spit out "yy_accept" array.  If we're doing "reject", it'll be
607
   * pointers into the "yy_acclist" array.  Otherwise it's actual
608
   * accepting numbers.  In either case, we just dump the numbers.
609
   */
610
611
  /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays
612
   * beginning at 0 and for "jam" state.
613
   */
614
0
  sz = lastdfa + 2;
615
616
0
  if (reject)
617
    /* We put a "cap" on the table associating lists of accepting
618
     * numbers with state numbers.  This is needed because we tell
619
     * where the end of an accepting list is by looking at where
620
     * the list for the next state starts.
621
     */
622
0
    ++sz;
623
624
  /* Note that this table is alternately defined if ctrl.fulltbl */
625
0
  ptype = optimize_pack(sz);
626
0
  outn ("m4_define([[M4_HOOK_NEED_ACCEPT]], 1)");
627
0
  out_str ("m4_define([[M4_HOOK_ACCEPT_TYPE]], [[%s]])", ptype->name);
628
0
  out_dec ("m4_define([[M4_HOOK_ACCEPT_SIZE]], [[%d]])", sz);
629
0
  outn ("m4_define([[M4_HOOK_ACCEPT_BODY]], [[m4_dnl");
630
631
0
  yyacc_tbl = calloc(1, sizeof (struct yytbl_data));
632
0
  yytbl_data_init (yyacc_tbl, YYTD_ID_ACCEPT);
633
0
  yyacc_tbl->td_lolen = (flex_uint32_t) sz;
634
0
  yyacc_tbl->td_data = yyacc_data =
635
0
      calloc(yyacc_tbl->td_lolen, sizeof (flex_int32_t));
636
0
  yyacc_curr=1;
637
638
0
  for (i = 1; i <= lastdfa; ++i) {
639
0
    mkdata (acc_array[i]);
640
0
    yyacc_data[yyacc_curr++] = acc_array[i];
641
642
0
    if (!reject && env.trace && acc_array[i])
643
0
      fprintf (stderr, _("state # %d accepts: [%d]\n"),
644
0
         i, acc_array[i]);
645
0
  }
646
647
  /* Add entry for "jam" state. */
648
0
  mkdata (acc_array[i]);
649
0
  yyacc_data[yyacc_curr++] = acc_array[i];
650
651
0
  if (reject) {
652
    /* Add "cap" for the list. */
653
0
    mkdata (acc_array[i]);
654
0
    yyacc_data[yyacc_curr++] = acc_array[i];
655
0
  }
656
657
0
  dataend (NULL);
658
0
  outn ("]])");
659
0
  footprint += sz * ptype->width;
660
661
0
  if (tablesext) {
662
0
    yytbl_data_compress (yyacc_tbl);
663
0
    if (yytbl_data_fwrite (&tableswr, yyacc_tbl) < 0)
664
0
      flexerror (_("Could not write yyacc_tbl"));
665
0
  }
666
0
  yytbl_data_destroy (yyacc_tbl);
667
0
  yyacc_tbl = NULL;
668
  /* End generating yy_accept */
669
670
0
  if (ctrl.useecs) {
671
672
0
    genecs ();
673
0
    if (tablesext) {
674
0
      struct yytbl_data *tbl;
675
676
0
      tbl = mkecstbl ();
677
0
      yytbl_data_compress (tbl);
678
0
      if (yytbl_data_fwrite (&tableswr, tbl) < 0)
679
0
        flexerror (_("Could not write ecstbl"));
680
0
      yytbl_data_destroy (tbl);
681
0
      tbl = 0;
682
0
    }
683
0
  }
684
685
0
  if (ctrl.usemecs) {
686
    /* Begin generating yy_meta */
687
    /* Write out meta-equivalence classes (used to index
688
     * templates with).
689
     */
690
0
    flex_int32_t *yymecs_data = 0;
691
0
    yymeta_tbl = calloc(1, sizeof (struct yytbl_data));
692
0
    yytbl_data_init (yymeta_tbl, YYTD_ID_META);
693
0
    yymeta_tbl->td_lolen = (flex_uint32_t) (numecs + 1);
694
0
    yymeta_tbl->td_data = yymecs_data =
695
0
        calloc(yymeta_tbl->td_lolen,
696
0
         sizeof (flex_int32_t));
697
698
0
    if (env.trace)
699
0
      fputs (_("\n\nMeta-Equivalence Classes:\n"),
700
0
             stderr);
701
0
    out_dec ("m4_define([[M4_HOOK_MECSTABLE_SIZE]], [[%d]])", numecs+1);
702
0
    outn ("m4_define([[M4_HOOK_MECSTABLE_BODY]], [[m4_dnl");
703
  
704
0
    for (i = 1; i <= numecs; ++i) {
705
0
      if (env.trace)
706
0
        fprintf (stderr, "%d = %d\n",
707
0
           i, ABS (tecbck[i]));
708
709
0
      mkdata (ABS (tecbck[i]));
710
0
      yymecs_data[i] = ABS (tecbck[i]);
711
0
    }
712
713
0
    dataend (NULL);
714
0
    outn ("]])");
715
0
    footprint += sizeof(YY_CHAR) * (numecs + 1);
716
0
    if (tablesext) {
717
0
      yytbl_data_compress (yymeta_tbl);
718
0
      if (yytbl_data_fwrite (&tableswr, yymeta_tbl) < 0)
719
0
        flexerror (_("Could not write yymeta_tbl"));
720
0
    }
721
0
    yytbl_data_destroy (yymeta_tbl);
722
0
    yymeta_tbl = NULL;
723
    /* End generating yy_meta */
724
0
  }
725
726
0
  total_states = lastdfa + numtemps;
727
728
  /* Begin generating yy_base */
729
0
  sz = total_states + 1;
730
0
  ptype = optimize_pack(sz);
731
0
  out_str ("m4_define([[M4_HOOK_BASE_TYPE]], [[%s]])", ptype->name);
732
0
  out_dec ("m4_define([[M4_HOOK_BASE_SIZE]], [[%d]])", sz);
733
0
  outn ("m4_define([[M4_HOOK_BASE_BODY]], [[m4_dnl");
734
735
0
  yybase_tbl = calloc (1, sizeof (struct yytbl_data));
736
0
  yytbl_data_init (yybase_tbl, YYTD_ID_BASE);
737
0
  yybase_tbl->td_lolen = (flex_uint32_t) (total_states + 1);
738
0
  yybase_tbl->td_data = yybase_data =
739
0
      calloc(yybase_tbl->td_lolen,
740
0
       sizeof (flex_int32_t));
741
0
  yybase_curr = 1;
742
743
0
  for (i = 1; i <= lastdfa; ++i) {
744
0
    int d = def[i];
745
746
0
    if (base[i] == JAMSTATE)
747
0
      base[i] = jambase;
748
749
0
    if (d == JAMSTATE)
750
0
      def[i] = jamstate;
751
752
0
    else if (d < 0) {
753
      /* Template reference. */
754
0
      ++tmpuses;
755
0
      def[i] = lastdfa - d + 1;
756
0
    }
757
758
0
    mkdata (base[i]);
759
0
    yybase_data[yybase_curr++] = base[i];
760
0
  }
761
762
  /* Generate jam state's base index. */
763
0
  mkdata (base[i]);
764
0
  yybase_data[yybase_curr++] = base[i];
765
766
0
  for (++i /* skip jam state */ ; i <= total_states; ++i) {
767
0
    mkdata (base[i]);
768
0
    yybase_data[yybase_curr++] = base[i];
769
0
    def[i] = jamstate;
770
0
  }
771
772
0
  dataend (NULL);
773
0
  outn ("]])");
774
0
  footprint += sz * ptype->width;
775
776
0
  if (tablesext) {
777
0
    yytbl_data_compress (yybase_tbl);
778
0
    if (yytbl_data_fwrite (&tableswr, yybase_tbl) < 0)
779
0
      flexerror (_("Could not write yybase_tbl"));
780
0
  }
781
0
  yytbl_data_destroy (yybase_tbl);
782
0
  yybase_tbl = NULL;
783
  /* End generating yy_base */
784
785
786
  /* Begin generating yy_def */
787
0
  ptype = optimize_pack(total_states + 1);
788
0
  out_str ("m4_define([[M4_HOOK_DEF_TYPE]], [[%s]])", ptype->name);
789
0
  out_dec ("m4_define([[M4_HOOK_DEF_SIZE]], [[%d]])", total_states + 1);
790
0
  outn ("m4_define([[M4_HOOK_DEF_BODY]], [[m4_dnl");
791
792
0
  yydef_tbl = calloc(1, sizeof (struct yytbl_data));
793
0
  yytbl_data_init (yydef_tbl, YYTD_ID_DEF);
794
0
  yydef_tbl->td_lolen = (flex_uint32_t)(total_states + 1);
795
0
  yydef_tbl->td_data = yydef_data =
796
0
      calloc(yydef_tbl->td_lolen, sizeof (flex_int32_t));
797
798
0
  for (i = 1; i <= total_states; ++i) {
799
0
    mkdata (def[i]);
800
0
    yydef_data[i] = def[i];
801
0
  }
802
803
0
  dataend (NULL);
804
0
  outn ("]])");
805
0
  footprint += (total_states + 1) * ptype->width;
806
807
0
  if (tablesext) {
808
0
    yytbl_data_compress (yydef_tbl);
809
0
    if (yytbl_data_fwrite (&tableswr, yydef_tbl) < 0)
810
0
      flexerror (_("Could not write yydef_tbl"));
811
0
  }
812
0
  yytbl_data_destroy (yydef_tbl);
813
0
  yydef_tbl = NULL;
814
  /* End generating yy_def */
815
816
817
0
  ptype = optimize_pack(tblend + 1);
818
  /* Note: Used when !ctrl.fulltbl && !ctrl.fullspd).
819
   * (Alternately defined when ctrl.fullspd)
820
   */
821
0
  out_str ("m4_define([[M4_HOOK_YYNXT_TYPE]], [[%s]])", ptype->name);
822
0
  out_dec ("m4_define([[M4_HOOK_YYNXT_SIZE]], [[%d]])", tblend + 1);
823
0
  outn ("m4_define([[M4_HOOK_YYNXT_BODY]], [[m4_dnl");
824
825
0
  yynxt_tbl = calloc (1, sizeof (struct yytbl_data));
826
0
  yytbl_data_init (yynxt_tbl, YYTD_ID_NXT);
827
0
  yynxt_tbl->td_lolen = (flex_uint32_t) (tblend + 1);
828
0
  yynxt_tbl->td_data = yynxt_data =
829
0
      calloc (yynxt_tbl->td_lolen, sizeof (flex_int32_t));
830
831
0
  for (i = 1; i <= tblend; ++i) {
832
    /* Note, the order of the following test is important.
833
     * If chk[i] is 0, then nxt[i] is undefined.
834
     */
835
0
    if (chk[i] == 0 || nxt[i] == 0)
836
0
      nxt[i] = jamstate; /* new state is the JAM state */
837
838
0
    mkdata (nxt[i]);
839
0
    yynxt_data[i] = nxt[i];
840
0
  }
841
842
0
  dataend (NULL);
843
0
  outn("]])");
844
0
  footprint += ptype->width * (tblend + 1);
845
846
0
  if (tablesext) {
847
0
    yytbl_data_compress (yynxt_tbl);
848
0
    if (yytbl_data_fwrite (&tableswr, yynxt_tbl) < 0)
849
0
      flexerror (_("Could not write yynxt_tbl"));
850
0
  }
851
0
  yytbl_data_destroy (yynxt_tbl);
852
0
  yynxt_tbl = NULL;
853
  /* End generating yy_nxt */
854
855
  /* Begin generating yy_chk */
856
0
  ptype = optimize_pack(tblend + 1);
857
0
  out_str ("m4_define([[M4_HOOK_CHK_TYPE]], [[%s]])", ptype->name);
858
0
  out_dec ("m4_define([[M4_HOOK_CHK_SIZE]], [[%d]])", tblend + 1);
859
0
  outn ("m4_define([[M4_HOOK_CHK_BODY]], [[m4_dnl");
860
  
861
0
  yychk_tbl = calloc (1, sizeof (struct yytbl_data));
862
0
  yytbl_data_init (yychk_tbl, YYTD_ID_CHK);
863
0
  yychk_tbl->td_lolen = (flex_uint32_t) (tblend + 1);
864
0
  yychk_tbl->td_data = yychk_data =
865
0
      calloc(yychk_tbl->td_lolen, sizeof (flex_int32_t));
866
867
0
  for (i = 1; i <= tblend; ++i) {
868
0
    if (chk[i] == 0)
869
0
      ++nummt;
870
871
0
    mkdata (chk[i]);
872
0
    yychk_data[i] = chk[i];
873
0
  }
874
875
0
  dataend (NULL);
876
0
  outn ("]])");
877
0
  footprint += ptype->width * (tblend + 1);
878
879
0
  if (tablesext) {
880
0
    yytbl_data_compress (yychk_tbl);
881
0
    if (yytbl_data_fwrite (&tableswr, yychk_tbl) < 0)
882
0
      flexerror (_("Could not write yychk_tbl"));
883
0
  }
884
0
  yytbl_data_destroy (yychk_tbl);
885
0
  yychk_tbl = NULL;
886
  /* End generating yy_chk */
887
888
0
  free(acc_array);
889
0
}
890
891
892
void visible_define (const char *symname)
893
0
{
894
0
  out_m4_define(symname, NULL);
895
0
  comment(symname);
896
0
  outc ('\n');
897
0
}
898
899
void visible_define_str (const char *symname, const char *val)
900
0
{
901
0
  char buf[128];
902
0
  out_m4_define(symname, val);
903
0
  snprintf(buf, sizeof(buf), "%s = %s", symname, val);
904
0
  comment(buf);
905
0
  outc ('\n');
906
0
}
907
908
void visible_define_int (const char *symname, const int val)
909
0
{
910
0
  char nbuf[24], buf[128];
911
0
  snprintf(nbuf, sizeof(nbuf), "%d", val);
912
0
  out_m4_define(symname, nbuf);
913
0
  snprintf(buf, sizeof(buf), "%s = %d", symname, val);
914
0
  comment(buf);
915
0
  outc ('\n');
916
0
}
917
918
/* make_tables - generate transition tables
919
 */
920
921
void make_tables (void)
922
0
{
923
0
  char buf[128];
924
0
  int i;
925
0
  struct yytbl_data *yynultrans_tbl = NULL;
926
927
  /* This is where we REALLY begin generating the tables. */
928
929
0
  if (ctrl.fullspd) {
930
0
    genctbl ();
931
0
    if (tablesext) {
932
0
      struct yytbl_data *tbl;
933
934
0
      tbl = mkctbl ();
935
0
      yytbl_data_compress (tbl);
936
0
      if (yytbl_data_fwrite (&tableswr, tbl) < 0)
937
0
        flexerror (_("Could not write ftbl"));
938
0
      yytbl_data_destroy (tbl);
939
940
0
      tbl = mkssltbl ();
941
0
      yytbl_data_compress (tbl);
942
0
      if (yytbl_data_fwrite (&tableswr, tbl) < 0)
943
0
        flexerror (_("Could not write ssltbl"));
944
0
      yytbl_data_destroy (tbl);
945
0
      tbl = 0;
946
947
0
      if (ctrl.useecs) {
948
0
        tbl = mkecstbl ();
949
0
        yytbl_data_compress (tbl);
950
0
        if (yytbl_data_fwrite (&tableswr, tbl) < 0)
951
0
          flexerror (_
952
0
               ("Could not write ecstbl"));
953
0
        yytbl_data_destroy (tbl);
954
0
        tbl = 0;
955
0
      }
956
0
    }
957
0
  }
958
0
  else if (ctrl.fulltbl) {
959
0
    genftbl ();
960
0
    if (tablesext) {
961
0
      struct yytbl_data *tbl;
962
963
      /* Alternately defined if !ctrl.ffullspd && !ctrl.fulltbl */
964
0
      struct packtype_t *ptype;
965
0
      tbl = mkftbl ();
966
0
      yytbl_data_compress (tbl);
967
0
      ptype = optimize_pack(tbl->td_lolen);
968
0
      out_str ("m4_define([[M4_HOOK_ACCEPT_TYPE]], [[%s]])", ptype->name);
969
0
      if (yytbl_data_fwrite (&tableswr, tbl) < 0)
970
0
        flexerror (_("Could not write ftbl"));
971
0
      yytbl_data_destroy (tbl);
972
0
      tbl = 0;
973
974
0
      if (ctrl.useecs) {
975
0
        tbl = mkecstbl ();
976
0
        yytbl_data_compress (tbl);
977
0
        if (yytbl_data_fwrite (&tableswr, tbl) < 0)
978
0
          flexerror (_
979
0
               ("Could not write ecstbl"));
980
0
        yytbl_data_destroy (tbl);
981
0
        tbl = 0;
982
0
      }
983
0
    }
984
0
  }
985
0
  else {
986
0
    gentabs ();
987
0
  }
988
989
0
  snprintf(buf, sizeof(buf), "footprint: %ld bytes\n", footprint);
990
0
  comment(buf);
991
0
  snprintf(buf, sizeof(buf), "tblend: %d\n", tblend);
992
0
  comment(buf);
993
0
  snprintf(buf, sizeof(buf), "numecs: %d\n", numecs);
994
0
  comment(buf);
995
0
  snprintf(buf, sizeof(buf), "num_rules: %d\n", num_rules);
996
0
  comment(buf);
997
0
  snprintf(buf, sizeof(buf), "lastdfa: %d\n", lastdfa);
998
0
  comment(buf);
999
0
  outc ('\n');
1000
  
1001
  // Only at this point do we know if the automaton has backups.
1002
  // Some m4 conditionals require this information.
1003
1004
0
  comment("m4 controls begin\n");
1005
1006
0
  if (num_backing_up > 0)
1007
0
    visible_define ( "M4_MODE_HAS_BACKING_UP");
1008
1009
  // These are used for NUL transitions
1010
0
  if ((num_backing_up > 0 && !reject) && (!nultrans || ctrl.fullspd || ctrl.fulltbl))
1011
0
    visible_define ( "M4_MODE_NEED_YY_CP");
1012
0
  if ((num_backing_up > 0 && !reject) && (ctrl.fullspd || ctrl.fulltbl))
1013
0
    visible_define ( "M4_MODE_NULTRANS_WRAP");
1014
1015
0
  comment("m4 controls end\n");
1016
0
  out ("\n");
1017
1018
0
  if (ctrl.do_yylineno) {
1019
1020
0
    geneoltbl ();
1021
1022
0
    if (tablesext) {
1023
0
      struct yytbl_data *tbl;
1024
1025
0
      tbl = mkeoltbl ();
1026
0
      yytbl_data_compress (tbl);
1027
0
      if (yytbl_data_fwrite (&tableswr, tbl) < 0)
1028
0
        flexerror (_("Could not write eoltbl"));
1029
0
      yytbl_data_destroy (tbl);
1030
0
      tbl = 0;
1031
0
    }
1032
0
  }
1033
1034
0
  if (nultrans) {
1035
0
    flex_int32_t *yynultrans_data = 0;
1036
1037
    /* Begin generating yy_NUL_trans */
1038
0
    out_str ("m4_define([[M4_HOOK_NULTRANS_TYPE]], [[%s]])", (ctrl.fullspd) ? "struct yy_trans_info*" : "M4_HOOK_INT32");
1039
0
    out_dec ("m4_define([[M4_HOOK_NULTRANS_SIZE]], [[%d]])", lastdfa + 1);
1040
0
    outn ("m4_define([[M4_HOOK_NULTRANS_BODY]], [[m4_dnl");
1041
1042
0
    yynultrans_tbl = calloc(1, sizeof (struct yytbl_data));
1043
0
    yytbl_data_init (yynultrans_tbl, YYTD_ID_NUL_TRANS);
1044
    // Performance kludge for C. Gives a small improvement
1045
    // in table loading time.
1046
0
    if (ctrl.fullspd && ctrl.have_state_entry_format)
1047
0
      yynultrans_tbl->td_flags |= YYTD_PTRANS;
1048
0
    yynultrans_tbl->td_lolen = (flex_uint32_t) (lastdfa + 1);
1049
0
    yynultrans_tbl->td_data = yynultrans_data =
1050
0
        calloc(yynultrans_tbl->td_lolen,
1051
0
         sizeof (flex_int32_t));
1052
1053
0
    for (i = 1; i <= lastdfa; ++i) {
1054
0
      if ((yynultrans_tbl->td_flags & YYTD_PTRANS) != 0) {
1055
        // Only works in very C-like languages  
1056
0
        out_dec ("    &yy_transition[%d],\n",
1057
0
           base[i]);
1058
0
        yynultrans_data[i] = base[i];
1059
0
      }
1060
0
      else {
1061
        // This will work anywhere
1062
0
        mkdata (nultrans[i]);
1063
0
        yynultrans_data[i] = nultrans[i];
1064
0
      }
1065
0
    }
1066
1067
0
    dataend (NULL);
1068
0
    outn("]])");
1069
0
    footprint += (lastdfa + 1) * (ctrl.fullspd ? sizeof(struct yy_trans_info *) : sizeof(int32_t));
1070
0
    if (tablesext) {
1071
0
      yytbl_data_compress (yynultrans_tbl);
1072
0
      if (yytbl_data_fwrite (&tableswr, yynultrans_tbl) <
1073
0
          0)
1074
0
        flexerror (_
1075
0
             ("Could not write yynultrans_tbl"));
1076
0
    }
1077
1078
0
    if (yynultrans_tbl != NULL) {
1079
0
      yytbl_data_destroy (yynultrans_tbl);
1080
0
      yynultrans_tbl = NULL;
1081
0
    }
1082
1083
    /* End generating yy_NUL_trans */
1084
0
  }
1085
1086
0
  if (ctrl.ddebug) {   /* Spit out table mapping rules to line numbers. */
1087
    /* Policy choice: we don't include this space
1088
     * in the table metering.
1089
     */
1090
0
    struct packtype_t *ptype = optimize_pack(num_rules);
1091
0
    out_str ("m4_define([[M4_HOOK_DEBUGTABLE_TYPE]], [[%s]])", ptype->name);
1092
0
    out_dec ("m4_define([[M4_HOOK_DEBUGTABLE_SIZE]], [[%d]])", num_rules);
1093
0
    outn ("m4_define([[M4_HOOK_DEBUGTABLE_BODY]], [[m4_dnl");
1094
1095
0
    for (i = 1; i < num_rules; ++i)
1096
0
      mkdata (rule_linenum[i]);
1097
    dataend (NULL);
1098
0
    outn("]])");
1099
0
  }
1100
0
}