home *** CD-ROM | disk | FTP | other *** search
- %right '='
- %left '+' '-'
- %left '*' '/' '%'
- %right '^'
- %left UMINUS
-
- %term LETTER DIGIT SQRT _IF FFF EQ
- %term _WHILE _FOR NE LE GE INCR DECR
- %term _RETURN _BREAK _DEFINE BASE OBASE SCALE
- %term EQPL EQMI EQMUL EQDIV EQREM EQEXP
- %term _AUTO DOT
- %term QSTR
-
- %{
- char cary[1000], *cp { cary };
- char string[1000], *str {string};
- int crs '0';
- int rcrs '0'; /* reset crs */
- int bindx 0;
- int lev 0;
- int bstack[10] { 0 };
- char *numb[15] {
- " 0", " 1", " 2", " 3", " 4", " 5",
- " 6", " 7", " 8", " 9", " 10", " 11",
- " 12", " 13", " 14" };
- int *pre, *post;
- %}
- %%
- start :
- | start stat tail
- = output( $2 );
- | start def dargs ')' '{' dlist slist '}'
- ={ bundle( pre, $7, post );
- conout( $$, $2 );
- rcrs = crs;
- output( "" );
- lev = bindx = 0;
- }
- ;
-
- dlist : tail
- | dlist _AUTO dlets tail
- ;
-
- stat : e
- ={ bundle( $1, "ps." ); }
- |
- ={ bundle( "" ); }
- | QSTR
- ={ bundle("[",$1,"]P");}
- | LETTER '=' e
- ={ bundle( $3, "s", $1 ); }
- | LETTER '[' e ']' '=' e
- ={ bundle( $6, $3, ":", geta($1)); }
- | LETTER EQOP e
- ={ bundle( "l", $1, $3, $2, "s", $1 ); }
- | LETTER '[' e ']' EQOP e
- ={ bundle($3, ";", geta($1), $6, $5, $3, ":", geta($1));}
- | _BREAK
- ={ bundle( numb[lev-bstack[bindx-1]], "Q" ); }
- | _RETURN '(' e ')'
- = bundle( $3, post, numb[lev], "Q" );
- | _RETURN '(' ')'
- = bundle( "0", post, numb[lev], "Q" );
- | SCALE e
- = bundle( $2, "k" );
- | SCALE '=' e
- = bundle( $3, "k");
- | SCALE EQOP e
- = bundle("K",$3,$2,"k");
- | BASE e
- = bundle( $2, "i" );
- | BASE '=' e
- = bundle($3, "i");
- | BASE EQOP e
- = bundle("I",$3,$2,"i");
- | OBASE e
- = bundle( $2, "o" );
- | OBASE '=' e
- = bundle($3,"o");
- | OBASE EQOP e
- = bundle("O",$3,$2,"o");
- | '{' slist '}'
- ={ $$ = $2; }
- | FFF
- ={ bundle("f"); }
- | error
- ={ bundle("c"); }
- | _IF CRS BLEV '(' re ')' stat
- ={ conout( $7, $2 );
- bundle( $5, $2, " " );
- }
- | _WHILE CRS '(' re ')' stat BLEV
- ={ bundle( $6, $4, $2 );
- conout( $$, $2 );
- bundle( $4, $2, " " );
- }
- | fprefix CRS re ';' e ')' stat BLEV
- ={ bundle( $7, $5, "s.", $3, $2 );
- conout( $$, $2 );
- bundle( $1, "s.", $3, $2, " " );
- }
- | '~' LETTER '=' e
- ={ bundle($4,"S",$2); }
- ;
-
- EQOP : EQPL
- ={ $$ = "+"; }
- | EQMI
- ={ $$ = "-"; }
- | EQMUL
- ={ $$ = "*"; }
- | EQDIV
- ={ $$ = "/"; }
- | EQREM
- ={ $$ = "%%"; }
- | EQEXP
- ={ $$ = "^"; }
- ;
-
- fprefix : _FOR '(' e ';'
- ={ $$ = $3; }
- ;
-
- BLEV :
- ={ --bindx; }
- ;
-
- slist : stat
- | slist tail stat
- ={ bundle( $1, $3 ); }
- ;
-
- tail : '\n'
- | ';'
- ;
-
- re : e EQ e
- = bundle( $1, $3, "=" );
- | e '<' e
- = bundle( $1, $3, ">" );
- | e '>' e
- = bundle( $1, $3, "<" );
- | e NE e
- = bundle( $1, $3, "!=" );
- | e GE e
- = bundle( $1, $3, "!>" );
- | e LE e
- = bundle( $1, $3, "!<" );
- | e
- = bundle( $1, " 0!=" );
- ;
-
- e : e '+' e
- = bundle( $1, $3, "+" );
- | e '-' e
- = bundle( $1, $3, "-" );
- | '-' e %prec UMINUS
- = bundle( " 0", $2, "-" );
- | e '*' e
- = bundle( $1, $3, "*" );
- | e '/' e
- = bundle( $1, $3, "/" );
- | e '%' e
- = bundle( $1, $3, "%%" );
- | e '^' e
- = bundle( $1, $3, "^" );
- | LETTER '[' e ']'
- ={ bundle($3, ";", geta($1)); }
- | LETTER INCR
- = bundle( "l", $1, "d1+s", $1 );
- | INCR LETTER
- = bundle( "l", $2, "1+ds", $2 );
- | DECR LETTER
- = bundle( "l", $2, "1-ds", $2 );
- | LETTER DECR
- = bundle( "l", $1, "d1-s", $1 );
- | LETTER '[' e ']' INCR
- = bundle($3,";",geta($1),"d1+",$3,":",geta($1));
- | INCR LETTER '[' e ']'
- = bundle($4,";",geta($2),"1+d",$4,":",geta($2));
- | LETTER '[' e ']' DECR
- = bundle($3,";",geta($1),"d1-",$3,":",geta($1));
- | DECR LETTER '[' e ']'
- = bundle($4,";",geta($2),"1-d",$4,":",geta($2));
- | SCALE INCR
- = bundle("Kd1+k");
- | INCR SCALE
- = bundle("K1+dk");
- | SCALE DECR
- = bundle("Kd1-k");
- | DECR SCALE
- = bundle("K1-dk");
- | BASE INCR
- = bundle("Id1+i");
- | INCR BASE
- = bundle("I1+di");
- | BASE DECR
- = bundle("Id1-i");
- | DECR BASE
- = bundle("I1-di");
- | OBASE INCR
- = bundle("Od1+o");
- | INCR OBASE
- = bundle("O1+do");
- | OBASE DECR
- = bundle("Od1-o");
- | DECR OBASE
- = bundle("O1-do");
- | LETTER '(' cargs ')'
- = bundle( $3, "l", getf($1), "x" );
- | LETTER '(' ')'
- = bundle( "l", getf($1), "x" );
- | cons
- ={ bundle( " ", $1 ); }
- | DOT cons
- ={ bundle( " .", $2 ); }
- | cons DOT cons
- ={ bundle( " ", $1, ".", $3 ); }
- | cons DOT
- ={ bundle( " ", $1, "." ); }
- | DOT
- ={ $$ = "l."; }
- | LETTER
- = { bundle( "l", $1 ); }
- | LETTER '=' e
- ={ bundle( $3, "ds", $1 ); }
- | LETTER EQOP e %prec '='
- ={ bundle( "l", $1, $3, $2, "ds", $1 ); }
- | '(' e ')'
- = { $$ = $2; }
- | '?'
- ={ bundle( "?" ); }
- | SQRT '(' e ')'
- ={ bundle( $3, "v" ); }
- | '~' LETTER
- ={ bundle("L",$2); }
- | SCALE e
- = bundle($2,"dk");
- | SCALE '=' e
- = bundle($3,"dk");
- | SCALE EQOP e %prec '='
- = bundle("K",$3,$2,"dk");
- | BASE e
- = bundle($2,"di");
- | BASE '=' e
- = bundle($3,"di");
- | BASE EQOP e %prec '='
- = bundle("I",$3,$2,"di");
- | OBASE e
- = bundle($2,"do");
- | OBASE '=' e
- = bundle($3,"do");
- | OBASE EQOP e %prec '='
- = bundle("O",$3,$2,"do");
- | SCALE
- = bundle("K");
- | BASE
- = bundle("I");
- | OBASE
- = bundle("O");
- ;
-
- cargs : eora
- | cargs ',' eora
- = bundle( $1, $3 );
- ;
- eora: e
- | LETTER '[' ']'
- =bundle("l",geta($1));
- ;
-
- cons : constant
- ={ *cp++ = '\0'; }
-
- constant:
- '_'
- ={ $$ = cp; *cp++ = '_'; }
- | DIGIT
- ={ $$ = cp; *cp++ = $1; }
- | constant DIGIT
- ={ *cp++ = $2; }
- ;
-
- CRS :
- ={ $$ = cp; *cp++ = crs++; *cp++ = '\0'; bstack[bindx++] = lev++; }
- ;
-
- def : _DEFINE LETTER '('
- ={ $$ = getf($2);
- pre = "";
- post = "";
- lev = 1;
- bstack[bindx=0] = 0;
- }
- ;
-
- dargs :
- | lora
- ={ pp( $1 ); }
- | dargs ',' lora
- ={ pp( $3 ); }
- ;
-
- dlets : lora
- ={ tp($1); }
- | dlets ',' lora
- ={ tp($3); }
- ;
- lora : LETTER
- | LETTER '[' ']'
- ={ $$ = geta($1); }
- ;
-
- %%
- # define error 256
-
- int peekc -1;
- int sargc;
- int ifile;
- char **sargv;
- extern int fin;
-
- char *funtab[26]{
- 01,02,03,04,05,06,07,010,011,012,013,014,015,016,017,
- 020,021,022,023,024,025,026,027,030,031,032 };
- char *atab[26]{
- 0241,0242,0243,0244,0245,0246,0247,0250,0251,0252,0253,
- 0254,0255,0256,0257,0260,0261,0262,0263,0264,0265,0266,
- 0267,0270,0271,0272};
- char *letr[26] {
- "a","b","c","d","e","f","g","h","i","j",
- "k","l","m","n","o","p","q","r","s","t",
- "u","v","w","x","y","z" } ;
- char *dot { "." };
- yylex(){
- int c,ch;
- restart:
- c = getc();
- peekc = -1;
- while( c == ' ' || c == '\t' ) c = getc();
- if( c<= 'z' && c >= 'a' ) {
- /* look ahead to look for reserved words */
- peekc = getc();
- if( peekc >= 'a' && peekc <= 'z' ){ /* must be reserved word */
- if( c=='i' && peekc=='f' ){ c=_IF; goto skip; }
- if( c=='w' && peekc=='h' ){ c=_WHILE; goto skip; }
- if( c=='f' && peekc=='o' ){ c=_FOR; goto skip; }
- if( c=='s' && peekc=='q' ){ c=SQRT; goto skip; }
- if( c=='r' && peekc=='e' ){ c=_RETURN; goto skip; }
- if( c=='b' && peekc=='r' ){ c=_BREAK; goto skip; }
- if( c=='d' && peekc=='e' ){ c=_DEFINE; goto skip; }
- if( c=='s' && peekc=='c' ){ c= SCALE; goto skip; }
- if( c=='b' && peekc=='a' ){ c=BASE; goto skip; }
- if( c=='o' && peekc=='b' ){ c=OBASE; goto skip; }
- if( c=='d' && peekc=='i' ){ c=FFF; goto skip; }
- if( c=='a' && peekc=='u' ){ c=_AUTO; goto skip; }
- if( c == 'q' && peekc == 'u')getout();
- /* could not be found */
- return( error );
- skip: /* skip over rest of word */
- peekc = -1;
- while( (ch = getc()) >= 'a' && ch <= 'z' );
- peekc = ch;
- return( c );
- }
-
- /* usual case; just one single letter */
-
- yylval = letr[c-'a'];
- return( LETTER );
- }
- if( c>= '0' && c <= '9' || c>= 'A' && c<= 'F' ){
- yylval = c;
- return( DIGIT );
- }
- switch( c ){
- case '.': return( DOT );
- case '=':
- switch( peekc = getc() ){
- case '=': c=EQ; goto gotit;
- case '+': c=EQPL; goto gotit;
- case '-': c=EQMI; goto gotit;
- case '*': c=EQMUL; goto gotit;
- case '/': c=EQDIV; goto gotit;
- case '%': c=EQREM; goto gotit;
- case '^': c=EQEXP; goto gotit;
- default: return( '=' );
- gotit: peekc = -1; return(c);
- }
- case '+': return( cpeek( '+', INCR, '+' ) );
- case '-': return( cpeek( '-', DECR, '-' ) );
- case '<': return( cpeek( '=', LE, '<' ) );
- case '>': return( cpeek( '=', GE, '>' ) );
- case '!': return( cpeek( '=', NE, '!' ) );
- case '/':
- if((peekc = getc()) == '*'){
- peekc = -1;
- while((getc() != '*') || ((peekc = getc()) != '/'));
- peekc = -1;
- goto restart;
- }
- else return(c);
- case '"':
- yylval = str;
- while((c=getc()) != '"')*str++ = c;
- *str++ = '\0';
- return(QSTR);
- default: return( c );
- }
- }
-
- cpeek( c, yes, no ){
- if( (peekc=getc()) != c ) return( no );
- else {
- peekc = -1;
- return( yes );
- }
- }
-
- getc(){
- int ch;
- loop:
- ch = (peekc < 0) ? getchar() : peekc;
- peekc = -1;
- if(ch != '\0')return(ch);
- if(++ifile > sargc){
- if(ifile >= sargc+2)getout();
- fin = dup(0);
- goto loop;
- }
- close(fin);
- if((fin = open(sargv[ifile],0)) >= 0)goto loop;
- yyerror("cannot open input file");
- }
- # define b_sp_max 1500
- int b_space [ b_sp_max ];
- int * b_sp_nxt { b_space };
-
- bdebug 0;
- bundle(a){
- int i, *p, *q;
-
- i = nargs();
- q = b_sp_nxt;
-
- if( bdebug ) printf("bundle %d elements at %o\n", i, q );
-
- for( p = &a; i-->0; ++p ){
-
- if( b_sp_nxt >= & b_space[b_sp_max] ) yyerror( "bundling space exceeded" );
-
- * b_sp_nxt++ = *p;
- }
- * b_sp_nxt++ = 0;
- yyval = q;
- return( q );
- }
-
- routput(p) int *p; {
- if( bdebug ) printf("routput(%o)\n", p );
- if( p >= &b_space[0] && p < &b_space[b_sp_max]){
- /* part of a bundle */
- while( *p != 0 ) routput( *p++ );
- }
- else printf( p ); /* character string */
- }
-
- output( p ) int *p; {
- routput( p );
- b_sp_nxt = & b_space[0];
- printf( "\n" );
- cp = cary;
- str = string;
- crs = rcrs;
- }
-
- conout( p, s ) int *p; char *s; {
- printf("[");
- routput( p );
- printf("]s%s\n", s );
- lev--;
- str = string;
- }
-
- yyerror( s ) char *s; {
- printf("c[%s]pc\n", s );
- cp = cary;
- crs = rcrs;
- bindx = 0;
- lev = 0;
- b_sp_nxt = &b_space[0];
- str = string;
- }
-
- pp( s ) char *s; {
- /* puts the relevant stuff on pre and post for the letter s */
-
- bundle( "S", s, pre );
- pre = yyval;
- bundle( post, "L", s, "s." );
- post = yyval;
- }
-
- tp( s ) char *s; { /* same as pp, but for temps */
- bundle( "0S", s, pre );
- pre = yyval;
- bundle( post, "L", s, "s." );
- post = yyval;
- }
-
- yyinit(argc,argv) int argc; char *argv[];{
- int (*getout)();
- signal( 2, getout ); /* ignore all interrupts */
- sargv=argv;
- sargc= -- argc;
- if(sargc == 0)fin=dup(0);
- else if((fin = open(sargv[1],0)) < 0)
- yyerror("cannot open input file");
- ifile = 1;
- }
- getout(){
- printf("q");
- exit();
- }
-
- getf(p) char *p;{
- return(&funtab[*p -0141]);
- }
- geta(p) char *p;{
- return(&atab[*p - 0141]);
- }
-
- main(argc, argv)
- char **argv;
- {
- int p[2];
-
-
- if (argc > 1 && *argv[1] == '-') {
- if(argv[1][1] == 'd'){
- yyinit(--argc, ++argv);
- yyparse();
- exit();
- }
- if(argv[1][1] != 'l'){
- printf("unrecognizable argument\n");
- exit();
- }
- argv[1] = "/usr/lib/lib.b";
- }
- pipe(p);
- if (fork()==0) {
- close(1);
- dup(p[1]);
- close(p[0]);
- close(p[1]);
- yyinit(argc, argv);
- yyparse();
- exit();
- }
- close(0);
- dup(p[0]);
- close(p[0]);
- close(p[1]);
- execl("/bin/dc", "dc", "-", 0);
- }
-