4.4BSD/usr/src/old/efl/gram.expr

expr:	  lhs
		{ if($1->tag == TCALL)
			$1 = funcinv($1);
		  if($1->vtype==TYUNDEFINED && $1->vext==0)
			impldecl($1);
		  else if($1->tag==TNAME && $1->vdcldone==0
			  && $1->vext==0 && !inbound)
				dclit($1);
		  if($1->vtype==TYFIELD)
			$$ = extrfield($1);
		}
	| CONST
	| logcon
		{ $$ = mkconst(TYLOG, ($1 == TRUE ? ".true." : ".false.") ); }
	| specs parexprs
		{ $$ = typexpr($1,$2); }
	| sizeof
	| lengthof
	| parexprs
		{ if( !ininit && $1->tag== TLIST)
			$$ = compconst($1); 
		  else $1->needpar = 1; }
	| expr ADDOP expr
		{ $$ = mknode(TAROP,$2,$1,$3); }
	| expr MULTOP expr
		{ $$ = mknode(TAROP,$2,$1,$3); }
	| expr POWER expr
		{ $$ = mknode(TAROP,$2,$1,$3); }
	| ADDOP expr  %prec MULTOP
		{ if($1==OPMINUS)
			$$ = mknode(TNEGOP,OPMINUS, $2, PNULL);
		  else	$$ = $2;  }
	| DOUBLEADDOP lhs  %prec MULTOP
		{ $$ =  mknode(TASGNOP,$1,$2,mkint(1)); }
	| expr RELOP expr
		{ $$ = mknode(TRELOP,$2,$1,$3); }
	| expr OR expr
		{ $$ = mknode(TLOGOP,$2,$1,$3); }
	| expr AND expr
		{ $$ = mknode(TLOGOP,$2,$1,$3); }
	| NOT expr
		{ $$ = mknode(TNOTOP,$1,$2,PNULL); }
	| lhs ASGNOP expr
		{ if($1->tag == TCALL)
			{
			exprerr("may not assign to a function", CNULL);
			$$ = errnode();
			}
		  else
			$$ = mknode(TASGNOP,$2,$1,$3);
		}
	| expr REPOP expr
		{ $$ = mknode(TREPOP,0,$1,$3); }
	| iostat
	| error
		{ $$ = errnode(); }
	;

lhs:	lhs1
		{ if($1->tag==TNAME && $1->vdcldone==0 &&
			$1->vsubs==0 && $1->vext==0 && !inbound)
				dclit($1);
		}
	;

lhs1:	  lhsname
	| lhsname parexprs
		{
		if($2->tag!=TLIST)
			$2 = mknode(TLIST,0, mkchain($2,CHNULL), PNULL);
		if($1->vdim)
			{
			if($1->vdcldone==0 && $1->vext==0)
				dclit($1);
			$$ = subscript($1,$2);
			}
		else	$$ = mkcall($1,$2);
		}
	| lhs QUALOP NAME
		{ $$ = strucelt($1,$3); }
	| lhs QUALOP NAME parexprs
		{ if($4->tag != TLIST)
			$4 = mknode(TLIST,0, mkchain($4,CHNULL), PNULL);
		  $$ = subscript(strucelt($1,$3), $4);
		}
	| lhs ARROW STRUCTNAME
		{ $$ = mkarrow($1,$3); }
	;

lhsname:  NAME
		{ if($1->varp == 0) mkvar($1);
		  if(inbound)
			  $1->varp->vadjdim = 1;
		  $$ = cpexpr($1->varp); }
	;

parexprs: LPAR RPAR
		{ $$ = mknode(TLIST, 0, PNULL, PNULL); }
	| LPAR expr RPAR
		{ $$ = $2; }
	| LPAR exprlist RPAR
		{ $$ = mknode(TLIST,0,$2,PNULL); }
	;

exprlist: expr COMMA expr
		{ $$ = mkchain($1, mkchain($3, CHNULL) ); }
	| exprlist COMMA expr
		{ hookup($1, mkchain($3,CHNULL) ); }
	;

sizeof:	  SIZEOF LPAR expr RPAR
		{ $$ = esizeof($3->vtype, $3->vtypep, $3->vdim);
		  frexpr($3); }
	| SIZEOF LPAR specs RPAR
		{ if($3->attype==TYREAL && $3->atprec)
			$3->attype = TYLREAL;
		  $$ = esizeof($3->attype, $3->attypep, $3->atdim);
		  cfree($3);
		}
	| SIZEOF LPAR CHARACTER RPAR
		{ $$ = mkint(tailor.ftnsize[FTNINT]/tailor.ftnchwd); }
	;

lengthof:	  LENGTHOF LPAR expr RPAR
		{ $$ = elenof($3->vtype, $3->vtypep, $3->vdim);
		  frexpr($3); }
	| LENGTHOF LPAR specs RPAR
		{ $$ = elenof($3->attype, $3->attypep, $3->atdim);
		  cfree($3);
		}
	| LENGTHOF LPAR CHARACTER RPAR
		{ $$ = mkint(1); }
	;

logcon:   logval
	| QUALOP logval QUALOP
		{ $$ = $2; }
	;

logval:   TRUE
	| FALSE
	;