General Information
Tutorials
Reference Manuals
Libraries
Translation Tasks
Tools
Administration
|
Tutorial for Name Analysis Using ScopeGraphsClassesA class is an entity that can encapsulate both storage and behavior. File `random.nl' contains an example: random.nl[29]== class Random { int state = 100001; float ran() { state = state * 125; state = state - (state / 2796203) * 2796203; return state / 2796203.0; } } { float p, q; p = Random.ran(); q = Random.ran(); } This macro is attached to a non-product file.
The behavior encapsulated by the class The general form of a NameLan class declaration is: Phrase structure[30]== Declaration: ClassDecl. ClassDecl: 'class' Ident Inheritance ClassBody. Inheritance: Default. Default: . ClassBody: '{' Declaration* '}'. This macro is defined in definitions 2, 25, 30, 32, 41, 50, 55, 67, 76, 97, 118, and 124. This macro is invoked in definition 3.
We need an abstract syntax symbol to distinguish the new identifier context
found in the Abstract syntax of identifiers[31]== RULE: ClassDecl ::= 'class' ClassDefName Inheritance ClassBody END; RULE: ClassDefName ::= Ident END; This macro is defined in definitions 8, 9, 26, 31, 33, 42, 51, and 120. This macro is invoked in definition 10. Here are our new and modified scope rules for NameLan with classes:
The LIDO computations associated with these scope rules are similar to the ones associated with methods, and we leave them to the reader as an exercise. Classes introduce two new facilities, both of which affect name analysis:
ExercisesThese exercises are based on files defined in the Tutorial. To obtain copies of those files in your current directory, enter Eli and give the following command:
-> $elipkg/Name/LearnSG%Class > . None of these files will have write permission in your current directory. You will need to add write permission in order to do the exercises.
Qualified names
The defining occurrences Phrase structure[32]== Name: Name '.' Ident. This macro is defined in definitions 2, 25, 30, 32, 41, 50, 55, 67, 76, 97, 118, and 124. This macro is invoked in definition 3.
The Abstract syntax of identifiers[33]== RULE: Name ::= Name '.' QualifiedId END; RULE: QualifiedId ::= Ident END; This macro is defined in definitions 8, 9, 26, 31, 33, 42, 51, and 120. This macro is invoked in definition 10. In order to formalize the intuitive meaning of a qualified name, we need one concept in addition to the four discussed earlier (see Basic Scope Rules of Name analysis according to scope rules).
As language designers, we provide the following rules to define the members of a class and the meaning of a qualified name:
Here is an analysis of the qualified name
The ownership relation between a class and its members
is established by overriding the default computation for the
Establish the ownership relation[34]== RULE: ClassDecl ::= 'class' ClassDefName Inheritance ClassBody COMPUTE ClassBody.ScopeKey = ClassDefName.Key; END; This macro is invoked in definition 38.
A qualified identifier plays the
In some contexts, the set of bindings owned by a qualifier may not be known
until some other computation has taken place (for an example,
see Type-qualified entity names).
This means that we need to establish a precondition, Qualified names lookup in complete graphs[35]== SYMBOL Name COMPUTE INH.ContextIsReady += "yes"; END; This macro is defined in definitions 35 and 36. This macro is invoked in definition 38.
By using an accumulating computation for the void attribute
If we use an attribute Qualified names lookup in complete graphs[36]== SYMBOL QualifiedId INHERITS GCQualName, ChkIdUse END; RULE: Name ::= Name '.' QualifiedId COMPUTE QualifiedId.ScopeKey = Name[2].Key <- Name[1].ContextIsReady; Name[1].Key = QualifiedId.Key; END; RULE: Name ::= SimpleName COMPUTE Name.Key = SimpleName.Key; END; This macro is defined in definitions 35 and 36. This macro is invoked in definition 38.
At this point the abstract syntax contains four
Statement ::= Name '(' Arguments ')' ';' Expr ::= Name '(' Arguments ')' Statement ::= Name '=' Expr ';' Expr ::= NameIn the first two contexts, Name is the name of a method, and in the
last two it is the name of a variable.
It is likely that method names and variable names will need different
attributes, and that those attributes will differ from the attributes needed
for qualified names.
Since attributes are associated with symbols of the abstract syntax, it
would be useful to add two new symbols, MethName and
ExprName , to the abstract syntax.
The technique is identical to the one we have been using to provide
abstract syntax symbols to distinguish identifier contexts
(see Basic Scope Rules of Name analysis according to scope rules).
We replace Name in each of the four rules with the
desired symbol and add rules defining each of the new symbols
as a Name :
Make contexts of complete names explicit[37]== RULE: Statement ::= MethName '(' Arguments ')' ';' END; RULE: Expr ::= MethName '(' Arguments ')' END; RULE: Statement ::= ExprName '=' Expr ';' END; RULE: Expr ::= ExprName END; RULE: MethName ::= Name END; RULE: ExprName ::= Name END; This macro is defined in definitions 37, 44, 56, 57, 68, 77, and 98. This macro is invoked in definition 38. We need to attach all of these rules to the abstract syntax tree: Abstract syntax tree[38]== Establish the ownership relation[34] Qualified names lookup in complete graphs[35] Make contexts of complete names explicit[37] This macro is defined in definitions 10, 18, 22, 38, 47, 52, 53, 65, 69, 71, 88, 89, 92, 93, 95, 96, 101, 105, 108, 110, 111, 112, 113, 122, 133, 134, 135, 136, 137, 144, and 153. This macro is invoked in definition 11.
ExercisesThese exercises are based on files defined in the Tutorial. To obtain copies of those files in your current directory, enter Eli and give the following command:
-> $elipkg/Name/LearnSG%Qual > . None of these files will have write permission in your current directory. You will need to add write permission in order to do the exercises.
Inheritance
The program `gambler.nl' implements a coin tossing class gambler.nl[39]== class Random { int state = 100001; float ran() { state = state * 125; state = state - (state / 2796203) * 2796203; return state / 2796203.0; } } class Coin extends Random { int state = 0; int toss() { state = 2 * ran(); return state; } } class Dice extends Random { int state = 1; int throw(int n) { state = n; return (6 * n) * ran() + 1; } } { int n; float p; n = Coin.toss(); n = Dice.throw(5); n = Coin.state; p = Coin.ran(); n = Dice.state; p = Dice.ran(); } This macro is attached to a non-product file.
Both
In `gambler.nl',
In contrast, although a binding for
Similar reasoning applies to class
It is important to understand that both
An inheritance relation is modeled in the scope graph by a path edge
that is directed from the node for a class to the node for its
direct superclass
(see Scope graphs of Name Analysis Reference Manual).
The tip of that path edge is given by a name, and
lookup operations are required to determine the node bound to that name.
The lookup of an edge tip name may depend on the existence of path edges
in the scope graph, and it contributes a path edge to the scope graph.
In `edges.nl', for example, the lookup for the edge tip edges.nl[40]== class X { int k; class A { class D { int k; } } class B extends C.D { int m() { return k; } } class C extends A { } } { } This macro is attached to a non-product file.
Our previous analysis of applied occurrences was based on the roles
Phrase structure[41]== Inheritance: 'extends' WLName. WLName: Ident. WLName: WLName '.' Ident. This macro is defined in definitions 2, 25, 30, 32, 41, 50, 55, 67, 76, 97, 118, and 124. This macro is invoked in definition 3.
We need abstract syntax symbols to distinguish the two new identifier
contexts found in this rule
(see Representation of identifiers of Name Analysis Reference Manual).
These contexts are analogous to Abstract syntax of identifiers[42]== RULE: WLName ::= SimpleWLName END; RULE: SimpleWLName ::= Ident END; RULE: WLName ::= WLName '.' QualifiedWLId END; RULE: QualifiedWLId ::= Ident END; This macro is defined in definitions 8, 9, 26, 31, 33, 42, 51, and 120. This macro is invoked in definition 10.
The attribute computations for Specify worklist computations[43]== ATTR FPItem: FPItemPtr; SYMBOL SimpleWLName INHERITS WLSimpleName, ChkIdUse END; SYMBOL QualifiedWLId INHERITS WLQualName, ChkIdUse END; RULE: WLName ::= SimpleWLName COMPUTE WLName.FPItem = SimpleWLName.FPItem; END; RULE: WLName ::= WLName '.' QualifiedWLId COMPUTE QualifiedWLId.DependsOn = WLName[2].FPItem; WLName[1].FPItem = QualifiedWLId.FPItem; END; This macro is invoked in definition 47.
RULE: Inheritance ::= 'extends' WLName END;As with Name in the last section, it is likely that the attributes
needed for WLName in this context will differ from
those needed to handle qualified names.
Therefore we provide a new abstract syntax symbol, SuperClass , to
distinguish this context:
Make contexts of complete names explicit[44]== RULE: Inheritance ::= 'extends' SuperClass END; RULE: SuperClass ::= WLName END; This macro is defined in definitions 37, 44, 56, 57, 68, 77, and 98. This macro is invoked in definition 38.
Each Specify the Key attribute of a WLName[45]== RULE: WLName ::= SimpleWLName COMPUTE WLName.Key = SimpleWLName.Key; END; RULE: WLName ::= WLName '.' QualifiedWLId COMPUTE WLName[1].Key = QualifiedWLId.Key; END; This macro is invoked in definition 47.
A path edge is established by the role Establish a path edge to a superclass[46]== SYMBOL SuperClass INHERITS WLCreateEdge END; RULE: SuperClass ::= WLName COMPUTE SuperClass.tailEnv = INCLUDING Inheritance.SubClassEnv; SuperClass.tipFPItem = WLName.FPItem; END; This macro is invoked in definition 47.
This rule obtains the computation for the tip value from its child,
but reaches up the tree for the tail value.
We leave the computation of The NameLan inheritance scope rule says that an inherited binding hides bindings from enclosing ranges. That means that the generic search algorithm must deal with inheritance before it moves to an enclosing range (see The generic lookup of Name Analysis Reference Manual). The two fragments discussed in this section form the basis for implementing NameLan inheritance: Abstract syntax tree[47]== Specify worklist computations[43] Specify the Key attribute of a WLName[45] Establish a path edge to a superclass[46] This macro is defined in definitions 10, 18, 22, 38, 47, 52, 53, 65, 69, 71, 88, 89, 92, 93, 95, 96, 101, 105, 108, 110, 111, 112, 113, 122, 133, 134, 135, 136, 137, 144, and 153. This macro is invoked in definition 11.
ExercisesThese exercises are based on files defined in the Tutorial. To obtain copies of those files in your current directory, enter Eli and give the following command:
-> $elipkg/Name/LearnSG%Path > . None of these files will have write permission in your current directory. You will need to add write permission in order to do the exercises.
|