home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 405_01 / flexpp / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-20  |  26.6 KB  |  987 lines

  1. /* flex - tool to generate fast lexical analyzers */
  2.  
  3. /*-
  4.  * Copyright (c) 1990 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Vern Paxson.
  9.  * 
  10.  * The United States Government has rights in this work pursuant
  11.  * to contract no. DE-AC03-76SF00098 between the United States
  12.  * Department of Energy and the University of California.
  13.  *
  14.  * Redistribution and use in source and binary forms are permitted provided
  15.  * that: (1) source distributions retain this entire copyright notice and
  16.  * comment, and (2) distributions including binaries display the following
  17.  * acknowledgement:  ``This product includes software developed by the
  18.  * University of California, Berkeley and its contributors'' in the
  19.  * documentation or other materials provided with the distribution and in
  20.  * all advertising materials mentioning features or use of this software.
  21.  * Neither the name of the University nor the names of its contributors may
  22.  * be used to endorse or promote products derived from this software without
  23.  * specific prior written permission.
  24.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  25.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  26.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  27.  */
  28.  
  29. #ifndef lint
  30. char copyright[] =
  31. "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
  32.  All rights reserved.\n";
  33. #endif /* not lint */
  34.  
  35. #ifndef lint
  36. static char rcsid[] =
  37.     "@(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/main.c,v 2.9 90/06/27 23:48:24 vern Exp $ (LBL)";
  38. #endif
  39.  
  40.  
  41. #include "flexdef.h"
  42.  
  43. static char flex_version[] = "2.3.8-4 (flex++), based on 2.3.8 and modified by coetmeur@icdc.fr for c++";
  44.  
  45. /* declare functions that have forward references */
  46.  
  47. void flexinit PROTO((int, char**));
  48. void readin PROTO(());
  49. void set_up_initial_allocations PROTO(());
  50.  
  51.  
  52. /* these globals are all defined and commented in flexdef.h */
  53. int printstats, syntaxerror, eofseen, ddebug, trace, spprdflt;
  54. int interactive, caseins, useecs, fulltbl, usemecs;
  55. int fullspd, gen_line_dirs, performance_report, backtrack_report, csize;
  56. int yymore_used, reject, real_reject, continued_action;
  57. int yymore_really_used, reject_really_used;
  58. int datapos, dataline, linenum;
  59. FILE *skelfile = NULL;
  60. char *infilename = NULL;
  61. char *headerfilename=NULL;
  62. FILE *headerfile=NULL;
  63. char *outputfilename=NULL;
  64. char *includefilename=NULL;
  65. char *skelheaderfilename=NULL;
  66. FILE *skelheaderfile=NULL;
  67. int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE];
  68. int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp;
  69. int current_mns, num_rules, current_max_rules, lastnfa;
  70. int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2;
  71. int *accptnum, *assoc_rule, *state_type, *rule_type, *rule_linenum;
  72. int current_state_type;
  73. int variable_trailing_context_rules;
  74. int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP];
  75. int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE];
  76. int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, tecfwd[CSIZE + 1];
  77. int tecbck[CSIZE + 1];
  78. int *xlation = (int *) 0;
  79. int num_xlations;
  80. int lastsc, current_max_scs, *scset, *scbol, *scxclu, *sceof, *actvsc;
  81. char **scname;
  82. int current_max_dfa_size, current_max_xpairs;
  83. int current_max_template_xpairs, current_max_dfas;
  84. int lastdfa, *nxt, *chk, *tnxt;
  85. int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz;
  86. union dfaacc_union *dfaacc;
  87. int *accsiz, *dhash, numas;
  88. int numsnpairs, jambase, jamstate;
  89. int lastccl, current_maxccls, *cclmap, *ccllen, *cclng, cclreuse;
  90. int current_max_ccl_tbl_size;
  91. Char *ccltbl;
  92. char *starttime, *endtime, nmstr[MAXLINE];
  93. int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs;
  94. int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave;
  95. int num_backtracking, bol_needed;
  96. FILE *temp_action_file;
  97. FILE *backtrack_file;
  98. int end_of_buffer_state;
  99. char *action_file_name = NULL;
  100. char **input_files;
  101. int num_input_files;
  102. char *program_name;
  103. char lexer_name[256]="lex";
  104. int name_defined=0;
  105. char *skelname = NULL;
  106.  
  107. #ifndef SHORT_FILE_NAMES
  108. static char *outfile = "lex.yy.c";
  109. #else
  110. static char *outfile = "lexyy.c";
  111. #endif
  112. static int outfile_created = 0;
  113. static int use_stdout;
  114. /* suffixes recognised to convert C/C++ outputfilename to headerfilename */
  115. static char *c_suffixes[]=
  116.    {".c",".cc",".cpp",".cxx",".C",".CPP",".CXX",".CC",(char *)0};
  117.  
  118.  
  119. int main( argc, argv )
  120. int argc;
  121. char **argv;
  122.  
  123.     {
  124.     flexinit( argc, argv );
  125.  
  126.     readin();
  127.  
  128.     if ( syntaxerror )
  129.     flexend( 1 );
  130.  
  131.     if ( yymore_really_used == REALLY_USED )
  132.     yymore_used = true;
  133.     else if ( yymore_really_used == REALLY_NOT_USED )
  134.     yymore_used = false;
  135.  
  136.     if ( reject_really_used == REALLY_USED )
  137.     reject = true;
  138.     else if ( reject_really_used == REALLY_NOT_USED )
  139.     reject = false;
  140.  
  141.     if ( performance_report )
  142.     {
  143.     if ( interactive )
  144.         fprintf( stderr,
  145.              "-I (interactive) entails a minor performance penalty\n" );
  146.  
  147.     if ( yymore_used )
  148.         fprintf( stderr, "yymore() entails a minor performance penalty\n" );
  149.  
  150.     if ( reject )
  151.         fprintf( stderr, "REJECT entails a large performance penalty\n" );
  152.  
  153.     if ( variable_trailing_context_rules )
  154.         fprintf( stderr,
  155. "Variable trailing context rules entail a large performance penalty\n" );
  156.     }
  157.  
  158.     if ( reject )
  159.     real_reject = true;
  160.  
  161.     if ( variable_trailing_context_rules )
  162.     reject = true;
  163.  
  164.     if ( (fulltbl || fullspd) && reject )
  165.     {
  166.     if ( real_reject )
  167.         flexerror( "REJECT cannot be used with -f or -F" );
  168.     else
  169.         flexerror(
  170.     "variable trailing context rules cannot be used with -f or -F" );
  171.     }
  172.  
  173.     ntod();
  174.  
  175.     /* generate the C state transition tables from the DFA */
  176.     make_tables();
  177.  
  178.     /* note, flexend does not return.  It exits with its argument as status. */
  179.  
  180.     flexend( 0 );
  181.  
  182.     /*NOTREACHED*/
  183.     }
  184.  
  185.  
  186. /* flexend - terminate flex
  187.  *
  188.  * synopsis
  189.  *    int status;
  190.  *    flexend( status );
  191.  *
  192.  *    status is exit status.
  193.  *
  194.  * note
  195.  *    This routine does not return.
  196.  */
  197.  
  198. void flexend( status )
  199. int status;
  200.  
  201.     {
  202.     int tblsiz;
  203.     char *flex_gettime();
  204.  
  205.     if ( skelfile != NULL )
  206.     {
  207.     if ( ferror( skelfile ) )
  208.         flexfatal( "error occurred when writing skeleton file" );
  209.  
  210.     else if ( fclose( skelfile ) )
  211.         flexfatal( "error occurred when closing skeleton file" );
  212.     }
  213.  
  214.     if ( skelheaderfile != NULL )
  215.     {
  216.     if ( ferror( skelheaderfile ) )
  217.         flexfatal( "error occurred when writing header skeleton file" );
  218.  
  219.     else if ( fclose( skelheaderfile ) )
  220.         flexfatal( "error occurred when closing haeder skeleton file" );
  221.     }
  222.  
  223.     if ( temp_action_file )
  224.     {
  225.     if ( ferror( temp_action_file ) )
  226.         flexfatal( "error occurred when writing temporary action file" );
  227.  
  228.     else if ( fclose( temp_action_file ) )
  229.         flexfatal( "error occurred when closing temporary action file" );
  230.  
  231.     else if ( unlink( action_file_name ) )
  232.         flexfatal( "error occurred when deleting temporary action file" );
  233.     }
  234.     else if ( headerfile  )
  235.     {
  236.     if ( ferror( headerfile ) )
  237.         flexfatal( "error occurred when writing header file" );
  238.  
  239.     else if ( fclose( headerfile ) )
  240.         flexfatal( "error occurred when closing header file" );
  241.  
  242.     else if ( unlink( action_file_name ) )
  243.         flexfatal( "error occurred when deleting temporary action file" );
  244.     }
  245.  
  246.     if ( status != 0 && outfile_created )
  247.     {
  248.     if ( ferror( stdout ) )
  249.         flexfatal( "error occurred when writing output file" );
  250.  
  251.     else if ( fclose( stdout ) )
  252.         flexfatal( "error occurred when closing output file" );
  253.  
  254.     else if ( unlink( outfile ) )
  255.         flexfatal( "error occurred when deleting output file" );
  256.     }
  257.  
  258.     if ( backtrack_report && backtrack_file )
  259.     {
  260.     if ( num_backtracking == 0 )
  261.         fprintf( backtrack_file, "No backtracking.\n" );
  262.     else if ( fullspd || fulltbl )
  263.         fprintf( backtrack_file,
  264.              "%d backtracking (non-accepting) states.\n",
  265.              num_backtracking );
  266.     else
  267.         fprintf( backtrack_file, "Compressed tables always backtrack.\n" );
  268.  
  269.     if ( ferror( backtrack_file ) )
  270.         flexfatal( "error occurred when writing backtracking file" );
  271.  
  272.     else if ( fclose( backtrack_file ) )
  273.         flexfatal( "error occurred when closing backtracking file" );
  274.     }
  275.  
  276.     if ( printstats )
  277.     {
  278.     endtime = flex_gettime();
  279.  
  280.     fprintf( stderr, "%s version %s usage statistics:\n", program_name,
  281.          flex_version );
  282.     fprintf( stderr, "  started at %s, finished at %s\n",
  283.          starttime, endtime );
  284.  
  285.     fprintf( stderr, "  scanner options: -" );
  286.  
  287.     if ( backtrack_report )
  288.         putc( 'b', stderr );
  289.     if ( ddebug )
  290.         putc( 'd', stderr );
  291.     if ( interactive )
  292.         putc( 'I', stderr );
  293.     if ( caseins )
  294.         putc( 'i', stderr );
  295.     if ( ! gen_line_dirs )
  296.         putc( 'L', stderr );
  297.     if ( performance_report )
  298.         putc( 'p', stderr );
  299.     if ( spprdflt )
  300.         putc( 's', stderr );
  301.     if ( use_stdout )
  302.         putc( 't', stderr );
  303.     if ( trace )
  304.         putc( 'T', stderr );
  305.     if ( printstats )
  306.         putc( 'v', stderr );        /* always true! */
  307.     if ( csize == 256 )
  308.         putc( '8', stderr );
  309.  
  310.     fprintf( stderr, " -C" );
  311.  
  312.     if ( fulltbl )
  313.         putc( 'f', stderr );
  314.     if ( fullspd )
  315.         putc( 'F', stderr );
  316.     if ( useecs )
  317.         putc( 'e', stderr );
  318.     if ( usemecs )
  319.         putc( 'm', stderr );
  320.  
  321.     if ( outputfilename )
  322.         fprintf( stderr, " -o%s", outputfilename );
  323.  
  324.     if ( headerfilename )
  325.         fprintf( stderr, " -h%s", headerfilename );
  326.  
  327.     if ( includefilename && headerfilename && 
  328.          ! strcmp(includefilename,headerfilename ))
  329.         fprintf( stderr, " -g%s", includefilename );
  330.         
  331.     if ( skelname && strcmp( skelname, DEFAULT_SKELETON_FILE ) )
  332.         fprintf( stderr, " -S%s", skelname );
  333.  
  334.     if ( strcmp( skelname, DEFAULT_SKELETONHEADER_FILE ) )
  335.         fprintf( stderr, " -H%s", skelheaderfilename );
  336.  
  337.     putc( '\n', stderr );
  338.  
  339.     fprintf( stderr, "  %d/%d NFA states\n", lastnfa, current_mns );
  340.     fprintf( stderr, "  %d/%d DFA states (%d words)\n", lastdfa,
  341.          current_max_dfas, totnst );
  342.     fprintf( stderr,
  343.          "  %d rules\n", num_rules - 1 /* - 1 for def. rule */ );
  344.  
  345.     if ( num_backtracking == 0 )
  346.         fprintf( stderr, "  No backtracking\n" );
  347.     else if ( fullspd || fulltbl )
  348.         fprintf( stderr, "  %d backtracking (non-accepting) states\n",
  349.              num_backtracking );
  350.     else
  351.         fprintf( stderr, "  compressed tables always backtrack\n" );
  352.  
  353.     if ( bol_needed )
  354.         fprintf( stderr, "  Beginning-of-line patterns used\n" );
  355.  
  356.     fprintf( stderr, "  %d/%d start conditions\n", lastsc,
  357.          current_max_scs );
  358.     fprintf( stderr, "  %d epsilon states, %d double epsilon states\n",
  359.          numeps, eps2 );
  360.  
  361.     if ( lastccl == 0 )
  362.         fprintf( stderr, "  no character classes\n" );
  363.     else
  364.         fprintf( stderr,
  365.     "  %d/%d character classes needed %d/%d words of storage, %d reused\n",
  366.              lastccl, current_maxccls,
  367.              cclmap[lastccl] + ccllen[lastccl],
  368.              current_max_ccl_tbl_size, cclreuse );
  369.  
  370.     fprintf( stderr, "  %d state/nextstate pairs created\n", numsnpairs );
  371.     fprintf( stderr, "  %d/%d unique/duplicate transitions\n",
  372.          numuniq, numdup );
  373.  
  374.     if ( fulltbl )
  375.         {
  376.         tblsiz = lastdfa * numecs;
  377.         fprintf( stderr, "  %d table entries\n", tblsiz );
  378.         }
  379.  
  380.     else
  381.         {
  382.         tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend;
  383.  
  384.         fprintf( stderr, "  %d/%d base-def entries created\n",
  385.              lastdfa + numtemps, current_max_dfas );
  386.         fprintf( stderr, "  %d/%d (peak %d) nxt-chk entries created\n",
  387.              tblend, current_max_xpairs, peakpairs );
  388.         fprintf( stderr,
  389.              "  %d/%d (peak %d) template nxt-chk entries created\n",
  390.              numtemps * nummecs, current_max_template_xpairs,
  391.              numtemps * numecs );
  392.         fprintf( stderr, "  %d empty table entries\n", nummt );
  393.         fprintf( stderr, "  %d protos created\n", numprots );
  394.         fprintf( stderr, "  %d templates created, %d uses\n",
  395.              numtemps, tmpuses );
  396.         }
  397.  
  398.     if ( useecs )
  399.         {
  400.         tblsiz = tblsiz + csize;
  401.         fprintf( stderr, "  %d/%d equivalence classes created\n",
  402.              numecs, csize );
  403.         }
  404.  
  405.     if ( usemecs )
  406.         {
  407.         tblsiz = tblsiz + numecs;
  408.         fprintf( stderr, "  %d/%d meta-equivalence classes created\n",
  409.              nummecs, csize );
  410.         }
  411.  
  412.     fprintf( stderr, "  %d (%d saved) hash collisions, %d DFAs equal\n",
  413.          hshcol, hshsave, dfaeql );
  414.     fprintf( stderr, "  %d sets of reallocations needed\n", num_reallocs );
  415.     fprintf( stderr, "  %d total table entries needed\n", tblsiz );
  416.     }
  417.  
  418. #ifndef VMS
  419.     exit( status );
  420. #else
  421.     exit( status + 1 );
  422. #endif
  423.     }
  424.  
  425.  
  426. /* flexinit - initialize flex
  427.  *
  428.  * synopsis
  429.  *    int argc;
  430.  *    char **argv;
  431.  *    flexinit( argc, argv );
  432.  */
  433.  
  434. void flexinit( argc, argv )
  435. int argc;
  436. char **argv;
  437.  
  438.     {
  439.     int i, sawcmpflag;
  440.     char *arg, *flex_gettime(), *mktemp();
  441.     char *tmp_action=(char *)0;
  442.     printstats = syntaxerror = trace = spprdflt = interactive = caseins = false;
  443.     backtrack_report = performance_report = ddebug = fulltbl = fullspd = false;
  444.     yymore_used = continued_action = reject = false;
  445.     yymore_really_used = reject_really_used = false;
  446.     gen_line_dirs = usemecs = useecs = true;
  447.  
  448.     sawcmpflag = false;
  449.     use_stdout = false;
  450.  
  451.     csize = DEFAULT_CSIZE;
  452.     starttime = flex_gettime();
  453.  
  454.     program_name = argv[0];
  455.  
  456.     /* read flags */
  457.     for ( --argc, ++argv; argc ; --argc, ++argv )
  458.     {
  459.     if ( argv[0][0] != '-' || argv[0][1] == '\0' )
  460.         break;
  461.  
  462.     arg = argv[0];
  463.  
  464.     for ( i = 1; arg[i] != '\0'; ++i )
  465.         switch ( arg[i] )
  466.         {
  467.         case 'a':
  468.             if ( i != 1 )
  469.             flexerror( "-a flag must be given separately" );
  470.             tmp_action = &arg[i+1];
  471.             goto get_next_arg;
  472.         case 'b':
  473.             backtrack_report = true;
  474.             break;
  475.  
  476.         case 'c':
  477.             fprintf( stderr,
  478.     "%s: Assuming use of deprecated -c flag is really intended to be -C\n",
  479.                  program_name );
  480.  
  481.             /* fall through */
  482.  
  483.         case 'C':
  484.             if ( i != 1 )
  485.             flexerror( "-C flag must be given separately" );
  486.  
  487.             if ( ! sawcmpflag )
  488.             {
  489.             useecs = false;
  490.             usemecs = false;
  491.             fulltbl = false;
  492.             sawcmpflag = true;
  493.             }
  494.  
  495.             for ( ++i; arg[i] != '\0'; ++i )
  496.             switch ( arg[i] )
  497.                 {
  498.                 case 'e':
  499.                 useecs = true;
  500.                 break;
  501.  
  502.                 case 'F':
  503.                 fullspd = true;
  504.                 break;
  505.  
  506.                 case 'f':
  507.                 fulltbl = true;
  508.                 break;
  509.  
  510.                 case 'm':
  511.                 usemecs = true;
  512.                 break;
  513.  
  514.                 default:
  515.                 fprintf(stderr, "unknown -C option '%c'",
  516.                     (int) arg[i] );
  517.                 flexinfo(1);
  518.                 break;
  519.                 }
  520.  
  521.             goto get_next_arg;
  522.  
  523.         case 'd':
  524.             ddebug = true;
  525.             break;
  526.  
  527.         case 'f':
  528.             useecs = usemecs = false;
  529.             fulltbl = true;
  530.             break;
  531.  
  532.         case 'F':
  533.             useecs = usemecs = false;
  534.             fullspd = true;
  535.             break;
  536.         case 'g':
  537.             if ( i != 1 )
  538.             flexerror( "-g flag must be given separately" );
  539.  
  540.             includefilename = arg + i + 1;
  541.             goto get_next_arg;
  542.         case 'h':
  543.             if ( i != 1 )
  544.             flexerror( "-h flag must be given separately" );
  545.  
  546.             headerfilename = arg + i + 1;
  547.             goto get_next_arg;
  548.         case 'o':
  549.             if ( i != 1 )
  550.             flexerror( "-o flag must be given separately" );
  551.  
  552.             outputfilename = arg + i + 1;
  553.             goto get_next_arg;
  554.  
  555.         case 'H':
  556.             if ( i != 1 )
  557.             flexerror( "-H flag must be given separately" );
  558.  
  559.             skelheaderfilename = arg + i + 1;
  560.             goto get_next_arg;
  561.  
  562.  
  563.         case 'I':
  564.             interactive = true;
  565.             break;
  566.  
  567.         case 'i':
  568.             caseins = true;
  569.             break;
  570.  
  571.         case 'L':
  572.             gen_line_dirs = false;
  573.             break;
  574.  
  575.         case 'n':
  576.             /* stupid do-nothing deprecated option */
  577.             break;
  578.  
  579.         case 'p':
  580.             performance_report = true;
  581.             break;
  582.  
  583.         case 'S':
  584.             if ( i != 1 )
  585.             flexerror( "-S flag must be given separately" );
  586.  
  587.             skelname = arg + i + 1;
  588.             goto get_next_arg;
  589.  
  590.         case 's':
  591.             spprdflt = true;
  592.             break;
  593.  
  594.         case 't':
  595.             use_stdout = true;
  596.             break;
  597.  
  598.         case 'T':
  599.             trace = true;
  600.             break;
  601.  
  602.         case 'v':
  603.             printstats = true;
  604.             break;
  605.  
  606.         case '8':
  607.             csize = CSIZE;
  608.             break;
  609.  
  610.         case '?':
  611.             flexinfo(0);
  612.             break;
  613.  
  614.         default:
  615.             fprintf(stderr, "unknown flag '%c'", (int) arg[i] );
  616.             flexinfo(1);
  617.             break;
  618.         }
  619.  
  620. get_next_arg: /* used by -C and -S flags in lieu of a "continue 2" control */
  621.     ;
  622.     }
  623.  
  624.     if ( (fulltbl || fullspd) && usemecs )
  625.     flexerror( "full table and -Cm don't make sense together" );
  626.  
  627.     if ( (fulltbl || fullspd) && interactive )
  628.     flexerror( "full table and -I are (currently) incompatible" );
  629.  
  630.     if ( fulltbl && fullspd )
  631.     flexerror( "full table and -F are mutually exclusive" );
  632.     if( use_stdout && outputfilename )
  633.     flexerror( "-t (generate to stdout) and -o (generate to file) are mutually exclusive" );
  634.     if ( ! skelname )
  635.     {
  636.     skelname=DEFAULT_SKELETON_FILE;
  637.     }
  638.  
  639.     if ( ! skelheaderfilename )
  640.     {
  641.     skelheaderfilename=DEFAULT_SKELETONHEADER_FILE;
  642.     }
  643.     if ( ! use_stdout )
  644.     {FILE *prev_stdout;
  645.     if(outputfilename && outputfilename[0] ) outfile=outputfilename;
  646.     prev_stdout = freopen( outfile, "w", stdout );
  647.  
  648.     if ( prev_stdout == NULL )
  649.         lerrsf( "could not create %s", outfile );
  650.  
  651.     outfile_created = 1;
  652.     }
  653.  
  654.     num_input_files = argc;
  655.     input_files = argv;
  656.     set_input_file( num_input_files > 0 ? input_files[0] : NULL );
  657.     if ( (skelheaderfile = fopen( skelheaderfilename, "r" )) == NULL )
  658. #ifdef _MSDOS
  659.      if(getenv("INIT")!=NULL)
  660.      {char *t;
  661.       t=malloc(strlen(getenv("INIT"))+strlen(skelheaderfilename)+2);
  662.       strcpy(t,getenv("INIT"));
  663.       strcat(t,"/");
  664.       strcat(t,skelheaderfilename);
  665.       skelheaderfilename=t;
  666.       if((skelheaderfile = fopen( skelheaderfilename, "r" )) == NULL)
  667.     lerrsf( "can't open skeleton header file %s", skelheaderfilename );
  668.      }
  669.      else
  670. #endif
  671.     lerrsf( "can't open skeleton header file %s", skelheaderfilename );
  672.     if(headerfilename==NULL) headerfile=stdout;
  673.     else  
  674.      {
  675.       if(headerfilename[0]=='\0')
  676.        {char **suffix;
  677.     headerfilename=malloc(strlen(outfile)+3);
  678.     strcpy(headerfilename,outfile);
  679.     for(suffix=c_suffixes;*suffix;suffix++)
  680.     /* try to detect .c .cpp options */
  681.       {if(strlen(headerfilename)>strlen(*suffix)
  682.           && strcmp(headerfilename+
  683.            strlen(headerfilename)-strlen(*suffix),*suffix)==0
  684.           )
  685.         { *(headerfilename+strlen(headerfilename)-strlen(*suffix))='\0';
  686.          break;}
  687.       };
  688.     strcat(headerfilename,".h");     
  689.     }
  690.       if(includefilename==NULL)
  691.      includefilename=headerfilename;
  692.       if ( (headerfile = fopen( headerfilename, "w" )) == NULL )
  693.     lerrsf( "can't open header file %s", headerfilename );
  694.       };
  695.     if ( backtrack_report )
  696.     {
  697. #ifndef SHORT_FILE_NAMES
  698.     backtrack_file = fopen( "lex.backtrack", "w" );
  699. #else
  700.     backtrack_file = fopen( "lex.bck", "w" );
  701. #endif
  702.     if ( backtrack_file == NULL )
  703.         flexerror( "could not create lex.backtrack" );
  704.     }
  705.  
  706.     else
  707.     backtrack_file = NULL;
  708.  
  709.  
  710.     lastccl = 0;
  711.     lastsc = 0;
  712.  
  713.     /* initialize the statistics */
  714.  
  715.     if ( (skelfile = fopen( skelname, "r" )) == NULL )
  716. #ifdef _MSDOS
  717.        if(getenv("INIT")!=NULL)
  718.      {char *t;
  719.       t=malloc(strlen(getenv("INIT"))+strlen(skelname)+2);
  720.       strcpy(t,getenv("INIT"));
  721.       strcat(t,"/");
  722.       strcat(t,skelname);
  723.       skelname=t;
  724.       if((skelfile = fopen(skelname , "r" )) == NULL)
  725.     lerrsf( "can't open skeleton file %s", skelname );
  726.      }
  727.      else
  728. #endif
  729.     lerrsf( "can't open skeleton file %s", skelname );
  730.     if(tmp_action)
  731.      {char *ftmp;
  732.       ftmp=malloc(strlen(tmp_action)+1+32);
  733.       strcpy(ftmp,tmp_action);
  734. #ifndef SHORT_FILE_NAMES
  735.     (void) strcat( ftmp, "/flexXXXXXX" );
  736. #else
  737.     (void) strcpy( ftmp, "/flXXXXXX.tmp" );
  738. #endif
  739.       action_file_name=ftmp;
  740.       (void) mktemp( action_file_name );
  741.      }
  742.     else
  743.      {
  744. #ifdef _MSDOS
  745.       action_file_name=_tempnam(".","flex");
  746. #else
  747. #ifdef SYS_V
  748.     action_file_name = tmpnam( NULL );
  749. #endif
  750. #endif
  751.      }
  752.     if ( action_file_name == NULL )
  753.     {
  754.     static char temp_action_file_name[32];
  755.  
  756. #ifndef SHORT_FILE_NAMES
  757.     (void) strcpy( temp_action_file_name, "/tmp/flexXXXXXX" );
  758. #else
  759.     (void) strcpy( temp_action_file_name, "flXXXXXX.tmp" );
  760. #endif
  761.     (void) mktemp( temp_action_file_name );
  762.     action_file_name = temp_action_file_name;
  763.     }
  764.  
  765.     if ( (temp_action_file = fopen( action_file_name, "w" )) == NULL )
  766.     lerrsf( "can't open temporary action file %s", action_file_name );
  767.  
  768.     lastdfa = lastnfa = num_rules = numas = numsnpairs = tmpuses = 0;
  769.     numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 0;
  770.     numuniq = numdup = hshsave = eofseen = datapos = dataline = 0;
  771.     num_backtracking = onesp = numprots = 0;
  772.     variable_trailing_context_rules = bol_needed = false;
  773.  
  774.     linenum = sectnum = 1;
  775.     firstprot = NIL;
  776.  
  777.     /* used in mkprot() so that the first proto goes in slot 1
  778.      * of the proto queue
  779.      */
  780.     lastprot = 1;
  781.  
  782.     if ( useecs )
  783.     { /* set up doubly-linked equivalence classes */
  784.     /* We loop all the way up to csize, since ecgroup[csize] is the
  785.      * position used for NUL characters
  786.      */
  787.     ecgroup[1] = NIL;
  788.  
  789.     for ( i = 2; i <= csize; ++i )
  790.         {
  791.         ecgroup[i] = i - 1;
  792.         nextecm[i - 1] = i;
  793.         }
  794.  
  795.     nextecm[csize] = NIL;
  796.     }
  797.  
  798.     else
  799.     { /* put everything in its own equivalence class */
  800.     for ( i = 1; i <= csize; ++i )
  801.         {
  802.         ecgroup[i] = i;
  803.         nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */
  804.         }
  805.     }
  806.  
  807.     set_up_initial_allocations();
  808.     }
  809.  
  810.  int flexinfo(status)
  811.  int status;
  812.  {
  813.     fprintf(stderr,"Syntax  :  flex  [options...] inp_file\n");
  814.     fprintf(stderr,"Function: fast lexical analyzer generator C/C++  V%s\n",flex_version);
  815.     fprintf(stderr,"Options : \n");
  816.     fprintf(stderr,"    -a dir_path  : directory path for temporary files\n");
  817.     fprintf(stderr,"    -b  : generate backtracking information to lex.backtrack\n");
  818.     fprintf(stderr,"    -c  : compressed table, no equiv., no meta equiv.classes\n");
  819.     fprintf(stderr,"    -C  : compressed table, no equiv., no meta equiv.classes\n");
  820.     fprintf(stderr,"    -Ce : compressed table, with equivalence classes\n");
  821.     fprintf(stderr,"    -Cem: compressed table, with equivalence and meta equiv. classes\n");
  822.     fprintf(stderr,"    -Cm: compressed table, with meta equivalence classes\n");
  823.     fprintf(stderr,"    -Cm: compressed table, with meta equivalence classes\n");
  824.     fprintf(stderr,"    -CF :  alternate fast table\n");
  825.     fprintf(stderr,"    -Cf :  full table\n");
  826.     fprintf(stderr,"    -CFe : alternate fast table, with equivalence classes\n");
  827.     fprintf(stderr,"    -Cfe : full table, with equivalence classes\n");
  828.     fprintf(stderr,"    -F  : fast table\n");
  829.     fprintf(stderr,"    -f  : full (not compressed) table\n");
  830.     fprintf(stderr,"    -d  : generate debugging scanner\n");
  831.     fprintf(stderr,"    -I  : generate interactive scanner\n");
  832.     fprintf(stderr,"    -i  : generate case-insensitive scanner\n");
  833.     fprintf(stderr,"    -L  : supress #line directives\n");
  834.  /*   fprintf(stderr,"    -n hexnum : generate scanner using <hexnum> as newline char.\n");*/
  835.     fprintf(stderr,"    -p  : generate performance report to stderr\n");
  836.     fprintf(stderr,"    -S skeleton_path : file path for skeleton file\n");
  837.     fprintf(stderr,"    -H header_skeleton_path : file path for header skeleton file\n");
  838.     fprintf(stderr,"    -s  : suppress echo of unmatched scanner input to stdout\n");
  839.     fprintf(stderr,"    -T  : run flex in trace mode\n");
  840.     fprintf(stderr,"    -t  : place result on stdout \n");
  841.     fprintf(stderr,"    -v  : print statistics of generated scanner\n");
  842.     fprintf(stderr,"    -o code_file  : set name of output code file\n");
  843.     fprintf(stderr,"    -h [header_file]  : generate a separate header_file\n");
  844.     fprintf(stderr,"    -g include_file  : name of header to include (default= same as -h)\n");
  845.     fprintf(stderr,"    -?   : this help\n");
  846.     fprintf(stderr,"    default =  -Cem\n");
  847.     exit(status);
  848.     return 0;
  849.  }
  850.  
  851.  
  852.  
  853. /* readin - read in the rules section of the input file(s)
  854.  *
  855.  * synopsis
  856.  *    readin();
  857.  */
  858.  
  859. void readin()
  860.  
  861.     {    
  862.     char *ch_type;
  863.  
  864.     if(headerfilename!=NULL)
  865.      {char symb[32],ch;
  866.       char *p=headerfilename;
  867.       int i=0;symb[0]='\0';
  868.       while(*p) 
  869.        {
  870.     if(*p=='/'
  871. #ifdef MS_DOS
  872.        || *p=='\\' || *p==':'
  873. #endif
  874.        ) {symb[0]='\0';i=0;}
  875.     else {
  876.      if((*p>='A' && *p<='Z')||((*p>='a' && *p<='z'))
  877.              ||((*p>='0' && *p<='9'))||(ch=='_')) 
  878.           ch=*p;
  879.      else 
  880.           ch='_';
  881.      if(i<sizeof(symb)-1)
  882.       {symb[i++]=ch;symb[i]='\0';}
  883.      }
  884.     p++; 
  885.        };
  886.       fprintf(headerfile,"#ifndef FLEX_HEADER_%s\n",symb );
  887.       fprintf(headerfile,"#define FLEX_HEADER_%s\n",symb );
  888.      }
  889.      if ( csize == 256 ) 
  890.       ch_type="unsigned char";
  891.      else 
  892.       ch_type="char";
  893.     if ( ddebug )
  894.       fprintf(stdout, "#define FLEX_DEBUG\n" );
  895.     fprintf(stdout, "#define YY_CHAR %s\n",ch_type );
  896.     skelout();
  897.     line_directive_out( stdout );
  898.  
  899.     if ( yyparse() )
  900.     {
  901.     pinpoint_message( "fatal parse error" );
  902.     flexend( 1 );
  903.     }
  904.  
  905.     if ( xlation )
  906.     {
  907.     numecs = ecs_from_xlation( ecgroup );
  908.     useecs = true;
  909.     }
  910.  
  911.     else if ( useecs )
  912.     numecs = cre8ecs( nextecm, ecgroup, csize );
  913.  
  914.     else
  915.     numecs = csize;
  916.  
  917.     /* now map the equivalence class for NUL to its expected place */
  918.     ecgroup[0] = ecgroup[csize];
  919.     NUL_ec = abs( ecgroup[0] );
  920.  
  921.     if ( useecs )
  922.     ccl2ecl();
  923.     line_directive_out( headerfile );
  924.     if(headerfilename!=NULL) fprintf(headerfile,"#endif\n" );
  925.     header_skeleton_out();
  926.  
  927.     }
  928.  
  929.  
  930.  
  931. /* set_up_initial_allocations - allocate memory for internal tables */
  932.  
  933. void set_up_initial_allocations()
  934.  
  935.     {
  936.     current_mns = INITIAL_MNS;
  937.     firstst = allocate_integer_array( current_mns );
  938.     lastst = allocate_integer_array( current_mns );
  939.     finalst = allocate_integer_array( current_mns );
  940.     transchar = allocate_integer_array( current_mns );
  941.     trans1 = allocate_integer_array( current_mns );
  942.     trans2 = allocate_integer_array( current_mns );
  943.     accptnum = allocate_integer_array( current_mns );
  944.     assoc_rule = allocate_integer_array( current_mns );
  945.     state_type = allocate_integer_array( current_mns );
  946.  
  947.     current_max_rules = INITIAL_MAX_RULES;
  948.     rule_type = allocate_integer_array( current_max_rules );
  949.     rule_linenum = allocate_integer_array( current_max_rules );
  950.  
  951.     current_max_scs = INITIAL_MAX_SCS;
  952.     scset = allocate_integer_array( current_max_scs );
  953.     scbol = allocate_integer_array( current_max_scs );
  954.     scxclu = allocate_integer_array( current_max_scs );
  955.     sceof = allocate_integer_array( current_max_scs );
  956.     scname = allocate_char_ptr_array( current_max_scs );
  957.     actvsc = allocate_integer_array( current_max_scs );
  958.  
  959.     current_maxccls = INITIAL_MAX_CCLS;
  960.     cclmap = allocate_integer_array( current_maxccls );
  961.     ccllen = allocate_integer_array( current_maxccls );
  962.     cclng = allocate_integer_array( current_maxccls );
  963.  
  964.     current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE;
  965.     ccltbl = allocate_character_array( current_max_ccl_tbl_size );
  966.  
  967.     current_max_dfa_size = INITIAL_MAX_DFA_SIZE;
  968.  
  969.     current_max_xpairs = INITIAL_MAX_XPAIRS;
  970.     nxt = allocate_integer_array( current_max_xpairs );
  971.     chk = allocate_integer_array( current_max_xpairs );
  972.  
  973.     current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS;
  974.     tnxt = allocate_integer_array( current_max_template_xpairs );
  975.  
  976.     current_max_dfas = INITIAL_MAX_DFAS;
  977.     base = allocate_integer_array( current_max_dfas );
  978.     def = allocate_integer_array( current_max_dfas );
  979.     dfasiz = allocate_integer_array( current_max_dfas );
  980.     accsiz = allocate_integer_array( current_max_dfas );
  981.     dhash = allocate_integer_array( current_max_dfas );
  982.     dss = allocate_int_ptr_array( current_max_dfas );
  983.     dfaacc = allocate_dfaacc_union( current_max_dfas );
  984.  
  985.     nultrans = (int *) 0;
  986.     }
  987.