Next: OperatorSymbol, Up: Expressions
The symbol on the left-hand side of a rule defining an expression node
characterizes the expression's result.
It inherits the ExpressionSymbol role.
Here are appropriate inheritance specifications for Mystery:
SYMBOL Expr INHERITS ExpressionSymbol END;
Two attributes of ExpressionSymbol describe its type:
RequiredDefTableKey value is
the type required by the surrounding context.
It may be provided by user computation at the root of the expression tree,
and is computed by the module at all other nodes.
A value of NoKey is provided at the root by default,
indicating that no specific type of value is required.
TypeDefTableKey value is
the type of the result delivered by the expression.
It must be provided by user computation at the leaves of the expression tree,
and is computed by the module at the root and all interior nodes.
The Mystery assignment statement illustrates two possible situations with
respect to the Required attribute at the root of an expression
tree:
RULE: Stmt ::= Expr ':=' Expr
COMPUTE Expr[2].Required=Expr[1].Type;
END;
There is no specific requirement on the type defined by the left-hand
expression, and therefore there is no need to override the default
computation of Expr[1].Required.
Because the type of the value returned by the right-hand expression of the
assignment must match the type defined by the left-hand expression, however,
that symbol computation is overridden here.
PrimaryContext(`e1',`type') is used to compute the value
of the Type attribute at the leaves of an expression tree.
Argument `e1' is the grammar symbol playing the ExpressionSymbol
role at that leaf, and `type' must be the definition table key of the
type delivered by the leaf.
Mystery constant and variable references are primary contexts:
RULE: Expr ::= Number
COMPUTE PrimaryContext(Expr,intType);
END;
RULE: Expr ::= ExpIdUse
COMPUTE PrimaryContext(Expr,ExpIdUse.Type);
END;
TransferContext(`e1',`e2')
marks an expression node in which the result and one
operand are identical with respect to type.
Arguments `e1' and `e2' are grammar symbols playing the
ExpressionSymbol role, with `e1' being the result.
The chain rule defining an argument as an expression in Mystery is an example of a transfer context:
SYMBOL Actual INHERITS ExpressionSymbol END;
RULE: Actual ::= Expr
COMPUTE TransferContext(Actual,Expr);
END;
Actual, a procedure argument, plays the role of an expression but
has additional properties and is therefore represented by a distinct
grammar symbol
(see Procedure Definition and Call).
BalanceContext(`e1',`e2',`e3')
marks an expression node in which the result and two operands are identical
with respect to type.
Arguments `e1', `e2', and `e3' are grammar symbols playing the
ExpressionSymbol role, with `e1' being the result.
A conditional expression like that of C is an example of a balance context:
RULE: Expr ::= Expr '?' Expr ':' Expr
COMPUTE
BalanceContext(Expr[1],Expr[3],Expr[4]);
Expr[1].Required=scalarType;
END;
(A scalar type in C is a pointer or a number.)