home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / make / gram.y < prev    next >
Encoding:
Lex Description  |  1979-01-10  |  4.9 KB  |  307 lines

  1. %{#include "defs"
  2. %}
  3.  
  4. %term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER
  5. %union
  6.     {
  7.     struct shblock *yshblock;
  8.     struct depblock *ydepblock;
  9.     struct nameblock *ynameblock;
  10.     }
  11.  
  12. %type <yshblock> SHELLINE, shlist, shellist
  13. %type <ynameblock> NAME, namelist
  14. %type <ydepblock> deplist, dlist
  15.  
  16.  
  17. %%
  18.  
  19. %{
  20. struct depblock *pp;
  21. FSTATIC struct shblock *prevshp;
  22.  
  23. FSTATIC struct nameblock *lefts[NLEFTS];
  24. struct nameblock *leftp;
  25. FSTATIC int nlefts;
  26.  
  27. struct lineblock *lp, *lpp;
  28. FSTATIC struct depblock *prevdep;
  29. FSTATIC int sepc;
  30. %}
  31.  
  32.  
  33. file:
  34.     | file comline
  35.     ;
  36.  
  37. comline:  START
  38.     | MACRODEF
  39.     | START namelist deplist shellist = {
  40.         while( --nlefts >= 0)
  41.         {
  42.         leftp = lefts[nlefts];
  43.         if(leftp->septype == 0)
  44.             leftp->septype = sepc;
  45.         else if(leftp->septype != sepc)
  46.             fprintf(stderr, "Inconsistent rules lines for `%s'\n",
  47.                 leftp->namep);
  48.         else if(sepc==ALLDEPS && *(leftp->namep)!='.' && $4!=0)
  49.             {
  50.             for(lp=leftp->linep; lp->nxtlineblock!=0; lp=lp->nxtlineblock)
  51.                 if(lp->shp)
  52.                 fprintf(stderr, "Multiple rules lines for `%s'\n",
  53.                     leftp->namep);
  54.             }
  55.  
  56.         lp = ALLOC(lineblock);
  57.         lp->nxtlineblock = NULL;
  58.         lp->depp = $3;
  59.         lp->shp = $4;
  60.  
  61.         if(! unequal(leftp->namep, ".SUFFIXES") && $3==0)
  62.             leftp->linep = 0;
  63.         else if(leftp->linep == 0)
  64.             leftp->linep = lp;
  65.         else    {
  66.             for(lpp = leftp->linep; lpp->nxtlineblock;
  67.                 lpp = lpp->nxtlineblock) ;
  68.                 if(sepc==ALLDEPS && leftp->namep[0]=='.')
  69.                     lpp->shp = 0;
  70.             lpp->nxtlineblock = lp;
  71.             }
  72.         }
  73.     }
  74.     | error
  75.     ;
  76.  
  77. namelist: NAME    = { lefts[0] = $1; nlefts = 1; }
  78.     | namelist NAME    = { lefts[nlefts++] = $2;
  79.             if(nlefts>NLEFTS) fatal("Too many lefts"); }
  80.     ;
  81.  
  82. deplist:
  83.         {
  84.         char junk[10];
  85.         sprintf(junk, "%d", yylineno);
  86.         fatal1("Must be a separator on rules line %s", junk);
  87.         }
  88.     | dlist
  89.     ;
  90.  
  91. dlist:  sepchar    = { prevdep = 0;  $$ = 0; }
  92.     | dlist NAME    = {
  93.               pp = ALLOC(depblock);
  94.               pp->nxtdepblock = NULL;
  95.               pp->depname = $2;
  96.               if(prevdep == 0) $$ = pp;
  97.               else  prevdep->nxtdepblock = pp;
  98.               prevdep = pp;
  99.               }
  100.     ;
  101.  
  102. sepchar:  COLON     = { sepc = ALLDEPS; }
  103.     | DOUBLECOLON    = { sepc = SOMEDEPS; }
  104.     ;
  105.  
  106. shellist:    = {$$ = 0; }
  107.     | shlist = { $$ = $1; }
  108.     ;
  109.  
  110. shlist:    SHELLINE   = { $$ = $1;  prevshp = $1; }
  111.     | shlist SHELLINE = { $$ = $1;
  112.             prevshp->nxtshblock = $2;
  113.             prevshp = $2;
  114.             }
  115.     ;
  116.  
  117. %%
  118.  
  119. char *zznextc;    /* zero if need another line; otherwise points to next char */
  120. int yylineno;
  121. extern FILE * fin;
  122.  
  123. yylex()
  124. {
  125. register char *p;
  126. register char *q;
  127. char word[INMAX];
  128.  
  129. if(zznextc == 0)
  130.     return( nextlin() );
  131.  
  132. while( isspace(*zznextc) )
  133.     ++zznextc;
  134.  
  135. if(*zznextc == '\0')
  136.     return( nextlin() );
  137.  
  138. if(*zznextc == ':')
  139.     {
  140.     if(*++zznextc == ':')
  141.         {
  142.         ++zznextc;
  143.         return(DOUBLECOLON);
  144.         }
  145.     else    return(COLON);
  146.     }
  147.  
  148. if(*zznextc == '>')
  149.     {
  150.     ++zznextc;
  151.     return(GREATER);
  152.     }
  153.  
  154. if(*zznextc == ';')
  155.     return( retsh(zznextc) );
  156.  
  157. p = zznextc;
  158. q = word;
  159.  
  160. while( ! ( funny[*p] & TERMINAL) )
  161.     *q++ = *p++;
  162.  
  163. if(p != zznextc)
  164.     {
  165.     *q = '\0';
  166.     if((yylval.ynameblock=srchname(word))==0)
  167.         yylval.ynameblock = makename(word);
  168.     zznextc = p;
  169.     return(NAME);
  170.     }
  171.  
  172. else    {
  173.     fprintf(stderr,"Bad character %c (octal %o), line %d",
  174.         *zznextc,*zznextc,yylineno);
  175.     fatal( (char *) NULL );
  176.     }
  177. return(0);    /* never executed */
  178. }
  179.  
  180.  
  181.  
  182.  
  183.  
  184. retsh(q)
  185. char *q;
  186. {
  187. register char *p;
  188. struct shblock *sp;
  189. char *copys();
  190.  
  191. for(p=q+1 ; *p==' '||*p=='\t' ; ++p)  ;
  192.  
  193. sp = ALLOC(shblock);
  194. sp->nxtshblock = NULL;
  195. sp->shbp = (fin == NULL ? p : copys(p) );
  196. yylval.yshblock = sp;
  197. zznextc = 0;
  198. return(SHELLINE);
  199. }
  200.  
  201. nextlin()
  202. {
  203. static char yytext[INMAX];
  204. static char *yytextl    = yytext+INMAX;
  205. char *text, templin[INMAX];
  206. register char c;
  207. register char *p, *t;
  208. char lastch, *lastchp;
  209. extern char **linesptr;
  210. int incom;
  211. int kc;
  212.  
  213. again:
  214.  
  215.     incom = NO;
  216.     zznextc = 0;
  217.  
  218. if(fin == NULL)
  219.     {
  220.     if( (text = *linesptr++) == 0)
  221.         return(0);
  222.     ++yylineno;
  223.     }
  224.  
  225. else    {
  226.     for(p = text = yytext ; p<yytextl ; *p++ = kc)
  227.         switch(kc = getc(fin))
  228.             {
  229.             case '\t':
  230.                 if(p != yytext)
  231.                     break;
  232.             case ';':
  233.                 incom = YES;
  234.                 break;
  235.  
  236.             case '#':
  237.                 if(! incom)
  238.                     kc = '\0';
  239.                 break;
  240.  
  241.             case '\n':
  242.                 ++yylineno;
  243.                 if(p==yytext || p[-1]!='\\')
  244.                     {
  245.                     *p = '\0';
  246.                     goto endloop;
  247.                     }
  248.                 p[-1] = ' ';
  249.                 while( (kc=getc(fin))=='\t' || kc==' ' || kc=='\n')
  250.                     if(kc == '\n')
  251.                         ++yylineno;
  252.     
  253.                 if(kc != EOF)
  254.                     break;
  255.             case EOF:
  256.                 *p = '\0';
  257.                 return(0);
  258.             }
  259.  
  260.     fatal("line too long");
  261.     }
  262.  
  263. endloop:
  264.  
  265.     if((c = text[0]) == '\t')
  266.         return( retsh(text) );
  267.     
  268.     if(isalpha(c) || isdigit(c) || c==' ' || c=='.')
  269.         for(p=text+1; *p!='\0'; )
  270.             if(*p == ':')
  271.                 break;
  272.             else if(*p++ == '=')
  273.                 {
  274.                 eqsign(text);
  275.                 return(MACRODEF);
  276.                 }
  277.  
  278. /* substitute for macros on dependency line up to the semicolon if any */
  279.  
  280. for(t = yytext ; *t!='\0' && *t!=';' ; ++t)
  281.     ;
  282.  
  283. lastchp = t;
  284. lastch = *t;
  285. *t = '\0';
  286.  
  287. subst(yytext, templin);        /* Substitute for macros on dependency lines */
  288.  
  289. if(lastch)
  290.     {
  291.     for(t = templin ; *t ; ++t)
  292.         ;
  293.     *t = lastch;
  294.     while( *++t = *++lastchp ) ;
  295.     }
  296.  
  297. p = templin;
  298. t = yytext;
  299. while( *t++ = *p++ )
  300.     ;
  301.  
  302. for(p = zznextc = text ; *p ; ++p )
  303.     if(*p!=' ' && *p!='\t')
  304.         return(START);
  305. goto again;
  306. }
  307.