// 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_syntax_cc_ah__ #define __ext_ac_syntax_cc_ah__ #include #include "Puma/ExtACSyntaxH.ah" // ************************* // C and CC-Syntax extension // ************************* slice void ExtACSyntax::skip_pointcut_expr () { static int stop_tokens[] = { Puma::TOK_COLON, Puma::TOK_OPEN_CURLY, 0 }; skip (stop_tokens, false); } slice Puma::CTree *ExtACSyntax::rule_pointcut_decl () { // 1: POINTCUT decl if (!parse (Puma::TOK_POINTCUT)) return (Puma::CTree*)0; semantic ().enter_pointcut_decl (); bool is_pointcut = decl (); semantic ().leave_pointcut_decl (); return is_pointcut ? semantic ().introduce_pointcut () : (Puma::CTree*)0; } slice bool ExtACSyntax::pointcut_decl () { return parse (&ExtACSyntax::rule_pointcut_decl); } slice Puma::CTree *ExtACSyntax::rule_class_slice_decl () { // 1: SLICE class_key? identifier? { intro * } ; return (parse (Puma::TOK_SLICE) && class_key () && (identifier () || private_name ()) && opt (class_slice_member_list ()) && parse (Puma::TOK_SEMI_COLON)) ? semantic ().introduce_class_slice () : (Puma::CTree*)0; } slice bool ExtACSyntax::class_slice_decl () { return parse (&ExtACSyntax::rule_class_slice_decl); } slice Puma::CTree *ExtACSyntax::rule_class_slice_member_decl () { return (parse (Puma::TOK_SLICE) && intro ()) ? semantic ().introduce_class_slice_member () : (Puma::CTree*)0; } slice bool ExtACSyntax::class_slice_member_decl () { return parse (&ExtACSyntax::rule_class_slice_member_decl); } slice Puma::CTree *ExtACCSyntax::rule_class_slice_decl () { // 4-6: SLICE class_key class_slice_name base_clause? ({ intro * })? ; return (parse (Puma::TOK_SLICE) && class_key () && class_slice_name () && opt (class_slice_base_clause ()) && opt (class_slice_member_list ()) && parse (Puma::TOK_SEMI_COLON)) ? semantic ().introduce_class_slice () : (Puma::CTree*)0; } slice bool ExtACCSyntax::class_slice_decl () { return parse (&ExtACCSyntax::rule_class_slice_decl); } slice Puma::CTree *ExtACCSyntax::rule_class_slice_name () { // 1: identifier // 2: nested_name_spec identifier // 2: :: identifier // 3: :: nested_name_spec identifier // 1: private_name bool ok = ((colon_colon (), nested_name_spec (), identifier ()) || private_name ()); semantic ().reset_search_scope (); return ok ? builder ().class_slice_name () : (Puma::CTree*)0; } slice bool ExtACCSyntax::class_slice_name () { return parse (&CCSyntax::rule_class_slice_name); } slice Puma::CTree *ExtACCSyntax::rule_class_slice_base_clause () { if (!parse (Puma::TOK_COLON)) return (Puma::CTree*)0; int tok; while ((tok = look_ahead ())) { if (tok == Puma::TOK_OPEN_CURLY || tok == Puma::TOK_SEMI_COLON) break; else consume (); } return builder ().intro (); } slice bool ExtACCSyntax::class_slice_base_clause () { return parse (&ExtACCSyntax::rule_class_slice_base_clause); } slice Puma::CTree *ExtACSyntax::rule_class_slice_member_list () { return (parse (Puma::TOK_OPEN_CURLY) && opt (seq (&Puma::CSyntax::intro)) && parse (Puma::TOK_CLOSE_CURLY)) ? builder ().class_slice_member_list () : (Puma::CTree*)0; } slice bool ExtACSyntax::class_slice_member_list () { return parse (&ExtACSyntax::rule_class_slice_member_list); } slice Puma::CTree *ExtACSyntax::rule_order_decl () { return (parse (Puma::TOK_ID) && strcmp (builder ().get_node ()->token ()->text (), "order") == 0 && order_list () && parse (Puma::TOK_SEMI_COLON)) ? builder ().order_decl () : (Puma::CTree*)0; } slice bool ExtACSyntax::order_decl () { return parse (&ExtACSyntax::rule_order_decl); } slice Puma::CTree *ExtACSyntax::rule_order_list () { return (parse (Puma::TOK_OPEN_ROUND) && opt (list (&Puma::CSyntax::pointcut_expr, Puma::TOK_COMMA)) && parse (Puma::TOK_CLOSE_ROUND)) ? builder ().order_list () : (Puma::CTree*)0; } slice bool ExtACSyntax::order_list () { return parse (&ExtACSyntax::rule_order_list); } slice Puma::CTree *ExtACSyntax::rule_advice_decl () { // 1: ADVICE pointcut : decl if (!parse (Puma::TOK_ADVICE)) return (Puma::CTree*)0; semantic ().enter_advice_decl (); Syntax::State before_expr = token_provider->get_state (); skip_pointcut_expr (); bool ok = (parse (Puma::TOK_COLON) && (order_decl () || slice_ref () || class_slice_decl () || intro () || decl ())); if (ok) { semantic ().enter_pointcut_expr (); token_provider->set_state (before_expr); ok = (pointcut_expr () && look_ahead (Puma::TOK_COLON)); semantic ().leave_pointcut_expr (); } semantic ().leave_advice_decl (); return ok ? semantic ().introduce_advice () : (Puma::CTree*)0; } slice bool ExtACSyntax::advice_decl () { return parse (&ExtACSyntax::rule_advice_decl); } slice Puma::CTree *ExtACSyntax::rule_pointcut_expr () { // 1: const_expr return const_expr () ? builder ().pointcut_expr () : (Puma::CTree*)0; } slice bool ExtACSyntax::pointcut_expr () { return parse (&ExtACSyntax::rule_pointcut_expr); } slice Puma::CTree *ExtACSyntax::rule_pointcut_member_decl () { // 1: POINTCUT decl if (!parse (Puma::TOK_POINTCUT)) return (Puma::CTree*)0; semantic ().enter_pointcut_decl (); bool is_pointcut = member_decl (); semantic ().leave_pointcut_decl (); return is_pointcut ? semantic ().introduce_pointcut () : (Puma::CTree*)0; } slice bool ExtACSyntax::pointcut_member_decl () { return parse (&ExtACSyntax::rule_pointcut_member_decl); } slice Puma::CTree *ExtACSyntax::rule_advice_member_decl () { // 1: ADVICE pointcut : decl if (!parse (Puma::TOK_ADVICE)) return (Puma::CTree*)0; semantic ().enter_advice_decl (); Syntax::State before_expr = token_provider->get_state (); skip_pointcut_expr (); bool ok = (parse (Puma::TOK_COLON) && (order_decl () || slice_ref () || class_slice_decl () || intro () || member_decl ())); if (ok) { semantic ().enter_pointcut_expr (); token_provider->set_state (before_expr); ok = (pointcut_expr () && look_ahead (Puma::TOK_COLON)); semantic ().leave_pointcut_expr (); } semantic ().leave_advice_decl (); return ok ? semantic ().introduce_member_advice () : (Puma::CTree*)0; } slice bool ExtACSyntax::advice_member_decl () { return parse (&ExtACSyntax::rule_advice_member_decl); } slice Puma::CTree *ExtACSyntax::rule_slice_ref () { // 3: SLICE identifier ; return (parse (Puma::TOK_SLICE) && identifier () && parse (Puma::TOK_SEMI_COLON)) ? builder ().slice_ref () : (Puma::CTree*)0; } slice bool ExtACSyntax::slice_ref () { return parse (&ExtACSyntax::rule_slice_ref); } slice Puma::CTree *ExtACCSyntax::rule_slice_ref () { // 3: SLICE class_name ; // 4: SLICE :: class_name ; // 4: SLICE nested_name_spec class_name ; // 5: SLICE :: nested_name_spec class_name ; if (! parse (Puma::TOK_SLICE)) return (Puma::CTree*)0; bool ok = ((colon_colon (), nested_name_spec (), class_name ()) && parse (Puma::TOK_SEMI_COLON)); semantic ().reset_search_scope (); return ok ? builder ().slice_ref () : (Puma::CTree*)0; } slice bool ExtACCSyntax::slice_ref () { return parse (&ExtACCSyntax::rule_slice_ref); } // FIXME tagging slice Puma::CTree *ExtACCSyntax::rule_tag_expr () { if(!semantic ().in_pointcut_expr ()) return (Puma::CTree*)0; bool ok = false; if (parse (Puma::TOK_AT)) { semantic ().enter_tag_expr (); if(identifier () && tag_parameter_list ()) ok = true; semantic ().leave_tag_expr (); } return ok ? builder ().tag_expr () : (Puma::CTree*)0; } slice bool ExtACCSyntax::tag_expr () { return parse (&ExtACCSyntax::rule_tag_expr); } // FIXME tagging slice Puma::CTree *ExtACSyntax::rule_intro () { if (look_ahead () == Puma::TOK_CLOSE_CURLY) return (Puma::CTree*)0; if (parse (Puma::TOK_ID)) { const char *id = builder ().get_node ()->token ()->text (); if (strcmp (id, "order") == 0 || strcmp (id, "before") == 0 || strcmp (id, "after") == 0 || strcmp (id, "around") == 0 || strcmp (id, "baseclass") == 0) return (Puma::CTree*)0; } if (parse (Puma::TOK_PRIVATE) || parse (Puma::TOK_PROTECTED) || parse (Puma::TOK_PUBLIC)) { return parse (Puma::TOK_COLON) ? builder ().intro () : (Puma::CTree*)0; } // look ahead bool is_fct = is_fct_def (); int tok; while ((tok = look_ahead ())) { // end of intro reached? if (tok == Puma::TOK_SEMI_COLON && !is_fct) { consume (); break; } if (tok == Puma::TOK_OPEN_CURLY) { parse_curly_block (); if (is_fct) break; } else if (tok == Puma::TOK_OPEN_ROUND) parse_round_block (); else consume (); } return builder ().intro (); } // FIXME tagging slice Puma::CTree *ExtACCSyntax::rule_intro () { if (look_ahead () == Puma::TOK_CLOSE_CURLY) return (Puma::CTree*)0; // ignore template decl if (parse (Puma::TOK_TEMPLATE)) { skip_block (Puma::TOK_LESS, Puma::TOK_GREATER); } if (parse (Puma::TOK_ID)) { const char *id = builder ().get_node ()->token ()->text (); if (strcmp (id, "order") == 0 || strcmp (id, "before") == 0 || strcmp (id, "after") == 0 || strcmp (id, "around") == 0 || strcmp (id, "baseclass") == 0) return (Puma::CTree*)0; } if (parse (Puma::TOK_PRIVATE) || parse (Puma::TOK_PROTECTED) || parse (Puma::TOK_PUBLIC)) { return parse (Puma::TOK_COLON) ? builder ().intro () : (Puma::CTree*)0; } // look ahead bool is_fct = is_fct_def (); int tok; while ((tok = look_ahead ())) { // end of intro reached? if (tok == Puma::TOK_SEMI_COLON && !is_fct) { consume (); break; } if (tok == Puma::TOK_OPEN_CURLY) { parse_curly_block (); if (is_fct) break; } else if (tok == Puma::TOK_OPEN_ROUND) parse_round_block (); else consume (); } return builder ().intro (); } // FIXME tagging slice bool ExtACSyntax::intro () { return parse (&ExtACSyntax::rule_intro); } // FIXME tagging slice bool ExtACCSyntax::intro () { return parse (&ExtACCSyntax::rule_intro); } // FIXME tagging #endif /* __ext_ac_syntax_cc_ah__ */