# Grammar ## General The grammar notation is described in [Grammars section](09-lexical-structure.md#grammars). ## Lexical Grammar
input-file::
input-element
input-file input-element
input-element::
comment
white-space
token
comment::
single-line-comment
delimited-comment
single-line-comment::
// input-charactersopt
# input-charactersopt
input-characters::
input-character
input-characters input-character
input-character::
Any source character except new-line
new-line::
Carriage-return character (0x0D)
Line-feed character (0x0A)
Carriage-return character (0x0D) followed by line-feed character (0x0A)
delimited-comment::
/* No characters or any source character sequence except */ */
white-space::
white-space-character
white-space white-space-character
white-space-character::
new-line
Space character (0x20)
Horizontal-tab character (0x09)
token::
variable-name
name
keyword
integer-literal
floating-literal
string-literal
operator-or-punctuator
variable-name::
$ name
namespace-name::
name
namespace-name \ name
namespace-name-as-a-prefix::
\
\opt namespace-name \
namespace \
namespace \ namespace-name \
qualified-name::
namespace-name-as-a-prefixopt name
name::
name-nondigit
name name-nondigit
name digit
name-nondigit::
nondigit
one of the characters 0x80–0xff
nondigit:: one of
_
a b c d e f g h i j k l m
n o p q r s t u v w x y z
A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z
keyword:: one of
abstract and array as break callable case catch class clone
const continue declare default die do echo else elseif empty
enddeclare endfor endforeach endif endswitch endwhile eval exit
extends final finally for foreach function global
goto if implements include include_once instanceof
insteadof interface isset list namespace new or print private
protected public require require_once return static switch
throw trait try unset use var while xor yield yield from
integer-literal::
decimal-literal
octal-literal
hexadecimal-literal
binary-literal
decimal-literal::
nonzero-digit
decimal-literal digit
octal-literal::
0
octal-literal octal-digit
hexadecimal-literal::
hexadecimal-prefix hexadecimal-digit
hexadecimal-literal hexadecimal-digit
hexadecimal-prefix:: one of
0x 0X
binary-literal::
binary-prefix binary-digit
binary-literal binary-digit
binary-prefix:: one of
0b 0B
digit:: one of
0 1 2 3 4 5 6 7 8 9
nonzero-digit:: one of
1 2 3 4 5 6 7 8 9
octal-digit:: one of
0 1 2 3 4 5 6 7
hexadecimal-digit:: one of
0 1 2 3 4 5 6 7 8 9
a b c d e f
A B C D E F
binary-digit:: one of
0 1
floating-literal::
fractional-literal exponent-partopt
digit-sequence exponent-part
fractional-literal::
digit-sequenceopt . digit-sequence
digit-sequence .
exponent-part::
e signopt digit-sequence
E signopt digit-sequence
sign:: one of
+ -
digit-sequence::
digit
digit-sequence digit
string-literal::
single-quoted-string-literal
double-quoted-string-literal
heredoc-string-literal
nowdoc-string-literal
single-quoted-string-literal::
b-prefixopt ' sq-char-sequenceopt '
sq-char-sequence::
sq-char
sq-char-sequence sq-char
sq-char::
sq-escape-sequence
\opt any member of the source character set except single-quote (') or backslash (\)
sq-escape-sequence:: one of
\' \\
b-prefix:: one of
b B
double-quoted-string-literal::
b-prefixopt " dq-char-sequenceopt "
dq-char-sequence::
dq-char
dq-char-sequence dq-char
dq-char::
dq-escape-sequence
any member of the source character set except double-quote (") or backslash (\)
\ any member of the source character set except "\$efnrtvxX or octal-digit
dq-escape-sequence::
dq-simple-escape-sequence
dq-octal-escape-sequence
dq-hexadecimal-escape-sequence
dq-unicode-escape-sequence
dq-simple-escape-sequence:: one of
\" \\ \$ \e \f \n \r \t \v
dq-octal-escape-sequence::
\ octal-digit
\ octal-digit octal-digit
\ octal-digit octal-digit octal-digit
dq-hexadecimal-escape-sequence::
\x hexadecimal-digit hexadecimal-digitopt
\X hexadecimal-digit hexadecimal-digitopt
dq-unicode-escape-sequence::
\u{ codepoint-digits }
codepoint-digits::
hexadecimal-digit
hexadecimal-digit codepoint-digits
string-variable::
variable-name offset-or-propertyopt
${ expression }
offset-or-property::
offset-in-string
property-in-string
offset-in-string::
[ name ]
[ variable-name ]
[ integer-literal ]
property-in-string::
-> name
heredoc-string-literal::
b-prefixopt <<< hd-start-identifier new-line hd-bodyopt hd-end-identifier ;opt new-line
hd-start-identifier::
name
" name "
hd-end-identifier::
name
hd-body::
hd-char-sequenceopt new-line
hd-char-sequence::
hd-char
hd-char-sequence hd-char
hd-char::
hd-escape-sequence
any member of the source character set except backslash (\)
\ any member of the source character set except \$efnrtvxX or octal-digit
hd-escape-sequence::
hd-simple-escape-sequence
dq-octal-escape-sequence
dq-hexadecimal-escape-sequence
dq-unicode-escape-sequence
hd-simple-escape-sequence:: one of
\\ \$ \e \f \n \r \t \v
nowdoc-string-literal::
b-prefixopt <<< ' name ' new-line hd-bodyopt name ;opt new-line
operator-or-punctuator:: one of
[ ] ( ) { } . -> ++ -- ** * + - ~ !
$ / % << >> < > <= >= == === != !== ^ |
& && || ? : ; = **= *= /= %= += -= .= <<=
>>= &= ^= |= , ?? <=> ... \
## Syntactic Grammar
### Basic Concepts
script: script-section script script-section script-section: textopt start-tag statement-listopt end-tagopt textopt start-tag: <?php <?= end-tag: ?> text: arbitrary text not containing any of start-tag sequences### Variables
function-static-declaration: static static-variable-name-list ; static-variable-name-list: static-variable-declaration static-variable-name-list , static-variable-declaration static-variable-declaration: variable-name function-static-initializeropt function-static-initializer: = constant-expression global-declaration: global variable-name-list ; variable-name-list: simple-variable variable-name-list , simple-variable### Expressions
primary-expression:
variable
class-constant-access-expression
constant-access-expression
literal
array-creation-expression
intrinsic
anonymous-function-creation-expression
object-creation-expression
postfix-increment-expression
postfix-decrement-expression
prefix-increment-expression
prefix-decrement-expression
byref-assignment-expression
shell-command-expression
( expression )
simple-variable:
variable-name
$ simple-variable
$ { expression }
dereferencable-expression:
variable
( expression )
array-creation-expression
string-literal
callable-expression:
callable-variable
( expression )
array-creation-expression
string-literal
callable-variable:
simple-variable
subscript-expression
member-call-expression
scoped-call-expression
function-call-expression
variable:
callable-variable
scoped-property-access-expression
member-access-expression
constant-access-expression:
qualified-name
literal:
integer-literal
floating-literal
string-literal
intrinsic:
empty-intrinsic
eval-intrinsic
exit-intrinsic
isset-intrinsic
empty-intrinsic:
empty ( expression )
eval-intrinsic:
eval ( expression )
exit-intrinsic:
exit
exit ( expressionopt )
die
die ( expressionopt )
isset-intrinsic:
isset ( variable-list ,opt )
variable-list:
variable
variable-list , variable
anonymous-function-creation-expression:
staticopt function &opt ( parameter-declaration-listopt ) anonymous-function-use-clauseopt return-typeopt compound-statement
anonymous-function-use-clause:
use ( use-variable-name-list )
use-variable-name-list:
&opt variable-name
use-variable-name-list , &opt variable-name
object-creation-expression:
new class-type-designator ( argument-expression-listopt )
new class-type-designator ( argument-expression-list ,opt )
new class-type-designator
new class ( argument-expression-listopt ) class-base-clauseopt class-interface-clauseopt { class-member-declarationsopt }
new class class-base-clauseopt class-interface-clauseopt { class-member-declarationsopt }
class-type-designator:
qualified-name
new-variable
new-variable:
simple-variable
new-variable [ expressionopt ]
new-variable { expression }
new-variable -> member-name
qualified-name :: simple-variable
relative-scope :: simple-variable
new-variable :: simple-variable
array-creation-expression:
array ( array-initializeropt )
[ array-initializeropt ]
array-initializer:
array-initializer-list ,opt
array-initializer-list:
array-element-initializer
array-element-initializer , array-initializer-list
array-element-initializer:
&opt element-value
element-key => &opt element-value
element-key:
expression
element-value:
expression
subscript-expression:
dereferencable-expression [ expressionopt ]
dereferencable-expression { expression } <b>[Deprecated form]</b>
function-call-expression:
qualified-name ( argument-expression-listopt )
qualified-name ( argument-expression-list , )
callable-expression ( argument-expression-listopt )
callable-expression ( argument-expression-list , )
argument-expression-list:
argument-expression
argument-expression-list , argument-expression
argument-expression:
variadic-unpacking
expression
variadic-unpacking:
... expression
member-access-expression:
dereferencable-expression -> member-name
member-name:
name
simple-variable
{ expression }
member-call-expression:
dereferencable-expression -> member-name ( argument-expression-listopt )
dereferencable-expression -> member-name ( argument-expression-list , )
postfix-increment-expression:
variable ++
postfix-decrement-expression:
variable --
prefix-increment-expression:
++ variable
prefix-decrement-expression:
-- variable
shell-command-expression:
` dq-char-sequenceopt `
scoped-property-access-expression:
scope-resolution-qualifier :: simple-variable
scoped-call-expression:
scope-resolution-qualifier :: member-name ( argument-expression-listopt )
scope-resolution-qualifier :: member-name ( argument-expression-list , )
class-constant-access-expression:
scope-resolution-qualifier :: name
scope-resolution-qualifier:
relative-scope
qualified-name
dereferencable-expression
relative-scope:
self
parent
static
clone-expression:
primary-expression
clone primary-expression
exponentiation-expression:
clone-expression
clone-expression ** exponentiation-expression
unary-expression:
exponentiation-expression
unary-op-expression
error-control-expression
cast-expression
unary-op-expression:
unary-operator unary-expression
unary-operator: one of
+ - ~
error-control-expression:
@ unary-expression
cast-expression:
( cast-type ) unary-expression
cast-type: one of
array binary bool boolean double int integer float object
real string unset
instanceof-expression:
unary-expression
instanceof-subject instanceof class-type-designator
instanceof-subject:
instanceof-expression
logical-NOT-expression:
instanceof-expression
! instanceof-expression
multiplicative-expression:
logical-NOT-expression
multiplicative-expression * logical-NOT-expression
multiplicative-expression / logical-NOT-expression
multiplicative-expression % logical-NOT-expression
additive-expression:
multiplicative-expression
additive-expression + multiplicative-expression
additive-expression - multiplicative-expression
additive-expression . multiplicative-expression
shift-expression:
additive-expression
shift-expression << additive-expression
shift-expression >> additive-expression
relational-expression:
shift-expression
relational-expression < shift-expression
relational-expression > shift-expression
relational-expression <= shift-expression
relational-expression >= shift-expression
relational-expression <=> shift-expression
equality-expression:
relational-expression
equality-expression == relational-expression
equality-expression != relational-expression
equality-expression <> relational-expression
equality-expression === relational-expression
equality-expression !== relational-expression
bitwise-AND-expression:
equality-expression
bitwise-AND-expression & equality-expression
bitwise-exc-OR-expression:
bitwise-AND-expression
bitwise-exc-OR-expression ^ bitwise-AND-expression
bitwise-inc-OR-expression:
bitwise-exc-OR-expression
bitwise-inc-OR-expression | bitwise-exc-OR-expression
logical-AND-expression-1:
bitwise-inc-OR-expression
logical-AND-expression-1 && bitwise-inc-OR-expression
logical-inc-OR-expression-1:
logical-AND-expression-1
logical-inc-OR-expression-1 || logical-AND-expression-1
coalesce-expression:
logical-inc-OR-expression-1
logical-inc-OR-expression-1 ?? coalesce-expression
conditional-expression:
coalesce-expression
conditional-expression ? expressionopt : coalesce-expression
assignment-expression:
conditional-expression
simple-assignment-expression
compound-assignment-expression
simple-assignment-expression:
variable = assignment-expression
list-intrinsic = assignment-expression
list-intrinsic:
list ( list-expression-list )
list-expression-list:
unkeyed-list-expression-list
keyed-list-expression-list ,opt
unkeyed-list-expression-list:
list-or-variable
,
unkeyed-list-expression-list , list-or-variableopt
keyed-list-expression-list:
expression => list-or-variable
keyed-list-expression-list , expression => list-or-variable
list-or-variable:
list-intrinsic
&opt variable
byref-assignment-expression:
variable = & variable
compound-assignment-expression:
variable compound-assignment-operator assignment-expression
compound-assignment-operator: one of
**= *= /= %= += -= .= <<= >>= &= ^= |=
yield-from-expression:
yield from assignment-expression
yield-expression:
yield-from-expression
yield
yield yield-expression
yield yield-from-expression => yield-expression
print-expression:
yield-expression
print print-expression
logical-AND-expression-2:
print-expression
logical-AND-expression-2 and yield-expression
logical-exc-OR-expression:
logical-AND-expression-2
logical-exc-OR-expression xor logical-AND-expression-2
logical-inc-OR-expression-2:
logical-exc-OR-expression
logical-inc-OR-expression-2 or logical-exc-OR-expression
expression:
logical-inc-OR-expression-2
include-expression
include-once-expression
require-expression
require-once-expression
include-expression:
include expression
include-once-expression:
include_once expression
require-expression:
require expression
require-once-expression:
require_once expression
constant-expression:
expression
### Statements
statement:
compound-statement
named-label-statement
expression-statement
selection-statement
iteration-statement
jump-statement
try-statement
declare-statement
echo-statement
unset-statement
const-declaration
function-definition
class-declaration
interface-declaration
trait-declaration
namespace-definition
namespace-use-declaration
global-declaration
function-static-declaration
compound-statement:
{ statement-listopt }
statement-list:
statement
statement-list statement
named-label-statement:
name :
expression-statement:
expressionopt ;
selection-statement:
if-statement
switch-statement
if-statement:
if ( expression ) statement elseif-clauses-1opt else-clause-1opt
if ( expression ) : statement-list elseif-clauses-2opt else-clause-2opt endif ;
elseif-clauses-1:
elseif-clause-1
elseif-clauses-1 elseif-clause-1
elseif-clause-1:
elseif ( expression ) statement
else-clause-1:
else statement
elseif-clauses-2:
elseif-clause-2
elseif-clauses-2 elseif-clause-2
elseif-clause-2:
elseif ( expression ) : statement-list
else-clause-2:
else : statement-list
switch-statement:
switch ( expression ) { case-statementsopt }
switch ( expression ) : case-statementsopt endswitch ;
case-statements:
case-statement case-statementsopt
default-statement case-statementsopt
case-statement:
case expression case-default-label-terminator statement-listopt
default-statement:
default case-default-label-terminator statement-listopt
case-default-label-terminator:
:
;
iteration-statement:
while-statement
do-statement
for-statement
foreach-statement
while-statement:
while ( expression ) statement
while ( expression ) : statement-list endwhile ;
do-statement:
do statement while ( expression ) ;
for-statement:
for ( for-initializeropt ; for-controlopt ; for-end-of-loopopt ) statement
for ( for-initializeropt ; for-controlopt ; for-end-of-loopopt ) : statement-list endfor ;
for-initializer:
for-expression-group
for-control:
for-expression-group
for-end-of-loop:
for-expression-group
for-expression-group:
expression
for-expression-group , expression
foreach-statement:
foreach ( foreach-collection-name as foreach-keyopt foreach-value ) statement
foreach ( foreach-collection-name as foreach-keyopt foreach-value ) : statement-list endforeach ;
foreach-collection-name:
expression
foreach-key:
expression =>
foreach-value:
&opt expression
list-intrinsic
jump-statement:
goto-statement
continue-statement
break-statement
return-statement
throw-statement
goto-statement:
goto name ;
continue-statement:
continue breakout-levelopt ;
breakout-level:
integer-literal
( breakout-level )
break-statement:
break breakout-levelopt ;
return-statement:
return expressionopt ;
throw-statement:
throw expression ;
try-statement:
try compound-statement catch-clauses
try compound-statement finally-clause
try compound-statement catch-clauses finally-clause
catch-clauses:
catch-clause
catch-clauses catch-clause
catch-clause:
catch ( catch-name-list variable-name ) compound-statement
catch-name-list:
qualified-name
catch-name-list | qualified-name
finally-clause:
finally compound-statement
declare-statement:
declare ( declare-directive ) statement
declare ( declare-directive ) : statement-list enddeclare ;
declare ( declare-directive ) ;
declare-directive:
ticks = literal
encoding = literal
strict_types = literal
echo-statement:
echo expression-list ;
expression-list:
expression
expression-list , expression
unset-statement:
unset ( variable-list ,opt ) ;
### Functions
function-definition: function-definition-header compound-statement function-definition-header: function &opt name ( parameter-declaration-listopt ) return-typeopt parameter-declaration-list: simple-parameter-declaration-list variadic-declaration-list simple-parameter-declaration-list: parameter-declaration parameter-declaration-list , parameter-declaration variadic-declaration-list: simple-parameter-declaration-list , variadic-parameter variadic-parameter parameter-declaration: type-declarationopt &opt variable-name default-argument-specifieropt variadic-parameter: type-declarationopt &opt ... variable-name return-type: : type-declaration : void type-declaration: ?opt base-type-declaration base-type-declaration: array callable iterable scalar-type qualified-name scalar-type: bool float int string default-argument-specifier: = constant-expression### Classes
class-declaration:
class-modifiersopt class name class-base-clauseopt class-interface-clauseopt { class-member-declarationsopt }
class-modifiers:
class-modifier
class-modifiers class-modifier
class-modifier:
abstract
final
readonly
class-base-clause:
extends qualified-name
class-interface-clause:
implements qualified-name
class-interface-clause , qualified-name
class-member-declarations:
class-member-declaration
class-member-declarations class-member-declaration
class-member-declaration:
class-const-declaration
property-declaration
method-declaration
constructor-declaration
destructor-declaration
trait-use-clause
const-declaration:
const const-elements ;
class-const-declaration:
visibility-modifieropt const const-elements ;
const-elements:
const-element
const-elements , const-element
const-element:
name = constant-expression
property-declaration:
property-modifier property-elements ;
property-modifier:
var
visibility-modifier static-modifieropt
static-modifier visibility-modifieropt
visibility-modifier:
public
protected
private
static-modifier:
static
property-elements:
property-element
property-elements property-element
property-element:
variable-name property-initializeropt ;
property-initializer:
= constant-expression
method-declaration:
method-modifiersopt function-definition
method-modifiers function-definition-header ;
method-modifiers:
method-modifier
method-modifiers method-modifier
method-modifier:
visibility-modifier
static-modifier
class-modifier
constructor-declaration:
method-modifiers function &opt __construct ( parameter-declaration-listopt ) compound-statement
destructor-declaration:
method-modifiers function &opt __destruct ( ) compound-statement
### Interfaces
interface-declaration:
interface name interface-base-clauseopt { interface-member-declarationsopt }
interface-base-clause:
extends qualified-name
interface-base-clause , qualified-name
interface-member-declarations:
interface-member-declaration
interface-member-declarations interface-member-declaration
interface-member-declaration:
class-const-declaration
method-declaration
### Traits
trait-declaration:
trait name { trait-member-declarationsopt }
trait-member-declarations:
trait-member-declaration
trait-member-declarations trait-member-declaration
trait-member-declaration:
property-declaration
method-declaration
constructor-declaration
destructor-declaration
trait-use-clauses
trait-use-clauses:
trait-use-clause
trait-use-clauses trait-use-clause
trait-use-clause:
use trait-name-list trait-use-specification
trait-name-list:
qualified-name
trait-name-list , qualified-name
trait-use-specification:
;
{ trait-select-and-alias-clausesopt }
trait-select-and-alias-clauses:
trait-select-and-alias-clause
trait-select-and-alias-clauses trait-select-and-alias-clause
trait-select-and-alias-clause:
trait-select-insteadof-clause ;
trait-alias-as-clause ;
trait-select-insteadof-clause:
qualified-name :: name insteadof trait-name-list
trait-alias-as-clause:
name as visibility-modifieropt name
name as visibility-modifier nameopt
### Namespaces
namespace-definition:
namespace namespace-name ;
namespace namespace-nameopt compound-statement
namespace-use-declaration:
use namespace-function-or-constopt namespace-use-clauses ;
use namespace-function-or-const \opt namespace-name \ { namespace-use-group-clauses-1 } ;
use \opt namespace-name \ { namespace-use-group-clauses-2 } ;
namespace-use-clauses:
namespace-use-clause
namespace-use-clauses , namespace-use-clause
namespace-use-clause:
qualified-name namespace-aliasing-clauseopt
namespace-aliasing-clause:
as name
namespace-function-or-const:
function
const
namespace-use-group-clauses-1:
namespace-use-group-clause-1
namespace-use-group-clauses-1 , namespace-use-group-clause-1
namespace-use-group-clause-1:
namespace-name namespace-aliasing-clauseopt
namespace-use-group-clauses-2:
namespace-use-group-clause-2
namespace-use-group-clauses-2 , namespace-use-group-clause-2
namespace-use-group-clause-2:
namespace-function-or-constopt namespace-name namespace-aliasing-clauseopt