/* gramm: cmm.g -> cmm_parser.hpp */

#ifndef __PROG_CMM_PARSER_HPP__
#define __PROG_CMM_PARSER_HPP__

#include "cmm_data.hpp"
#include "cmm_lexer.hpp"

OPEN_NAMESPACE

class CmmParser;

class CmmParser : public CmmLexer
{
   // parse
   public:
      string identifier ();
      string numeric_literal ();
      string char_literal ();
      string string_literal ();
      void base_subst (CmmName * p_result);
      void base_name (CmmName * p_result);
      void base_args (CmmName * p_result);
      CmmContName * cont_item ();
      void cont_subst (CmmContName * p_result);
      void cont_name (CmmContName * p_result);
      void cont_args (CmmContName * p_result);
      void compound_name (CmmName * p_result);
      void simple_name (CmmName * p_result);
      void global_mark (CmmName * p_result);
      CmmName * qualified_name ();
      CmmName * global_name ();
      CmmName * global_declaring_name ();
      CmmName * global_type_name ();
      CmmName * simple_new_name ();
      CmmName * global_new_name ();
      CmmName * id_expr ();
      CmmExpr * primary_expr ();
      CmmNumValue * numeric_literal_expr ();
      CmmCharValue * char_literal_expr ();
      CmmStringCont * string_literal_cont ();
      CmmStringValue * string_literal_expr ();
      CmmThisExpr * this_expr ();
      CmmSubexprExpr * subexpr_expr ();
      CmmExpr * postfix_start ();
      CmmModernCastExpr * modern_cast_expr ();
      CmmTypeidExpr * typeid_expr ();
      CmmTypenameExpr * typename_expr ();
      CmmTypechangeExpr * type_change_expr ();
      CmmExpr * postfix_expr ();
      CmmIndexExpr * index_expr (CmmExpr * p_store);
      CmmCallExpr * call_expr (CmmExpr * p_store);
      CmmFieldExpr * field_expr (CmmExpr * p_store);
      CmmPtrFieldExpr * ptr_field_expr (CmmExpr * p_store);
      CmmPostIncExpr * post_inc_expr (CmmExpr * p_store);
      CmmPostDecExpr * post_dec_expr (CmmExpr * p_store);
      CmmExprList * expr_list ();
      CmmExpr * unary_expr ();
      CmmUnaryExpr * inc_expr ();
      CmmUnaryExpr * dec_expr ();
      CmmUnaryExpr * deref_expr ();
      CmmUnaryExpr * addr_expr ();
      CmmUnaryExpr * plus_expr ();
      CmmUnaryExpr * minus_expr ();
      CmmUnaryExpr * bit_not_expr ();
      CmmUnaryExpr * log_not_expr ();
      CmmUnaryExpr * scope_expr ();
      CmmSizeofExp * sizeof_expr ();
      CmmNewExpr * allocation_expr ();
      CmmNewPlacement * new_placement ();
      CmmNewTypeId * new_type_id ();
      CmmNewArrayLimit * allocation_array_limit ();
      CmmDeleteExpr * deallocation_expr ();
      CmmExpr * cast_expr ();
      CmmCastFormula * cast_formula ();
      CmmExpr * pm_expr ();
      CmmExpr * multiplicative_expr ();
      CmmExpr * additive_expr ();
      CmmExpr * shift_expr ();
      CmmExpr * relational_expr ();
      CmmExpr * equality_expr ();
      CmmExpr * and_expr ();
      CmmExpr * exclusive_or_expr ();
      CmmExpr * inclusive_or_expr ();
      CmmExpr * logical_and_expr ();
      CmmExpr * logical_or_expr ();
      CmmExpr * conditional_expr ();
      CmmCondExpr * conditional_cont_expr (CmmExpr * p_store);
      CmmExpr * assignment_expr ();
      CmmExpr * simple_assignment_expr ();
      CmmExpr * expr ();
      CmmExpr * const_expr ();
      CmmStat * stat ();
      CmmStat * inner_stat ();
      CmmStat * tail_stat ();
      CmmStatSect * stat_list ();
      CmmStatSect * inner_stat_list ();
      CmmDeclStat * declaration_stat ();
      CmmLabeledStat * labeled_stat ();
      CmmCaseStat * case_stat ();
      CmmDefaultStat * default_stat ();
      CmmExprStat * expression_stat ();
      CmmEmptyStat * empty_stat ();
      CmmCompoundStat * compound_stat ();
      CmmCondition * condition ();
      CmmCondition * for_condition ();
      CmmIfStat * if_stat ();
      CmmSwitchStat * switch_stat ();
      CmmWhileStat * while_stat ();
      CmmDoStat * do_stat ();
      CmmForStat * for_stat ();
      CmmBreakStat * break_stat ();
      CmmContinueStat * continue_stat ();
      CmmReturnStat * return_stat ();
      CmmGotoStat * goto_stat ();
      CmmDeclSect * declaration_list ();
      CmmDecl * declaration ();
      CmmDecl * block_declaration ();
      CmmSimpleDecl * simple_declaration ();
      CmmSimpleDecl * simple_declaration_content ();
      CmmComplexDecl * complex_declaration ();
      CmmCtorHead * constructor_head ();
      CmmDeclarator * constructor_head_declarator ();
      CmmContSpecifierSect * constructor_head_specifier_list ();
      CmmContSpecifier * constructor_head_specifier ();
      CmmCtorDecl * constructor_declaration ();
      CmmFunctionBody * function_body ();
      CmmEnumDecl * elaborated_enum_specifier ();
      CmmClassDecl * elaborated_class_specifier ();
      CmmClassDecl * class_declaration ();
      CmmEnumDecl * enum_declaration ();
      CmmNamespaceDecl * namespace_definition ();
      void namespace_body (CmmNamespaceDecl * p_result);
      CmmUsingDecl * using_declaration ();
      CmmExternDecl * linkage_specification ();
      CmmAsmDecl * asm_declaration ();
      CmmEmptyDecl * empty_declaration ();
      CmmDeclSpec * decl_specifiers ();
      CmmDeclSpec * type_specifiers ();
      CmmTypenameSpec * typename_specifier ();
      void simple_decl_specifiers (CmmDeclSpec * p_result);
      CmmDeclSpec * constructor_decl_specifiers ();
      void simple_cv_specifiers (CmmDeclSpec * p_result);
      void simple_type_specifiers (CmmDeclSpec * p_result);
      CmmEnumDecl * enum_specifier ();
      void enum_body (CmmEnumDecl * p_result);
      CmmEnumSect * enum_list ();
      CmmEnumItem * enumerator ();
      CmmEnumItem * flexible_enumerator ();
      CmmTypeId * type_id ();
      CmmTypeId * common_type_id ();
      CmmDeclarator * declarator ();
      CmmDeclarator * abstract_declarator ();
      void common_declarator_name (CmmDeclarator * p_result);
      CmmDeclarator * common_declarator ();
      CmmPtrSpecifierSect * ptr_specifier_list ();
      CmmPtrSpecifier * ptr_specifier ();
      CmmPtrSpecifier * member_specifier ();
      void member_specifier_tail (CmmPtrSpecifier * p_result);
      void ptr_cv_specifier_list (CmmPtrSpecifier * p_result);
      CmmContSpecifierSect * cont_specifier_list ();
      CmmContSpecifier * cont_specifier ();
      CmmFunctionSpecifier * function_specifier ();
      CmmArraySpecifier * array_specifier ();
      CmmParamSect * parameter_declaration_list ();
      CmmParamItem * parameter_declaration ();
      void parameter_initialization (CmmParamItem * p_result);
      CmmDeclarator * init_declarator ();
      CmmInitializer * initializer ();
      CmmInitItem * initializer_item ();
      CmmInitItem * flexible_initializer_item ();
      CmmInitEmpty * empty_initializer ();
      CmmInitSimple * simple_initializer ();
      CmmInitList * initializer_list ();
      CmmClassDecl * class_specifier ();
      void class_body (CmmClassDecl * p_result);
      CmmMemberVisibility * member_visibility ();
      CmmDecl * member_item ();
      CmmDeclSect * member_list ();
      CmmBaseSect * base_specifier_list ();
      CmmBaseItem * base_specifier ();
      CmmCtorInitializer * ctor_initializer ();
      CmmMemberInitializer * member_initializer ();
      CmmDeclSpec * conversion_specifiers ();
      CmmSpecialFuction * special_function ();
      CmmTemplateDecl * template_declaration ();
      CmmExxternTemplateDecl * extern_template_declaration ();
      void common_template_declaration (CmmTemplateDecl * p_result);
      void template_specification (CmmTemplateDecl * p_result);
      CmmTemplateParamSect * template_param_list ();
      CmmTemplateParam * template_param ();
      CmmTemplateTypeParam * template_type_param ();
      CmmTemplateValueParam * template_value_param ();
      CmmTemplateArgSect * template_arg_list ();
      CmmTemplateArg * template_arg ();
      CmmTemplateTypeArg * template_type_arg ();
      CmmTemplateValueArg * template_value_arg ();
      CmmTryStat * try_stat ();
      CmmHandlerSect * handler_list ();
      CmmHandlerItem * handler ();
      CmmThrowExpr * throw_expr ();
      CmmExceptionSect * exception_specification ();
      CmmExceptionItem * exception_specification_item ();

