Research V7 development
[unix-history] / usr / src / cmd / struct / beauty.y
%term xxif 300 xxelse 301 xxwhile 302 xxrept 303 xxdo 304 xxrb 305 xxpred 306
%term xxident 307 xxle 308 xxge 309 xxne 310 xxnum 311 xxcom 312
%term xxstring 313 xxexplist 314 xxidpar 315 xxelseif 316 xxlb 318 xxend 319
%term xxcase 320 xxswitch 321 xxuntil 322 xxdefault 323
%term xxeq 324
%left '|'
%left '&'
%left '!'
%binary '<' '>' xxeq xxne xxge xxle
%left '+' '-'
%left '*' '/'
%left xxuminus
%right '^'
%{
#include "b.h"
#include <stdio.h>
%}
%%
%{
struct node *t;
%}
allprog: prog xxnew
;
prog: stat
| prog stat
;
stat: iftok pred nlevel elsetok nlevel
| iftok pred nlevel
| xxtab whtok pred nlevel
| xxtab rpttok nlevel optuntil
| xxtab dotok nlevel
| xxtab swtok oppred pindent lbtok caseseq xxtab rbtok mindent
| xxtab fstok
| lbtok prog xxtab rbtok
| lbtok rbtok
| labtok stat
| xxnl comtok stat
| error
;
xxtab: = {
if (!xxlablast) tab(xxindent);
xxlablast = 0;
}
xxnl: = newline();
xxnew: = putout('\n',"\n");
nlevel: pindent stat mindent;
pindent: =
{
if (xxstack[xxstind] != xxlb)
++xxindent;
};
mindent: =
{if (xxstack[xxstind] != xxlb && xxstack[xxstind] != xxelseif)
--xxindent;
pop();
};
caseseq: casetok caseseq
| casetok
;
casetok: xxtab xxctok predlist pindent prog mindent
| xxtab xxctok predlist pindent mindent
| xxtab deftok pindent prog mindent
| xxnl comtok casetok
;
xxctok: xxcase = {putout(xxcase,"case "); free ($1); push(xxcase); }
deftok: xxdefault ':' = {
putout(xxcase,"default");
free($1);
putout(':',":");
free($2);
push(xxcase);
}
swtok: xxswitch = {putout(xxswitch,"switch"); free($1); push(xxswitch); }
fstok: xxend = {
free($1);
putout(xxident,"end");
putout('\n',"\n");
putout('\n',"\n");
putout('\n',"\n");
}
| xxident = {
putout(xxident,$1);
free($1);
newflag = 1;
forst();
newflag = 0;
};
identtok: xxident '(' explist ')' = {
xxt = addroot($1,xxident,0,0);
$$ = addroot("",xxidpar,xxt,$3);
}
| xxident = $$ = addroot($1,xxident,0,0);
;
predlist: explist ':' = {
yield($1,0);
putout(':',":");
freetree($1);
}
explist: expr ',' explist = $$ = addroot($2,xxexplist,checkneg($1,0),$3);
| expr = $$ = checkneg($1,0);
;
oppred: pred
|
;
pred: '(' expr ')' = { t = checkneg($2,0);
yield(t,100); freetree(t); };
expr: '(' expr ')' = $$ = $2;
| '-' expr %prec xxuminus = $$ = addroot($1,xxuminus,$2,0);
| '+' expr %prec xxuminus = $$ = $2;
| '!' expr = $$ = addroot($1,'!',$2,0);
| expr '+' expr = $$ = addroot($2,'+',$1,$3);
| expr '-' expr = $$ = addroot($2,'-',$1,$3);
| expr '*' expr = $$ = addroot($2,'*',$1,$3);
| expr '/' expr = $$ = addroot($2,'/',$1,$3);
| expr '^' expr = $$ = addroot($2,'^',$1,$3);
| expr '|' expr = $$ = addroot($2,'|',$1,$3);
| expr '&' expr = $$ = addroot($2,'&',$1,$3);
| expr '>' expr = $$ = addroot($2,'>',$1,$3);
| expr '<' expr = $$ = addroot($2,'<',$1,$3);
| expr xxeq expr = $$ = addroot($2,xxeq,$1,$3);
| expr xxle expr = $$ = addroot($2,xxle,$1,$3);
| expr xxge expr = $$ = addroot($2,xxge,$1,$3);
| expr xxne expr = $$ = addroot($2,xxne,$1,$3);
| identtok = $$ = $1;
| xxnum = $$ = addroot($1,xxnum,0,0);
| xxstring = $$ = addroot($1,xxstring,0,0);
;
iftok: xxif =
{
if (xxstack[xxstind] == xxelse && !xxlablast)
{
--xxindent;
xxstack[xxstind] = xxelseif;
putout(' '," ");
}
else
{
if (!xxlablast)
tab(xxindent);
xxlablast = 0;
}
putout(xxif,"if");
free($1);
push(xxif);
}
elsetok: xxelse =
{
tab(xxindent);
putout(xxelse,"else");
free($1);
push(xxelse);
}
whtok: xxwhile = {
putout(xxwhile,"while");
free($1);
push(xxwhile);
}
rpttok: xxrept = {
putout(xxrept,"repeat");
free($1);
push(xxrept);
}
optuntil: xxtab unttok pred
|
;
unttok: xxuntil = {
putout('\t',"\t");
putout(xxuntil,"until");
free($1);
}
dotok: dopart opdotok
;
dopart: xxdo identtok '=' expr ',' expr =
{push(xxdo);
putout(xxdo,"do");
free($1);
puttree($2);
putout('=',"=");
free($3);
puttree($4);
putout(',',",");
free($5);
puttree($6);
}
opdotok: ',' expr = {
putout(',',",");
puttree($2);
}
| ;
lbtok: '{' = {
putout('{'," {");
push(xxlb);
}
rbtok: '}' = { putout('}',"}"); pop(); }
labtok: xxnum = {
tab(xxindent);
putout(xxnum,$1);
putout(' '," ");
xxlablast = 1;
}
comtok: xxcom = { putout(xxcom,$1); free($1); xxlablast = 0; }
| comtok xxcom = { putout ('\n',"\n"); putout(xxcom,$2); free($2); xxlablast = 0; };
%%
#define ASSERT(X,Y) if (!(X)) error("struct bug: assertion 'X' invalid in routine Y","","");
yyerror(s)
char *s;
{
extern int yychar;
fprintf(stderr,"\n%s",s);
fprintf(stderr," in beautifying, output line %d,",xxlineno + 1);
fprintf(stderr," on input: ");
switch (yychar) {
case '\t': fprintf(stderr,"\\t\n"); return;
case '\n': fprintf(stderr,"\\n\n"); return;
case '\0': fprintf(stderr,"$end\n"); return;
default: fprintf(stderr,"%c\n",yychar); return;
}
}
yyinit(argc, argv) /* initialize pushdown store */
int argc;
char *argv[];
{
xxindent = 0;
xxbpertab = 8;
xxmaxchars = 120;
}
#include <signal.h>
main()
{
int exit();
if ( signal(SIGINT, SIG_IGN) != SIG_IGN)
signal(SIGINT, exit);
yyinit();
yyparse();
}
putout(type,string) /* output string with proper indentation */
int type;
char *string;
{
static int lasttype;
if ( (lasttype != 0) && (lasttype != '\n') && (lasttype != ' ') && (lasttype != '\t') && (type == xxcom))
accum("\t");
else if (lasttype == xxcom && type != '\n')
tab(xxindent);
else
if (lasttype == xxif ||
lasttype == xxwhile ||
lasttype == xxdo ||
type == '=' ||
lasttype == '=' ||
(lasttype == xxident && (type == xxident || type == xxnum) ) ||
(lasttype == xxnum && type == xxnum) )
accum(" ");
accum(string);
lasttype = type;
}
accum(token) /* fill output buffer, generate continuation lines */
char *token;
{
static char *buffer;
static int lstatus,llen,bufind;
int tstatus,tlen,i;
#define NEW 0
#define MID 1
#define CONT 2
if (buffer == 0)
{
buffer = malloc(xxmaxchars);
if (buffer == 0) error("malloc out of space","","");
}
tlen = slength(token);
if (tlen == 0) return;
for (i = 0; i < tlen; ++i)
ASSERT(token[i] != '\n' || tlen == 1,accum);
switch(token[tlen-1])
{
case '\n': tstatus = NEW;
break;
case '+':
case '-':
case '*':
case ',':
case '|':
case '&':
case '(': tstatus = CONT;
break;
default: tstatus = MID;
}
if (llen + bufind + tlen > xxmaxchars && lstatus == CONT && tstatus != NEW)
{
putchar('\n');
++xxlineno;
for (i = 0; i < xxindent; ++i)
putchar('\t');
putchar(' ');putchar(' ');
llen = 2 + xxindent * xxbpertab;
lstatus = NEW;
}
if (lstatus == CONT && tstatus == MID)
{ /* store in buffer in case need \n after last CONT char */
ASSERT(bufind + tlen < xxmaxchars,accum);
for (i = 0; i < tlen; ++i)
buffer[bufind++] = token[i];
}
else
{
for (i = 0; i < bufind; ++i)
putchar(buffer[i]);
llen += bufind;
bufind = 0;
for (i = 0; i < tlen; ++i)
putchar(token[i]);
if (tstatus == NEW) ++xxlineno;
llen = (tstatus == NEW) ? 0 : llen + tlen;
lstatus = tstatus;
}
}
tab(n)
int n;
{
int i;
newline();
for ( i = 0; i < n; ++i)
putout('\t',"\t");
}
newline()
{
static int already;
if (already)
putout('\n',"\n");
else
already = 1;
}
error(mess1, mess2, mess3)
char *mess1, *mess2, *mess3;
{
fprintf(stderr,"\nerror in beautifying, output line %d: %s %s %s \n",
xxlineno, mess1, mess2, mess3);
exit(1);
}
push(type)
int type;
{
if (++xxstind > xxtop)
error("nesting too deep, stack overflow","","");
xxstack[xxstind] = type;
}
pop()
{
if (xxstind <= 0)
error("stack exhausted, can't be popped as requested","","");
--xxstind;
}
forst()
{
while( (xxval = yylex()) != '\n')
{
putout(xxval, yylval);
free(yylval);
}
free(yylval);
}