Translating Modula2 into D: variant records, pointer
Frits van Bommel
fvbommel at REMwOVExCAPSs.nl
Tue Jan 9 12:06:36 PST 2007
BLS wrote:
> Thanks Frits,
> a lot of interesting stuff for a D newbie like me.
> Frits van Bommel schrieb:
>
>> * If you only ever set the union members right after constructing the
>> Node instance, you may also want to think about classes and
>> inheritance if you're OOP-inclined.
>
> Indeed the snippet is part of a table driven (better data-structure)
> general parser. So I allways check Terminal first and then I set the
> union values.
> It was anyway my next question : How to implement this the OOP way ?
> and ... Can opCall() help somehow ?
OOP looks a lot cleaner:
-----
abstract class Node {
Node suc;
Node alt;
}
class TerminalNode : Node {
char tsym;
}
class NonTerminalNode : Node {
Header nSym;
}
-----
That's just the skeleton though. For starters, you'll want to either
declare those members public or provide accessors ;).
Constructors would also be nice. Since you asked though, pretty much the
same effect can be achieved with static opCall (one in each child class
and/or two overloaded versions in Node itself) that creates a new object
of the appropriate type and fills in the fields.
To check whether a node is a terminal or not, there are several options:
* Try to cast a node to (Non)TerminalNode. If it's not of the
appropriate type, the cast returns null. This has the benefit that it
also returns a usable reference if it _is_ of the appropriate type, so
that you can access its special members.
* Add 'abstract bool isTerminal()' to Node and override it in the
subclasses.
* Add a 'const bool isTerminal' field to Node and initialize it in the
constructor from a parameter.
* Add 'TerminalNode asTerminal() { return null; }' to Node and override
it in TerminalNode to read 'return this;'. (Do something similar with
NonTerminalNode)
* {{ Probably some others I can't think of right now }}
More information about the Digitalmars-d-learn
mailing list