====== C3 - tutorial/cecko3.g ==== Gramatika zjednodušeného C++ používaná v kapitole "Objektově orientované syntaktické stromy" [[http://gitlab.fjfi.cvut.cz/culikzde/view/-/blob/master/tutorial/cecko3.g|cecko3.g]] Abychom odlišili lokální deklaraci od jednoduchého příkazu obsahujícího výraz a středník, \\ musíme si jazyk upravit a před deklaraci přidat klíčové slovo **dcl**. decl_stat < CmmDeclStat: CmmStat >: "dcl" inner_decl:simple_decl ; simple_stat < CmmSimpleStat: CmmStat >: inner_expr:expr ';' ; stat < select CmmStat > : decl_stat | while_stat | if_stat | for_stat | return_stat | compound_stat | simple_stat | empty_stat ; Gramatika je již poměrně dlouhá: /* statements */ while_stat < CmmWhileStat: CmmStat > : "while" '(' cond:expr ')' body_stat:inner_stat ; if_stat < CmmIfStat: CmmStat > : "if" '(' cond:expr ')' then_stat:inner_stat ( "else" else_stat:inner_stat )? ; for_stat : "for" '(' ( from_expr:expr )? ';' ( cond_expr:expr )? ';' ( step_expr:expr) ? ')' body_stat:inner_stat ; return_stat : "return" ( return_expr:expr )? ';' ; compound_stat < CmmCompoundStat: CmmStat > : '{' ( stat )* '}' ; simple_stat < CmmSimpleStat: CmmStat >: inner_expr:expr ';' ; decl_stat < CmmDeclStat: CmmStat >: "dcl" inner_decl:simple_decl ; empty_stat < CmmEmptyStat: CmmStat > : ';' ; stat < select CmmStat > : decl_stat | while_stat | if_stat | for_stat | return_stat | compound_stat | simple_stat | empty_stat ; inner_stat < return CmmStat > : stat ; /* -------------------------------------------------------------------- */ /* expressions */ < struct CmmExpr { enum kind; } > < struct CmmPostfixExpr : CmmExpr { CmmExpr left; } > < struct CmmBinaryExpr : CmmExpr { } > < group expr * CmmExpr > variable_expr : name:identifier ; int_value_expr : value:number; real_value_expr : value:real_number; char_value_expr : value:character_literal; string_value_expr : value:string_literal; subexpr_expr : '(' inner_expr:expr ')' ; sequence_expr : '[' param:expr_list ']' ; this_expr : "this"; simple_expr : inc_expr | dec_expr | deref_expr | addr_expr | plus_expr | minus_expr | bit_not_expr | log_not_expr | allocation_expr | deallocation_expr | postfix_expr ; inc_expr : "++" param:unary_expr; dec_expr : "--" param:unary_expr; deref_expr : '*' param:unary_expr; addr_expr : '&' param:unary_expr; plus_expr : '+' param:unary_expr; minus_expr : '-' param:unary_expr; bit_not_expr : '~' param:unary_expr; log_not_expr : '!' param:unary_expr; allocation_expr : "new" type:identifier ( '(' init_list:expr_list ')' )? ; deallocation_expr : "delete" param:unary_expr ; /* binary expressions */ multiplicative_expr : unary_expr ( ( '*' | '/' | '%' ) right:unary_expr )* ; additive_expr : multiplicative_expr ( ( '+' | '-' ) right:multiplicative_expr )* ; shift_expr : additive_expr ( ( "<<" | ">>" ) right:additive_expr )* ; relational_expr : shift_expr ( ( '<' | '>' | "<=" | ">=" ) right:shift_expr )* ; equality_expr : relational_expr ( ( "==" | "!=" ) right:relational_expr )* ; and_expr : equality_expr ( '&' right:equality_expr )* ; exclusive_or_expr : and_expr ( '^' right:and_expr )* ; inclusive_or_expr : exclusive_or_expr ( ( '|' ) right:exclusive_or_expr )* ; logical_and_expr : inclusive_or_expr ( "&&" right:inclusive_or_expr )* ; logical_or_expr : logical_and_expr ( "||" right:logical_and_expr )* ; assignment_expr : logical_or_expr ( ( '=' | "+=" | "-=" ) right:assignment_expr )? ; expr : assignment_expr ; expr_list : ( expr ( ',' expr )* )? ; /* -------------------------------------------------------------------- */ namespace_decl : "namespace" name:identifier '{' ( decl ) * '}' ; /* -------------------------------------------------------------------- */ class_decl : "class" name:identifier '{' ( simple_decl ) * '}' ; /* -------------------------------------------------------------------- */ enum_decl : "enum" name:identifier '{' enum_item ( ',' enum_item ) * '}' ; enum_item : name:identifier ; /* -------------------------------------------------------------------- */ template_decl : "template" '<' ( template_param ( ',' template_param )* )? '>' inner_decl:decl ; template_param : name:identifier ; /* -------------------------------------------------------------------- */ simple_decl : type:identifier ( '*' )? name:identifier ( ( '=' init_value:expr )? ';' | init_stat:compound_stat | param_list:parameter_list body:compound_stat ) ; parameter_list : '(' ( parameter_decl ( ',' parameter_decl )* )? ')' ; parameter_decl : type:identifier name:identifier ; empty_decl : ';' ; /* -------------------------------------------------------------------- */ decl