home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume19 / flex2 / part06 < prev    next >
Text File  |  1989-06-21  |  28KB  |  1,137 lines

  1. Subject:  v19i060:  Flex, a fast LEX replacement, Part06/07
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Vern Paxson <vern@csam.lbl.gov>
  7. Posting-number: Volume 19, Issue 60
  8. Archive-name: flex2/part06
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 6 (of 7)."
  17. # Contents:  flex/gen.c
  18. # Wrapped by rsalz@prune.bbn.com on Thu Jun 22 19:01:54 1989
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'flex/gen.c' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'flex/gen.c'\"
  22. else
  23. echo shar: Extracting \"'flex/gen.c'\" \(25254 characters\)
  24. sed "s/^X//" >'flex/gen.c' <<'END_OF_FILE'
  25. X/* gen - actual generation (writing) of flex scanners */
  26. X
  27. X/*
  28. X * Copyright (c) 1989 The Regents of the University of California.
  29. X * All rights reserved.
  30. X *
  31. X * This code is derived from software contributed to Berkeley by
  32. X * Vern Paxson.
  33. X * 
  34. X * The United States Government has rights in this work pursuant to
  35. X * contract no. DE-AC03-76SF00098 between the United States Department of
  36. X * Energy and the University of California.
  37. X *
  38. X * Redistribution and use in source and binary forms are permitted
  39. X * provided that the above copyright notice and this paragraph are
  40. X * duplicated in all such forms and that any documentation,
  41. X * advertising materials, and other materials related to such
  42. X * distribution and use acknowledge that the software was developed
  43. X * by the University of California, Berkeley.  The name of the
  44. X * University may not be used to endorse or promote products derived
  45. X * from this software without specific prior written permission.
  46. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  47. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  48. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  49. X */
  50. X
  51. X#ifndef lint
  52. X
  53. Xstatic char copyright[] =
  54. X    "@(#) Copyright (c) 1989 The Regents of the University of California.\n";
  55. Xstatic char CR_continuation[] = "@(#) All rights reserved.\n";
  56. X
  57. Xstatic char rcsid[] =
  58. X    "@(#) $Header: gen.c,v 2.0 89/06/20 15:49:54 vern Locked $ (LBL)";
  59. X
  60. X#endif
  61. X
  62. X#include "flexdef.h"
  63. X
  64. X
  65. Xstatic int indent_level = 0; /* each level is 4 spaces */
  66. X
  67. X#define indent_up() (++indent_level)
  68. X#define indent_down() (--indent_level)
  69. X#define set_indent(indent_val) indent_level = indent_val
  70. X
  71. X
  72. X
  73. X/* indent to the current level */
  74. X
  75. Xdo_indent()
  76. X
  77. X    {
  78. X    register int i = indent_level * 4;
  79. X
  80. X    while ( i >= 8 )
  81. X    {
  82. X    putchar( '\t' );
  83. X    i -= 8;
  84. X    }
  85. X    
  86. X    while ( i > 0 )
  87. X    {
  88. X    putchar( ' ' );
  89. X    --i;
  90. X    }
  91. X    }
  92. X
  93. X
  94. X/* generate the code to keep backtracking information */
  95. X
  96. Xgen_backtracking()
  97. X
  98. X    {
  99. X    if ( reject || num_backtracking == 0 )
  100. X    return;
  101. X
  102. X    if ( fullspd )
  103. X    indent_puts( "if ( yy_current_state[-1].yy_nxt )" );
  104. X    else
  105. X    indent_puts( "if ( yy_accept[yy_current_state] )" );
  106. X
  107. X    indent_up();
  108. X    indent_puts( "{" );
  109. X    indent_puts( "yy_last_accepting_state = yy_current_state;" );
  110. X    indent_puts( "yy_last_accepting_cpos = yy_cp;" );
  111. X    indent_puts( "}" );
  112. X    indent_down();
  113. X    }
  114. X
  115. X
  116. X/* generate the code to perform the backtrack */
  117. X
  118. Xgen_bt_action()
  119. X
  120. X    {
  121. X    if ( reject || num_backtracking == 0 )
  122. X    return;
  123. X
  124. X    set_indent( 4 );
  125. X
  126. X    indent_puts( "case 0: /* must backtrack */" );
  127. X    indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" );
  128. X    indent_puts( "*yy_cp = yy_hold_char;" );
  129. X
  130. X    if ( fullspd || fulltbl )
  131. X    indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" );
  132. X    else
  133. X    /* backtracking info for compressed tables is taken \after/
  134. X     * yy_cp has been incremented for the next state
  135. X     */
  136. X    indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  137. X
  138. X    indent_puts( "yy_current_state = yy_last_accepting_state;" );
  139. X    indent_puts( "continue; /* go to \"YY_DO_BEFORE_ACTION\" */" );
  140. X    putchar( '\n' );
  141. X
  142. X    set_indent( 0 );
  143. X    }
  144. X
  145. X
  146. X/* genctbl - generates full speed compressed transition table
  147. X *
  148. X * synopsis
  149. X *     genctbl();
  150. X */
  151. X
  152. Xgenctbl()
  153. X
  154. X    {
  155. X    register int i;
  156. X    int end_of_buffer_action = num_rules + 1;
  157. X
  158. X    /* table of verify for transition and offset to next state */
  159. X    printf( "static const struct yy_trans_info yy_transition[%d] =\n",
  160. X        tblend + numecs + 1 );
  161. X    printf( "    {\n" );
  162. X    
  163. X    /* We want the transition to be represented as the offset to the
  164. X     * next state, not the actual state number, which is what it currently is.
  165. X     * The offset is base[nxt[i]] - base[chk[i]].  That's just the
  166. X     * difference between the starting points of the two involved states
  167. X     * (to - from).
  168. X     *
  169. X     * first, though, we need to find some way to put in our end-of-buffer
  170. X     * flags and states.  We do this by making a state with absolutely no
  171. X     * transitions.  We put it at the end of the table.
  172. X     */
  173. X    /* at this point, we're guaranteed that there's enough room in nxt[]
  174. X     * and chk[] to hold tblend + numecs entries.  We need just two slots.
  175. X     * One for the action and one for the end-of-buffer transition.  We
  176. X     * now *assume* that we're guaranteed the only character we'll try to
  177. X     * index this nxt/chk pair with is EOB, i.e., 0, so we don't have to
  178. X     * make sure there's room for jam entries for other characters.
  179. X     */
  180. X
  181. X    base[lastdfa + 1] = tblend + 2;
  182. X    nxt[tblend + 1] = end_of_buffer_action;
  183. X    chk[tblend + 1] = numecs + 1;
  184. X    chk[tblend + 2] = 1; /* anything but EOB */
  185. X    nxt[tblend + 2] = 0; /* so that "make test" won't show arb. differences */
  186. X
  187. X    /* make sure every state has a end-of-buffer transition and an action # */
  188. X    for ( i = 0; i <= lastdfa; ++i )
  189. X    {
  190. X    register int anum = dfaacc[i].dfaacc_state;
  191. X
  192. X    chk[base[i]] = EOB_POSITION;
  193. X    chk[base[i] - 1] = ACTION_POSITION;
  194. X    nxt[base[i] - 1] = anum;    /* action number */
  195. X    }
  196. X
  197. X    dataline = 0;
  198. X    datapos = 0;
  199. X
  200. X    for ( i = 0; i <= tblend; ++i )
  201. X    {
  202. X    if ( chk[i] == EOB_POSITION )
  203. X        transition_struct_out( 0, base[lastdfa + 1] - i );
  204. X
  205. X    else if ( chk[i] == ACTION_POSITION )
  206. X        transition_struct_out( 0, nxt[i] );
  207. X
  208. X    else if ( chk[i] > numecs || chk[i] == 0 )
  209. X        transition_struct_out( 0, 0 );        /* unused slot */
  210. X
  211. X    else    /* verify, transition */
  212. X        transition_struct_out( chk[i], base[nxt[i]] - (i - chk[i]) );
  213. X    }
  214. X
  215. X
  216. X    /* here's the final, end-of-buffer state */
  217. X    transition_struct_out( chk[tblend + 1], nxt[tblend + 1] );
  218. X    transition_struct_out( chk[tblend + 2], nxt[tblend + 2] );
  219. X
  220. X    printf( "    };\n" );
  221. X    printf( "\n" );
  222. X
  223. X    /* table of pointers to start states */
  224. X    printf( "static const struct yy_trans_info *yy_start_state_list[%d] =\n",
  225. X    lastsc * 2 + 1 );
  226. X    printf( "    {\n" );
  227. X
  228. X    for ( i = 0; i <= lastsc * 2; ++i )
  229. X    printf( "    &yy_transition[%d],\n", base[i] );
  230. X
  231. X    printf( "    };\n" );
  232. X
  233. X    if ( useecs )
  234. X    genecs();
  235. X    }
  236. X
  237. X
  238. X/* generate equivalence-class tables */
  239. X
  240. Xgenecs()
  241. X
  242. X    {
  243. X    register int i, j;
  244. X    static char C_char_decl[] = "static const char %s[%d] =\n    {   0,\n";
  245. X    int numrows;
  246. X    char clower();
  247. X
  248. X    printf( C_char_decl, ECARRAY, CSIZE + 1 );
  249. X
  250. X    for ( i = 1; i <= CSIZE; ++i )
  251. X    {
  252. X    if ( caseins && (i >= 'A') && (i <= 'Z') )
  253. X        ecgroup[i] = ecgroup[clower( i )];
  254. X
  255. X    ecgroup[i] = abs( ecgroup[i] );
  256. X    mkdata( ecgroup[i] );
  257. X    }
  258. X
  259. X    dataend();
  260. X
  261. X    if ( trace )
  262. X    {
  263. X    fputs( "\n\nEquivalence Classes:\n\n", stderr );
  264. X
  265. X    numrows = (CSIZE + 1) / 8;
  266. X
  267. X    for ( j = 1; j <= numrows; ++j )
  268. X        {
  269. X        for ( i = j; i <= CSIZE; i = i + numrows )
  270. X        {
  271. X        char *readable_form();
  272. X
  273. X        fprintf( stderr, "%4s = %-2d",
  274. X             readable_form( i ), ecgroup[i] );
  275. X
  276. X        putc( ' ', stderr );
  277. X        }
  278. X
  279. X        putc( '\n', stderr );
  280. X        }
  281. X    }
  282. X    }
  283. X
  284. X
  285. X/* generate the code to find the action number */
  286. X
  287. Xgen_find_action()
  288. X
  289. X    {
  290. X    if ( fullspd )
  291. X    indent_puts( "yy_act = yy_current_state[-1].yy_nxt;" );
  292. X
  293. X    else if ( fulltbl )
  294. X    indent_puts( "yy_act = yy_accept[yy_current_state];" );
  295. X
  296. X    else if ( reject )
  297. X    {
  298. X    indent_puts( "yy_current_state = *--yy_state_ptr;" );
  299. X    indent_puts( "yy_lp = yy_accept[yy_current_state];" );
  300. X
  301. X    puts( "find_rule: /* we branch to this label when backtracking */" );
  302. X
  303. X    indent_puts( "for ( ; ; ) /* until we find what rule we matched */" );
  304. X
  305. X    indent_up();
  306. X
  307. X    indent_puts( "{" );
  308. X
  309. X    indent_puts( "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" );
  310. X    indent_up();
  311. X    indent_puts( "{" );
  312. X    indent_puts( "yy_act = yy_acclist[yy_lp];" );
  313. X
  314. X    if ( variable_trailing_context_rules )
  315. X        {
  316. X        indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" );
  317. X        indent_puts( "     yy_looking_for_trail_begin )" );
  318. X        indent_up();
  319. X        indent_puts( "{" );
  320. X
  321. X        indent_puts( "if ( yy_act == yy_looking_for_trail_begin )" );
  322. X        indent_up();
  323. X        indent_puts( "{" );
  324. X        indent_puts( "yy_looking_for_trail_begin = 0;" );
  325. X        indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" );
  326. X        indent_puts( "break;" );
  327. X        indent_puts( "}" );
  328. X        indent_down();
  329. X
  330. X        indent_puts( "}" );
  331. X        indent_down();
  332. X
  333. X        indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" );
  334. X        indent_up();
  335. X        indent_puts( "{" );
  336. X        indent_puts(
  337. X        "yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" );
  338. X        indent_puts(
  339. X        "yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" );
  340. X
  341. X        if ( real_reject )
  342. X        {
  343. X        /* remember matched text in case we back up due to REJECT */
  344. X        indent_puts( "yy_full_match = yy_cp;" );
  345. X        indent_puts( "yy_full_state = yy_state_ptr;" );
  346. X        indent_puts( "yy_full_lp = yy_lp;" );
  347. X        }
  348. X
  349. X        indent_puts( "}" );
  350. X        indent_down();
  351. X
  352. X        indent_puts( "else" );
  353. X        indent_up();
  354. X        indent_puts( "{" );
  355. X        indent_puts( "yy_full_match = yy_cp;" );
  356. X        indent_puts( "yy_full_state = yy_state_ptr;" );
  357. X        indent_puts( "yy_full_lp = yy_lp;" );
  358. X        indent_puts( "break;" );
  359. X        indent_puts( "}" );
  360. X        indent_down();
  361. X
  362. X        indent_puts( "++yy_lp;" );
  363. X        indent_puts( "goto find_rule;" );
  364. X        }
  365. X
  366. X    else
  367. X        {
  368. X        /* remember matched text in case we back up due to trailing context
  369. X         * plus REJECT
  370. X         */
  371. X        indent_up();
  372. X        indent_puts( "{" );
  373. X        indent_puts( "yy_full_match = yy_cp;" );
  374. X        indent_puts( "break;" );
  375. X        indent_puts( "}" );
  376. X        indent_down();
  377. X        }
  378. X
  379. X    indent_puts( "}" );
  380. X    indent_down();
  381. X
  382. X    indent_puts( "--yy_cp;" );
  383. X
  384. X    /* we could consolidate the following two lines with those at
  385. X     * the beginning, but at the cost of complaints that we're
  386. X     * branching inside a loop
  387. X     */
  388. X    indent_puts( "yy_current_state = *--yy_state_ptr;" );
  389. X    indent_puts( "yy_lp = yy_accept[yy_current_state];" );
  390. X
  391. X    indent_puts( "}" );
  392. X
  393. X    indent_down();
  394. X    }
  395. X
  396. X    else
  397. X    /* compressed */
  398. X    indent_puts( "yy_act = yy_accept[yy_current_state];" );
  399. X    }
  400. X
  401. X
  402. X/* genftbl - generates full transition table
  403. X *
  404. X * synopsis
  405. X *     genftbl();
  406. X */
  407. X
  408. Xgenftbl()
  409. X
  410. X    {
  411. X    register int i;
  412. X    int end_of_buffer_action = num_rules + 1;
  413. X
  414. X    /* *everything* is done in terms of arrays starting at 1, so provide
  415. X     * a null entry for the zero element of all C arrays
  416. X     */
  417. X    static char C_short_decl[] =
  418. X    "static const short int %s[%d] =\n    {   0,\n";
  419. X
  420. X    printf( C_short_decl, ALIST, lastdfa + 1 );
  421. X
  422. X
  423. X    dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
  424. X
  425. X    for ( i = 1; i <= lastdfa; ++i )
  426. X    {
  427. X    register int anum = dfaacc[i].dfaacc_state;
  428. X
  429. X    mkdata( anum );
  430. X
  431. X    if ( trace && anum )
  432. X        fprintf( stderr, "state # %d accepts: [%d]\n", i, anum );
  433. X    }
  434. X
  435. X    dataend();
  436. X
  437. X    if ( useecs )
  438. X    genecs();
  439. X
  440. X    /* don't have to dump the actual full table entries - they were created
  441. X     * on-the-fly
  442. X     */
  443. X    }
  444. X
  445. X
  446. X/* generate the code to find the next compressed-table state */
  447. X
  448. Xgen_next_compressed_state()
  449. X
  450. X    {
  451. X    char *char_map = useecs ? "yy_ec[*yy_cp]" : "*yy_cp";
  452. X
  453. X    indent_put2s( "register char yy_c = %s;", char_map );
  454. X
  455. X    /* save the backtracking info \before/ computing the next state
  456. X     * because we always compute one more state than needed - we
  457. X     * always proceed until we reach a jam state
  458. X     */
  459. X    gen_backtracking();
  460. X
  461. X    indent_puts(
  462. X    "while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" );
  463. X    indent_up();
  464. X    indent_puts( "{" );
  465. X    indent_puts( "yy_current_state = yy_def[yy_current_state];" );
  466. X
  467. X    if ( usemecs )
  468. X    {
  469. X    /* we've arrange it so that templates are never chained
  470. X     * to one another.  This means we can afford make a
  471. X     * very simple test to see if we need to convert to
  472. X     * yy_c's meta-equivalence class without worrying
  473. X     * about erroneously looking up the meta-equivalence
  474. X     * class twice
  475. X     */
  476. X    do_indent();
  477. X    /* lastdfa + 2 is the beginning of the templates */
  478. X    printf( "if ( yy_current_state >= %d )\n", lastdfa + 2 );
  479. X
  480. X    indent_up();
  481. X    indent_puts( "yy_c = yy_meta[yy_c];" );
  482. X    indent_down();
  483. X    }
  484. X
  485. X    indent_puts( "}" );
  486. X    indent_down();
  487. X
  488. X    indent_puts(
  489. X    "yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];" );
  490. X    }
  491. X
  492. X
  493. X/* generate the code to find the next match */
  494. X
  495. Xgen_next_match()
  496. X
  497. X    { /* NOTE - changes in here should be reflected in get_next_state() */
  498. X    char *char_map = useecs ? "yy_ec[*yy_cp]" : "*yy_cp";
  499. X    char *char_map_2 = useecs ? "yy_ec[*++yy_cp]" : "*++yy_cp";
  500. X    
  501. X    if ( fulltbl )
  502. X    {
  503. X    indent_put2s(
  504. X        "while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )",
  505. X        char_map );
  506. X
  507. X    indent_up();
  508. X
  509. X    if ( num_backtracking > 0 )
  510. X        {
  511. X        indent_puts( "{" );
  512. X        gen_backtracking();
  513. X        putchar( '\n' );
  514. X        }
  515. X
  516. X    indent_puts( "++yy_cp;" );
  517. X
  518. X    if ( num_backtracking > 0 )
  519. X        indent_puts( "}" );
  520. X
  521. X    indent_down();
  522. X
  523. X    putchar( '\n' );
  524. X    indent_puts( "yy_current_state = -yy_current_state;" );
  525. X    }
  526. X
  527. X    else if ( fullspd )
  528. X    {
  529. X    indent_puts( "{" );
  530. X    indent_puts( "register struct yy_trans_info *yy_trans_info;\n" );
  531. X    indent_puts( "register char yy_c;\n" );
  532. X    indent_put2s( "for ( yy_c = %s;", char_map );
  533. X    indent_puts(
  534. X    "      (yy_trans_info = &yy_current_state[yy_c])->yy_verify == yy_c;" );
  535. X    indent_put2s( "      yy_c = %s )", char_map_2 );
  536. X
  537. X    indent_up();
  538. X
  539. X    if ( num_backtracking > 0 )
  540. X        indent_puts( "{" );
  541. X
  542. X    indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );
  543. X
  544. X    if ( num_backtracking > 0 )
  545. X        {
  546. X        putchar( '\n' );
  547. X        gen_backtracking();
  548. X        indent_puts( "}" );
  549. X        }
  550. X
  551. X    indent_down();
  552. X    indent_puts( "}" );
  553. X    }
  554. X
  555. X    else
  556. X    { /* compressed */
  557. X    indent_puts( "do" );
  558. X
  559. X    indent_up();
  560. X    indent_puts( "{" );
  561. X
  562. X    gen_next_state();
  563. X
  564. X    indent_puts( "++yy_cp;" );
  565. X
  566. X    indent_puts( "}" );
  567. X    indent_down();
  568. X
  569. X    do_indent();
  570. X
  571. X    if ( interactive )
  572. X        printf( "while ( yy_base[yy_current_state] != %d );\n", jambase );
  573. X    else
  574. X        printf( "while ( yy_current_state != %d );\n", jamstate );
  575. X
  576. X    if ( ! reject && ! interactive )
  577. X        {
  578. X        /* do the guaranteed-needed backtrack to figure out the match */
  579. X        indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  580. X        indent_puts( "yy_current_state = yy_last_accepting_state;" );
  581. X        }
  582. X    }
  583. X    }
  584. X
  585. X
  586. X/* generate the code to find the next state */
  587. X
  588. Xgen_next_state()
  589. X
  590. X    { /* NOTE - changes in here should be reflected in get_next_match() */
  591. X    char *char_map = useecs ? "yy_ec[*yy_cp]" : "*yy_cp";
  592. X    
  593. X    if ( fulltbl )
  594. X    {
  595. X    indent_put2s( "yy_current_state = yy_nxt[yy_current_state][%s];", 
  596. X        char_map );
  597. X    gen_backtracking();
  598. X    }
  599. X
  600. X    else if ( fullspd )
  601. X    {
  602. X    indent_put2s( "yy_current_state += yy_current_state[%s].yy_nxt;",
  603. X        char_map );
  604. X    gen_backtracking();
  605. X    }
  606. X
  607. X    else
  608. X    {
  609. X    gen_next_compressed_state();
  610. X
  611. X    if ( reject )
  612. X        indent_puts( "*yy_state_ptr++ = yy_current_state;" );
  613. X    }
  614. X    }
  615. X
  616. X
  617. X/* generate the code to find the start state */
  618. X
  619. Xgen_start_state()
  620. X
  621. X    {
  622. X    if ( fullspd )
  623. X    indent_put2s( "yy_current_state = yy_start_state_list[yy_start%s];",
  624. X        bol_needed ? " + (yy_bp[-1] == '\\n' ? 1 : 0)" : "" );
  625. X
  626. X    else
  627. X    {
  628. X    indent_puts( "yy_current_state = yy_start;" );
  629. X
  630. X    if ( bol_needed )
  631. X        {
  632. X        indent_puts( "if ( yy_bp[-1] == '\\n' )" );
  633. X        indent_up();
  634. X        indent_puts( "++yy_current_state;" );
  635. X        indent_down();
  636. X        }
  637. X
  638. X    if ( reject )
  639. X        {
  640. X        /* set up for storing up states */
  641. X        indent_puts( "yy_state_ptr = yy_state_buf;" );
  642. X        indent_puts( "*yy_state_ptr++ = yy_current_state;" );
  643. X        }
  644. X    }
  645. X    }
  646. X
  647. X
  648. X/* gentabs - generate data statements for the transition tables
  649. X *
  650. X * synopsis
  651. X *    gentabs();
  652. X */
  653. X
  654. Xgentabs()
  655. X
  656. X    {
  657. X    int i, j, k, *accset, nacc, *acc_array, total_states;
  658. X    int end_of_buffer_action = num_rules + 1;
  659. X
  660. X    /* *everything* is done in terms of arrays starting at 1, so provide
  661. X     * a null entry for the zero element of all C arrays
  662. X     */
  663. X    static char C_long_decl[] =
  664. X    "static const long int %s[%d] =\n    {   0,\n";
  665. X    static char C_short_decl[] =
  666. X    "static const short int %s[%d] =\n    {   0,\n";
  667. X    static char C_char_decl[] =
  668. X    "static const char %s[%d] =\n    {   0,\n";
  669. X
  670. X    acc_array = allocate_integer_array( current_max_dfas );
  671. X    nummt = 0;
  672. X
  673. X    /* the compressed table format jams by entering the "jam state",
  674. X     * losing information about the previous state in the process.
  675. X     * In order to recover the previous state, we effectively need
  676. X     * to keep backtracking information.
  677. X     */
  678. X    ++num_backtracking;
  679. X
  680. X    if ( reject )
  681. X    {
  682. X    /* write out accepting list and pointer list
  683. X     *
  684. X     * first we generate the ACCEPT array.  In the process, we compute
  685. X     * the indices that will go into the ALIST array, and save the
  686. X     * indices in the dfaacc array
  687. X     */
  688. X    int EOB_accepting_list[2];
  689. X
  690. X    printf( C_short_decl, ACCEPT, max( numas, 1 ) + 1 );
  691. X    
  692. X    /* set up accepting structures for the End Of Buffer state */
  693. X    EOB_accepting_list[0] = 0;
  694. X    EOB_accepting_list[1] = end_of_buffer_action;
  695. X    accsiz[end_of_buffer_state] = 1;
  696. X    dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list;
  697. X
  698. X    j = 1;    /* index into ACCEPT array */
  699. X
  700. X    for ( i = 1; i <= lastdfa; ++i )
  701. X        {
  702. X        acc_array[i] = j;
  703. X
  704. X        if ( accsiz[i] != 0 )
  705. X        {
  706. X        accset = dfaacc[i].dfaacc_set;
  707. X        nacc = accsiz[i];
  708. X
  709. X        if ( trace )
  710. X            fprintf( stderr, "state # %d accepts: ", i );
  711. X
  712. X        for ( k = 1; k <= nacc; ++k )
  713. X            {
  714. X            int accnum = accset[k];
  715. X
  716. X            ++j;
  717. X
  718. X            if ( variable_trailing_context_rules &&
  719. X             ! (accnum & YY_TRAILING_HEAD_MASK) &&
  720. X             accnum > 0 &&
  721. X             rule_type[accnum] == RULE_VARIABLE )
  722. X            {
  723. X            /* special hack to flag accepting number as part
  724. X             * of trailing context rule
  725. X             */
  726. X            accnum |= YY_TRAILING_MASK;
  727. X            }
  728. X
  729. X            mkdata( accnum );
  730. X
  731. X            if ( trace )
  732. X            {
  733. X            fprintf( stderr, "[%d]", accset[k] );
  734. X
  735. X            if ( k < nacc )
  736. X                fputs( ", ", stderr );
  737. X            else
  738. X                putc( '\n', stderr );
  739. X            }
  740. X            }
  741. X        }
  742. X        }
  743. X
  744. X    /* add accepting number for the "jam" state */
  745. X    acc_array[i] = j;
  746. X
  747. X    dataend();
  748. X    }
  749. X
  750. X    else
  751. X    {
  752. X    dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
  753. X
  754. X    for ( i = 1; i <= lastdfa; ++i )
  755. X        acc_array[i] = dfaacc[i].dfaacc_state;
  756. X
  757. X    /* add accepting number for jam state */
  758. X    acc_array[i] = 0;
  759. X    }
  760. X
  761. X    /* spit out ALIST array.  If we're doing "reject", it'll be pointers
  762. X     * into the ACCEPT array.  Otherwise it's actual accepting numbers.
  763. X     * In either case, we just dump the numbers.
  764. X     */
  765. X
  766. X    /* "lastdfa + 2" is the size of ALIST; includes room for C arrays
  767. X     * beginning at 0 and for "jam" state
  768. X     */
  769. X    k = lastdfa + 2;
  770. X
  771. X    if ( reject )
  772. X    /* we put a "cap" on the table associating lists of accepting
  773. X     * numbers with state numbers.  This is needed because we tell
  774. X     * where the end of an accepting list is by looking at where
  775. X     * the list for the next state starts.
  776. X     */
  777. X    ++k;
  778. X
  779. X    printf( C_short_decl, ALIST, k );
  780. X
  781. X    for ( i = 1; i <= lastdfa; ++i )
  782. X    {
  783. X    mkdata( acc_array[i] );
  784. X
  785. X    if ( ! reject && trace && acc_array[i] )
  786. X        fprintf( stderr, "state # %d accepts: [%d]\n", i, acc_array[i] );
  787. X    }
  788. X
  789. X    /* add entry for "jam" state */
  790. X    mkdata( acc_array[i] );
  791. X
  792. X    if ( reject )
  793. X    /* add "cap" for the list */
  794. X    mkdata( acc_array[i] );
  795. X
  796. X    dataend();
  797. X
  798. X    if ( useecs )
  799. X    genecs();
  800. X
  801. X    if ( usemecs )
  802. X    {
  803. X    /* write out meta-equivalence classes (used to index templates with) */
  804. X
  805. X    if ( trace )
  806. X        fputs( "\n\nMeta-Equivalence Classes:\n", stderr );
  807. X
  808. X    printf( C_char_decl, MATCHARRAY, numecs + 1 );
  809. X
  810. X    for ( i = 1; i <= numecs; ++i )
  811. X        {
  812. X        if ( trace )
  813. X        fprintf( stderr, "%d = %d\n", i, abs( tecbck[i] ) );
  814. X
  815. X        mkdata( abs( tecbck[i] ) );
  816. X        }
  817. X
  818. X    dataend();
  819. X    }
  820. X
  821. X    total_states = lastdfa + numtemps;
  822. X
  823. X    printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl,
  824. X        BASEARRAY, total_states + 1 );
  825. X
  826. X    for ( i = 1; i <= lastdfa; ++i )
  827. X    {
  828. X    register int d = def[i];
  829. X
  830. X    if ( base[i] == JAMSTATE )
  831. X        base[i] = jambase;
  832. X
  833. X    if ( d == JAMSTATE )
  834. X        def[i] = jamstate;
  835. X
  836. X    else if ( d < 0 )
  837. X        {
  838. X        /* template reference */
  839. X        ++tmpuses;
  840. X        def[i] = lastdfa - d + 1;
  841. X        }
  842. X
  843. X    mkdata( base[i] );
  844. X    }
  845. X
  846. X    /* generate jam state's base index */
  847. X    mkdata( base[i] );
  848. X
  849. X    for ( ++i /* skip jam state */; i <= total_states; ++i )
  850. X    {
  851. X    mkdata( base[i] );
  852. X    def[i] = jamstate;
  853. X    }
  854. X
  855. X    dataend();
  856. X
  857. X    printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl,
  858. X        DEFARRAY, total_states + 1 );
  859. X
  860. X    for ( i = 1; i <= total_states; ++i )
  861. X    mkdata( def[i] );
  862. X
  863. X    dataend();
  864. X
  865. X    printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl,
  866. X        NEXTARRAY, tblend + 1 );
  867. X
  868. X    for ( i = 1; i <= tblend; ++i )
  869. X    {
  870. X    if ( nxt[i] == 0 || chk[i] == 0 )
  871. X        nxt[i] = jamstate;    /* new state is the JAM state */
  872. X
  873. X    mkdata( nxt[i] );
  874. X    }
  875. X
  876. X    dataend();
  877. X
  878. X    printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl,
  879. X        CHECKARRAY, tblend + 1 );
  880. X
  881. X    for ( i = 1; i <= tblend; ++i )
  882. X    {
  883. X    if ( chk[i] == 0 )
  884. X        ++nummt;
  885. X
  886. X    mkdata( chk[i] );
  887. X    }
  888. X
  889. X    dataend();
  890. X    }
  891. X
  892. X
  893. X/* write out a formatted string (with a secondary string argument) at the
  894. X * current indentation level, adding a final newline
  895. X */
  896. X
  897. Xindent_put2s( fmt, arg )
  898. Xchar fmt[], arg[];
  899. X
  900. X    {
  901. X    do_indent();
  902. X    printf( fmt, arg );
  903. X    putchar( '\n' );
  904. X    }
  905. X
  906. X
  907. X/* write out a string at the current indentation level, adding a final
  908. X * newline
  909. X */
  910. X
  911. Xindent_puts( str )
  912. Xchar str[];
  913. X
  914. X    {
  915. X    do_indent();
  916. X    puts( str );
  917. X    }
  918. X
  919. X
  920. X/* make_tables - generate transition tables
  921. X *
  922. X * synopsis
  923. X *     make_tables();
  924. X *
  925. X * Generates transition tables and finishes generating output file
  926. X */
  927. X
  928. Xmake_tables()
  929. X
  930. X    {
  931. X    register int i;
  932. X    int did_eof_rule = false;
  933. X
  934. X    printf( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 );
  935. X
  936. X    if ( fullspd )
  937. X    { /* need to define the transet type as a size large
  938. X       * enough to hold the biggest offset
  939. X       */
  940. X    int total_table_size = tblend + numecs + 1;
  941. X    char *trans_offset_type =
  942. X        total_table_size > MAX_SHORT ? "long" : "short";
  943. X
  944. X    set_indent( 0 );
  945. X    indent_puts( "struct yy_trans_info" );
  946. X    indent_up();
  947. X        indent_puts( "{" );
  948. X        indent_puts( "short yy_verify;" );
  949. X
  950. X        /* in cases where its sister yy_verify *is* a "yes, there is a
  951. X     * transition", yy_nxt is the offset (in records) to the next state.
  952. X     * In most cases where there is no transition, the value of yy_nxt
  953. X     * is irrelevant.  If yy_nxt is the -1th  record of a state, though,
  954. X     * then yy_nxt is the action number for that state
  955. X         */
  956. X
  957. X        indent_put2s( "%s yy_nxt;", trans_offset_type );
  958. X        indent_puts( "};" );
  959. X    indent_down();
  960. X
  961. X    indent_puts( "typedef struct yy_trans_info *yy_state_type;" );
  962. X    }
  963. X    
  964. X    else
  965. X    indent_puts( "typedef int yy_state_type;" );
  966. X
  967. X    if ( fullspd )
  968. X    genctbl();
  969. X
  970. X    else if ( fulltbl )
  971. X    genftbl();
  972. X
  973. X    else
  974. X    gentabs();
  975. X
  976. X    if ( reject )
  977. X    {
  978. X    /* declare state buffer variables */
  979. X    puts( "yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" );
  980. X    puts( "char *yy_full_match;" );
  981. X    puts( "int yy_lp;" );
  982. X
  983. X    if ( variable_trailing_context_rules )
  984. X        {
  985. X        puts( "int yy_looking_for_trail_begin = 0;" );
  986. X        puts( "int yy_full_lp;" );
  987. X        puts( "int *yy_full_state;" );
  988. X        printf( "#define YY_TRAILING_MASK 0x%x\n", YY_TRAILING_MASK );
  989. X        printf( "#define YY_TRAILING_HEAD_MASK 0x%x\n",
  990. X            YY_TRAILING_HEAD_MASK );
  991. X        }
  992. X
  993. X    puts( "#define REJECT \\" );
  994. X        puts( "{ \\" );
  995. X        puts(
  996. X    "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" );
  997. X        puts(
  998. X        "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" );
  999. X
  1000. X    if ( variable_trailing_context_rules )
  1001. X        {
  1002. X        puts( "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" );
  1003. X        puts(
  1004. X        "yy_state_ptr = yy_full_state; /* restore orig. state */ \\" );
  1005. X        puts(
  1006. X        "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" );
  1007. X        }
  1008. X
  1009. X        puts( "++yy_lp; \\" );
  1010. X        puts( "goto find_rule; \\" );
  1011. X        puts( "}" );
  1012. X    }
  1013. X    
  1014. X    else
  1015. X    {
  1016. X    puts( "/* the intent behind this definition is that it'll catch" );
  1017. X    puts( " * any uses of REJECT which flex missed" );
  1018. X    puts( " */" );
  1019. X    puts( "#define REJECT reject_used_but_not_detected" );
  1020. X    }
  1021. X    
  1022. X    if ( yymore_used )
  1023. X    {
  1024. X    indent_puts( "static char *yy_more_pos = (char *) 0;" );
  1025. X    indent_puts( "#define yymore() (yy_more_pos = yy_bp)" );
  1026. X    }
  1027. X    
  1028. X    else
  1029. X    indent_puts( "#define yymore() yymore_used_but_not_detected" );
  1030. X
  1031. X
  1032. X    skelout();
  1033. X
  1034. X    (void) fclose( temp_action_file );
  1035. X    temp_action_file = fopen( action_file_name, "r" );
  1036. X
  1037. X    /* copy prolog from action_file to output file */
  1038. X    action_out();
  1039. X
  1040. X    skelout();
  1041. X
  1042. X    set_indent( 2 );
  1043. X
  1044. X    if ( yymore_used )
  1045. X    {
  1046. X    indent_puts( "if ( yy_more_pos )" );
  1047. X    indent_up();
  1048. X    indent_puts( "{" );
  1049. X    indent_puts( "yy_bp = yy_more_pos;" );
  1050. X    indent_puts( "yy_more_pos = (char *) 0;" );
  1051. X    indent_puts( "}" );
  1052. X    indent_down();
  1053. X    indent_puts( "else" );
  1054. X    indent_up();
  1055. X    indent_puts( "yy_bp = yy_cp;" );
  1056. X    indent_down();
  1057. X    }
  1058. X
  1059. X    else
  1060. X    indent_puts( "yy_bp = yy_cp;" );
  1061. X
  1062. X    skelout();
  1063. X
  1064. X    gen_start_state();
  1065. X    gen_next_match();
  1066. X
  1067. X    skelout();
  1068. X    set_indent( 3 );
  1069. X    gen_find_action();
  1070. X
  1071. X    /* copy actions from action_file to output file */
  1072. X    skelout();
  1073. X    indent_up();
  1074. X    gen_bt_action();
  1075. X    action_out();
  1076. X
  1077. X    /* generate cases for any missing EOF rules */
  1078. X    for ( i = 1; i <= lastsc; ++i )
  1079. X    if ( ! sceof[i] )
  1080. X        {
  1081. X        do_indent();
  1082. X        printf( "case YY_STATE_EOF(%s):\n", scname[i] );
  1083. X        did_eof_rule = true;
  1084. X        }
  1085. X    
  1086. X    if ( did_eof_rule )
  1087. X    {
  1088. X    indent_up();
  1089. X    indent_puts( "yyterminate();" );
  1090. X    indent_down();
  1091. X    }
  1092. X
  1093. X
  1094. X    /* generate code for yy_get_previous_state() */
  1095. X    set_indent( 1 );
  1096. X    skelout();
  1097. X
  1098. X    if ( bol_needed )
  1099. X    indent_puts( "register char *yy_bp = yytext;\n" );
  1100. X
  1101. X    gen_start_state();
  1102. X
  1103. X    set_indent( 2 );
  1104. X    skelout();
  1105. X    gen_next_state();
  1106. X
  1107. X    skelout();
  1108. X
  1109. X    /* copy remainder of input to output */
  1110. X
  1111. X    line_directive_out( stdout );
  1112. X    (void) flexscan(); /* copy remainder of input to output */
  1113. X    }
  1114. END_OF_FILE
  1115. if test 25254 -ne `wc -c <'flex/gen.c'`; then
  1116.     echo shar: \"'flex/gen.c'\" unpacked with wrong size!
  1117. fi
  1118. # end of 'flex/gen.c'
  1119. fi
  1120. echo shar: End of archive 6 \(of 7\).
  1121. cp /dev/null ark6isdone
  1122. MISSING=""
  1123. for I in 1 2 3 4 5 6 7 ; do
  1124.     if test ! -f ark${I}isdone ; then
  1125.     MISSING="${MISSING} ${I}"
  1126.     fi
  1127. done
  1128. if test "${MISSING}" = "" ; then
  1129.     echo You have unpacked all 7 archives.
  1130.     rm -f ark[1-9]isdone
  1131. else
  1132.     echo You still need to unpack the following archives:
  1133.     echo "        " ${MISSING}
  1134. fi
  1135. ##  End of shell archive.
  1136. exit 0
  1137.