// This file is part of PUMA. // Copyright (C) 1999-2003 The PUMA developer team. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of // the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public // License along with this program; if not, write to the Free // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, // MA 02111-1307 USA #ifndef __ext_ac_keywords_ah__ #define __ext_ac_keywords_ah__ #include #include "Puma/CProject.h" #include "Puma/FileUnit.h" #include "Puma/CLexer.h" #include "Puma/Token.h" // ***************************************** // AspectC++ keyword handling in the scanner // ***************************************** aspect ExtACKeywords { static const unsigned int _config_mask = 1; int _prj_keywords; // -1 - not set, 0 - no, 1 - yes Puma::CProject *_project; // active project protected: ExtACKeywords () : _prj_keywords (-1) {} public: // allow/forbid AspectC++ keywords in normal project files void prj_keywords (bool kw) { _prj_keywords = kw; } // obtain a project reference wherever possible advice execution ("% Puma::Parser::parse(...)") && args ("%", project, "%") : before (Puma::CProject &project) { _project = &project; } advice execution ("% Puma::CProject::scanFile(...)") : before () { _project = tjp->that (); } advice execution ("% Puma::CScanner::fill_unit(...)") && args ("%", unit) && (cflow (execution ("% Puma::Parser::parse(...)")|| execution ("% Puma::CProject::scanFile(...)"))) : before (Puma::Unit &unit) { if (_prj_keywords == -1 || !unit.isFile ()) return; bool ac_kw = _prj_keywords; // in external files the AspectC++ keywords are always identifiers if (!((Puma::FileUnit*)&unit)->belongsTo (*_project)) { ac_kw = false; } // in aspect headers keywords are keywords else if (unit.name ()) { size_t len = strlen (unit.name ()); if (len > 2 && strcmp (unit.name () + (len - 3), ".ah") == 0) { ac_kw = true; } } // finally the right flag tjp->that ()->allow_aspectc (ac_kw); } advice execution ("% Puma::CLexer::add_keywords(...)") : after () { if (tjp->that ()->_config_mask & _config_mask) { lexertl::rules &rules = *tjp->arg<0>(); // AspectC++ keywords rules.add ("pointcut", Puma::TOK_POINTCUT, LID(Puma::Token::keyword_id)); rules.add ("aspect", Puma::TOK_ASPECT, LID(Puma::Token::keyword_id)); rules.add ("advice", Puma::TOK_ADVICE, LID(Puma::Token::keyword_id)); rules.add ("slice", Puma::TOK_SLICE, LID(Puma::Token::keyword_id)); rules.add ("__unknown_t", Puma::TOK_UNKNOWN_T, LID(Puma::Token::keyword_id)); } } advice call ("% Puma::CCLexer::instance(...)") && within ("Puma::CScanner"): before () { if (tjp->that ()->aspectc) *tjp->arg<0>() |= _config_mask; } }; #endif /* __ext_ac_keywords_ah__ */