⬆️ Upgrade lib : nikic/php-parser

We were on v3 that is no longer maintained and compatibility is annonced for PHP 7.2.
v4 is active and supports PHP up to 8.0
No problem to update as this is only used in the config editor (\Combodo\iTop\Config\Validator\iTopConfigAstValidator)
This commit is contained in:
Pierre Goiffon
2021-03-29 16:35:30 +02:00
parent c11fd4f0ab
commit a7e7e62245
279 changed files with 17983 additions and 13776 deletions

View File

@@ -16,7 +16,7 @@ top_statement_list_ex:
top_statement_list:
top_statement_list_ex
{ makeNop($nop, $this->lookaheadStartAttributes);
{ makeZeroLengthNop($nop, $this->lookaheadStartAttributes);
if ($nop !== null) { $1[] = $nop; } $$ = $1; }
;
@@ -27,7 +27,8 @@ reserved_non_modifiers:
| T_FINALLY | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO
| T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT
| T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS
| T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER
| T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER | T_FN
| T_MATCH
;
semi_reserved:
@@ -35,18 +36,37 @@ semi_reserved:
| T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC
;
identifier:
T_STRING { $$ = $1; }
| semi_reserved { $$ = $1; }
identifier_ex:
T_STRING { $$ = Node\Identifier[$1]; }
| semi_reserved { $$ = Node\Identifier[$1]; }
;
namespace_name_parts:
T_STRING { init($1); }
| namespace_name_parts T_NS_SEPARATOR T_STRING { push($1, $3); }
identifier:
T_STRING { $$ = Node\Identifier[$1]; }
;
reserved_non_modifiers_identifier:
reserved_non_modifiers { $$ = Node\Identifier[$1]; }
;
namespace_declaration_name:
T_STRING { $$ = Name[$1]; }
| semi_reserved { $$ = Name[$1]; }
| T_NAME_QUALIFIED { $$ = Name[$1]; }
;
namespace_name:
namespace_name_parts { $$ = Name[$1]; }
T_STRING { $$ = Name[$1]; }
| T_NAME_QUALIFIED { $$ = Name[$1]; }
;
legacy_namespace_name:
namespace_name { $$ = $1; }
| T_NAME_FULLY_QUALIFIED { $$ = Name[substr($1, 1)]; }
;
plain_variable:
T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; }
;
semi:
@@ -62,6 +82,31 @@ no_comma:
optional_comma:
/* empty */
| ','
;
attribute_decl:
class_name { $$ = Node\Attribute[$1, []]; }
| class_name argument_list { $$ = Node\Attribute[$1, $2]; }
;
attribute_group:
attribute_decl { init($1); }
| attribute_group ',' attribute_decl { push($1, $3); }
;
attribute:
T_ATTRIBUTE attribute_group optional_comma ']' { $$ = Node\AttributeGroup[$2]; }
;
attributes:
attribute { init($1); }
| attributes attribute { push($1, $2); }
;
optional_attributes:
/* empty */ { $$ = []; }
| attributes { $$ = $1; }
;
top_statement:
statement { $$ = $1; }
@@ -69,11 +114,11 @@ top_statement:
| class_declaration_statement { $$ = $1; }
| T_HALT_COMPILER
{ $$ = Stmt\HaltCompiler[$this->lexer->handleHaltCompiler()]; }
| T_NAMESPACE namespace_name semi
| T_NAMESPACE namespace_declaration_name semi
{ $$ = Stmt\Namespace_[$2, null];
$$->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON);
$this->checkNamespace($$); }
| T_NAMESPACE namespace_name '{' top_statement_list '}'
| T_NAMESPACE namespace_declaration_name '{' top_statement_list '}'
{ $$ = Stmt\Namespace_[$2, $4];
$$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
$this->checkNamespace($$); }
@@ -92,16 +137,11 @@ use_type:
| T_CONST { $$ = Stmt\Use_::TYPE_CONSTANT; }
;
/* Using namespace_name_parts here to avoid s/r conflict on T_NS_SEPARATOR */
group_use_declaration:
T_USE use_type namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}'
{ $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, $2]; }
| T_USE use_type T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}'
{ $$ = Stmt\GroupUse[new Name($4, stackAttributes(#4)), $7, $2]; }
| T_USE namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}'
{ $$ = Stmt\GroupUse[new Name($2, stackAttributes(#2)), $5, Stmt\Use_::TYPE_UNKNOWN]; }
| T_USE T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}'
{ $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, Stmt\Use_::TYPE_UNKNOWN]; }
T_USE use_type legacy_namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations '}'
{ $$ = Stmt\GroupUse[$3, $6, $2]; }
| T_USE legacy_namespace_name T_NS_SEPARATOR '{' inline_use_declarations '}'
{ $$ = Stmt\GroupUse[$2, $5, Stmt\Use_::TYPE_UNKNOWN]; }
;
unprefixed_use_declarations:
@@ -136,13 +176,15 @@ non_empty_inline_use_declarations:
unprefixed_use_declaration:
namespace_name
{ $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); }
| namespace_name T_AS T_STRING
| namespace_name T_AS identifier
{ $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); }
;
use_declaration:
unprefixed_use_declaration { $$ = $1; }
| T_NS_SEPARATOR unprefixed_use_declaration { $$ = $2; }
legacy_namespace_name
{ $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); }
| legacy_namespace_name T_AS identifier
{ $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); }
;
inline_use_declaration:
@@ -161,7 +203,7 @@ non_empty_constant_declaration_list:
;
constant_declaration:
T_STRING '=' expr { $$ = Node\Const_[$1, $3]; }
identifier '=' expr { $$ = Node\Const_[$1, $3]; }
;
class_const_list:
@@ -174,7 +216,7 @@ non_empty_class_const_list:
;
class_const:
identifier '=' expr { $$ = Node\Const_[$1, $3]; }
identifier_ex '=' expr { $$ = Node\Const_[$1, $3]; }
;
inner_statement_list_ex:
@@ -184,7 +226,7 @@ inner_statement_list_ex:
inner_statement_list:
inner_statement_list_ex
{ makeNop($nop, $this->lookaheadStartAttributes);
{ makeZeroLengthNop($nop, $this->lookaheadStartAttributes);
if ($nop !== null) { $1[] = $nop; } $$ = $1; }
;
@@ -202,7 +244,7 @@ non_empty_statement:
if ($2) {
$$ = $2; prependLeadingComments($$);
} else {
makeNop($$, $this->startAttributeStack[#1]);
makeNop($$, $this->startAttributeStack[#1], $this->endAttributes);
if (null === $$) { $$ = array(); }
}
}
@@ -220,27 +262,37 @@ non_empty_statement:
| T_RETURN optional_expr semi { $$ = Stmt\Return_[$2]; }
| T_GLOBAL global_var_list semi { $$ = Stmt\Global_[$2]; }
| T_STATIC static_var_list semi { $$ = Stmt\Static_[$2]; }
| T_ECHO expr_list semi { $$ = Stmt\Echo_[$2]; }
| T_ECHO expr_list_forbid_comma semi { $$ = Stmt\Echo_[$2]; }
| T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; }
| expr semi { $$ = $1; }
| expr semi {
$e = $1;
if ($e instanceof Expr\Throw_) {
// For backwards-compatibility reasons, convert throw in statement position into
// Stmt\Throw_ rather than Stmt\Expression(Expr\Throw_).
$$ = Stmt\Throw_[$e->expr];
} else {
$$ = Stmt\Expression[$e];
}
}
| T_UNSET '(' variables_list ')' semi { $$ = Stmt\Unset_[$3]; }
| T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement
{ $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; }
| T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement
{ $$ = Stmt\Foreach_[$3, $7[0], ['keyVar' => $5, 'byRef' => $7[1], 'stmts' => $9]]; }
| T_FOREACH '(' expr error ')' foreach_statement
{ $$ = Stmt\Foreach_[$3, new Expr\Error(stackAttributes(#4)), ['stmts' => $6]]; }
| T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt\Declare_[$3, $5]; }
| T_TRY '{' inner_statement_list '}' catches optional_finally
{ $$ = Stmt\TryCatch[$3, $5, $6]; $this->checkTryCatch($$); }
| T_THROW expr semi { $$ = Stmt\Throw_[$2]; }
| T_GOTO T_STRING semi { $$ = Stmt\Goto_[$2]; }
| T_STRING ':' { $$ = Stmt\Label[$1]; }
| T_GOTO identifier semi { $$ = Stmt\Goto_[$2]; }
| identifier ':' { $$ = Stmt\Label[$1]; }
| error { $$ = array(); /* means: no statement */ }
;
statement:
non_empty_statement { $$ = $1; }
| ';'
{ makeNop($$, $this->startAttributeStack[#1]);
{ makeNop($$, $this->startAttributeStack[#1], $this->endAttributes);
if ($$ === null) $$ = array(); /* means: no statement */ }
;
@@ -255,8 +307,8 @@ name_union:
;
catch:
T_CATCH '(' name_union T_VARIABLE ')' '{' inner_statement_list '}'
{ $$ = Stmt\Catch_[$3, parseVar($4), $7]; }
T_CATCH '(' name_union optional_plain_variable ')' '{' inner_statement_list '}'
{ $$ = Stmt\Catch_[$3, $4, $7]; }
;
optional_finally:
@@ -265,7 +317,7 @@ optional_finally:
;
variables_list:
non_empty_variables_list no_comma { $$ = $1; }
non_empty_variables_list optional_comma { $$ = $1; }
;
non_empty_variables_list:
@@ -283,20 +335,27 @@ optional_ellipsis:
| T_ELLIPSIS { $$ = true; }
;
block_or_error:
'{' inner_statement_list '}' { $$ = $2; }
| error { $$ = []; }
;
function_declaration_statement:
T_FUNCTION optional_ref T_STRING '(' parameter_list ')' optional_return_type '{' inner_statement_list '}'
{ $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $9]]; }
T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type block_or_error
{ $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $8, 'attrGroups' => []]]; }
| attributes T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type block_or_error
{ $$ = Stmt\Function_[$4, ['byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9, 'attrGroups' => $1]]; }
;
class_declaration_statement:
class_entry_type T_STRING extends_from implements_list '{' class_statement_list '}'
{ $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6]];
$this->checkClass($$, #2); }
| T_INTERFACE T_STRING interface_extends_list '{' class_statement_list '}'
{ $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]];
$this->checkInterface($$, #2); }
| T_TRAIT T_STRING '{' class_statement_list '}'
{ $$ = Stmt\Trait_[$2, ['stmts' => $4]]; }
optional_attributes class_entry_type identifier extends_from implements_list '{' class_statement_list '}'
{ $$ = Stmt\Class_[$3, ['type' => $2, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]];
$this->checkClass($$, #3); }
| optional_attributes T_INTERFACE identifier interface_extends_list '{' class_statement_list '}'
{ $$ = Stmt\Interface_[$3, ['extends' => $4, 'stmts' => $6, 'attrGroups' => $1]];
$this->checkInterface($$, #3); }
| optional_attributes T_TRAIT identifier '{' class_statement_list '}'
{ $$ = Stmt\Trait_[$3, ['stmts' => $5, 'attrGroups' => $1]]; }
;
class_entry_type:
@@ -355,7 +414,7 @@ non_empty_declare_list:
;
declare_list_element:
T_STRING '=' expr { $$ = Stmt\DeclareDeclare[$1, $3]; }
identifier '=' expr { $$ = Stmt\DeclareDeclare[$1, $3]; }
;
switch_case_list:
@@ -380,6 +439,25 @@ case_separator:
| ';'
;
match:
T_MATCH '(' expr ')' '{' match_arm_list '}' { $$ = Expr\Match_[$3, $6]; }
;
match_arm_list:
/* empty */ { $$ = []; }
| non_empty_match_arm_list optional_comma { $$ = $1; }
;
non_empty_match_arm_list:
match_arm { init($1); }
| non_empty_match_arm_list ',' match_arm { push($1, $3); }
;
match_arm:
expr_list_allow_comma T_DOUBLE_ARROW expr { $$ = Node\MatchArm[$1, $3]; }
| T_DEFAULT optional_comma T_DOUBLE_ARROW expr { $$ = Node\MatchArm[null, $4]; }
;
while_statement:
statement { $$ = toArray($1); }
| ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; }
@@ -421,7 +499,7 @@ foreach_variable:
;
parameter_list:
non_empty_parameter_list no_comma { $$ = $1; }
non_empty_parameter_list optional_comma { $$ = $1; }
| /* empty */ { $$ = array(); }
;
@@ -430,37 +508,71 @@ non_empty_parameter_list:
| non_empty_parameter_list ',' parameter { push($1, $3); }
;
optional_visibility_modifier:
/* empty */ { $$ = 0; }
| T_PUBLIC { $$ = Stmt\Class_::MODIFIER_PUBLIC; }
| T_PROTECTED { $$ = Stmt\Class_::MODIFIER_PROTECTED; }
| T_PRIVATE { $$ = Stmt\Class_::MODIFIER_PRIVATE; }
;
parameter:
optional_param_type optional_ref optional_ellipsis T_VARIABLE
{ $$ = Node\Param[parseVar($4), null, $1, $2, $3]; $this->checkParam($$); }
| optional_param_type optional_ref optional_ellipsis T_VARIABLE '=' expr
{ $$ = Node\Param[parseVar($4), $6, $1, $2, $3]; $this->checkParam($$); }
optional_attributes optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis plain_variable
{ $$ = new Node\Param($6, null, $3, $4, $5, attributes(), $2, $1);
$this->checkParam($$); }
| optional_attributes optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis plain_variable '=' expr
{ $$ = new Node\Param($6, $8, $3, $4, $5, attributes(), $2, $1);
$this->checkParam($$); }
| optional_attributes optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis error
{ $$ = new Node\Param(Expr\Error[], null, $3, $4, $5, attributes(), $2, $1); }
;
type_expr:
type { $$ = $1; }
| '?' type { $$ = Node\NullableType[$2]; }
| union_type { $$ = Node\UnionType[$1]; }
;
type:
name { $$ = $this->handleBuiltinTypes($1); }
| T_ARRAY { $$ = 'array'; }
| T_CALLABLE { $$ = 'callable'; }
type_without_static { $$ = $1; }
| T_STATIC { $$ = Node\Name['static']; }
;
optional_param_type:
type_without_static:
name { $$ = $this->handleBuiltinTypes($1); }
| T_ARRAY { $$ = Node\Identifier['array']; }
| T_CALLABLE { $$ = Node\Identifier['callable']; }
;
union_type:
type '|' type { init($1, $3); }
| union_type '|' type { push($1, $3); }
;
union_type_without_static:
type_without_static '|' type_without_static { init($1, $3); }
| union_type_without_static '|' type_without_static { push($1, $3); }
;
type_expr_without_static:
type_without_static { $$ = $1; }
| '?' type_without_static { $$ = Node\NullableType[$2]; }
| union_type_without_static { $$ = Node\UnionType[$1]; }
;
optional_type_without_static:
/* empty */ { $$ = null; }
| type_expr { $$ = $1; }
| type_expr_without_static { $$ = $1; }
;
optional_return_type:
/* empty */ { $$ = null; }
| ':' type_expr { $$ = $2; }
| ':' error { $$ = null; }
;
argument_list:
'(' ')' { $$ = array(); }
| '(' non_empty_argument_list no_comma ')' { $$ = $2; }
| '(' non_empty_argument_list optional_comma ')' { $$ = $2; }
;
non_empty_argument_list:
@@ -472,6 +584,8 @@ argument:
expr { $$ = Node\Arg[$1, false, false]; }
| '&' variable { $$ = Node\Arg[$2, true, false]; }
| T_ELLIPSIS expr { $$ = Node\Arg[$2, false, true]; }
| identifier_ex ':' expr
{ $$ = new Node\Arg($3, false, false, attributes(), $1); }
;
global_var_list:
@@ -484,7 +598,7 @@ non_empty_global_var_list:
;
global_var:
simple_variable { $$ = Expr\Variable[$1]; }
simple_variable { $$ = $1; }
;
static_var_list:
@@ -497,24 +611,33 @@ non_empty_static_var_list:
;
static_var:
T_VARIABLE { $$ = Stmt\StaticVar[parseVar($1), null]; }
| T_VARIABLE '=' expr { $$ = Stmt\StaticVar[parseVar($1), $3]; }
plain_variable { $$ = Stmt\StaticVar[$1, null]; }
| plain_variable '=' expr { $$ = Stmt\StaticVar[$1, $3]; }
;
class_statement_list:
class_statement_list class_statement { push($1, $2); }
class_statement_list_ex:
class_statement_list_ex class_statement { if ($2 !== null) { push($1, $2); } }
| /* empty */ { init(); }
;
class_statement_list:
class_statement_list_ex
{ makeZeroLengthNop($nop, $this->lookaheadStartAttributes);
if ($nop !== null) { $1[] = $nop; } $$ = $1; }
;
class_statement:
variable_modifiers property_declaration_list ';'
{ $$ = Stmt\Property[$1, $2]; $this->checkProperty($$, #1); }
| method_modifiers T_CONST class_const_list ';'
{ $$ = Stmt\ClassConst[$3, $1]; $this->checkClassConst($$, #1); }
| method_modifiers T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type method_body
{ $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]];
$this->checkClassMethod($$, #1); }
optional_attributes variable_modifiers optional_type_without_static property_declaration_list semi
{ $$ = new Stmt\Property($2, $4, attributes(), $3, $1);
$this->checkProperty($$, #2); }
| optional_attributes method_modifiers T_CONST class_const_list semi
{ $$ = new Stmt\ClassConst($4, $2, attributes(), $1);
$this->checkClassConst($$, #2); }
| optional_attributes method_modifiers T_FUNCTION optional_ref identifier_ex '(' parameter_list ')' optional_return_type method_body
{ $$ = Stmt\ClassMethod[$5, ['type' => $2, 'byRef' => $4, 'params' => $7, 'returnType' => $9, 'stmts' => $10, 'attrGroups' => $1]];
$this->checkClassMethod($$, #2); }
| T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; }
| error { $$ = null; /* will be skipped */ }
;
trait_adaptations:
@@ -530,27 +653,27 @@ trait_adaptation_list:
trait_adaptation:
trait_method_reference_fully_qualified T_INSTEADOF class_name_list ';'
{ $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; }
| trait_method_reference T_AS member_modifier identifier ';'
| trait_method_reference T_AS member_modifier identifier_ex ';'
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; }
| trait_method_reference T_AS member_modifier ';'
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; }
| trait_method_reference T_AS T_STRING ';'
| trait_method_reference T_AS identifier ';'
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; }
| trait_method_reference T_AS reserved_non_modifiers ';'
| trait_method_reference T_AS reserved_non_modifiers_identifier ';'
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; }
;
trait_method_reference_fully_qualified:
name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = array($1, $3); }
name T_PAAMAYIM_NEKUDOTAYIM identifier_ex { $$ = array($1, $3); }
;
trait_method_reference:
trait_method_reference_fully_qualified { $$ = $1; }
| identifier { $$ = array(null, $1); }
| identifier_ex { $$ = array(null, $1); }
;
method_body:
';' /* abstract method */ { $$ = null; }
| '{' inner_statement_list '}' { $$ = $2; }
| block_or_error { $$ = $1; }
;
variable_modifiers:
@@ -587,15 +710,23 @@ non_empty_property_declaration_list:
{ push($1, $3); }
;
property_declaration:
T_VARIABLE { $$ = Stmt\PropertyProperty[parseVar($1), null]; }
| T_VARIABLE '=' expr { $$ = Stmt\PropertyProperty[parseVar($1), $3]; }
property_decl_name:
T_VARIABLE { $$ = Node\VarLikeIdentifier[parseVar($1)]; }
;
expr_list:
property_declaration:
property_decl_name { $$ = Stmt\PropertyProperty[$1, null]; }
| property_decl_name '=' expr { $$ = Stmt\PropertyProperty[$1, $3]; }
;
expr_list_forbid_comma:
non_empty_expr_list no_comma { $$ = $1; }
;
expr_list_allow_comma:
non_empty_expr_list optional_comma { $$ = $1; }
;
non_empty_expr_list:
non_empty_expr_list ',' expr { push($1, $3); }
| expr { init($1); }
@@ -603,7 +734,7 @@ non_empty_expr_list:
for_expr:
/* empty */ { $$ = array(); }
| expr_list { $$ = $1; }
| expr_list_forbid_comma { $$ = $1; }
;
expr:
@@ -613,6 +744,7 @@ expr:
| variable '=' expr { $$ = Expr\Assign[$1, $3]; }
| variable '=' '&' variable { $$ = Expr\AssignRef[$1, $4]; }
| new_expr { $$ = $1; }
| match { $$ = $1; }
| T_CLONE expr { $$ = Expr\Clone_[$2]; }
| variable T_PLUS_EQUAL expr { $$ = Expr\AssignOp\Plus [$1, $3]; }
| variable T_MINUS_EQUAL expr { $$ = Expr\AssignOp\Minus [$1, $3]; }
@@ -626,6 +758,7 @@ expr:
| variable T_SL_EQUAL expr { $$ = Expr\AssignOp\ShiftLeft [$1, $3]; }
| variable T_SR_EQUAL expr { $$ = Expr\AssignOp\ShiftRight[$1, $3]; }
| variable T_POW_EQUAL expr { $$ = Expr\AssignOp\Pow [$1, $3]; }
| variable T_COALESCE_EQUAL expr { $$ = Expr\AssignOp\Coalesce [$1, $3]; }
| variable T_INC { $$ = Expr\PostInc[$1]; }
| T_INC variable { $$ = Expr\PreInc [$2]; }
| variable T_DEC { $$ = Expr\PostDec[$1]; }
@@ -665,7 +798,7 @@ expr:
| expr '?' expr ':' expr { $$ = Expr\Ternary[$1, $3, $5]; }
| expr '?' ':' expr { $$ = Expr\Ternary[$1, null, $4]; }
| expr T_COALESCE expr { $$ = Expr\BinaryOp\Coalesce[$1, $3]; }
| T_ISSET '(' variables_list ')' { $$ = Expr\Isset_[$3]; }
| T_ISSET '(' expr_list_allow_comma ')' { $$ = Expr\Isset_[$3]; }
| T_EMPTY '(' expr ')' { $$ = Expr\Empty_[$3]; }
| T_INCLUDE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE]; }
| T_INCLUDE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE_ONCE]; }
@@ -673,7 +806,10 @@ expr:
| T_REQUIRE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE]; }
| T_REQUIRE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE_ONCE]; }
| T_INT_CAST expr { $$ = Expr\Cast\Int_ [$2]; }
| T_DOUBLE_CAST expr { $$ = Expr\Cast\Double [$2]; }
| T_DOUBLE_CAST expr
{ $attrs = attributes();
$attrs['kind'] = $this->getFloatCastKind($1);
$$ = new Expr\Cast\Double($2, $attrs); }
| T_STRING_CAST expr { $$ = Expr\Cast\String_ [$2]; }
| T_ARRAY_CAST expr { $$ = Expr\Cast\Array_ [$2]; }
| T_OBJECT_CAST expr { $$ = Expr\Cast\Object_ [$2]; }
@@ -691,18 +827,32 @@ expr:
| T_YIELD expr { $$ = Expr\Yield_[$2, null]; }
| T_YIELD expr T_DOUBLE_ARROW expr { $$ = Expr\Yield_[$4, $2]; }
| T_YIELD_FROM expr { $$ = Expr\YieldFrom[$2]; }
| T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type
'{' inner_statement_list '}'
{ $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $9]]; }
| T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type
'{' inner_statement_list '}'
{ $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $10]]; }
| T_THROW expr { $$ = Expr\Throw_[$2]; }
| T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr
{ $$ = Expr\ArrowFunction[['static' => false, 'byRef' => $2, 'params' => $4, 'returnType' => $6, 'expr' => $8, 'attrGroups' => []]]; }
| T_STATIC T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr
{ $$ = Expr\ArrowFunction[['static' => true, 'byRef' => $3, 'params' => $5, 'returnType' => $7, 'expr' => $9, 'attrGroups' => []]]; }
| T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type block_or_error
{ $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $8, 'attrGroups' => []]]; }
| T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type block_or_error
{ $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $9, 'attrGroups' => []]]; }
| attributes T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr
{ $$ = Expr\ArrowFunction[['static' => false, 'byRef' => $3, 'params' => $5, 'returnType' => $7, 'expr' => $9, 'attrGroups' => $1]]; }
| attributes T_STATIC T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr
{ $$ = Expr\ArrowFunction[['static' => true, 'byRef' => $4, 'params' => $6, 'returnType' => $8, 'expr' => $10, 'attrGroups' => $1]]; }
| attributes T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type block_or_error
{ $$ = Expr\Closure[['static' => false, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $9, 'attrGroups' => $1]]; }
| attributes T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type block_or_error
{ $$ = Expr\Closure[['static' => true, 'byRef' => $4, 'params' => $6, 'uses' => $8, 'returnType' => $9, 'stmts' => $10, 'attrGroups' => $1]]; }
;
anonymous_class:
T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}'
{ $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $3, 'implements' => $4, 'stmts' => $6]], $2);
optional_attributes T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}'
{ $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]], $3);
$this->checkClass($$[0], -1); }
;
new_expr:
T_NEW class_name_reference ctor_arguments { $$ = Expr\New_[$2, $3]; }
@@ -716,7 +866,7 @@ lexical_vars:
;
lexical_var_list:
non_empty_lexical_var_list no_comma { $$ = $1; }
non_empty_lexical_var_list optional_comma { $$ = $1; }
;
non_empty_lexical_var_list:
@@ -725,7 +875,7 @@ non_empty_lexical_var_list:
;
lexical_var:
optional_ref T_VARIABLE { $$ = Expr\ClosureUse[parseVar($2), $1]; }
optional_ref plain_variable { $$ = Expr\ClosureUse[$2, $1]; }
;
function_call:
@@ -741,20 +891,22 @@ class_name:
;
name:
namespace_name_parts { $$ = Name[$1]; }
| T_NS_SEPARATOR namespace_name_parts { $$ = Name\FullyQualified[$2]; }
| T_NAMESPACE T_NS_SEPARATOR namespace_name_parts { $$ = Name\Relative[$3]; }
T_STRING { $$ = Name[$1]; }
| T_NAME_QUALIFIED { $$ = Name[$1]; }
| T_NAME_FULLY_QUALIFIED { $$ = Name\FullyQualified[substr($1, 1)]; }
| T_NAME_RELATIVE { $$ = Name\Relative[substr($1, 10)]; }
;
class_name_reference:
class_name { $$ = $1; }
| new_variable { $$ = $1; }
| '(' expr ')' { $$ = $2; }
| error { $$ = Expr\Error[]; $this->errorState = 2; }
;
class_name_or_var:
class_name { $$ = $1; }
| dereferencable { $$ = $1; }
| fully_dereferencable { $$ = $1; }
;
exit_expr:
@@ -776,9 +928,20 @@ ctor_arguments:
constant:
name { $$ = Expr\ConstFetch[$1]; }
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier
| T_LINE { $$ = Scalar\MagicConst\Line[]; }
| T_FILE { $$ = Scalar\MagicConst\File[]; }
| T_DIR { $$ = Scalar\MagicConst\Dir[]; }
| T_CLASS_C { $$ = Scalar\MagicConst\Class_[]; }
| T_TRAIT_C { $$ = Scalar\MagicConst\Trait_[]; }
| T_METHOD_C { $$ = Scalar\MagicConst\Method[]; }
| T_FUNC_C { $$ = Scalar\MagicConst\Function_[]; }
| T_NS_C { $$ = Scalar\MagicConst\Namespace_[]; }
;
class_constant:
class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier_ex
{ $$ = Expr\ClassConstFetch[$1, $3]; }
/* We interpret and isolated FOO:: as an unfinished class constant fetch. It could also be
/* We interpret an isolated FOO:: as an unfinished class constant fetch. It could also be
an unfinished static property fetch or unfinished scoped call. */
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM error
{ $$ = Expr\ClassConstFetch[$1, new Expr\Error(stackAttributes(#3))]; $this->errorState = 2; }
@@ -798,33 +961,23 @@ dereferencable_scalar:
| T_CONSTANT_ENCAPSED_STRING
{ $attrs = attributes(); $attrs['kind'] = strKind($1);
$$ = new Scalar\String_(Scalar\String_::parse($1), $attrs); }
| '"' encaps_list '"'
{ $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED;
parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); }
;
scalar:
T_LNUMBER { $$ = $this->parseLNumber($1, attributes()); }
| T_DNUMBER { $$ = Scalar\DNumber[Scalar\DNumber::parse($1)]; }
| T_LINE { $$ = Scalar\MagicConst\Line[]; }
| T_FILE { $$ = Scalar\MagicConst\File[]; }
| T_DIR { $$ = Scalar\MagicConst\Dir[]; }
| T_CLASS_C { $$ = Scalar\MagicConst\Class_[]; }
| T_TRAIT_C { $$ = Scalar\MagicConst\Trait_[]; }
| T_METHOD_C { $$ = Scalar\MagicConst\Method[]; }
| T_FUNC_C { $$ = Scalar\MagicConst\Function_[]; }
| T_NS_C { $$ = Scalar\MagicConst\Namespace_[]; }
| dereferencable_scalar { $$ = $1; }
| constant { $$ = $1; }
| class_constant { $$ = $1; }
| T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC
{ $attrs = attributes(); setDocStringAttrs($attrs, $1);
$$ = new Scalar\String_(Scalar\String_::parseDocString($1, $2), $attrs); }
{ $$ = $this->parseDocString($1, $2, $3, attributes(), stackAttributes(#3), true); }
| T_START_HEREDOC T_END_HEREDOC
{ $attrs = attributes(); setDocStringAttrs($attrs, $1);
$$ = new Scalar\String_('', $attrs); }
| '"' encaps_list '"'
{ $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED;
parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); }
{ $$ = $this->parseDocString($1, '', $2, attributes(), stackAttributes(#2), true); }
| T_START_HEREDOC encaps_list T_END_HEREDOC
{ $attrs = attributes(); setDocStringAttrs($attrs, $1);
parseEncapsedDoc($2, true); $$ = new Scalar\Encapsed($2, $attrs); }
{ $$ = $this->parseDocString($1, $2, $3, attributes(), stackAttributes(#3), true); }
;
optional_expr:
@@ -832,10 +985,16 @@ optional_expr:
| expr { $$ = $1; }
;
dereferencable:
fully_dereferencable:
variable { $$ = $1; }
| '(' expr ')' { $$ = $2; }
| dereferencable_scalar { $$ = $1; }
| class_constant { $$ = $1; }
;
array_object_dereferencable:
fully_dereferencable { $$ = $1; }
| constant { $$ = $1; }
;
callable_expr:
@@ -845,87 +1004,100 @@ callable_expr:
;
callable_variable:
simple_variable { $$ = Expr\Variable[$1]; }
| dereferencable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
| constant '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
| dereferencable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; }
simple_variable { $$ = $1; }
| array_object_dereferencable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
| array_object_dereferencable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; }
| function_call { $$ = $1; }
| dereferencable T_OBJECT_OPERATOR property_name argument_list
| array_object_dereferencable T_OBJECT_OPERATOR property_name argument_list
{ $$ = Expr\MethodCall[$1, $3, $4]; }
| array_object_dereferencable T_NULLSAFE_OBJECT_OPERATOR property_name argument_list
{ $$ = Expr\NullsafeMethodCall[$1, $3, $4]; }
;
optional_plain_variable:
/* empty */ { $$ = null; }
| plain_variable { $$ = $1; }
;
variable:
callable_variable { $$ = $1; }
| static_member { $$ = $1; }
| dereferencable T_OBJECT_OPERATOR property_name { $$ = Expr\PropertyFetch[$1, $3]; }
| array_object_dereferencable T_OBJECT_OPERATOR property_name
{ $$ = Expr\PropertyFetch[$1, $3]; }
| array_object_dereferencable T_NULLSAFE_OBJECT_OPERATOR property_name
{ $$ = Expr\NullsafePropertyFetch[$1, $3]; }
;
simple_variable:
T_VARIABLE { $$ = parseVar($1); }
| '$' '{' expr '}' { $$ = $3; }
plain_variable { $$ = $1; }
| '$' '{' expr '}' { $$ = Expr\Variable[$3]; }
| '$' simple_variable { $$ = Expr\Variable[$2]; }
| '$' error { $$ = Expr\Error[]; $this->errorState = 2; }
| '$' error { $$ = Expr\Variable[Expr\Error[]]; $this->errorState = 2; }
;
static_member_prop_name:
simple_variable
{ $var = $1->name; $$ = \is_string($var) ? Node\VarLikeIdentifier[$var] : $var; }
;
static_member:
class_name_or_var T_PAAMAYIM_NEKUDOTAYIM simple_variable
class_name_or_var T_PAAMAYIM_NEKUDOTAYIM static_member_prop_name
{ $$ = Expr\StaticPropertyFetch[$1, $3]; }
;
new_variable:
simple_variable { $$ = Expr\Variable[$1]; }
simple_variable { $$ = $1; }
| new_variable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
| new_variable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; }
| new_variable T_OBJECT_OPERATOR property_name { $$ = Expr\PropertyFetch[$1, $3]; }
| class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable { $$ = Expr\StaticPropertyFetch[$1, $3]; }
| new_variable T_PAAMAYIM_NEKUDOTAYIM simple_variable { $$ = Expr\StaticPropertyFetch[$1, $3]; }
| new_variable T_NULLSAFE_OBJECT_OPERATOR property_name { $$ = Expr\NullsafePropertyFetch[$1, $3]; }
| class_name T_PAAMAYIM_NEKUDOTAYIM static_member_prop_name
{ $$ = Expr\StaticPropertyFetch[$1, $3]; }
| new_variable T_PAAMAYIM_NEKUDOTAYIM static_member_prop_name
{ $$ = Expr\StaticPropertyFetch[$1, $3]; }
;
member_name:
identifier { $$ = $1; }
| '{' expr '}' { $$ = $2; }
| simple_variable { $$ = Expr\Variable[$1]; }
identifier_ex { $$ = $1; }
| '{' expr '}' { $$ = $2; }
| simple_variable { $$ = $1; }
;
property_name:
T_STRING { $$ = $1; }
| '{' expr '}' { $$ = $2; }
| simple_variable { $$ = Expr\Variable[$1]; }
identifier { $$ = $1; }
| '{' expr '}' { $$ = $2; }
| simple_variable { $$ = $1; }
| error { $$ = Expr\Error[]; $this->errorState = 2; }
;
list_expr:
T_LIST '(' list_expr_elements ')' { $$ = Expr\List_[$3]; }
;
list_expr_elements:
list_expr_elements ',' list_expr_element { push($1, $3); }
| list_expr_element { init($1); }
;
list_expr_element:
variable { $$ = Expr\ArrayItem[$1, null, false]; }
| list_expr { $$ = Expr\ArrayItem[$1, null, false]; }
| expr T_DOUBLE_ARROW variable { $$ = Expr\ArrayItem[$3, $1, false]; }
| expr T_DOUBLE_ARROW list_expr { $$ = Expr\ArrayItem[$3, $1, false]; }
| /* empty */ { $$ = null; }
T_LIST '(' inner_array_pair_list ')' { $$ = Expr\List_[$3]; }
;
array_pair_list:
inner_array_pair_list
{ $$ = $1; $end = count($$)-1; if ($$[$end] === null) unset($$[$end]); }
{ $$ = $1; $end = count($$)-1; if ($$[$end] === null) array_pop($$); }
;
comma_or_error:
','
| error
{ /* do nothing -- prevent default action of $$=$1. See #551. */ }
;
inner_array_pair_list:
inner_array_pair_list ',' array_pair { push($1, $3); }
inner_array_pair_list comma_or_error array_pair { push($1, $3); }
| array_pair { init($1); }
;
array_pair:
expr T_DOUBLE_ARROW expr { $$ = Expr\ArrayItem[$3, $1, false]; }
| expr { $$ = Expr\ArrayItem[$1, null, false]; }
| expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; }
expr { $$ = Expr\ArrayItem[$1, null, false]; }
| '&' variable { $$ = Expr\ArrayItem[$2, null, true]; }
| list_expr { $$ = Expr\ArrayItem[$1, null, false]; }
| expr T_DOUBLE_ARROW expr { $$ = Expr\ArrayItem[$3, $1, false]; }
| expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; }
| expr T_DOUBLE_ARROW list_expr { $$ = Expr\ArrayItem[$3, $1, false]; }
| T_ELLIPSIS expr { $$ = Expr\ArrayItem[$2, null, false, attributes(), true]; }
| /* empty */ { $$ = null; }
;
@@ -940,18 +1112,19 @@ encaps_string_part:
T_ENCAPSED_AND_WHITESPACE { $$ = Scalar\EncapsedStringPart[$1]; }
;
encaps_base_var:
T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; }
encaps_str_varname:
T_STRING_VARNAME { $$ = Expr\Variable[$1]; }
;
encaps_var:
encaps_base_var { $$ = $1; }
| encaps_base_var '[' encaps_var_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
| encaps_base_var T_OBJECT_OPERATOR T_STRING { $$ = Expr\PropertyFetch[$1, $3]; }
plain_variable { $$ = $1; }
| plain_variable '[' encaps_var_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
| plain_variable T_OBJECT_OPERATOR identifier { $$ = Expr\PropertyFetch[$1, $3]; }
| plain_variable T_NULLSAFE_OBJECT_OPERATOR identifier { $$ = Expr\NullsafePropertyFetch[$1, $3]; }
| T_DOLLAR_OPEN_CURLY_BRACES expr '}' { $$ = Expr\Variable[$2]; }
| T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' { $$ = Expr\Variable[$2]; }
| T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
{ $$ = Expr\ArrayDimFetch[Expr\Variable[$2], $4]; }
| T_DOLLAR_OPEN_CURLY_BRACES encaps_str_varname '[' expr ']' '}'
{ $$ = Expr\ArrayDimFetch[$2, $4]; }
| T_CURLY_OPEN variable '}' { $$ = $2; }
;
@@ -959,7 +1132,7 @@ encaps_var_offset:
T_STRING { $$ = Scalar\String_[$1]; }
| T_NUM_STRING { $$ = $this->parseNumString($1, attributes()); }
| '-' T_NUM_STRING { $$ = $this->parseNumString('-' . $2, attributes()); }
| T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; }
| plain_variable { $$ = $1; }
;
%%