   // syntactic predicates
   public:
      bool condition_1 ();
      bool condition_2 ();
      bool condition_3 ();
      bool condition_4 ();
      bool condition_5 ();
      bool condition_6 ();

   // semantic predicates
   public:
      bool is_template_arg (CmmName * item);
      bool is_cont_template_arg (CmmContName * item);
      bool is_type ();
      bool is_type_in_parenthesis ();
      bool is_parenthesis_and_expression ();
      bool is_declaration ();
      bool is_constructor ();
      bool is_inner_abstract_declarator ();
      bool is_inner_common_declarator ();
      bool is_parameter ();
      bool is_initializer_acceptable ();
      bool is_width_acceptable (CmmDeclarator * item);

   // execute directives
   public:
      void add_name (CmmContName * item);
      void open_name (CmmName * item);
      void start_name (CmmName * item);
      void close_name (CmmName * item);
      void check_type (CmmName * item);
      void open_type_name (CmmName * item);
      void close_type_name (CmmName * item);
      void open_new_name (CmmName * item);
      void close_new_name (CmmName * item);
      void open_field_template (CmmFieldExpr * item);
      void close_field_template (CmmFieldExpr * item);
      void open_ptr_field_template (CmmPtrFieldExpr * item);
      void close_ptr_field_template (CmmPtrFieldExpr * item);
      void open_block ();
      void read_block ();
      void close_block ();
      void open_simple_declaration (CmmSimpleDecl * item);
      void close_simple_declaration (CmmSimpleDecl * item);
      void open_complex_declaration (CmmComplexDecl * item);
      void close_complex_declaration (CmmComplexDecl * item);
      void open_declarator (CmmDeclarator * item);
      void close_declarator (CmmDeclarator * item);
      void open_constructor_declaration (CmmCtorDecl * item);
      void close_constructor_declaration (CmmCtorDecl * item);
      void open_function (CmmFunctionBody * item);
      void close_function (CmmFunctionBody * item);
      void add_namespace_alias (CmmNamespaceDecl * item);
      void open_namespace (CmmNamespaceDecl * item);
      void close_namespace (CmmNamespaceDecl * item);
      void open_using (CmmUsingDecl * item);
      void close_using (CmmUsingDecl * item);
      void open_decl_specifiers (CmmDeclSpec * item);
      void close_decl_specifiers (CmmDeclSpec * item);
      void add_enum_forw (CmmEnumDecl * item);
      void open_enum_type (CmmEnumDecl * item);
      void close_enum_type (CmmEnumDecl * item);
      void add_enum_item (CmmEnumItem * item);
      void member_pointer_list (CmmPtrSpecifierSect * item);
      void open_parameters (CmmFunctionSpecifier * item);
      void close_parameters (CmmFunctionSpecifier * item);
      void read_param_init ();
      void add_parameter (CmmParamItem * item);
      void add_declarator (CmmDeclarator * item);
      void read_initializer ();
      void add_class_forw (CmmClassDecl * item);
      void open_class (CmmClassDecl * item);
      void close_class (CmmClassDecl * item);
      void add_visibility (CmmMemberVisibility * item);
      void add_base (CmmBaseItem * item);
      void read_member_initializer ();
      void open_conversion ();
      void close_conversion ();
      void open_template (CmmTemplateDecl * item);
      void add_template (CmmTemplateDecl * item);
      void close_template (CmmTemplateDecl * item);
      void add_template_type_param (CmmTemplateTypeParam * item);
      void add_template_value_param (CmmTemplateValueParam * item);
      void open_template_arguments (CmmTemplateArgSect * item);
      void close_template_arguments (CmmTemplateArgSect * item);

   public:
      bool examine_type_name (CmmName * name);
      bool examine_type_or_declaration (bool decl, bool parenthesis, bool common);

   public:
      CmmParser ();
};

CLOSE_NAMESPACE

#endif /* __PROG_CMM_PARSER_HPP__ */