home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / struct / beauty.y < prev    next >
Encoding:
Text File  |  1979-01-16  |  8.0 KB  |  412 lines

  1. %term  xxif 300 xxelse 301 xxwhile 302 xxrept 303 xxdo 304 xxrb 305 xxpred 306
  2. %term xxident 307 xxle 308 xxge 309 xxne 310 xxnum 311 xxcom 312
  3. %term xxstring 313 xxexplist 314 xxidpar 315 xxelseif 316  xxlb 318 xxend 319
  4. %term xxcase 320 xxswitch 321 xxuntil 322 xxdefault 323 
  5. %term xxeq 324
  6.  
  7. %left    '|'
  8. %left    '&'
  9. %left    '!'
  10. %binary    '<' '>' xxeq xxne xxge xxle
  11. %left    '+' '-'
  12. %left    '*' '/'
  13. %left    xxuminus
  14. %right    '^'
  15.  
  16. %{
  17. #include "b.h"
  18. #include <stdio.h>
  19. %}
  20.  
  21. %%
  22. %{
  23. struct node *t;
  24. %}
  25.  
  26.  
  27. allprog:    prog xxnew
  28.     ;
  29.  
  30. prog:    stat
  31.     |    prog stat
  32.     ;
  33.  
  34. stat:         iftok pred nlevel elsetok nlevel
  35.     |     iftok  pred  nlevel
  36.     |    xxtab whtok  pred  nlevel
  37.     |    xxtab rpttok nlevel optuntil
  38.     |    xxtab dotok nlevel
  39.     |    xxtab swtok oppred pindent lbtok caseseq xxtab rbtok mindent
  40.     |    xxtab fstok
  41.     |    lbtok prog xxtab rbtok
  42.     |    lbtok rbtok
  43.     |     labtok stat
  44.     |    xxnl comtok stat
  45.     |    error
  46.     ;
  47.  
  48.  
  49. xxtab:        =    {
  50.             if (!xxlablast) tab(xxindent);
  51.             xxlablast = 0;
  52.             }
  53.  
  54. xxnl:    =    newline();
  55. xxnew:    =    putout('\n',"\n");
  56. nlevel:    pindent stat mindent;
  57. pindent:        =
  58.                 {
  59.                 if (xxstack[xxstind] != xxlb)
  60.                     ++xxindent;
  61.                 };
  62. mindent:            =
  63.                 {if (xxstack[xxstind] != xxlb && xxstack[xxstind] != xxelseif)
  64.                     --xxindent;
  65.                 pop();
  66.                 };
  67. caseseq:    casetok caseseq
  68.     |    casetok
  69.     ;
  70.  
  71. casetok:    xxtab xxctok predlist pindent prog mindent
  72.     |    xxtab xxctok predlist pindent mindent
  73.     |    xxtab deftok pindent prog mindent
  74.     |    xxnl comtok casetok
  75.     ;
  76.  
  77. xxctok:    xxcase        =    {putout(xxcase,"case "); free ($1); push(xxcase); }
  78.  
  79.  
  80. deftok:        xxdefault ':'        =        {
  81.                         putout(xxcase,"default");
  82.                         free($1);
  83.                         putout(':',":");
  84.                         free($2);
  85.                         push(xxcase);
  86.                         }
  87. swtok:    xxswitch            =    {putout(xxswitch,"switch"); free($1); push(xxswitch); }
  88.  
  89. fstok:    xxend        =    {
  90.                 free($1);
  91.                 putout(xxident,"end");
  92.                 putout('\n',"\n");
  93.                 putout('\n',"\n");
  94.                 putout('\n',"\n");
  95.                 }
  96.     |    xxident    =    {
  97.                 putout(xxident,$1);
  98.                 free($1);
  99.                 newflag = 1;
  100.                 forst();
  101.                 newflag = 0;
  102.                 };
  103.  
  104.         
  105.  
  106. identtok:    xxident '(' explist ')'    =    {
  107.                 xxt = addroot($1,xxident,0,0);
  108.                 $$ = addroot("",xxidpar,xxt,$3);
  109.                 }
  110.  
  111.     |    xxident        =    $$ = addroot($1,xxident,0,0);
  112.     ;
  113.  
  114. predlist:    explist  ':'        =    {
  115.                 yield($1,0);
  116.                 putout(':',":");
  117.                 freetree($1);
  118.                 }
  119. explist:    expr ',' explist        =    $$ = addroot($2,xxexplist,checkneg($1,0),$3);
  120.     |    expr                    =    $$ = checkneg($1,0);
  121.     ;
  122.  
  123.  
  124. oppred:    pred
  125.     |
  126.     ;
  127.  
  128. pred:    '(' expr ')'    =    { t = checkneg($2,0);
  129.                 yield(t,100);  freetree(t);    };
  130.  
  131. expr:        '(' expr ')'    =    $$ = $2;
  132.     |    '-' expr    %prec xxuminus    =    $$ = addroot($1,xxuminus,$2,0);
  133.     |    '+' expr    %prec xxuminus    =    $$ = $2;
  134.     |    '!' expr    =    $$ = addroot($1,'!',$2,0);
  135.     |    expr '+' expr    =    $$ = addroot($2,'+',$1,$3);
  136.     |    expr '-' expr    =    $$ = addroot($2,'-',$1,$3);
  137.     |    expr '*' expr    =    $$ = addroot($2,'*',$1,$3);
  138.     |    expr '/' expr    =    $$ = addroot($2,'/',$1,$3);
  139.     |    expr '^' expr    =    $$ = addroot($2,'^',$1,$3);
  140.     |    expr '|' expr    =    $$ = addroot($2,'|',$1,$3);
  141.     |    expr '&' expr    =    $$ = addroot($2,'&',$1,$3);
  142.     |    expr '>' expr    =    $$ = addroot($2,'>',$1,$3);
  143.     |    expr '<' expr    =    $$ = addroot($2,'<',$1,$3);
  144.     |    expr xxeq expr    =    $$ = addroot($2,xxeq,$1,$3);
  145.     |    expr xxle expr    =    $$ = addroot($2,xxle,$1,$3);
  146.     |    expr xxge expr    =    $$ = addroot($2,xxge,$1,$3);
  147.     |    expr xxne expr    =    $$ = addroot($2,xxne,$1,$3);
  148.     |    identtok        =    $$ = $1;
  149.     |    xxnum        =    $$ = addroot($1,xxnum,0,0);
  150.     |    xxstring        =    $$ = addroot($1,xxstring,0,0);
  151.     ;
  152.  
  153. iftok:    xxif        =
  154.                 {
  155.                 if (xxstack[xxstind] == xxelse && !xxlablast)
  156.                     {
  157.                     --xxindent;
  158.                     xxstack[xxstind] = xxelseif;
  159.                     putout(' '," ");
  160.                     }
  161.                 else
  162.                     {
  163.                     if (!xxlablast)
  164.                         tab(xxindent);
  165.                     xxlablast = 0;
  166.                     }
  167.                 putout(xxif,"if");
  168.                 free($1);
  169.                 push(xxif);
  170.                 }
  171. elsetok:    xxelse    =
  172.                 {
  173.                 tab(xxindent);
  174.                 putout(xxelse,"else");
  175.                 free($1);
  176.                 push(xxelse);
  177.                 }
  178. whtok:    xxwhile        =    {
  179.                 putout(xxwhile,"while");
  180.                 free($1);
  181.                 push(xxwhile);
  182.                 }
  183. rpttok:    xxrept    =            {
  184.                     putout(xxrept,"repeat");
  185.                     free($1);
  186.                     push(xxrept);
  187.                     }
  188. optuntil:    xxtab unttok pred
  189.         |
  190.         ;
  191.  
  192. unttok:    xxuntil      =     {
  193.             putout('\t',"\t");
  194.             putout(xxuntil,"until");
  195.             free($1);
  196.             }
  197. dotok:    dopart opdotok
  198.     ;
  199. dopart:    xxdo    identtok '=' expr  ',' expr         =
  200.                     {push(xxdo);
  201.                     putout(xxdo,"do");
  202.                     free($1);
  203.                     puttree($2);
  204.                     putout('=',"=");
  205.                     free($3);
  206.                     puttree($4);
  207.                     putout(',',",");
  208.                     free($5);
  209.                     puttree($6);
  210.                     }
  211. opdotok:    ',' expr        =    {
  212.                         putout(',',",");
  213.                         puttree($2);
  214.                         }
  215.     |    ;
  216. lbtok:    '{'        =    {
  217.                 putout('{'," {");
  218.                 push(xxlb);
  219.                 }
  220. rbtok:    '}'            =    { putout('}',"}");  pop();   }
  221. labtok:    xxnum        =    {
  222.                 tab(xxindent);
  223.                 putout(xxnum,$1);
  224.                 putout(' ',"  ");
  225.                 xxlablast = 1;
  226.                 }
  227. comtok:    xxcom        =    { putout(xxcom,$1);  free($1);  xxlablast = 0; }
  228.     |    comtok xxcom        = { putout ('\n',"\n"); putout(xxcom,$2);  free($2);  xxlablast = 0; };
  229. %%
  230. #define ASSERT(X,Y)    if (!(X)) error("struct bug: assertion 'X' invalid in routine Y","","");
  231.  
  232. yyerror(s)
  233. char *s;
  234.     {
  235.     extern int yychar;
  236.     fprintf(stderr,"\n%s",s);
  237.     fprintf(stderr," in beautifying, output line %d,",xxlineno + 1);
  238.     fprintf(stderr," on input: ");
  239.         switch (yychar) {
  240.             case '\t': fprintf(stderr,"\\t\n"); return;
  241.             case '\n': fprintf(stderr,"\\n\n"); return;
  242.             case '\0': fprintf(stderr,"$end\n"); return;
  243.             default: fprintf(stderr,"%c\n",yychar); return;
  244.             }
  245.     }
  246.  
  247. yyinit(argc, argv)            /* initialize pushdown store */
  248. int argc;
  249. char *argv[];
  250.     {
  251.     xxindent = 0;
  252.     xxbpertab = 8;
  253.     xxmaxchars = 120;
  254.     }
  255.  
  256.  
  257. #include <signal.h>
  258. main()
  259.     {
  260.     int exit();
  261.     if ( signal(SIGINT, SIG_IGN) != SIG_IGN)
  262.         signal(SIGINT, exit);
  263.     yyinit();
  264.     yyparse();
  265.     }
  266.  
  267.  
  268. putout(type,string)            /* output string with proper indentation */
  269. int type;
  270. char *string;
  271.     {
  272.     static int lasttype;
  273.     if ( (lasttype != 0) && (lasttype != '\n') && (lasttype != ' ') && (lasttype != '\t') && (type == xxcom))
  274.         accum("\t");
  275.     else if (lasttype == xxcom && type != '\n')
  276.         tab(xxindent);
  277.     else
  278.         if (lasttype == xxif    ||
  279.             lasttype == xxwhile    ||
  280.             lasttype == xxdo    ||
  281.             type == '='    ||
  282.             lasttype == '='    ||
  283.             (lasttype == xxident && (type == xxident || type == xxnum) )    ||
  284.             (lasttype == xxnum && type == xxnum) )
  285.             accum(" ");
  286.     accum(string);
  287.     lasttype = type;
  288.     }
  289.  
  290.  
  291. accum(token)        /* fill output buffer, generate continuation lines */
  292. char *token;
  293.     {
  294.     static char *buffer;
  295.     static int lstatus,llen,bufind;
  296.     int tstatus,tlen,i;
  297.  
  298. #define NEW    0
  299. #define MID    1
  300. #define CONT    2
  301.  
  302.     if (buffer == 0)
  303.         {
  304.         buffer = malloc(xxmaxchars);
  305.         if (buffer == 0) error("malloc out of space","","");
  306.         }
  307.     tlen = slength(token);
  308.     if (tlen == 0) return;
  309.     for (i = 0; i < tlen; ++i)
  310.         ASSERT(token[i] != '\n' || tlen == 1,accum);
  311.     switch(token[tlen-1])
  312.         {
  313.         case '\n':    tstatus = NEW;
  314.                 break;
  315.         case '+':
  316.         case '-':
  317.         case '*':
  318.         case ',':
  319.         case '|':
  320.         case '&':
  321.         case '(':    tstatus = CONT;
  322.                 break;
  323.         default:    tstatus = MID;
  324.         }
  325.     if (llen + bufind + tlen > xxmaxchars && lstatus == CONT && tstatus != NEW)
  326.         {
  327.         putchar('\n');
  328.         ++xxlineno;
  329.         for (i = 0; i < xxindent; ++i)
  330.             putchar('\t');
  331.         putchar(' ');putchar(' ');
  332.         llen = 2 + xxindent * xxbpertab;
  333.         lstatus = NEW;
  334.         }
  335.     if (lstatus == CONT && tstatus == MID)
  336.         {            /* store in buffer in case need \n after last CONT char */
  337.         ASSERT(bufind + tlen < xxmaxchars,accum);
  338.         for (i = 0; i < tlen; ++i)
  339.             buffer[bufind++] = token[i];
  340.         }
  341.     else
  342.         {
  343.         for (i = 0; i < bufind; ++i)
  344.             putchar(buffer[i]);
  345.         llen += bufind;
  346.         bufind = 0;
  347.         for (i = 0; i < tlen; ++i)
  348.             putchar(token[i]);
  349.         if (tstatus == NEW) ++xxlineno;
  350.         llen = (tstatus == NEW) ? 0 : llen + tlen;
  351.         lstatus = tstatus;
  352.         }
  353.     }
  354.  
  355. tab(n)
  356. int n;
  357.     {
  358.     int i;
  359.     newline();
  360.     for ( i = 0;  i < n; ++i)
  361.         putout('\t',"\t");
  362.     }
  363.  
  364. newline()
  365.     {
  366.     static int already;
  367.     if (already)
  368.         putout('\n',"\n");
  369.     else
  370.         already = 1;
  371.     }
  372.  
  373. error(mess1, mess2, mess3)
  374. char *mess1, *mess2, *mess3;
  375.     {
  376.     fprintf(stderr,"\nerror in beautifying, output line %d: %s %s %s \n",
  377.         xxlineno, mess1, mess2, mess3);
  378.     exit(1);
  379.     }
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387. push(type)
  388. int type;
  389.     {
  390.     if (++xxstind > xxtop)
  391.         error("nesting too deep, stack overflow","","");
  392.     xxstack[xxstind] = type;
  393.     }
  394.  
  395. pop()
  396.     {
  397.     if (xxstind <= 0)
  398.         error("stack exhausted, can't be popped as requested","","");
  399.     --xxstind;
  400.     }
  401.  
  402.  
  403. forst()
  404.     {
  405.     while( (xxval = yylex()) != '\n')
  406.         {
  407.         putout(xxval, yylval);
  408.         free(yylval);
  409.         }
  410.     free(yylval);
  411.     }
  412.