Implement semi-reserved identifiers

This commit is contained in:
Nikita Popov 2015-06-13 12:47:13 +02:00
parent 1a1bd1448d
commit dca46febc9
3 changed files with 2244 additions and 1579 deletions

View File

@ -131,6 +131,25 @@ top_statement_list:
| /* empty */ { init(); } | /* empty */ { init(); }
; ;
reserved_non_modifiers:
T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND
| T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE
| T_ENDWHILE | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH
| 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
;
semi_reserved:
reserved_non_modifiers
| T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC
;
identifier:
T_STRING { $$ = $1; }
| semi_reserved { $$ = $1; }
;
namespace_name_parts: namespace_name_parts:
T_STRING { init($1); } T_STRING { init($1); }
| namespace_name_parts T_NS_SEPARATOR T_STRING { push($1, $3); } | namespace_name_parts T_NS_SEPARATOR T_STRING { push($1, $3); }
@ -199,6 +218,15 @@ constant_declaration:
T_STRING '=' static_scalar { $$ = Node\Const_[$1, $3]; } T_STRING '=' static_scalar { $$ = Node\Const_[$1, $3]; }
; ;
class_const_list:
class_const_list ',' class_const { push($1, $3); }
| class_const { init($1); }
;
class_const:
identifier '=' static_scalar { $$ = Node\Const_[$1, $3]; }
;
inner_statement_list: inner_statement_list:
inner_statement_list inner_statement { pushNormalizing($1, $2); } inner_statement_list inner_statement { pushNormalizing($1, $2); }
| /* empty */ { init(); } | /* empty */ { init(); }
@ -483,8 +511,8 @@ class_statement_list:
class_statement: class_statement:
variable_modifiers property_declaration_list ';' { $$ = Stmt\Property[$1, $2]; } variable_modifiers property_declaration_list ';' { $$ = Stmt\Property[$1, $2]; }
| T_CONST constant_declaration_list ';' { $$ = Stmt\ClassConst[$2]; } | T_CONST class_const_list ';' { $$ = Stmt\ClassConst[$2]; }
| method_modifiers T_FUNCTION optional_ref T_STRING '(' parameter_list ')' optional_return_type method_body | 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]]; } { $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]]; }
| T_USE name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; } | T_USE name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; }
; ;
@ -502,20 +530,22 @@ trait_adaptation_list:
trait_adaptation: trait_adaptation:
trait_method_reference_fully_qualified T_INSTEADOF name_list ';' trait_method_reference_fully_qualified T_INSTEADOF name_list ';'
{ $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; } { $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; }
| trait_method_reference T_AS member_modifier T_STRING ';' | trait_method_reference T_AS member_modifier identifier ';'
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; } { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; }
| trait_method_reference T_AS member_modifier ';' | trait_method_reference T_AS member_modifier ';'
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; } { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; }
| trait_method_reference T_AS T_STRING ';' | trait_method_reference T_AS T_STRING ';'
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; }
| trait_method_reference T_AS reserved_non_modifiers ';'
{ $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; }
; ;
trait_method_reference_fully_qualified: trait_method_reference_fully_qualified:
name T_PAAMAYIM_NEKUDOTAYIM T_STRING { $$ = array($1, $3); } name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = array($1, $3); }
; ;
trait_method_reference: trait_method_reference:
trait_method_reference_fully_qualified { $$ = $1; } trait_method_reference_fully_qualified { $$ = $1; }
| T_STRING { $$ = array(null, $1); } | identifier { $$ = array(null, $1); }
; ;
method_body: method_body:
@ -709,7 +739,7 @@ lexical_var:
function_call: function_call:
name argument_list { $$ = Expr\FuncCall[$1, $2]; } name argument_list { $$ = Expr\FuncCall[$1, $2]; }
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM T_STRING argument_list | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier argument_list
{ $$ = Expr\StaticCall[$1, $3, $4]; } { $$ = Expr\StaticCall[$1, $3, $4]; }
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' argument_list | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' argument_list
{ $$ = Expr\StaticCall[$1, $4, $6]; } { $$ = Expr\StaticCall[$1, $4, $6]; }
@ -806,7 +836,7 @@ common_scalar:
static_scalar: static_scalar:
common_scalar { $$ = $1; } common_scalar { $$ = $1; }
| class_name T_PAAMAYIM_NEKUDOTAYIM class_const_name { $$ = Expr\ClassConstFetch[$1, $3]; } | class_name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = Expr\ClassConstFetch[$1, $3]; }
| name { $$ = Expr\ConstFetch[$1]; } | name { $$ = Expr\ConstFetch[$1]; }
| T_ARRAY '(' static_array_pair_list ')' { $$ = Expr\Array_[$3]; } | T_ARRAY '(' static_array_pair_list ')' { $$ = Expr\Array_[$3]; }
| '[' static_array_pair_list ']' { $$ = Expr\Array_[$2]; } | '[' static_array_pair_list ']' { $$ = Expr\Array_[$2]; }
@ -851,7 +881,7 @@ static_operation:
constant: constant:
name { $$ = Expr\ConstFetch[$1]; } name { $$ = Expr\ConstFetch[$1]; }
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM class_const_name | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier
{ $$ = Expr\ClassConstFetch[$1, $3]; } { $$ = Expr\ClassConstFetch[$1, $3]; }
; ;
@ -864,11 +894,6 @@ scalar:
{ parseEncapsedDoc($2); $$ = Scalar\Encapsed[$2]; } { parseEncapsedDoc($2); $$ = Scalar\Encapsed[$2]; }
; ;
class_const_name:
T_STRING { $$ = $1; }
| T_CLASS { $$ = 'class'; }
;
static_array_pair_list: static_array_pair_list:
/* empty */ { $$ = array(); } /* empty */ { $$ = array(); }
| non_empty_static_array_pair_list optional_comma { $$ = $1; } | non_empty_static_array_pair_list optional_comma { $$ = $1; }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,324 @@
Valid usages of reserved keywords as identifiers
-----
<?php
class Test {
function array() {}
function public() {}
static function list() {}
static function protected() {}
public $class;
public $private;
const TRAIT = 3, FINAL = 4;
}
$t = new Test;
$t->array();
$t->public();
Test::list();
Test::protected();
$t->class;
$t->private;
Test::TRAIT;
Test::FINAL;
class Foo {
use TraitA, TraitB {
TraitA::catch insteadof namespace\TraitB;
TraitA::list as foreach;
TraitB::throw as protected public;
TraitB::self as protected;
exit as die;
\TraitC::exit as bye;
namespace\TraitC::exit as byebye;
TraitA::
//
/** doc comment */
#
catch /* comment */
// comment
# comment
insteadof TraitB;
}
}
-----
array(
0: Stmt_Class(
type: 0
name: Test
extends: null
implements: array(
)
stmts: array(
0: Stmt_ClassMethod(
type: 0
byRef: false
name: array
params: array(
)
returnType: null
stmts: array(
)
)
1: Stmt_ClassMethod(
type: 0
byRef: false
name: public
params: array(
)
returnType: null
stmts: array(
)
)
2: Stmt_ClassMethod(
type: 8
byRef: false
name: list
params: array(
)
returnType: null
stmts: array(
)
)
3: Stmt_ClassMethod(
type: 8
byRef: false
name: protected
params: array(
)
returnType: null
stmts: array(
)
)
4: Stmt_Property(
type: 1
props: array(
0: Stmt_PropertyProperty(
name: class
default: null
)
)
)
5: Stmt_Property(
type: 1
props: array(
0: Stmt_PropertyProperty(
name: private
default: null
)
)
)
6: Stmt_ClassConst(
consts: array(
0: Const(
name: TRAIT
value: Scalar_LNumber(
value: 3
)
)
1: Const(
name: FINAL
value: Scalar_LNumber(
value: 4
)
)
)
)
)
)
1: Expr_Assign(
var: Expr_Variable(
name: t
)
expr: Expr_New(
class: Name(
parts: array(
0: Test
)
)
args: array(
)
)
)
2: Expr_MethodCall(
var: Expr_Variable(
name: t
)
name: array
args: array(
)
)
3: Expr_MethodCall(
var: Expr_Variable(
name: t
)
name: public
args: array(
)
)
4: Expr_StaticCall(
class: Name(
parts: array(
0: Test
)
)
name: list
args: array(
)
)
5: Expr_StaticCall(
class: Name(
parts: array(
0: Test
)
)
name: protected
args: array(
)
)
6: Expr_PropertyFetch(
var: Expr_Variable(
name: t
)
name: class
)
7: Expr_PropertyFetch(
var: Expr_Variable(
name: t
)
name: private
)
8: Expr_ClassConstFetch(
class: Name(
parts: array(
0: Test
)
)
name: TRAIT
)
9: Expr_ClassConstFetch(
class: Name(
parts: array(
0: Test
)
)
name: FINAL
)
10: Stmt_Class(
type: 0
name: Foo
extends: null
implements: array(
)
stmts: array(
0: Stmt_TraitUse(
traits: array(
0: Name(
parts: array(
0: TraitA
)
)
1: Name(
parts: array(
0: TraitB
)
)
)
adaptations: array(
0: Stmt_TraitUseAdaptation_Precedence(
trait: Name(
parts: array(
0: TraitA
)
)
method: catch
insteadof: array(
0: Name_Relative(
parts: array(
0: TraitB
)
)
)
)
1: Stmt_TraitUseAdaptation_Alias(
trait: Name(
parts: array(
0: TraitA
)
)
method: list
newModifier: null
newName: foreach
)
2: Stmt_TraitUseAdaptation_Alias(
trait: Name(
parts: array(
0: TraitB
)
)
method: throw
newModifier: 2
newName: public
)
3: Stmt_TraitUseAdaptation_Alias(
trait: Name(
parts: array(
0: TraitB
)
)
method: self
newModifier: 2
newName: null
)
4: Stmt_TraitUseAdaptation_Alias(
trait: null
method: exit
newModifier: null
newName: die
)
5: Stmt_TraitUseAdaptation_Alias(
trait: Name_FullyQualified(
parts: array(
0: TraitC
)
)
method: exit
newModifier: null
newName: bye
)
6: Stmt_TraitUseAdaptation_Alias(
trait: Name_Relative(
parts: array(
0: TraitC
)
)
method: exit
newModifier: null
newName: byebye
)
7: Stmt_TraitUseAdaptation_Precedence(
trait: Name(
parts: array(
0: TraitA
)
)
method: catch
insteadof: array(
0: Name(
parts: array(
0: TraitB
)
)
)
)
)
)
)
)
)