aspect Nullable { // *** API *** // A nonterminal has a boolean attribute *nullable* // which is true if the nonterminal can derive the empty string. inh boolean NDecl.nullable() circular [false]; // *** Implementation *** syn boolean Prod.nullable() circular [false]; syn boolean Symbol.nullable() circular [false]; eq Terminal.nullable() { return false; } eq NUse.nullable(){ return decl().nullable(); } eq Rule.getNDecl().nullable() { for (int i = 0; i < getNumProd(); i++) { if (getProd(i).nullable()) return true; } return false; } eq Prod.nullable() { for (int i = 0; i < getNumSymbol(); i++) { if (!getSymbol(i).nullable()) return false; } return true; } }