⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgram.y

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 Y
📖 第 1 页 / 共 2 页
字号:
		|  ifprefix statement			={ deflab($1);			   reached = 1;			   }		|  ifelprefix statement			={  if( $1 != NOLAB ){				deflab( $1 );				reached = 1;				}			    }		|  whprefix statement			={  branch(  contlab );			    deflab( brklab );			    if( (flostat&FBRK) || !(flostat&FLOOP)) reached = 1;			    else reached = 0;			    resetbc(0);			    }		|  doprefix statement WHILE  LP  e  RP   SM			={  deflab( contlab );			    if( flostat & FCONT ) reached = 1;			    ecomp( buildtree( CBRANCH, buildtree( NOT, $5, NIL ), bcon( $1 ) ) );			    deflab( brklab );			    reached = 1;			    resetbc(0);			    }		|  forprefix .e RP statement			={  deflab( contlab );			    if( flostat&FCONT ) reached = 1;			    if( $2 ) ecomp( $2 );			    branch( $1 );			    deflab( brklab );			    if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1;			    else reached = 0;			    resetbc(0);			    }		| switchpart statement			={  if( reached ) branch( brklab );			    deflab( $1 );			   swend();			    deflab(brklab);			    if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1;			    resetbc(FCONT);			    }		|  BREAK  SM			={  if( brklab == NOLAB ) uerror( "illegal break");			    else if(reached) branch( brklab );			    flostat |= FBRK;			    if( brkflag ) goto rch;			    reached = 0;			    }		|  CONTINUE  SM			={  if( contlab == NOLAB ) uerror( "illegal continue");			    else branch( contlab );			    flostat |= FCONT;			    goto rch;			    }		|  RETURN  SM			={  retstat |= NRETVAL;			    branch( retlab );			rch:			    if( !reached ) werror( "statement not reached");			    reached = 0;			    }		|  RETURN e  SM			={  register NODE *temp;			    idname = curftn;			    temp = buildtree( NAME, NIL, NIL );			    if(temp->in.type == TVOID)				uerror("void function %s cannot return value",					stab[idname].sname);			    temp->in.type = DECREF( temp->in.type );			    temp = buildtree( RETURN, temp, $2 );			    /* now, we have the type of the RHS correct */			    temp->in.left->in.op = FREE;			    temp->in.op = FREE;			    ecomp( buildtree( FORCE, temp->in.right, NIL ) );			    retstat |= RETVAL;			    branch( retlab );			    reached = 0;			    }		|  GOTO NAME SM			={  register NODE *q;			    q = block( FREE, NIL, NIL, INT|ARY, 0, INT );			    q->tn.rval = idname = $2;			    defid( q, ULABEL );			    stab[idname].suse = -lineno;			    branch( stab[idname].offset );			    goto rch;			    }		|   SM		|  error  SM		|  error RC		|  label statement		;asmpartnow:	   ASM  			={			   procasm();		/* Read in the asm info */			   outasm(asmptr);	/* Put it out now */			 }  /* RAP001 */		;asmpart:	   ASM			={ $$ = $1;			   procasm(); 		/* Read in the asm info */						/* (put out in match.c) */			 }  /* RAP001 */		;label:		   NAME COLON			={  register NODE *q;			    q = block( FREE, NIL, NIL, INT|ARY, 0, LABEL );			    q->tn.rval = $1;			    defid( q, LABEL );			    reached = 1;			    }		|  CASE e COLON			={  addcase($2);			    reached = 1;			    }		|  DEFAULT COLON			={  reached = 1;			    adddef();			    flostat |= FDEF;			    }		;doprefix:	DO			={  savebc();			    if( !reached ) werror( "loop not entered at top");			    brklab = getlab();			    contlab = getlab();			    deflab( $$ = getlab() );			    reached = 1;			    }		;ifprefix:	IF LP e RP			={  ecomp( buildtree( CBRANCH, $3, bcon( $$=getlab()) ) ) ;			    reached = 1;			    }		;ifelprefix:	  ifprefix statement ELSE			={  if( reached ) branch( $$ = getlab() );			    else $$ = NOLAB;			    deflab( $1 );			    reached = 1;			    }		;whprefix:	  WHILE  LP  e  RP			={  savebc();			    if( !reached ) werror( "loop not entered at top");			    if( $3->in.op == ICON && $3->tn.lval != 0 ) flostat = FLOOP;			    deflab( contlab = getlab() );			    reached = 1;			    brklab = getlab();			    if( flostat == FLOOP ) tfree( $3 );			    else ecomp( buildtree( CBRANCH, $3, bcon( brklab) ) );			    }		;forprefix:	  FOR  LP  .e  SM .e  SM 			={  if( $3 ) ecomp( $3 );			    else if( !reached ) werror( "loop not entered at top");			    savebc();			    contlab = getlab();			    brklab = getlab();			    deflab( $$ = getlab() );			    reached = 1;			    if( $5 ) ecomp( buildtree( CBRANCH, $5, bcon( brklab) ) );			    else flostat |= FLOOP;			    }		;switchpart:	   SWITCH  LP  e  RP			={  savebc();			    brklab = getlab();			    ecomp( buildtree( FORCE, $3, NIL ) );			    branch( $$ = getlab() );			    swstart();			    reached = 0;			    }		;/*	EXPRESSIONS	*/con_e:		   { $<intval>$=instruct; stwart=instruct=0; } e			%prec CM			={  $$ = icons( $2 );  instruct=$<intval>1; }		;.e:		   e		|			={ $$=0; }		;elist:		   e			%prec CM		|  elist  CM  e			={  goto bop; }		;e:		   e RELOP e			={			preconf:			    if( yychar==RELOP||yychar==EQUOP||yychar==AND||yychar==OR||yychar==ER ){			    precplaint:				if( hflag ) werror( "precedence confusion possible: parenthesize!" );				}			bop:			    $$ = buildtree( $2, $1, $3 );			    }		|  e CM e			={  $2 = COMOP;			    goto bop;			    }		|  e DIVOP e			={  goto bop; }		|  e PLUS e			={  if(yychar==SHIFTOP) goto precplaint; else goto bop; }		|  e MINUS e			={  if(yychar==SHIFTOP ) goto precplaint; else goto bop; }		|  e SHIFTOP e			={						/* resolve qar 2001: */	/* Detect cases of shifts larger than the object; eg:	*  y = x << 2 + 40;	*	* yypvt[-2].nodep (aka 'l' in buldtree) would have l.in.op = 2 (NAME x)	* 	and l.in.type = 5 (long if x is a long) or set to the proper value    * similary yypvt[-3].nodep (aka 'r'), would have	*       r.tn.type = 4 (ICON constant)	*    and r.tn.lval = 42 (the value).    */ 				NODE *l, * r;				l = yypvt[-2].nodep;				r = yypvt[-0].nodep;				if  (r->tn.op == ICON)				{					if (r->tn.lval > dimtab[ l->in.type ])					{						werror("Shift of %d is > object size of %d",							   r->tn.lval, dimtab[ l->in.type]);					}				}								if(yychar==PLUS||yychar==MINUS) goto precplaint;				else goto bop;			}		|  e MUL e			={  goto bop; }		|  e EQUOP  e			={  goto preconf; }		|  e AND e			={  if( yychar==RELOP||yychar==EQUOP ) goto preconf;  else goto bop; }		|  e OR e			={  if(yychar==RELOP||yychar==EQUOP) goto preconf; else goto bop; }		|  e ER e			={  if(yychar==RELOP||yychar==EQUOP) goto preconf; else goto bop; }		|  e ANDAND e			={  goto bop; }		|  e OROR e			={  goto bop; }		|  e MUL ASSIGN e			={  abop:				$$ = buildtree( ASG $2, $1, $4 );				}		|  e DIVOP ASSIGN e			={  goto abop; }		|  e PLUS ASSIGN e			={  goto abop; }		|  e MINUS ASSIGN e			={  goto abop; }		|  e SHIFTOP ASSIGN e			={  goto abop; }		|  e AND ASSIGN e			={  goto abop; }		|  e OR ASSIGN e			={  goto abop; }		|  e ER ASSIGN e			={  goto abop; }		|  e QUEST e COLON e			={  $$=buildtree(QUEST, $1, buildtree( COLON, $3, $5 ) );			    }		|  e ASOP e			={  werror( "old-fashioned assignment operator" );  goto bop; }		|  e ASSIGN e			={  goto bop; }		|  term		;term:		   term INCOP			={  $$ = buildtree( $2, $1, bcon(1) ); }		|  MUL term			={ ubop:			    $$ = buildtree( UNARY $1, $2, NIL );			    }		|  AND term			={  if( ISFTN($2->in.type) || ISARY($2->in.type) ){				werror( "& before array or function: ignored" );				$$ = $2;				}			    else goto ubop;			    }		|  MINUS term			={  goto ubop; }		|  UNOP term			={			    $$ = buildtree( $1, $2, NIL );			    }		|  INCOP term			={  $$ = buildtree( $1==INCR ? ASG PLUS : ASG MINUS,						$2,						bcon(1)  );			    }		|  SIZEOF term			={  $$ = doszof( $2 ); }		|  LP cast_type RP term  %prec INCOP			={  $$ = buildtree( CAST, $2, $4 );			    $$->in.left->in.op = FREE;			    $$->in.op = FREE;			    $$ = $$->in.right;			    }		|  SIZEOF LP cast_type RP  %prec SIZEOF			={  $$ = doszof( $3 ); }		|  term LB e RB			={  $$ = buildtree( UNARY MUL, buildtree( PLUS, $1, $3 ), NIL ); }		|  asm_idn	/* RAP001 */			={  $$=buildtree(UNARY CALL,$1,NIL); }		|  funct_idn  RP			={  $$=buildtree(UNARY CALL,$1,NIL); }		|  funct_idn elist  RP			={  $$=buildtree(CALL,$1,$2); }		|  term STROP NAME			={  if( $2 == DOT ){				if( notlval( $1 ) )uerror("structure reference must be addressable");				$1 = buildtree( UNARY AND, $1, NIL );				}			    idname = $3;			    $$ = buildtree( STREF, $1, buildtree( NAME, NIL, NIL ) );			    }		|  NAME			={  idname = $1;			    /* recognize identifiers in initializations */			    if( blevel==0 && stab[idname].stype == UNDEF ) {				register NODE *q;#ifndef FLEXNAMES				werror( "undeclared initializer name %.8s", stab[idname].sname );#else				werror( "undeclared initializer name %s", stab[idname].sname );#endif				q = block( FREE, NIL, NIL, INT, 0, INT );				q->tn.rval = idname;				defid( q, EXTERN );				}			    $$=buildtree(NAME,NIL,NIL);			    stab[$1].suse = -lineno;			}		|  ICON			={  $$=bcon(0);			    $$->tn.lval = lastcon;			    $$->tn.rval = NONAME;			    if( $1 ) $$->fn.csiz = $$->in.type = ctype(LONG);			    }		|  FCON			={  $$=buildtree(FCON,NIL,NIL);			    $$->fpn.fval = fcon;			    }			/* vdp004 -maintain a distinction between floating 			 * constants and double constants 			 */ 		|  DCON			={  $$= buildtree(DCON,NIL,NIL);			    $$->dpn.dval = dcon;			    }		|  STRING			={  $$ = getstr(); /* get string contents */ }		|   LP  e  RP			={ $$=$2; }		;cast_type:	  typehead null_decl			={			$$ = tymerge( $1, $2 );			$$->in.op = NAME;			$1->in.op = FREE;			}		;null_decl:	   /* empty */			={ $$ = bdty( NAME, NIL, -1 ); }		|  LP RP			={ $$ = bdty( UNARY CALL, bdty(NAME,NIL,-1),0); }		|  LP null_decl RP LP RP			={  $$ = bdty( UNARY CALL, $2, 0 ); }		|  MUL null_decl			={  goto umul; }		|  null_decl LB RB			={  goto uary; }		|  null_decl LB con_e RB			={  goto bary;  }		|  LP null_decl RP			={ $$ = $2; }		;funct_idn:	   NAME  LP 			={  			    if( stab[$1].stype == UNDEF ){				register NODE *q;				q = block( FREE, NIL, NIL, FTN|INT, 0, INT );				q->tn.rval = $1;				defid( q, EXTERN );				}			    idname = $1;			    $$=buildtree(NAME,NIL,NIL);			    stab[idname].suse = -lineno;			}		|  term  LP 		;asm_idn:	asmpart /* RAP001 				Put asm in the symbol table as a function that				doesn't return a value (if not already there).				Then build a NAME node with it and pass back				a pointer to it.								Store asmptr (set up by procasm in scan.c) in				the NAME node. This is a pointer to a block				containing the characters in the asm. The code				will be put out later in match.c			*/			={  			    if( stab[$1].stype == UNDEF ){				register NODE *q;				q = block( FREE, NIL, NIL, FTN|UNDEF, 0, INT );				q->tn.rval = $1;				defid( q, EXTERN );				}			    idname = $1;			    $$=buildtree(NAME,NIL,NIL);#ifdef ONEPASS			    $$->in.asminfo = asmptr;#endif			    stab[idname].suse = -lineno;			}%%NODE *mkty( t, d, s ) unsigned t; {	return( block( TYPE, NIL, NIL, t, d, s ) );	}NODE *bdty( op, p, v ) NODE *p; {	register NODE *q;	q = block( op, p, NIL, INT, 0, INT );	switch( op ){	case UNARY MUL:		if (v == BCONST_PTR || v == BVOLATILE_PTR) {  /* vjh005 */		    q->in.typattr = v;		} else {		    q->in.typattr = 0;		}		break;	case UNARY CALL:		break;	case LB:		q->in.right = bcon(v);		break;	case NAME:		q->tn.rval = v;		break;	default:		cerror( "bad bdty" );		}	return( q );	}dstash( n ){ /* put n into the dimension table */	if( curdim >= DIMTABSZ-1 ){		cerror( "dimension table overflow");		}	dimtab[ curdim++ ] = n;	}savebc() {	if( psavbc > & asavbc[BCSZ-4 ] ){		cerror( "whiles, fors, etc. too deeply nested");		}	*psavbc++ = brklab;	*psavbc++ = contlab;	*psavbc++ = flostat;	*psavbc++ = swx;	flostat = 0;	}resetbc(mask){	swx = *--psavbc;	flostat = *--psavbc | (flostat&mask);	contlab = *--psavbc;	brklab = *--psavbc;	}addcase(p) NODE *p; { /* add case to switch */	p = optim( p );  /* change enum to ints */	if( p->in.op != ICON ){		uerror( "non-constant case expression");		return;		}	if( swp == swtab ){		uerror( "case not in switch");		return;		}	if( swp >= &swtab[SWITSZ] ){		cerror( "switch table overflow");		}	swp->sval = p->tn.lval;	deflab( swp->slab = getlab() );	++swp;	tfree(p);	}adddef(){ /* add default case to switch */	if( swtab[swx].slab >= 0 ){		uerror( "duplicate default in switch");		return;		}	if( swp == swtab ){		uerror( "default not inside switch");		return;		}	deflab( swtab[swx].slab = getlab() );	}swstart(){	/* begin a switch block */	if( swp >= &swtab[SWITSZ] ){		cerror( "switch table overflow");		}	swx = swp - swtab;	swp->slab = -1;	++swp;	}swend(){ /* end a switch block */	register struct sw *swbeg, *p, *q, *r, *r1;	CONSZ temp;	int tempi;	swbeg = &swtab[swx+1];	/* sort */	r1 = swbeg;	r = swp-1;	while( swbeg < r ){		/* bubble largest to end */		for( q=swbeg; q<r; ++q ){			if( q->sval > (q+1)->sval ){				/* swap */				r1 = q+1;				temp = q->sval;				q->sval = r1->sval;				r1->sval = temp;				tempi = q->slab;				q->slab = r1->slab;				r1->slab = tempi;				}			}		r = r1;		r1 = swbeg;		}	/* it is now sorted */	for( p = swbeg+1; p<swp; ++p ){		if( p->sval == (p-1)->sval ){			uerror( "duplicate case in switch, %d", tempi=p->sval );			return;			}		}	genswitch( swbeg-1, swp-swbeg );	swp = swbeg-1;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -