1: %{
   2:     int *getout();
   3: %}
   4: %right '='
   5: %left '+' '-'
   6: %left '*' '/' '%'
   7: %right '^'
   8: %left UMINUS
   9: 
  10: %term LETTER DIGIT SQRT LENGTH _IF  FFF EQ
  11: %term _WHILE _FOR NE LE GE INCR DECR
  12: %term _RETURN _BREAK _DEFINE BASE OBASE SCALE
  13: %term EQPL EQMI EQMUL EQDIV EQREM EQEXP
  14: %term _AUTO DOT
  15: %term QSTR
  16: 
  17: %{
  18: #include <stdio.h>
  19: int in;
  20: char cary[1000], *cp = { cary };
  21: char string[1000], *str = {string};
  22: int crs = '0';
  23: int rcrs = '0';  /* reset crs */
  24: int bindx = 0;
  25: int lev = 0;
  26: int ln;
  27: char *ss;
  28: int bstack[10] = { 0 };
  29: char *numb[15] = {
  30:   " 0", " 1", " 2", " 3", " 4", " 5",
  31:   " 6", " 7", " 8", " 9", " 10", " 11",
  32:   " 12", " 13", " 14" };
  33: int *pre, *post;
  34: %}
  35: %%
  36: start   :
  37:     |  start stat tail
  38:         = output( $2 );
  39:     |  start def dargs ')' '{' dlist slist '}'
  40:         ={  bundle( 6,pre, $7, post ,"0",numb[lev],"Q");
  41:             conout( $$, $2 );
  42:             rcrs = crs;
  43:             output( "" );
  44:             lev = bindx = 0;
  45:             }
  46:     ;
  47: 
  48: dlist   :  tail
  49:     | dlist _AUTO dlets tail
  50:     ;
  51: 
  52: stat    :  e
  53:         ={ bundle(2, $1, "ps." ); }
  54:     |
  55:         ={ bundle(1, "" ); }
  56:     |  QSTR
  57:         ={ bundle(3,"[",$1,"]P");}
  58:     |  LETTER '=' e
  59:         ={ bundle(3, $3, "s", $1 ); }
  60:     |  LETTER '[' e ']' '=' e
  61:         ={ bundle(4, $6, $3, ":", geta($1)); }
  62:     |  LETTER EQOP e
  63:         ={ bundle(6, "l", $1, $3, $2, "s", $1 ); }
  64:     |  LETTER '[' e ']' EQOP e
  65:         ={ bundle(8,$3, ";", geta($1), $6, $5, $3, ":", geta($1));}
  66:     |  _BREAK
  67:         ={ bundle(2, numb[lev-bstack[bindx-1]], "Q" ); }
  68:     |  _RETURN '(' e ')'
  69:         = bundle(4, $3, post, numb[lev], "Q" );
  70:     |  _RETURN '(' ')'
  71:         = bundle(4, "0", post, numb[lev], "Q" );
  72:     | _RETURN
  73:         = bundle(4,"0",post,numb[lev],"Q");
  74:     | SCALE '=' e
  75:         = bundle(2, $3, "k");
  76:     | SCALE EQOP e
  77:         = bundle(4,"K",$3,$2,"k");
  78:     | BASE '=' e
  79:         = bundle(2,$3, "i");
  80:     | BASE EQOP e
  81:         = bundle(4,"I",$3,$2,"i");
  82:     | OBASE '=' e
  83:         = bundle(2,$3,"o");
  84:     | OBASE EQOP e
  85:         = bundle(4,"O",$3,$2,"o");
  86:     |  '{' slist '}'
  87:         ={ $$ = $2; }
  88:     |  FFF
  89:         ={ bundle(1,"fY"); }
  90:     |  error
  91:         ={ bundle(1,"c"); }
  92:     |  _IF CRS BLEV '(' re ')' stat
  93:         ={  conout( $7, $2 );
  94:             bundle(3, $5, $2, " " );
  95:             }
  96:     |  _WHILE CRS '(' re ')' stat BLEV
  97:         ={  bundle(3, $6, $4, $2 );
  98:             conout( $$, $2 );
  99:             bundle(3, $4, $2, " " );
 100:             }
 101:     |  fprefix CRS re ';' e ')' stat BLEV
 102:         ={  bundle(5, $7, $5, "s.", $3, $2 );
 103:             conout( $$, $2 );
 104:             bundle(5, $1, "s.", $3, $2, " " );
 105:             }
 106:     |  '~' LETTER '=' e
 107:         ={  bundle(3,$4,"S",$2); }
 108:     ;
 109: 
 110: EQOP    :  EQPL
 111:         ={ $$ = "+"; }
 112:     |  EQMI
 113:         ={ $$ = "-"; }
 114:     |  EQMUL
 115:         ={ $$ = "*"; }
 116:     |  EQDIV
 117:         ={ $$ = "/"; }
 118:     |  EQREM
 119:         ={ $$ = "%%"; }
 120:     |  EQEXP
 121:         ={ $$ = "^"; }
 122:     ;
 123: 
 124: fprefix :  _FOR '(' e ';'
 125:         ={ $$ = $3; }
 126:     ;
 127: 
 128: BLEV    :
 129:         ={ --bindx; }
 130:     ;
 131: 
 132: slist   :  stat
 133:     |  slist tail stat
 134:         ={ bundle(2, $1, $3 ); }
 135:     ;
 136: 
 137: tail    :  '\n'
 138:         ={ln++;}
 139:     |  ';'
 140:     ;
 141: 
 142: re  :  e EQ e
 143:         = bundle(3, $1, $3, "=" );
 144:     |  e '<' e
 145:         = bundle(3, $1, $3, ">" );
 146:     |  e '>' e
 147:         = bundle(3, $1, $3, "<" );
 148:     |  e NE e
 149:         = bundle(3, $1, $3, "!=" );
 150:     |  e GE e
 151:         = bundle(3, $1, $3, "!>" );
 152:     |  e LE e
 153:         = bundle(3, $1, $3, "!<" );
 154:     |  e
 155:         = bundle(2, $1, " 0!=" );
 156:     ;
 157: 
 158: e   :  e '+' e
 159:         = bundle(3, $1, $3, "+" );
 160:     |  e '-' e
 161:         = bundle(3, $1, $3, "-" );
 162:     | '-' e     %prec UMINUS
 163:         = bundle(3, " 0", $2, "-" );
 164:     |  e '*' e
 165:         = bundle(3, $1, $3, "*" );
 166:     |  e '/' e
 167:         = bundle(3, $1, $3, "/" );
 168:     |  e '%' e
 169:         = bundle(3, $1, $3, "%%" );
 170:     |  e '^' e
 171:         = bundle(3, $1, $3, "^" );
 172:     |  LETTER '[' e ']'
 173:         ={ bundle(3,$3, ";", geta($1)); }
 174:     |  LETTER INCR
 175:         = bundle(4, "l", $1, "d1+s", $1 );
 176:     |  INCR LETTER
 177:         = bundle(4, "l", $2, "1+ds", $2 );
 178:     |  DECR LETTER
 179:         = bundle(4, "l", $2, "1-ds", $2 );
 180:     |  LETTER DECR
 181:         = bundle(4, "l", $1, "d1-s", $1 );
 182:     | LETTER '[' e ']' INCR
 183:         = bundle(7,$3,";",geta($1),"d1+",$3,":",geta($1));
 184:     | INCR LETTER '[' e ']'
 185:         = bundle(7,$4,";",geta($2),"1+d",$4,":",geta($2));
 186:     | LETTER '[' e ']' DECR
 187:         = bundle(7,$3,";",geta($1),"d1-",$3,":",geta($1));
 188:     | DECR LETTER '[' e ']'
 189:         = bundle(7,$4,";",geta($2),"1-d",$4,":",geta($2));
 190:     | SCALE INCR
 191:         = bundle(1,"Kd1+k");
 192:     | INCR SCALE
 193:         = bundle(1,"K1+dk");
 194:     | SCALE DECR
 195:         = bundle(1,"Kd1-k");
 196:     | DECR SCALE
 197:         = bundle(1,"K1-dk");
 198:     | BASE INCR
 199:         = bundle(1,"Id1+i");
 200:     | INCR BASE
 201:         = bundle(1,"I1+di");
 202:     | BASE DECR
 203:         = bundle(1,"Id1-i");
 204:     | DECR BASE
 205:         = bundle(1,"I1-di");
 206:     | OBASE INCR
 207:         = bundle(1,"Od1+o");
 208:     | INCR OBASE
 209:         = bundle(1,"O1+do");
 210:     | OBASE DECR
 211:         = bundle(1,"Od1-o");
 212:     | DECR OBASE
 213:         = bundle(1,"O1-do");
 214:     |  LETTER '(' cargs ')'
 215:         = bundle(4, $3, "l", getf($1), "x" );
 216:     |  LETTER '(' ')'
 217:         = bundle(3, "l", getf($1), "x" );
 218:     |  cons
 219:         ={ bundle(2, " ", $1 ); }
 220:     |  DOT cons
 221:         ={ bundle(2, " .", $2 ); }
 222:     |  cons DOT cons
 223:         ={ bundle(4, " ", $1, ".", $3 ); }
 224:     |  cons DOT
 225:         ={ bundle(3, " ", $1, "." ); }
 226:     |  DOT
 227:         ={ $$ = "l."; }
 228:     |  LETTER
 229:         = { bundle(2, "l", $1 ); }
 230:     |  LETTER '=' e
 231:         ={ bundle(3, $3, "ds", $1 ); }
 232:     |  LETTER EQOP e    %prec '='
 233:         ={ bundle(6, "l", $1, $3, $2, "ds", $1 ); }
 234:     | LETTER '[' e ']' '=' e
 235:         = { bundle(5,$6,"d",$3,":",geta($1)); }
 236:     | LETTER '[' e ']' EQOP e
 237:         = { bundle(9,$3,";",geta($1),$6,$5,"d",$3,":",geta($1)); }
 238:     | LENGTH '(' e ')'
 239:         = bundle(2,$3,"Z");
 240:     | SCALE '(' e ')'
 241:         = bundle(2,$3,"X"); /* must be before '(' e ')' */
 242:     |  '(' e ')'
 243:         = { $$ = $2; }
 244:     |  '?'
 245:         ={ bundle(1, "?" ); }
 246:     |  SQRT '(' e ')'
 247:         ={ bundle(2, $3, "v" ); }
 248:     | '~' LETTER
 249:         ={ bundle(2,"L",$2); }
 250:     | SCALE '=' e
 251:         = bundle(2,$3,"dk");
 252:     | SCALE EQOP e      %prec '='
 253:         = bundle(4,"K",$3,$2,"dk");
 254:     | BASE '=' e
 255:         = bundle(2,$3,"di");
 256:     | BASE EQOP e       %prec '='
 257:         = bundle(4,"I",$3,$2,"di");
 258:     | OBASE '=' e
 259:         = bundle(2,$3,"do");
 260:     | OBASE EQOP e      %prec '='
 261:         = bundle(4,"O",$3,$2,"do");
 262:     | SCALE
 263:         = bundle(1,"K");
 264:     | BASE
 265:         = bundle(1,"I");
 266:     | OBASE
 267:         = bundle(1,"O");
 268:     ;
 269: 
 270: cargs   :  eora
 271:     |  cargs ',' eora
 272:         = bundle(2, $1, $3 );
 273:     ;
 274: eora:     e
 275:     | LETTER '[' ']'
 276:         =bundle(2,"l",geta($1));
 277:     ;
 278: 
 279: cons    :  constant
 280:         ={ *cp++ = '\0'; }
 281: 
 282: constant:
 283:       '_'
 284:         ={ $$ = cp; *cp++ = '_'; }
 285:     |  DIGIT
 286:         ={ $$ = cp; *cp++ = $1; }
 287:     |  constant DIGIT
 288:         ={ *cp++ = $2; }
 289:     ;
 290: 
 291: CRS :
 292:         ={ $$ = cp; *cp++ = crs++; *cp++ = '\0';
 293:             if(crs == '[')crs=+3;
 294:             if(crs == 'a')crs='{';
 295:             if(crs >= 0241){yyerror("program too big");
 296:                 getout();
 297:             }
 298:             bstack[bindx++] = lev++; }
 299:     ;
 300: 
 301: def :  _DEFINE LETTER '('
 302:         ={  $$ = getf($2);
 303:             pre = "";
 304:             post = "";
 305:             lev = 1;
 306:             bstack[bindx=0] = 0;
 307:             }
 308:     ;
 309: 
 310: dargs   :
 311:     |  lora
 312:         ={ pp( $1 ); }
 313:     |  dargs ',' lora
 314:         ={ pp( $3 ); }
 315:     ;
 316: 
 317: dlets   :  lora
 318:         ={ tp($1); }
 319:     |  dlets ',' lora
 320:         ={ tp($3); }
 321:     ;
 322: lora    :  LETTER
 323:     |  LETTER '[' ']'
 324:         ={ $$ = geta($1); }
 325:     ;
 326: 
 327: %%
 328: # define error 256
 329: 
 330: int peekc = -1;
 331: int sargc;
 332: int ifile;
 333: char **sargv;
 334: 
 335: char funtab[52] = {
 336:     01,0,02,0,03,0,04,0,05,0,06,0,07,0,010,0,011,0,012,0,013,0,014,0,015,0,016,0,017,0,
 337:     020,0,021,0,022,0,023,0,024,0,025,0,026,0,027,0,030,0,031,0,032,0 };
 338: char atab[52] = {
 339:     0241,0,0242,0,0243,0,0244,0,0245,0,0246,0,0247,0,0250,0,0251,0,0252,0,0253,0,
 340:     0254,0,0255,0,0256,0,0257,0,0260,0,0261,0,0262,0,0263,0,0264,0,0265,0,0266,0,
 341:     0267,0,0270,0,0271,0,0272,0};
 342: char *letr[26] = {
 343:   "a","b","c","d","e","f","g","h","i","j",
 344:   "k","l","m","n","o","p","q","r","s","t",
 345:   "u","v","w","x","y","z" } ;
 346: char *dot = { "." };
 347: yylex(){
 348:     int c, ch;
 349: restart:
 350:     c = getch();
 351:     peekc = -1;
 352:     while( c == ' ' || c == '\t' ) c = getch();
 353:     if(c == '\\'){
 354:         getch();
 355:         goto restart;
 356:     }
 357:     if( c<= 'z' && c >= 'a' ) {
 358:         /* look ahead to look for reserved words */
 359:         peekc = getch();
 360:         if( peekc >= 'a' && peekc <= 'z' ){ /* must be reserved word */
 361:             if( c=='i' && peekc=='f' ){ c=_IF; goto skip; }
 362:             if( c=='w' && peekc=='h' ){ c=_WHILE; goto skip; }
 363:             if( c=='f' && peekc=='o' ){ c=_FOR; goto skip; }
 364:             if( c=='s' && peekc=='q' ){ c=SQRT; goto skip; }
 365:             if( c=='r' && peekc=='e' ){ c=_RETURN; goto skip; }
 366:             if( c=='b' && peekc=='r' ){ c=_BREAK; goto skip; }
 367:             if( c=='d' && peekc=='e' ){ c=_DEFINE; goto skip; }
 368:             if( c=='s' && peekc=='c' ){ c= SCALE; goto skip; }
 369:             if( c=='b' && peekc=='a' ){ c=BASE; goto skip; }
 370:             if( c=='i' && peekc == 'b'){ c=BASE; goto skip; }
 371:             if( c=='o' && peekc=='b' ){ c=OBASE; goto skip; }
 372:             if( c=='d' && peekc=='i' ){ c=FFF; goto skip; }
 373:             if( c=='a' && peekc=='u' ){ c=_AUTO; goto skip; }
 374:             if( c == 'l' && peekc=='e'){ c=LENGTH; goto skip; }
 375:             if( c == 'q' && peekc == 'u'){getout();}
 376:             /* could not be found */
 377:             return( error );
 378:         skip:   /* skip over rest of word */
 379:             peekc = -1;
 380:             while( (ch = getch()) >= 'a' && ch <= 'z' );
 381:             peekc = ch;
 382:             return( c );
 383:         }
 384: 
 385:         /* usual case; just one single letter */
 386: 
 387:         yylval = letr[c-'a'];
 388:         return( LETTER );
 389:     }
 390:     if( c>= '0' && c <= '9' || c>= 'A' && c<= 'F' ){
 391:         yylval = c;
 392:         return( DIGIT );
 393:     }
 394:     switch( c ){
 395:     case '.':   return( DOT );
 396:     case '=':
 397:         switch( peekc = getch() ){
 398:         case '=': c=EQ; goto gotit;
 399:         case '+': c=EQPL; goto gotit;
 400:         case '-': c=EQMI; goto gotit;
 401:         case '*': c=EQMUL; goto gotit;
 402:         case '/': c=EQDIV; goto gotit;
 403:         case '%': c=EQREM; goto gotit;
 404:         case '^': c=EQEXP; goto gotit;
 405:         default:   return( '=' );
 406:               gotit:     peekc = -1; return(c);
 407:           }
 408:     case '+':   return( cpeek( '+', INCR, '+' ) );
 409:     case '-':   return( cpeek( '-', DECR, '-' ) );
 410:     case '<':   return( cpeek( '=', LE, '<' ) );
 411:     case '>':   return( cpeek( '=', GE, '>' ) );
 412:     case '!':   return( cpeek( '=', NE, '!' ) );
 413:     case '/':
 414:         if((peekc = getch()) == '*'){
 415:             peekc = -1;
 416:             while((getch() != '*') || ((peekc = getch()) != '/'));
 417:             peekc = -1;
 418:             goto restart;
 419:         }
 420:         else return(c);
 421:     case '"':
 422:          yylval = str;
 423:          while((c=getch()) != '"'){*str++ = c;
 424:             if(str >= &string[999]){yyerror("string space exceeded");
 425:             getout();
 426:         }
 427:     }
 428:      *str++ = '\0';
 429:     return(QSTR);
 430:     default:     return( c );
 431:     }
 432: }
 433: 
 434: cpeek( c, yes, no ){
 435:     if( (peekc=getch()) != c ) return( no );
 436:     else {
 437:         peekc = -1;
 438:         return( yes );
 439:     }
 440: }
 441: 
 442: getch(){
 443:     int ch;
 444: loop:
 445:     ch = (peekc < 0) ? getc(in) : peekc;
 446:     peekc = -1;
 447:     if(ch != EOF)return(ch);
 448:     if(++ifile > sargc){
 449:         if(ifile >= sargc+2)getout();
 450:         in = stdin;
 451:         ln = 0;
 452:         goto loop;
 453:     }
 454:     fclose(in);
 455:     if((in = fopen(sargv[ifile],"r")) != NULL){
 456:         ln = 0;
 457:         ss = sargv[ifile];
 458:         goto loop;
 459:     }
 460:     yyerror("cannot open input file");
 461: }
 462: # define b_sp_max 3000
 463: int b_space [ b_sp_max ];
 464: int * b_sp_nxt = { b_space };
 465: 
 466: int bdebug = 0;
 467: bundle(a){
 468:     int i, *p, *q;
 469: 
 470:     p = &a;
 471:     i = *p++;
 472:     q = b_sp_nxt;
 473:     if( bdebug ) printf("bundle %d elements at %o\n",i,  q );
 474:     while(i-- > 0){
 475:         if( b_sp_nxt >= & b_space[b_sp_max] ) yyerror( "bundling space exceeded" );
 476:         * b_sp_nxt++ = *p++;
 477:     }
 478:     * b_sp_nxt++ = 0;
 479:     yyval = q;
 480:     return( q );
 481: }
 482: 
 483: routput(p) int *p; {
 484:     if( bdebug ) printf("routput(%o)\n", p );
 485:     if( p >= &b_space[0] && p < &b_space[b_sp_max]){
 486:         /* part of a bundle */
 487:         while( *p != 0 ) routput( *p++ );
 488:     }
 489:     else printf( p );    /* character string */
 490: }
 491: 
 492: output( p ) int *p; {
 493:     routput( p );
 494:     b_sp_nxt = & b_space[0];
 495:     printf( "\n" );
 496:     fflush(stdout);
 497:     cp = cary;
 498:     crs = rcrs;
 499: }
 500: 
 501: conout( p, s ) int *p; char *s; {
 502:     printf("[");
 503:     routput( p );
 504:     printf("]s%s\n", s );
 505:     fflush(stdout);
 506:     lev--;
 507: }
 508: 
 509: yyerror( s ) char *s; {
 510:     if(ifile > sargc)ss="teletype";
 511:     printf("c[%s on line %d, %s]pc\n", s ,ln+1,ss);
 512:     fflush(stdout);
 513:     cp = cary;
 514:     crs = rcrs;
 515:     bindx = 0;
 516:     lev = 0;
 517:     b_sp_nxt = &b_space[0];
 518: }
 519: 
 520: pp( s ) char *s; {
 521:     /* puts the relevant stuff on pre and post for the letter s */
 522: 
 523:     bundle(3, "S", s, pre );
 524:     pre = yyval;
 525:     bundle(4, post, "L", s, "s." );
 526:     post = yyval;
 527: }
 528: 
 529: tp( s ) char *s; { /* same as pp, but for temps */
 530:     bundle(3, "0S", s, pre );
 531:     pre = yyval;
 532:     bundle(4, post, "L", s, "s." );
 533:     post = yyval;
 534: }
 535: 
 536: yyinit(argc,argv) int argc; char *argv[];{
 537:     signal( 2, (int(*)())1 );   /* ignore all interrupts */
 538:     sargv=argv;
 539:     sargc= -- argc;
 540:     if(sargc == 0)in=stdin;
 541:     else if((in = fopen(sargv[1],"r")) == NULL)
 542:         yyerror("cannot open input file");
 543:     ifile = 1;
 544:     ln = 0;
 545:     ss = sargv[1];
 546: }
 547: int *getout(){
 548:     printf("q");
 549:     fflush(stdout);
 550:     exit();
 551: }
 552: 
 553: int *
 554: getf(p) char *p;{
 555:     return(&funtab[2*(*p -0141)]);
 556: }
 557: int *
 558: geta(p) char *p;{
 559:     return(&atab[2*(*p - 0141)]);
 560: }
 561: 
 562: main(argc, argv)
 563: char **argv;
 564: {
 565:     int p[2];
 566: 
 567: 
 568:     if (argc > 1 && *argv[1] == '-') {
 569:         if((argv[1][1] == 'd')||(argv[1][1] == 'c')){
 570:             yyinit(--argc, ++argv);
 571:             yyparse();
 572:             exit();
 573:         }
 574:         if(argv[1][1] != 'l'){
 575:             printf("unrecognizable argument\n");
 576:             fflush(stdout);
 577:             exit();
 578:         }
 579:         argv[1] = "/usr/lib/lib.b";
 580:     }
 581:     pipe(p);
 582:     if (fork()==0) {
 583:         close(1);
 584:         dup(p[1]);
 585:         close(p[0]);
 586:         close(p[1]);
 587:         yyinit(argc, argv);
 588:         yyparse();
 589:         exit();
 590:     }
 591:     close(0);
 592:     dup(p[0]);
 593:     close(p[0]);
 594:     close(p[1]);
 595:     execl("/bin/dc", "dc", "-", 0);
 596:     execl("/usr/bin/dc", "dc", "-", 0);
 597: }

Defined functions

_bundle defined in line 467; used 93 times
_conout defined in line 501; used 4 times
_cpeek defined in line 434; used 5 times
_geta defined in line 557; used 17 times
_getch defined in line 442; used 11 times
_getf defined in line 553; used 3 times
_getout defined in line 547; used 5 times
_main defined in line 562; never used
_output defined in line 492; used 2 times
_pp defined in line 520; used 2 times
_routput defined in line 483; used 3 times
_tp defined in line 529; used 2 times
_yyerror defined in line 509; used 5 times
_yyinit defined in line 536; used 2 times
_yylex defined in line 347; never used

Defined variables

_atab defined in line 338; used 1 times
_b_sp_nxt defined in line 464; used 6 times
_b_space defined in line 463; used 6 times
_bdebug defined in line 466; used 2 times
_dot defined in line 346; never used
_funtab defined in line 335; used 1 times
_ifile defined in line 332; used 6 times
_letr defined in line 342; used 1 times
_peekc defined in line 330; used 32 times
_sargc defined in line 331; used 5 times
_sargv defined in line 333; used 5 times

Defined macros

b_sp_max defined in line 462; used 3 times
error defined in line 328; used 2 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1328
Valid CSS Valid XHTML 1.0 Strict