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