@@ -82,6 +82,31 @@ no_comma:
82
82
optional_comma :
83
83
/* empty */
84
84
| ' ,'
85
+ ;
86
+
87
+ attribute_decl :
88
+ class_name { $$ = Node\Attribute[$1 , []]; }
89
+ | class_name argument_list { $$ = Node\Attribute[$1 , $2 ]; }
90
+ ;
91
+
92
+ attribute_group :
93
+ attribute_decl { init($1 ); }
94
+ | attribute_group ' ,' attribute_decl { push($1 , $3 ); }
95
+ ;
96
+
97
+ attribute :
98
+ T_ATTRIBUTE attribute_group optional_comma ' ]' { $$ = Node\AttributeGroup[$2 ]; }
99
+ ;
100
+
101
+ attributes :
102
+ attribute { init($1 ); }
103
+ | attributes attribute { push($1 , $2 ); }
104
+ ;
105
+
106
+ optional_attributes :
107
+ /* empty */ { $$ = []; }
108
+ | attributes { $$ = $1 ; }
109
+ ;
85
110
86
111
top_statement :
87
112
statement { $$ = $1 ; }
@@ -316,19 +341,24 @@ block_or_error:
316
341
;
317
342
318
343
function_declaration_statement :
319
- T_FUNCTION optional_ref identifier ' (' parameter_list ' )' optional_return_type block_or_error
320
- { $$ = Stmt\Function_[$3 , [' byRef' => $2 , ' params' => $5 , ' returnType' => $7 , ' stmts' => $8 ]]; }
344
+ T_FUNCTION optional_ref identifier ' (' parameter_list ' )' optional_return_type block_or_error
345
+ { $$ = Stmt\Function_[$3 , [' byRef' => $2 , ' params' => $5 , ' returnType' => $7 , ' stmts' => $8 , ' attrGroups' => []]]; }
346
+ | attributes T_FUNCTION optional_ref identifier ' (' parameter_list ' )' optional_return_type block_or_error
347
+ { $$ = Stmt\Function_[$4 , [' byRef' => $3 , ' params' => $6 , ' returnType' => $8 , ' stmts' => $9 , ' attrGroups' => $1 ]]; }
321
348
;
322
349
323
350
class_declaration_statement :
324
351
class_entry_type identifier extends_from implements_list ' {' class_statement_list ' }'
325
- { $$ = Stmt\Class_[$2 , [' type' => $1 , ' extends' => $3 , ' implements' => $4 , ' stmts' => $6 ]];
352
+ { $$ = Stmt\Class_[$2 , [' type' => $1 , ' extends' => $3 , ' implements' => $4 , ' stmts' => $6 , ' attrGroups ' => [] ]];
326
353
$this- >checkClass ($$, #2 ); }
327
- | T_INTERFACE identifier interface_extends_list ' {' class_statement_list ' }'
328
- { $$ = Stmt\Interface_[$2 , [' extends' => $3 , ' stmts' => $5 ]];
329
- $this- >checkInterface ($$, #2 ); }
330
- | T_TRAIT identifier ' {' class_statement_list ' }'
331
- { $$ = Stmt\Trait_[$2 , [' stmts' => $4 ]]; }
354
+ | attributes class_entry_type identifier extends_from implements_list ' {' class_statement_list ' }'
355
+ { $$ = Stmt\Class_[$3 , [' type' => $2 , ' extends' => $4 , ' implements' => $5 , ' stmts' => $7 , ' attrGroups' => $1 ]];
356
+ $this- >checkClass ($$, #3 ); }
357
+ | optional_attributes T_INTERFACE identifier interface_extends_list ' {' class_statement_list ' }'
358
+ { $$ = Stmt\Interface_[$3 , [' extends' => $4 , ' stmts' => $6 , ' attrGroups' => $1 ]];
359
+ $this- >checkInterface ($$, #3 ); }
360
+ | optional_attributes T_TRAIT identifier ' {' class_statement_list ' }'
361
+ { $$ = Stmt\Trait_[$3 , [' stmts' => $5 , ' attrGroups' => $1 ]]; }
332
362
;
333
363
334
364
class_entry_type :
@@ -489,14 +519,14 @@ optional_visibility_modifier:
489
519
;
490
520
491
521
parameter :
492
- optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis plain_variable
493
- { $$ = new Node\Param($5 , null, $2 , $3 , $4 , attributes(), $1 );
522
+ optional_attributes optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis plain_variable
523
+ { $$ = new Node\Param($6 , null, $3 , $4 , $5 , attributes(), $2 , $1 );
494
524
$this- >checkParam ($$); }
495
- | optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis plain_variable ' =' expr
496
- { $$ = new Node\Param($5 , $7 , $2 , $3 , $4 , attributes(), $1 );
525
+ | optional_attributes optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis plain_variable ' =' expr
526
+ { $$ = new Node\Param($6 , $8 , $3 , $4 , $5 , attributes(), $2 , $1 );
497
527
$this- >checkParam ($$); }
498
- | optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis error
499
- { $$ = new Node\Param(Expr\Error[], null, $2 , $3 , $4 , attributes(), $1 ); }
528
+ | optional_attributes optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis error
529
+ { $$ = new Node\Param(Expr\Error[], null, $3 , $4 , $5 , attributes(), $2 , $1 ); }
500
530
;
501
531
502
532
type_expr :
@@ -600,14 +630,15 @@ class_statement_list:
600
630
;
601
631
602
632
class_statement :
603
- variable_modifiers optional_type_without_static property_declaration_list ' ;'
604
- { $attrs = attributes();
605
- $$ = new Stmt\Property($1 , $3 , $attrs , $2 ); $this- >checkProperty ($$, #1 ); }
606
- | method_modifiers T_CONST class_const_list ' ;'
607
- { $$ = Stmt\ClassConst[$3 , $1 ]; $this- >checkClassConst ($$, #1 ); }
608
- | method_modifiers T_FUNCTION optional_ref identifier_ex ' (' parameter_list ' )' optional_return_type method_body
609
- { $$ = Stmt\ClassMethod[$4 , [' type' => $1 , ' byRef' => $3 , ' params' => $6 , ' returnType' => $8 , ' stmts' => $9 ]];
610
- $this- >checkClassMethod ($$, #1 ); }
633
+ optional_attributes variable_modifiers optional_type_without_static property_declaration_list ' ;'
634
+ { $$ = new Stmt\Property($2 , $4 , attributes(), $3 , $1 );
635
+ $this- >checkProperty ($$, #2 ); }
636
+ | optional_attributes method_modifiers T_CONST class_const_list ' ;'
637
+ { $$ = new Stmt\ClassConst($4 , $2 , attributes(), $1 );
638
+ $this- >checkClassConst ($$, #2 ); }
639
+ | optional_attributes method_modifiers T_FUNCTION optional_ref identifier_ex ' (' parameter_list ' )' optional_return_type method_body
640
+ { $$ = Stmt\ClassMethod[$5 , [' type' => $2 , ' byRef' => $4 , ' params' => $7 , ' returnType' => $9 , ' stmts' => $10 , ' attrGroups' => $1 ]];
641
+ $this- >checkClassMethod ($$, #2 ); }
611
642
| T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2 , $3 ]; }
612
643
| error { $$ = null; /* will be skipped */ }
613
644
;
@@ -802,21 +833,27 @@ expr:
802
833
| T_THROW expr { $$ = Expr\Throw_[$2 ]; }
803
834
804
835
| T_FN optional_ref ' (' parameter_list ' )' optional_return_type T_DOUBLE_ARROW expr
805
- { $$ = Expr\ArrowFunction[[' static' => false , ' byRef' => $2 , ' params' => $4 , ' returnType' => $6 , ' expr' => $8 ]]; }
836
+ { $$ = Expr\ArrowFunction[[' static' => false , ' byRef' => $2 , ' params' => $4 , ' returnType' => $6 , ' expr' => $8 , ' attrGroups ' => [] ]]; }
806
837
| T_STATIC T_FN optional_ref ' (' parameter_list ' )' optional_return_type T_DOUBLE_ARROW expr
807
- { $$ = Expr\ArrowFunction[[' static' => true , ' byRef' => $3 , ' params' => $5 , ' returnType' => $7 , ' expr' => $9 ]]; }
808
-
809
- | T_FUNCTION optional_ref ' (' parameter_list ' )' lexical_vars optional_return_type
810
- block_or_error
811
- { $$ = Expr\Closure[[' static' => false , ' byRef' => $2 , ' params' => $4 , ' uses' => $6 , ' returnType' => $7 , ' stmts' => $8 ]]; }
812
- | T_STATIC T_FUNCTION optional_ref ' (' parameter_list ' )' lexical_vars optional_return_type
813
- block_or_error
814
- { $$ = Expr\Closure[[' static' => true , ' byRef' => $3 , ' params' => $5 , ' uses' => $7 , ' returnType' => $8 , ' stmts' => $9 ]]; }
838
+ { $$ = Expr\ArrowFunction[[' static' => true , ' byRef' => $3 , ' params' => $5 , ' returnType' => $7 , ' expr' => $9 , ' attrGroups' => []]]; }
839
+ | T_FUNCTION optional_ref ' (' parameter_list ' )' lexical_vars optional_return_type block_or_error
840
+ { $$ = Expr\Closure[[' static' => false , ' byRef' => $2 , ' params' => $4 , ' uses' => $6 , ' returnType' => $7 , ' stmts' => $8 , ' attrGroups' => []]]; }
841
+ | T_STATIC T_FUNCTION optional_ref ' (' parameter_list ' )' lexical_vars optional_return_type block_or_error
842
+ { $$ = Expr\Closure[[' static' => true , ' byRef' => $3 , ' params' => $5 , ' uses' => $7 , ' returnType' => $8 , ' stmts' => $9 , ' attrGroups' => []]]; }
843
+
844
+ | attributes T_FN optional_ref ' (' parameter_list ' )' optional_return_type T_DOUBLE_ARROW expr
845
+ { $$ = Expr\ArrowFunction[[' static' => false , ' byRef' => $3 , ' params' => $5 , ' returnType' => $7 , ' expr' => $9 , ' attrGroups' => $1 ]]; }
846
+ | attributes T_STATIC T_FN optional_ref ' (' parameter_list ' )' optional_return_type T_DOUBLE_ARROW expr
847
+ { $$ = Expr\ArrowFunction[[' static' => true , ' byRef' => $4 , ' params' => $6 , ' returnType' => $8 , ' expr' => $10 , ' attrGroups' => $1 ]]; }
848
+ | attributes T_FUNCTION optional_ref ' (' parameter_list ' )' lexical_vars optional_return_type block_or_error
849
+ { $$ = Expr\Closure[[' static' => false , ' byRef' => $3 , ' params' => $5 , ' uses' => $7 , ' returnType' => $8 , ' stmts' => $9 , ' attrGroups' => $1 ]]; }
850
+ | attributes T_STATIC T_FUNCTION optional_ref ' (' parameter_list ' )' lexical_vars optional_return_type block_or_error
851
+ { $$ = Expr\Closure[[' static' => true , ' byRef' => $4 , ' params' => $6 , ' uses' => $8 , ' returnType' => $9 , ' stmts' => $10 , ' attrGroups' => $1 ]]; }
815
852
;
816
853
817
854
anonymous_class :
818
- T_CLASS ctor_arguments extends_from implements_list ' {' class_statement_list ' }'
819
- { $$ = array(Stmt\Class_[null, [' type' => 0 , ' extends' => $3 , ' implements' => $4 , ' stmts' => $6 ]], $2 );
855
+ optional_attributes T_CLASS ctor_arguments extends_from implements_list ' {' class_statement_list ' }'
856
+ { $$ = array(Stmt\Class_[null, [' type' => 0 , ' extends' => $4 , ' implements' => $5 , ' stmts' => $7 , ' attrGroups ' => $1 ]], $3 );
820
857
$this- >checkClass ($$[0 ], -1 ); }
821
858
;
822
859
0 commit comments