home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / alde_c / misc / comm / yaccunx / ysetup.2c < prev    next >
Encoding:
Text File  |  1983-12-25  |  12.6 KB  |  450 lines

  1. #include "y2.h"
  2. /*
  3.  * YSETUP.C  -- Modified for use with DECUS LEX
  4.  *              Variable "yylval" resides in yylex(), not in yypars();
  5.  *              Therefore, is defined "extern" here.
  6.  *
  7.  *              Also, the command line processing for the Decus version
  8.  *              has been changed.  A new switch has been added to allow
  9.  *              specification of the "table" file name(s), and unused
  10.  *              switch processing removed.
  11.  *
  12.  *                               NOTE
  13.  *              This probably won't run on UNIX any more.
  14.  *
  15.  * Bob Denny 27-Aug-81
  16.  * Bob Denny 22-Mar-82 (01) Added header line, changes for 'new' DECUS library
  17.  * Bob Denny 12-Apr-83 (02) Make filename[] size per #define'd FNAMESIZE so
  18.  *                          VAX filenames won't blow out.  Conditionalize
  19.  *                          time handling for banner.  Make filespec buffer
  20.  *                          static for safety, since global "infile" is
  21.  *                          pointed to it.
  22.  * Scott Guthery 15-May-83  (03) Fixed up option flag handling for RT-11
  23.  *                 23-Dec-83  Adapted for IBM PC/XT & DeSmet C compiler
  24.  */
  25.  
  26. static char filename[FNAMESIZE];
  27.  
  28. int i,j,lev,t, ty;
  29. int c;
  30. int tempty;
  31. int *p;
  32. int defsw, infsw;
  33. char actname[8];
  34. char *cp;
  35.  
  36. setup(argc,argv)
  37. int argc;
  38. char *argv[];
  39.    {
  40.    char finsave[FNAMESIZE];
  41.  
  42.    defsw = infsw = 0;
  43.    foutput = NULL;
  44.    fdefine = NULL;
  45.    i = 1;                                               /*(03)*/
  46.    while( argc > 1 && argv[i][0] == '-' )               /*(03)*/
  47.       {
  48.       while( *++(argv[i]) )
  49.          {
  50.          switch( *argv[i] )
  51.             {
  52.          case 'i':
  53.          case 'I':
  54.             infsw++;
  55.             continue;
  56.          case 'h':
  57.          case 'H':
  58.  
  59.             defsw++;
  60.             continue;
  61.          default:
  62.             fprintf(stderr, "Illegal option: %c\n", *argv[i]);
  63.             usage();
  64.             }
  65.          }
  66.       i++;                                              /*(03)*/
  67.       argc--;
  68.       }
  69.  
  70.    if(argc < 2) usage();               /* Catch no filename given */
  71.  
  72. /*
  73.  * Now open the input file with a default extension of ".Y",
  74.  * then replace the period in argv[1] with a null, so argv[1]
  75.  * can be used to form the table, defs and info filenames.
  76.  */
  77.  
  78.    cp = argv[i];
  79.    while(*cp++ != '.' && *cp != '\0'); /* Scan past '.' or to null */
  80.    if(*cp == '\0') {
  81.       strcpy(filename, argv[i]); strcat(filename, ".Y");
  82.    } else
  83.       {
  84.       strcpy(filename, argv[i]);
  85.       *(argv[i]-1) = '\0';             /* Null the period */
  86.       }
  87.  
  88.    strcpy(finsave, filename);
  89.    if((finput=fopen( filename, "r" )) == NULL )
  90.       error( "cannot open input file \"%s\"", filename );
  91.  
  92. /*
  93.  * Now open the .H and .I files if requested.
  94.  */
  95.  
  96.    if(defsw)
  97.       {
  98.       strcpy(filename, argv[i]); strcat(filename, ".H");
  99.       fdefine = fopen(filename, "w");
  100.       if(fdefine == NULL) error("cannot open defs file\"%s\"", filename);
  101.       }
  102.  
  103.    if(infsw)
  104.       {
  105.       strcpy(filename, argv[i]); strcat(filename, ".I");
  106.       foutput = fopen(filename, "w");
  107.       if(foutput == NULL) error("cannot open info file\"%s\"", filename);
  108.       }
  109. /*
  110.  * Now the "table" output C file.
  111.  */
  112.    strcpy(filename, argv[i]); strcat(filename, ".C");
  113.    ftable = fopen(filename, "w");
  114.    if( ftable == NULL ) error( "cannot open table file\"%s\"", filename);
  115. /*
  116.  * Finally, the temp files.
  117.  */
  118.    ftemp = fopen( TEMPNAME, "w" );
  119.    if( ftemp==NULL ) error( "cannot open temp file" );
  120.    faction = fopen( ACTNAME, "w" );
  121.    if( faction==NULL ) error( "cannot open action file" );
  122.  
  123. /*
  124.  * Now put the full filename of the input file into
  125.  * the "filename" buffer for cpyact(), and point the
  126.  * global cell "infile" at it.
  127.  */
  128.    strcpy(filename, finsave);
  129.    infile = filename;
  130. /*
  131.  * Put out a header line at the beginning of the 'table' file.
  132.  */
  133. fprintf(ftable, "/*\n * Created by CSD YACC (IBM PC) from \"%s\" */\n",
  134.         infile);
  135. /*
  136.  * Complete  initialization.
  137.  */
  138.    cnamp = cnames;
  139.    defin(0,"$end");
  140.    extval = 0400;
  141.    defin(0,"error");
  142.    defin(1,"$accept");
  143.    mem=mem0;
  144.    lev = 0;
  145.    ty = 0;
  146.    i=0;
  147.  
  148.    yyparse();
  149.    }
  150.  
  151. yyparse()
  152.    {
  153.    /* sorry -- no yacc parser here.....
  154.                 we must bootstrap somehow... */
  155.  
  156.    for( t=gettok();  t!=MARK && t!= ENDFILE; )
  157.       {
  158.       switch( t )
  159.          {
  160.  
  161.       case ';':
  162.          t = gettok();
  163.          break;
  164.  
  165.       case START:
  166.          if( (t=gettok()) != IDENTIFIER )
  167.             {
  168.             error( "bad %%start construction" );
  169.             }
  170.          start = chfind(1,tokname);
  171.          t = gettok();
  172.          continue;
  173.  
  174.       case TYPEDEF:
  175.          if( (t=gettok()) != TYPENAME ) error( "bad syntax in %%type" );
  176.          ty = numbval;
  177.          for(;;)
  178.  
  179.             {
  180.             t = gettok();
  181.             switch( t )
  182.                {
  183.  
  184.             case IDENTIFIER:
  185.                if( (t=chfind( 1, tokname ) ) < NTBASE )
  186.                   {
  187.                   j = TYPE( toklev[t] );
  188.                   if( j!= 0 && j != ty )
  189.                      {
  190.                      error( "type redeclaration of token %s",
  191.                      tokset[t].name );
  192.                      }
  193.                   else SETTYPE( toklev[t],ty);
  194.                   }
  195.                else
  196.                   {
  197.                   j = nontrst[t-NTBASE].tvalue;
  198.                   if( j != 0 && j != ty )
  199.                      {
  200.                      error( "type redeclaration of nonterminal %s",
  201.                      nontrst[t-NTBASE].name );
  202.                      }
  203.                   else nontrst[t-NTBASE].tvalue = ty;
  204.                   }
  205.             case ',':
  206.                continue;
  207.  
  208.             case ';':
  209.                t = gettok();
  210.                break;
  211.             default:
  212.                break;
  213.                }
  214.             break;
  215.             }
  216.          continue;
  217.  
  218.       case UNION:
  219.          /* copy the union declaration to the output */
  220.          cpyunion();
  221.          t = gettok();
  222.          continue;
  223.  
  224.       case LEFT:
  225.       case BINARY:
  226.       case RIGHT:
  227.          ++i;
  228.       case TERM:
  229.          lev = t-TERM;  /* nonzero means new prec. and assoc. */
  230.          ty = 0;
  231.  
  232.          /* get identifiers so defined */
  233.  
  234.          t = gettok();
  235.          if( t == TYPENAME )
  236.             {
  237.             /* there is a type defined */
  238.             ty = numbval;
  239.             t = gettok();
  240.             }
  241.  
  242.          for(;;)
  243.             {
  244.             switch( t )
  245.                {
  246.  
  247.             case ',':
  248.                t = gettok();
  249.                continue;
  250.  
  251.             case ';':
  252.                break;
  253.  
  254.             case IDENTIFIER:
  255.                j = chfind(0,tokname);
  256.                if( lev )
  257.                   {
  258.                   if( ASSOC(toklev[j]) ) error( "redeclaration of precedence of%s", tokname );
  259.                   SETASC(toklev[j],lev);
  260.                   SETPLEV(toklev[j],i);
  261.                   }
  262.                if( ty )
  263.                   {
  264.                   if( TYPE(toklev[j]) ) error( "redeclaration of type of %s", tokname );
  265.                   SETTYPE(toklev[j],ty);
  266.                   }
  267.                if( (t=gettok()) == NUMBER )
  268.                   {
  269.                   tokset[j].value = numbval;
  270.                   if( j < ndefout && j>2 )
  271.                      {
  272.                      error( "please define type number of %s earlier",
  273.                      tokset[j].name );
  274.                      }
  275.                   t=gettok();
  276.                   }
  277.                continue;
  278.  
  279.                }
  280.  
  281.             break;
  282.             }
  283.  
  284.          continue;
  285.  
  286.       case LCURLY:
  287.          defout();
  288.          cpycode();
  289.          t = gettok();
  290.          continue;
  291.  
  292.       default:
  293.          printf("Unrecognized character: %o\n", t);
  294.          error( "syntax error" );
  295.  
  296.          }
  297.  
  298.       }
  299.  
  300.    if( t == ENDFILE )
  301.       {
  302.       error( "unexpected EOF before %%" );
  303.       }
  304.  
  305.    /* t is MARK */
  306.  
  307.    defout();
  308.  
  309.    fprintf( ftable,"#define yyclearin yychar = -1\n" );
  310.    fprintf( ftable,"#define yyerrok yyerrflag = 0\n" );
  311. /*
  312.    fprintf( ftable,"extern int yychar;\nextern short yyerrflag;\n" );
  313. */
  314.    fprintf( ftable,"#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n" );
  315.    if(!ntypes)
  316.       fprintf( ftable,  "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n" );
  317. #ifdef unix
  318.    fprintf( ftable,  "YYSTYPE yylval, yyval;\n" );
  319. #else
  320.    fprintf( ftable, "extern YYSTYPE yylval;  /*CSD & DECUS LEX */\n");
  321.    fprintf( ftable, "YYSTYPE yyval;          /*CSD & DECUS LEX */\n");
  322. #endif
  323.    prdptr[0]=mem;
  324.    /* added production */
  325.    *mem++ = NTBASE;
  326.    *mem++ = start;  /* if start is 0, we will overwrite with the lhs of the firstrule */
  327.    *mem++ = 1;
  328.    *mem++ = 0;
  329.    prdptr[1]=mem;
  330.    while( (t=gettok()) == LCURLY ) cpycode();
  331.    if( t != C_IDENTIFIER ) error( "bad syntax on first rule" );
  332.    if( !start ) prdptr[0][1] = chfind(1,tokname);
  333.  
  334.    /* read rules */
  335.  
  336.    while( t!=MARK && t!=ENDFILE )
  337.       {
  338.  
  339.       /* process a rule */
  340.  
  341.       if( t == '|' )
  342.          {
  343.          *mem++ = *prdptr[nprod-1];
  344.          }
  345.       else if( t == C_IDENTIFIER )
  346.          {
  347.          *mem = chfind(1,tokname);
  348.          if( *mem < NTBASE ) error( "token illegal on LHS of grammar rule" );
  349.          ++mem;
  350.          }
  351.       else error( "illegal rule: missing semicolon or | ?" );
  352.  
  353.       /* read rule body */
  354.       t = gettok();
  355. more_rule:
  356.       while( t == IDENTIFIER )
  357.          {
  358.          *mem = chfind(1,tokname);
  359.          if( *mem<NTBASE ) levprd[nprod] = toklev[*mem];
  360.          ++mem;
  361.          t = gettok();
  362.          }
  363.       if( t == PREC )
  364.  
  365.          {
  366.          if( gettok()!=IDENTIFIER) error( "illegal %%prec syntax" );
  367.          j = chfind(2,tokname);
  368.          if( j>=NTBASE)error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name);
  369.          levprd[nprod]=toklev[j];
  370.          t = gettok();
  371.          }
  372.       if( t == '=' )
  373.          {
  374.          levprd[nprod] |= ACTFLAG;
  375.          fprintf( faction, "\ncase %d:", nprod );
  376.          cpyact( mem-prdptr[nprod]-1 );
  377.          fprintf( faction, " break;" );
  378.          if( (t=gettok()) == IDENTIFIER )
  379.             {
  380.             /* action within rule... */
  381.             sprintf( actname, "$$%d", nprod );
  382.             j = chfind(1,actname);  /* make it a nonterminal */
  383.             /* the current rule will become rule number nprod+1 */
  384.             /* move the contents down, and make room for the null */
  385.             for( p=mem; p>=prdptr[nprod]; --p ) p[2] = *p;
  386.             mem += 2;
  387.             /* enter null production for action */
  388.             p = prdptr[nprod];
  389.             *p++ = j;
  390.             *p++ = -nprod;
  391.  
  392.             /* update the production information */
  393.             levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
  394.             levprd[nprod] = ACTFLAG;
  395.  
  396.             if( ++nprod >= NPROD ) error( "more than %d rules", NPROD );
  397.             prdptr[nprod] = p;
  398.  
  399.             /* make the action appear in the original rule */
  400.             *mem++ = j;
  401.  
  402.             /* get some more of the rule */
  403.  
  404.             goto more_rule;
  405.             }
  406.  
  407.          }
  408.  
  409.       while( t == ';' ) t = gettok();
  410.  
  411.       *mem++ = -nprod;
  412.  
  413.       /* check that default action is reasonable */
  414.  
  415.       if( ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].tvalue )
  416.          {
  417.          /* no explicit action, LHS has value */
  418.          /*01*/
  419.          tempty = prdptr[nprod][1];
  420.          if( tempty < 0 ) error( "must return a value, since LHS has a type" );
  421.          else if( tempty >= NTBASE ) tempty = nontrst[tempty-NTBASE].tvalue;
  422.          else tempty = TYPE( toklev[tempty] );
  423.          if( tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue )
  424.             {
  425.             error( "default action causes potential type clash" );
  426.             }
  427.  
  428.          }
  429.       if( ++nprod >= NPROD ) error( "more than %d rules", NPROD );
  430.       prdptr[nprod] = mem;
  431.       levprd[nprod]=0;
  432.       }
  433.    /* end of all rules */
  434.    fprintf(faction, "/* End of actions */"); /* Properly terminate the last line */
  435.    finact();
  436.    if( t == MARK )
  437.       {
  438.       fprintf( ftable, "\n#line %d\n", lineno );
  439.       while( (c=unix_getc(finput)) != EOF ) putc( c, ftable );
  440.       }
  441.    fclose( finput );
  442.    }
  443.  
  444. usage()
  445.  
  446.    {
  447.    fprintf(stderr,"UNIX YACC (CSD Variant):\n");
  448.    fprintf(stderr,"   yacc -hi infile\n\n");
  449.    fprintf(stderr,"Switches:\n");
  450.    fprintf(stderr,"   -h   Create definitions header file\n");
  451.    fprintf(stderr,"   -i   Create parser description file\n\n");
  452.    fprintf(stderr,"Default input file extension is \".Y\"\n");
  453.    fprintf(stderr,"Defs file same name, \".H\" extension.\n");
  454.    fprintf(stderr,"Info file same name, \".I\" extension.\n");
  455.    exit(EX_ERR);
  456.    }
  457.