====== C-- ====== ===== Sémantické predikáty ===== { function_name }? grammar_expression flexible_stat : expr ( { is_expression }? simple_stat | { is_expression }? block_stat | continue_simple_declaration ) ; simple_stat : ';' ; block_stat : body:compound_stat ; def parse_flexible_stat (self) : self.on_begin_flexible_expr () result = self.parse_expr () self.on_end_flexible_expr () if self.tokenText == ";" and self.is_expression (result) : result = self.parse_simple_stat (result) elif self.tokenText == "{" and self.is_expression (result) : result = self.parse_block_stat (result) elif self.set_8 [self.token] : result = self.parse_continue_simple_declaration (result) else : self.error ("Unexpected token") return result ===== Gramatika C-- ===== [[http://gitlab.fjfi.cvut.cz/culikzde/view/-/blob/master/cmm/cmm.g|cmm.g]] /* cmm.g */ /* --------------------------------------------------------------------- */ < struct CmmExpr { enum kind; bool type_flag; bool remember_enable_declaration; ptr item_decl; ptr item_type; str alt_assign; str alt_connect; ptr alt_connect_dcl; str alt_connect_signal; } > < struct CmmName : CmmExpr { } > < struct CmmBinaryExpr : CmmExpr { } > < struct CmmCondition { enum kind; } > < struct CmmDeclarationCondition : CmmCondition { ptr decl_spec; bool a_destructor; } > < struct CmmStat { enum mode; } > < struct CmmDecl : CmmStat { } > < struct CmmDeclarator { enum kind; } > < struct CmmPtrSpecifier { enum kind; } > < struct CmmContSpecifier { enum kind; } > < struct CmmParam { enum kind; } > < struct CmmTextStat : CmmStat, mode = textStat { str text; } > < struct CmmEolStat : CmmStat, mode = eolStat > < struct CmmIndentStat : CmmStat, mode = indentStat > < struct CmmUnindentStat : CmmStat, mode = unindentStat > < struct CmmEmptyLineStat : CmmStat, mode = emptyLineStat > < struct CmmCppOnlyStat : CmmStat, mode = cppOnlyStat { ptr inner_stat; } > < struct CmmPythonOnlyStat : CmmStat, mode = pythonOnlyStat { ptr inner_stat; } > < group expr * CmmExpr > < group stat % CmmStat : stat, flexible_stat, declaration, member_item / nested_stat, continue_simple_declaration > < group param * CmmParam > < artificial stat, text_stat, CmmTextStat > < artificial stat, eol_stat, CmmEolStat > < artificial stat, indent_stat, CmmIndentStat > < artificial stat, unindent_stat, CmmUnindentStat > < artificial stat, empty_line_stat, CmmEmptyLineStat > < artificial stat, cpp_only_stat, CmmCppOnlyStat > < artificial stat, python_only_stat, CmmPythonOnlyStat > < execute_on_entry_no_param on_begin_flexible_expr : flexible_stat, parameter_declaration, condition, template_arg > < execute_on_fork_no_param on_end_flexible_expr : flexible_stat, parameter_declaration, condition, template_arg > < execute_on_choose on_binary_expr : // postfix_expr, pm_expr, multiplicative_expr, additive_expr, shift_expr, relational_expr, equality_expr, and_expr, exclusive_or_expr, inclusive_or_expr, logical_and_expr, logical_or_expr, assignment_expr, colon_expr, comma_expr > < predicate_on_choose is_binary_expression : // postfix_expr, pm_expr, // multiplicative_expr, additive_expr, shift_expr, relational_expr, equality_expr, // and_expr, exclusive_or_expr, inclusive_or_expr, logical_and_expr, logical_or_expr, assignment_expr, colon_expr, comma_expr > < predicate_on_choose is_postfix_expression : postfix_expr > < predicate_on_choose is_multiplicative_expression : multiplicative_expr > < predicate_on_choose is_and_expression : and_expr > < execute_on_end on_ident_expr : ident_expr > < execute_on_end on_int_value : int_value > < execute_on_end on_real_value : real_value > < execute_on_end on_char_value : char_value > < execute_on_end on_string_value : string_value > < execute_on_end on_this_expr : this_expr > < execute_on_end on_subexpr_expr : subexpr_expr > < execute_on_end on_field_expr : field_expr > < execute_on_end on_ptr_field_expr : ptr_field_expr > < execute_on_end on_call_expr : call_expr > < execute_on_end on_type_specifier : type_specifier > < execute_on_end on_type_name : type_name > < execute_on_end on_cv_specifier : const_specifier, volatile_specifier > < execute_on_end on_bit_not_expr : bit_not_expr > < execute_on_end on_name_expr : base_variant > < execute_on_begin_no_param on_other_expr : int_value, real_value, char_value, string_value, this_expr, subexpr_expr, modern_cast_expr, typeid_expr, type_name, type_specifier, const_specifier, volatile_specifier, inc_expr, dec_expr, deref_expr, addr_expr, plus_expr, minus_expr, bit_not_expr, log_not_expr, sizeof_expr, allocation_expr, deallocation_expr, throw_expr, cast_formula > /* identifier number real_number character_literal string_literal */ /* --------------------------------------------------------------------- */ /* simple name */ simple_name : id:identifier ; // only identifier /* base name */ global_variant : global_name | simple_name | special_function ; template_name : template_args:template_arg_list ; base_name : base_variant ( { is_template }? template_name )? ; /* compound name */ cont_name : id:identifier // same as simple_name, but used in compound_name ; destructor_name : "~" inner_name:simple_name ; cont_variant : ident_expr | int_value | real_value | char_value | string_value | this_expr | subexpr_expr ; ident_expr : qualified_name ; int_value : value:number ; real_value : value:real_number ; char_value : value:character_literal ; string_value : value:string_literal ( string_value_cont )* ; // !? string_value_cont : value:string_literal ; this_expr : "this" ; subexpr_expr : '(' param:expr ')' ; /* postfix expression */ postfix_start : postfix_expr | inc_expr | dec_expr | deref_expr | addr_expr | plus_expr | minus_expr | bit_not_expr | log_not_expr | sizeof_expr | allocation_expr | deallocation_expr | throw_expr ; inc_expr : "++" param:cast_expr ; dec_expr : "--" param:cast_expr ; deref_expr : '*' param:cast_expr ; addr_expr : '&' param:cast_expr ; plus_expr : '+' param:cast_expr ; minus_expr : '-' param:cast_expr ; bit_not_expr : '~' param:cast_expr ; log_not_expr : '!' param:cast_expr ; sizeof_expr : "sizeof" value:unary_expr ; /* new */ allocation_expr : "new" ( type1:new_type_id | '(' type2:type_id ')' ) ( '(' init_list:expr_list ')' )? ; new_type_id : type_spec:type_specifiers ptr:ptr_specifier_list ( allocation_array_limit )* ; allocation_array_limit : '[' value:expr ']' ; /* delete */ deallocation_expr : // ( "::" )? "delete" ( '[' ']' )? param:cast_expr ; /* cast expression */ cast_expr : flexible_stat | empty_stat | compound_stat | if_stat | while_stat | do_stat | for_stat | switch_stat | case_stat | default_stat | break_stat | continue_stat | return_stat | goto_stat | try_stat ; nested_stat : /* statement with different output indentation */ stat ; empty_stat : ';' ; compound_stat : '{' ( stat )* '}' ; if_stat : "if" '(' cond:expr ')' then_stat:nested_stat ( "else" else_stat:nested_stat )? ; while_stat : "while" '(' cond:expr ')' body:nested_stat ; do_stat : "do" body:nested_stat "while" '(' cond_expr:expr ')' ';' ; for_stat : "for" '(' ( from_expr:condition )? ( ':' iter_expr:expr | ';' (to_expr:expr)? ';' (cond_expr:expr)? ) ')' body:nested_stat ; switch_stat : "switch" '(' cond:expr ')' body:nested_stat ; case_stat : "case" case_expr:expr ':' body:nested_stat ; default_stat : "default" ':' body:nested_stat ; break_stat : "break" ';' ; continue_stat : "continue" ';' ; return_stat : "return" (return_expr:expr)? ';' ; goto_stat : "goto" goto_lab:identifier ';' ; /* simple statement */ flexible_stat : expr ( { is_expression }? simple_stat | { is_expression }? block_stat | continue_simple_declaration ) ; simple_stat : ';' ; block_stat : body:compound_stat ; /* ---------------------------------------------------------------------- */ /* declaration specifiers */ decl_specifiers : ( "inline" | "virtual" | "explicit" | "mutable" | // "extern" | "static" | // "auto" | "register" )* ; /* const / volatile */ const_specifier : "const" param:type_specifiers ; volatile_specifier : "volatile" param:type_specifiers ; /* type specifier */ type_specifier : ( "signed" | "unsigned" )? ( "short" | "long" ( "long" | "double" )? | "bool" | "char" | "wchar_t" | "int" | "float" | "double" | "void" ) ; /* typename */ type_name : "typename" qual_name:qualified_name ; /* type specifiers */ type_specifiers : pointer_specifier | reference_specifier ; /* pointer specifiers */ pointer_specifier : '*' cv_spec:cv_specifier_list ; /* reference specifiers */ reference_specifier : '&' cv_spec:cv_specifier_list ; cv_specifier_list : ( "const" | "volatile" )* ; /* ---------------------------------------------------------------------- */ cont_specifier_list : ( cont_specifier )* ; cont_specifier : simple_initializer | initializer_list ; simple_initializer : inner_expr:assignment_expr ; initializer_list : '{' ( initializer_item ( ',' initializer_item )* )? '}' ; /* ---------------------------------------------------------------------- */ /* attributes */ attr_item : attr_expr:assignment_expr ; attr_group : "[[" attr_item ( ',' attr_item )* "]]"; attr_list : ( attr_group )* ; /* ---------------------------------------------------------------------- */ /* simple declaration */ simple_declaration : ( decl_spec:decl_specifiers )? // !? ( '~' )? type_spec:type_specifiers modify_simple_declaration ; continue_simple_declaration : modify_simple_declaration ; modify_simple_declaration : simple_item ( ',' simple_item )* ( ( { is_constructor }? ':' ctor_init:ctor_initializer )? body:compound_stat | ';' ) ; simple_item : decl:declarator ( ':' width:const_expr )? ( init:initializer )? attr:attr_list ; /* condition */ condition : expr ( { is_expression }? condition_value | condition_declaration ) ; condition_declaration : ( simple_item ( ',' simple_item )* ) ; condition_value : ; /* ---------------------------------------------------------------------- */ /* declaration */ declaration_list : ( declaration )* ; declaration : member_visibility | flexible_stat | empty_stat | compound_stat | if_stat | while_stat | for_stat | class_declaration | enum_declaration | typedef_declaration | friend_declaration | using_declaration | template_declaration ; member_list : ( member_item )* ; /* base specification */ base_specifier_list : base_specifier ( ',' base_specifier )* ; base_specifier : ( "virtual" )? ( "private" | "protected" | "public" | ) from_cls:qualified_name ; /* constructor initializer */ ctor_initializer : member_initializer ( ',' member_initializer )* ; member_initializer : simp_name:simple_name // !? qualified_name '(' params:expr_list ')' ; /* ---------------------------------------------------------------------- */ /* special member functions */ conversion_specifiers : // !? type_spec:type_specifiers ptr_spec:ptr_specifier_list ; special_function : "operator" ( conv:conversion_specifiers // !? | "new" // ( ('[' ']') => '[' ']' )? // !? | "delete" // ( ('[' ']') => '[' ']' )? | "+" | "-" | "*" | "/" | "%" | "^" | "&" | "|" | "~" | "!" | "=" | "<" | ">" | "+=" | "-=" | "*=" | "/=" | "%=" | "^=" | "&=" | "|=" | "<<" | ">>" | ">>=" | "<<=" | "==" | "!=" | "<=" | ">=" | "&&" | "||" | "++" | "--" | "," | "->*" | "->" | "(" ")" | "[" "]" ) ; /* ---------------------------------------------------------------------- */ /* template declaration */ template_declaration : "template" ( '<' params:template_param_list '>' )? inner_declaration:declaration ; template_param_list : ( template_param ( ',' template_param )* )? ; /* template parameter */ template_param