From: wjw@eb.ele.tue.nl (Willem Jan Withagen)
Newsgroups: comp.compilers
Subject: constant folding at parse time
Keywords: parse, attribute
Date: 17 Aug 92 08:24:58 GMT
Reply-To: wjw@eb.ele.tue.nl (Willem Jan Withagen)
Organization: Compilers Central

drw@kronecker.mit.edu (Dale R. Worley) writes:
> 
>This is handled by duplicating all the nonterminals into a ".c"
> (constant expression) and ".nc" (non-constant expression) version:
> 
> Really, what you're doing is constructing a synthesized (passed-upwards)
> attribute (constant vs. non-constant), but most LALR parser generators
> don't support that.  When you're parsing C, you want a lot of these
> attributes, and you want the attributes to control some aspects of the
> parsing.  The result is that some productions are cloned 6 or 8 times.
> Ugh.

Well just a little nit pick here. I do not consider this part of a
parser. Determining wether an expression is constant or not is part of
constant folding, which is usually not done while parsing. But the
taken approach could be made to work.

> [This certainly works, but I'd think it'd be a lot easier to handle
> synthesized attributes in the value cells, where they're easy to
> construct and pass up the tree. -John]

The following is how I determine whether an expression is constant or 
not using one of the tools in the Cocktail toolset.

Please note that the grammar is totally separated from this,
and that rules xxxxx = {........}. give the calculations for a specific
node in the tree build from the input file. 
The order of the attribute evaluation is however determined by the 
requirements of the rules: Obviously one can only calculate the Object in
Qualid after the calculation of the environment Env, ....

DECLARE
	/* What is the expression type.
	 */
        Expr
                = -> [ Typ: tType OUT ]
                     .
        /* Is the expression (so far) constant
        /* and what is the value.
         */
        Expr
                = -> [ IsConst: Boolean OUT ]
                     [ Val :tValue ]
                .
RULE
UniExpr         = {     Typ     := UniResultType( Expr:Typ, Operator );
                        IsConst := UniIsConstant( Expr:Typ, Operator );
                        Val     := UniVal( Expr:Typ, Operator );
}.
BinExpr         = {     Typ     := BinResultType( LExpr:Typ, Operator,
							RExpr:Typ);
                        IsConst := BinIsConstant( LExpr:IsConst, Operator,
							RExpr:IsConst);
                        Val     := BinVal( LExpr:Val, Operator, RExpr:Val);
}.
IntConst        = {     Typ     := nTypeINTEGER;
                        Val     := CVal;
                        IsConst := True;
}.
RealConst       = {     Typ     := nTypeREAL;
                        Val     := CVal;
                        IsConst := True;
}.
/* Process the reference to an identifier 
 */
Qualid          = {     Object  := IdentifyNameEnv(Ident, Env);
                        Typ     := GetObjectType(Object);
                        IsConst := IsSimpleConstant(Object);
                        Val     := { if (IsConst) {
                                        Val = GetObjectValue(Object);
                                     } else {
					Val = NoValue;
				     }
                        };

Willem Jan Withagen.
-- 
Digital Information Systems Group, Room EH 10.35 
Eindhoven University of Technology   
P.O. 513                     		Tel: +31-40-473401,Fax: +31-40-448375
5600 MB Eindhoven            		The Netherlands
Internet:  wjw@eb.ele.tue.nl    
X400:      C=nl;ADMD=400net;PRMD=surf;O=tue;OU=ele;OU=eb;S=WJW;
[The GMD Cocktail toolset has been most recently discussed in message
92-03-025.  It's available for FTP.  -John]
-- 
Send compilers articles to compilers@iecc.cambridge.ma.us or
{ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.