From ad1a8bdba48ed23f118fe743f6930d1d57cd8042 Mon Sep 17 00:00:00 2001 From: Andrea Faulds Date: Fri, 5 Feb 2016 12:30:11 +0000 Subject: [PATCH 001/146] Void return type --- spec/09-lexical-structure.md | 2 +- spec/11-statements.md | 4 ++++ spec/13-functions.md | 4 ++++ spec/19-grammar.md | 1 + tests/functions/void_allowed.phpt | 20 ++++++++++++++++++++ tests/functions/void_disallowed1.phpt | 12 ++++++++++++ tests/functions/void_disallowed2.phpt | 12 ++++++++++++ tests/functions/void_parameter.phpt | 8 ++++++++ 8 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 tests/functions/void_allowed.phpt create mode 100644 tests/functions/void_disallowed1.phpt create mode 100644 tests/functions/void_disallowed2.phpt create mode 100644 tests/functions/void_parameter.phpt diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index f8af64a0..bb72aa40 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -269,7 +269,7 @@ Unless stated otherwise ([functions](13-functions.md#function-definitions), Names beginning with two underscores (__) are reserved by the PHP language and should not be defined by the user code. -The following names cannot be used as the names of classes, interfaces, or traits: `bool`, `FALSE`, `float`, `int`, `NULL`, `string`, and `TRUE`. +The following names cannot be used as the names of classes, interfaces, or traits: `bool`, `FALSE`, `float`, `int`, `NULL`, `string`, `TRUE` and `void`. The following names are reserved for future use and should not be used as the names of classes, interfaces, or traits: `mixed`, `numeric`, `object`, and `resource`. diff --git a/spec/11-statements.md b/spec/11-statements.md index 415f1f9b..6a11b603 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -903,6 +903,10 @@ by value or byRef. If *expression* is omitted the value `NULL` is used. If execution flows into the closing brace (`}`) of a function, `return NULL;` is implied. +Explicit `return` statements with *expression* given are not permitted within a +function with a `void` [return type](13-functions.md#return-typing) and MUST +cause a compile-time fatal error. + A function may have any number of `return` statements, whose returned values may have different types. diff --git a/spec/13-functions.md b/spec/13-functions.md index 850ad0ef..247c3440 100644 --- a/spec/13-functions.md +++ b/spec/13-functions.md @@ -74,6 +74,7 @@ A function is called via the function-call operator [`()`](10-expressions.md#fun return-type: : type-declaration + : void type-declaration: array @@ -185,6 +186,9 @@ be compatible with the defined type, using the same rules as for parameter type are not allowed for typed returns. If the value of the [`return` statement](11-statements.md#the-return-statement) does not pass the type check, a fatal error is produced. +The `void` type is a special type that can only be used as a return type, and +not in other contexts. It has no effect at runtime, see the [`return` statement](11-statements.md#the-return-statement). + ## Type check modes The type checking can be performed in two modes, strict and coercive (default). diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 2918d248..bb1f77eb 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -1035,6 +1035,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# return-type: : type-declaration + : void type-declaration: array diff --git a/tests/functions/void_allowed.phpt b/tests/functions/void_allowed.phpt new file mode 100644 index 00000000..8f07c739 --- /dev/null +++ b/tests/functions/void_allowed.phpt @@ -0,0 +1,20 @@ +--TEST-- +void return type: acceptable cases +--FILE-- + Date: Thu, 18 Feb 2016 13:02:22 +0000 Subject: [PATCH 002/146] Restore Oxford comma --- spec/09-lexical-structure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index bb72aa40..c24508d7 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -269,7 +269,7 @@ Unless stated otherwise ([functions](13-functions.md#function-definitions), Names beginning with two underscores (__) are reserved by the PHP language and should not be defined by the user code. -The following names cannot be used as the names of classes, interfaces, or traits: `bool`, `FALSE`, `float`, `int`, `NULL`, `string`, `TRUE` and `void`. +The following names cannot be used as the names of classes, interfaces, or traits: `bool`, `FALSE`, `float`, `int`, `NULL`, `string`, `TRUE`, and `void`. The following names are reserved for future use and should not be used as the names of classes, interfaces, or traits: `mixed`, `numeric`, `object`, and `resource`. From 2888f580bd887e6a37e0821beca714843fc095e1 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Thu, 18 Feb 2016 10:16:58 -0800 Subject: [PATCH 003/146] Use descriptive mode --- spec/11-statements.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/11-statements.md b/spec/11-statements.md index 6a11b603..956c059d 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -904,8 +904,8 @@ If execution flows into the closing brace (`}`) of a function, `return NULL;` is implied. Explicit `return` statements with *expression* given are not permitted within a -function with a `void` [return type](13-functions.md#return-typing) and MUST -cause a compile-time fatal error. +function with a `void` [return type](13-functions.md#return-typing) and cause +a fatal error. A function may have any number of `return` statements, whose returned values may have different types. From 0b1a497a6c847f6566f32057f55259f68bb9ce38 Mon Sep 17 00:00:00 2001 From: Andrea Faulds Date: Fri, 25 Mar 2016 17:27:45 +0000 Subject: [PATCH 004/146] Allow specifying keys on list() elements Squashed commit of the following: commit c56f6e3a7be00f330225e34d15fc0a2aee507e67 Author: Andrea Faulds Date: Wed Feb 24 13:49:17 2016 +0000 Import Zend Engine tests for list() commit 3afd58a6c65c48940583fc49841fa2087434fc82 Author: Andrea Faulds Date: Wed Feb 24 13:49:05 2016 +0000 Update specification for list() keys --- spec/10-expressions.md | 40 +++++++++- spec/19-grammar.md | 10 ++- tests/expressions/list/list_001.phpt | 14 ++++ tests/expressions/list/list_002.phpt | 20 +++++ tests/expressions/list/list_003.phpt | 24 ++++++ tests/expressions/list/list_004.phpt | 21 +++++ tests/expressions/list/list_005.phpt | 50 ++++++++++++ tests/expressions/list/list_006.phpt | 12 +++ tests/expressions/list/list_007.phpt | 15 ++++ ...st_destructuring_to_special_variables.phpt | 49 ++++++++++++ tests/expressions/list/list_empty_error.phpt | 10 +++ tests/expressions/list/list_keyed.phpt | 71 +++++++++++++++++ .../list/list_keyed_ArrayAccess.phpt | 54 +++++++++++++ .../list/list_keyed_conversions.phpt | 32 ++++++++ .../list/list_keyed_evaluation_order.inc | 60 +++++++++++++++ .../list/list_keyed_evaluation_order.phpt | 35 +++++++++ .../list/list_keyed_evaluation_order_2.phpt | 77 +++++++++++++++++++ .../list/list_keyed_evaluation_order_3.phpt | 24 ++++++ .../list_keyed_evaluation_order_nested.phpt | 77 +++++++++++++++++++ .../list/list_keyed_non_literals.phpt | 30 ++++++++ .../list/list_keyed_trailing_comma.phpt | 38 +++++++++ .../list/list_keyed_undefined.phpt | 22 ++++++ .../list/list_mixed_keyed_unkeyed.phpt | 16 ++++ .../list/list_mixed_nested_keyed_unkeyed.phpt | 34 ++++++++ tests/expressions/list/list_self_assign.phpt | 56 ++++++++++++++ 25 files changed, 888 insertions(+), 3 deletions(-) create mode 100644 tests/expressions/list/list_001.phpt create mode 100644 tests/expressions/list/list_002.phpt create mode 100644 tests/expressions/list/list_003.phpt create mode 100644 tests/expressions/list/list_004.phpt create mode 100644 tests/expressions/list/list_005.phpt create mode 100644 tests/expressions/list/list_006.phpt create mode 100644 tests/expressions/list/list_007.phpt create mode 100644 tests/expressions/list/list_destructuring_to_special_variables.phpt create mode 100644 tests/expressions/list/list_empty_error.phpt create mode 100644 tests/expressions/list/list_keyed.phpt create mode 100644 tests/expressions/list/list_keyed_ArrayAccess.phpt create mode 100644 tests/expressions/list/list_keyed_conversions.phpt create mode 100644 tests/expressions/list/list_keyed_evaluation_order.inc create mode 100644 tests/expressions/list/list_keyed_evaluation_order.phpt create mode 100644 tests/expressions/list/list_keyed_evaluation_order_2.phpt create mode 100644 tests/expressions/list/list_keyed_evaluation_order_3.phpt create mode 100644 tests/expressions/list/list_keyed_evaluation_order_nested.phpt create mode 100644 tests/expressions/list/list_keyed_non_literals.phpt create mode 100644 tests/expressions/list/list_keyed_trailing_comma.phpt create mode 100644 tests/expressions/list/list_keyed_undefined.phpt create mode 100644 tests/expressions/list/list_mixed_keyed_unkeyed.phpt create mode 100644 tests/expressions/list/list_mixed_nested_keyed_unkeyed.phpt create mode 100644 tests/expressions/list/list_self_assign.phpt diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 55863ba7..12ab39f3 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -414,9 +414,17 @@ isset($v1, $v2, $v3); // results in FALSE list ( list-expression-listopt ) list-expression-list: + unkeyed-list-expression-list + keyed-list-expression-list ,opt + + unkeyed-list-expression-list: list-or-variable , - list-expression-list , list-or-variableopt + 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 @@ -446,7 +454,8 @@ target variables. On success, it returns a copy of the source array. If the source array is not an array or object implementing `ArrayAccess` no assignments are performed and the return value is `NULL`. -All elements in the source array having keys of type `string` are ignored. +For *unkeyed-list-expression-list*, all elements in the source array having +keys of type `string` are ignored. The element having an `int` key of 0 is assigned to the first target variable, the element having an `int` key of 1 is assigned to the second target variable, and so on, until all target variables have been @@ -455,6 +464,15 @@ fewer source array elements having int keys than there are target variables, the unassigned target variables are set to `NULL` and a non-fatal error is produced. +For *keyed-list-expression-list*, each key-variable pair is handled in turn, +with the key and variable being separated by the `=>` symbol. +The element having the first key, with the key having been converted using the +same rules as the [subscript operator](10-expressions.md#subscript-operator), +is assigned to the frst target variable. This process is repeated for the +second `=>` pair, if any, and so on. Any other array elements are ignored. +If there is no array element with a given key, the unassigned target variable +is set to `NULL` and a non-fatal error is produced. + The assignments must occur in this order. Any target variable may be a list, in which case, the corresponding @@ -481,6 +499,24 @@ list($arr[1], $arr[0]) = [0, 1]; // $arr is [1 => 0, 0 => 1], in this order list($arr2[], $arr2[]) = [0, 1]; // $arr2 is [0, 1] + +list("one" => $one, "two" => $two) = ["one" => 1, "two" => 2]; + // $one is 1, $two is 2 +list( + "one" => $one, + "two" => $two, +) = [ + "one" => 1, + "two" => 2, +]; + // $one is 1, $two is 2 +list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = [ + ["x" => 1, "y" => 2], + ["x" => 3, "y" => 4] +]; + // $x1 is 1, $y1 is 2, $x2 is 3, $y2 is 4 +list(0 => list($x1, $x2), 1 => list($x2, $y2)) = [[1, 2], [3, 4]]; + // $x1 is 1, $y1 is 2, $x2 is 3, $y2 is 4 ``` ####print diff --git a/spec/19-grammar.md b/spec/19-grammar.md index bb1f77eb..f7fa7249 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -426,9 +426,17 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# list ( list-expression-listopt ) list-expression-list: + unkeyed-list-expression-list + keyed-list-expression-list ,opt + + unkeyed-list-expression-list: list-or-variable , - list-expression-list , list-or-variableopt + 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 diff --git a/tests/expressions/list/list_001.phpt b/tests/expressions/list/list_001.phpt new file mode 100644 index 00000000..a9fff550 --- /dev/null +++ b/tests/expressions/list/list_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +"Nested" list() +--FILE-- + +--EXPECT-- +object(stdClass)#1 (0) { +} +object(stdClass)#2 (0) { +} diff --git a/tests/expressions/list/list_002.phpt b/tests/expressions/list/list_002.phpt new file mode 100644 index 00000000..ac0d8974 --- /dev/null +++ b/tests/expressions/list/list_002.phpt @@ -0,0 +1,20 @@ +--TEST-- +Testing full-reference on list() +--FILE-- + +--EXPECT-- +object(stdClass)#1 (0) { +} +object(stdClass)#1 (0) { +} +bool(true) diff --git a/tests/expressions/list/list_003.phpt b/tests/expressions/list/list_003.phpt new file mode 100644 index 00000000..4a509f6a --- /dev/null +++ b/tests/expressions/list/list_003.phpt @@ -0,0 +1,24 @@ +--TEST-- +list() with non-array +--FILE-- + +--EXPECT-- +NULL +NULL +NULL +NULL +NULL diff --git a/tests/expressions/list/list_004.phpt b/tests/expressions/list/list_004.phpt new file mode 100644 index 00000000..862a4e43 --- /dev/null +++ b/tests/expressions/list/list_004.phpt @@ -0,0 +1,21 @@ +--TEST-- +list() with array reference +--FILE-- + +--EXPECT-- +int(1) +array(2) { + [0]=> + int(2) + [1]=> + int(1) +} diff --git a/tests/expressions/list/list_005.phpt b/tests/expressions/list/list_005.phpt new file mode 100644 index 00000000..7dc3bf6f --- /dev/null +++ b/tests/expressions/list/list_005.phpt @@ -0,0 +1,50 @@ +--TEST-- +Testing list() with several variables +--FILE-- + +--EXPECTF-- +NULL +NULL +NULL +---- +NULL +NULL +NULL +---- + +Fatal error: Uncaught Error: Cannot use object of type stdClass as array in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/tests/expressions/list/list_006.phpt b/tests/expressions/list/list_006.phpt new file mode 100644 index 00000000..d380235d --- /dev/null +++ b/tests/expressions/list/list_006.phpt @@ -0,0 +1,12 @@ +--TEST-- +Testing nested list() with empty array +--FILE-- + +--EXPECTF-- +Notice: Undefined offset: 0 in %s on line %d + +Notice: Undefined offset: 1 in %s on line %d diff --git a/tests/expressions/list/list_007.phpt b/tests/expressions/list/list_007.phpt new file mode 100644 index 00000000..67c65245 --- /dev/null +++ b/tests/expressions/list/list_007.phpt @@ -0,0 +1,15 @@ +--TEST-- +Using lambda with list() +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Cannot use object of type Closure as array in %slist_007.php:3 +Stack trace: +#0 {main} + thrown in %slist_007.php on line 3 diff --git a/tests/expressions/list/list_destructuring_to_special_variables.phpt b/tests/expressions/list/list_destructuring_to_special_variables.phpt new file mode 100644 index 00000000..4418c967 --- /dev/null +++ b/tests/expressions/list/list_destructuring_to_special_variables.phpt @@ -0,0 +1,49 @@ +--TEST-- +list() can be used to destructure to string offsets, __set and ArrayAccess::offsetSet +--FILE-- +values[$name] = $value; + } +} + +class Arr implements ArrayAccess { + public $values = []; + public function offsetSet($name, $value) { + $this->values[$name] = $value; + } + public function offsetGet($name) {} + public function offsetExists($name) {} + public function offsetUnset($name) {} +} + +$str = 'ab'; +list($str[0], $str[1]) = ['x', 'y']; +var_dump($str); + +$obj = new Obj; +list($obj->foo, $obj->bar) = ['foo', 'bar']; +var_dump($obj->values); + +$arr = new Arr; +list($arr['foo'], $arr['bar']) = ['foo', 'bar']; +var_dump($arr->values); + +?> +--EXPECT-- +string(2) "xy" +array(2) { + ["foo"]=> + string(3) "foo" + ["bar"]=> + string(3) "bar" +} +array(2) { + ["foo"]=> + string(3) "foo" + ["bar"]=> + string(3) "bar" +} diff --git a/tests/expressions/list/list_empty_error.phpt b/tests/expressions/list/list_empty_error.phpt new file mode 100644 index 00000000..78de2e95 --- /dev/null +++ b/tests/expressions/list/list_empty_error.phpt @@ -0,0 +1,10 @@ +--TEST-- +Empty list() assignments are not allowed +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use empty list in %s on line %d diff --git a/tests/expressions/list/list_keyed.phpt b/tests/expressions/list/list_keyed.phpt new file mode 100644 index 00000000..b549ed9b --- /dev/null +++ b/tests/expressions/list/list_keyed.phpt @@ -0,0 +1,71 @@ +--TEST-- +list() with keys +--FILE-- + "bad", + "happy" => "sad", +]; + +list("good" => $good_antonym, "happy" => $happy_antonym) = $antonyms; +var_dump($good_antonym, $happy_antonym); + +echo PHP_EOL; + +$powersOfTwo = [ + 1 => 2, + 2 => 4, + 3 => 8 +]; + +list(1 => $two_1, 2 => $two_2, 3 => $two_3) = $powersOfTwo; +var_dump($two_1, $two_2, $two_3); + +echo PHP_EOL; + +$contrivedMixedKeyTypesExample = [ + 7 => "the best PHP version", + "elePHPant" => "the cutest mascot" +]; + +list(7 => $seven, "elePHPant" => $elePHPant) = $contrivedMixedKeyTypesExample; +var_dump($seven, $elePHPant); + +echo PHP_EOL; + +$allTogetherNow = [ + "antonyms" => $antonyms, + "powersOfTwo" => $powersOfTwo, + "contrivedMixedKeyTypesExample" => $contrivedMixedKeyTypesExample +]; + +list( + "antonyms" => list("good" => $good_antonym, "happy" => $happy_antonym), + "powersOfTwo" => list(1 => $two_1, 2 => $two_2, 3 => $two_3), + "contrivedMixedKeyTypesExample" => list(7 => $seven, "elePHPant" => $elePHPant) +) = $allTogetherNow; + +var_dump($good_antonym, $happy_antonym); +var_dump($two_1, $two_2, $two_3); +var_dump($seven, $elePHPant); + +?> +--EXPECT-- +string(3) "bad" +string(3) "sad" + +int(2) +int(4) +int(8) + +string(20) "the best PHP version" +string(17) "the cutest mascot" + +string(3) "bad" +string(3) "sad" +int(2) +int(4) +int(8) +string(20) "the best PHP version" +string(17) "the cutest mascot" diff --git a/tests/expressions/list/list_keyed_ArrayAccess.phpt b/tests/expressions/list/list_keyed_ArrayAccess.phpt new file mode 100644 index 00000000..1bb20130 --- /dev/null +++ b/tests/expressions/list/list_keyed_ArrayAccess.phpt @@ -0,0 +1,54 @@ +--TEST-- +list() with keys and ArrayAccess +--FILE-- + $good, "happy" => $happy) = $antonymObject; +var_dump($good, $happy); + +echo PHP_EOL; + +$stdClassCollection = new SplObjectStorage; +$foo = new StdClass; +$stdClassCollection[$foo] = "foo"; +$bar = new StdClass; +$stdClassCollection[$bar] = "bar"; + +list($foo => $fooStr, $bar => $barStr) = $stdClassCollection; +var_dump($fooStr, $barStr); + +echo PHP_EOL; + +class IndexPrinter implements ArrayAccess +{ + public function offsetGet($offset) { + echo "GET "; + var_dump($offset); + } + public function offsetSet($offset, $value) { + } + public function offsetExists($offset) { + } + public function offsetUnset($offset) { + } +} + +$op = new IndexPrinter; +list(123 => $x) = $op; +// PHP shouldn't convert this to an integer offset, because it's ArrayAccess +list("123" => $x) = $op; + +?> +--EXPECT-- +string(3) "bad" +string(3) "sad" + +string(3) "foo" +string(3) "bar" + +GET int(123) +GET string(3) "123" diff --git a/tests/expressions/list/list_keyed_conversions.phpt b/tests/expressions/list/list_keyed_conversions.phpt new file mode 100644 index 00000000..e2cf91a2 --- /dev/null +++ b/tests/expressions/list/list_keyed_conversions.phpt @@ -0,0 +1,32 @@ +--TEST-- +list() with non-integer-or-string keys +--FILE-- + 0, + 1 => 1, + "" => "" +]; + +list(NULL => $NULL, 1.5 => $float, FALSE => $FALSE, TRUE => $TRUE) = $results; +var_dump($NULL, $float, $FALSE, $TRUE); + +echo PHP_EOL; + +list("0" => $zeroString, "1" => $oneString) = $results; +var_dump($zeroString, $oneString); + +list(STDIN => $resource) = []; + +?> +--EXPECTF-- +string(0) "" +int(1) +int(0) +int(1) + +int(0) +int(1) + +Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d diff --git a/tests/expressions/list/list_keyed_evaluation_order.inc b/tests/expressions/list/list_keyed_evaluation_order.inc new file mode 100644 index 00000000..490a6d84 --- /dev/null +++ b/tests/expressions/list/list_keyed_evaluation_order.inc @@ -0,0 +1,60 @@ +name = $name; + } + + public function __toString(): string { + echo "$this->name evaluated.", PHP_EOL; + return $this->name; + } +} + +class Indexable implements ArrayAccess +{ + private $array; + public function __construct(array $array) { + $this->array = $array; + } + + public function offsetExists($offset): bool { + echo "Existence of offset $offset checked for.", PHP_EOL; + return isset($this->array[$offset]); + } + + public function offsetUnset($offset): void { + unset($this->array[$offset]); + echo "Offset $offset removed.", PHP_EOL; + } + + public function offsetGet($offset) { + echo "Offset $offset retrieved.", PHP_EOL; + return $this->array[$offset]; + } + + public function offsetSet($offset, $value): void { + $this->array[$offset] = $value; + echo "Offset $offset set to $value.", PHP_EOL; + } +} + +class IndexableRetrievable +{ + private $label; + private $indexable; + + public function __construct(string $label, Indexable $indexable) { + $this->label = $label; + $this->indexable = $indexable; + } + + public function getIndexable(): Indexable { + echo "Indexable $this->label retrieved.", PHP_EOL; + return $this->indexable; + } +} diff --git a/tests/expressions/list/list_keyed_evaluation_order.phpt b/tests/expressions/list/list_keyed_evaluation_order.phpt new file mode 100644 index 00000000..0f0652b6 --- /dev/null +++ b/tests/expressions/list/list_keyed_evaluation_order.phpt @@ -0,0 +1,35 @@ +--TEST-- +list() with keys, evaluation order +--FILE-- + "value for offset A", "C" => "value for offset C"])); + +$store = new Indexable([]); + +// list($a => $b, $c => $d) = $e; +// Should be evaluated in the order: +// 1. Evaluate $e +// 2. Evaluate $a +// 3. Evaluate $e[$a] +// 4. Assign $b from $e[$a] +// 5. Evaluate $c +// 6. Evaluate $e[$c] +// 7. Assign $c from $e[$a] + +list((string)$a => $store["B"], (string)$c => $store["D"]) = $e->getIndexable(); + +?> +--EXPECT-- +Indexable E retrieved. +A evaluated. +Offset A retrieved. +Offset B set to value for offset A. +C evaluated. +Offset C retrieved. +Offset D set to value for offset C. diff --git a/tests/expressions/list/list_keyed_evaluation_order_2.phpt b/tests/expressions/list/list_keyed_evaluation_order_2.phpt new file mode 100644 index 00000000..ddfba68c --- /dev/null +++ b/tests/expressions/list/list_keyed_evaluation_order_2.phpt @@ -0,0 +1,77 @@ +--TEST-- +list() with keys, evaluation order #2 +--FILE-- + $a, 1 => $b) = ['a', 'b']; +var_dump($a); +var_dump($b); + +list(1 => $b, 0 => $a) = ['a', 'b']; +var_dump($a); +var_dump($b); + +$arr = []; +list($arr[], $arr[]) = ['a', 'b']; +var_dump($arr[0]); +var_dump($arr[1]); + +$arr = []; +list(0 => $arr[], 1 => $arr[]) = ['a', 'b']; +var_dump($arr[0]); +var_dump($arr[1]); + +$arr = []; +list(1 => $arr[], 0 => $arr[]) = ['b', 'a']; +var_dump($arr[0]); +var_dump($arr[1]); + +$arr = []; +list(list(1 => $arr[], 0 => $arr[])) = [['b', 'a']]; +var_dump($arr[0]); +var_dump($arr[1]); + +$arr = []; +list('key1' => $arr[], 'key2' => $arr[]) = ['key2' => 'b', 'key1' => 'a']; +var_dump($arr[0]); +var_dump($arr[1]); + +// This should print 'foo' +$a = 0; +list($a => $a) = ['foo', 'bar']; +var_dump($a); + +// This should print 'bar' then 'foo' +$a = 0; +$b = 1; +list($b => $a, $a => $c) = ['bar' => 'foo', 1 => 'bar']; +var_dump($a); +var_dump($c); + +?> +--EXPECT-- +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(3) "foo" +string(3) "bar" +string(3) "foo" diff --git a/tests/expressions/list/list_keyed_evaluation_order_3.phpt b/tests/expressions/list/list_keyed_evaluation_order_3.phpt new file mode 100644 index 00000000..7850834c --- /dev/null +++ b/tests/expressions/list/list_keyed_evaluation_order_3.phpt @@ -0,0 +1,24 @@ +--TEST-- +list() with keys, evaluation order #3 +--FILE-- + [ + 'b' => 'bar', + 'a' => 'foo', + ], + 1 => 'a', + 3 => 'b', +]; +list($a[$i++] => $a[$i++], $a[$i++] => $a[$i++]) = $a[$i++]; +var_dump($i); // should be 5 +var_dump($a[2]); // should be 'foo' +var_dump($a[4]); // should be 'bar' + +?> +--EXPECT-- +int(5) +string(3) "foo" +string(3) "bar" diff --git a/tests/expressions/list/list_keyed_evaluation_order_nested.phpt b/tests/expressions/list/list_keyed_evaluation_order_nested.phpt new file mode 100644 index 00000000..8a7725d4 --- /dev/null +++ b/tests/expressions/list/list_keyed_evaluation_order_nested.phpt @@ -0,0 +1,77 @@ +--TEST-- +list() with keys, evaluation order: nested +--FILE-- + "offset value for A", + "C" => new Indexable([ + 0 => "offset value for 0", + 1 => "offset value for 1" + ]), + "F" => new Indexable([ + "G" => "offset value for G", + "I" => "offset value for I" + ]) +])); + +$store = new Indexable([]); + +// list($a => $b, $c => list($d, $e), $f => list($g => $h, $i => $j)) = $k; +// Should be evaluated in the order: +// 1. Evaluate $k +// 2. Evaluate $a +// 3. Evaluate $k[$a] +// 4. Assign $b from $k[$a] +// 5. Evaluate $c +// 6. Evaluate $k[$c] +// 7. Evaluate $k[$c][0] +// 8. Assign $d from $k[$c][0] +// 9. Evaluate $k[$c][1] +// 10. Assign $e from $k[$c][1] +// 11. Evaluate $f +// 12. Evaluate $k[$f] +// 13. Evaluate $g +// 14. Evaluate $k[$f][$g] +// 15. Assign $h from $k[$f][$g] +// 16. Evaluate $i +// 17. Evaluate $k[$f][$i] +// 18. Assign $j from $k[$f][$i] + +list( + (string)$a => $store["B"], + (string)$c => list($store["D"], $store["E"]), + (string)$f => list( + (string)$g => $store["H"], + (string)$i => $store["J"] + ) +) = $k->getIndexable(); + +?> +--EXPECT-- +Indexable K retrieved. +A evaluated. +Offset A retrieved. +Offset B set to offset value for A. +C evaluated. +Offset C retrieved. +Offset 0 retrieved. +Offset D set to offset value for 0. +Offset 1 retrieved. +Offset E set to offset value for 1. +F evaluated. +Offset F retrieved. +G evaluated. +Offset G retrieved. +Offset H set to offset value for G. +I evaluated. +Offset I retrieved. +Offset J set to offset value for I. diff --git a/tests/expressions/list/list_keyed_non_literals.phpt b/tests/expressions/list/list_keyed_non_literals.phpt new file mode 100644 index 00000000..80f22eda --- /dev/null +++ b/tests/expressions/list/list_keyed_non_literals.phpt @@ -0,0 +1,30 @@ +--TEST-- +list() with constant keys +--FILE-- + "one", + 2 => "two", + 3 => "three" +]; + +const COMPILE_TIME_RESOLVABLE = 1; + +define('PROBABLY_NOT_COMPILE_TIME_RESOLVABLE', file_get_contents("data:text/plain,2")); + +$probablyNotCompileTimeResolvable3 = cos(0) * 3; + +list( + COMPILE_TIME_RESOLVABLE => $one, + PROBABLY_NOT_COMPILE_TIME_RESOLVABLE => $two, + $probablyNotCompileTimeResolvable3 => $three +) = $arr; + +var_dump($one, $two, $three); + +?> +--EXPECTF-- +string(3) "one" +string(3) "two" +string(5) "three" diff --git a/tests/expressions/list/list_keyed_trailing_comma.phpt b/tests/expressions/list/list_keyed_trailing_comma.phpt new file mode 100644 index 00000000..e0af0aed --- /dev/null +++ b/tests/expressions/list/list_keyed_trailing_comma.phpt @@ -0,0 +1,38 @@ +--TEST-- +list() with keys and a trailing comma +--FILE-- + "bad", + "happy" => "sad", +]; + +list( + "good" => $good, + "happy" => $happy +) = $antonyms; + +var_dump($good, $happy); + +echo PHP_EOL; + +$antonyms = [ + "good" => "bad", + "happy" => "sad", +]; + +list( + "good" => $good, + "happy" => $happy, +) = $antonyms; + +var_dump($good, $happy); + +?> +--EXPECT-- +string(3) "bad" +string(3) "sad" + +string(3) "bad" +string(3) "sad" diff --git a/tests/expressions/list/list_keyed_undefined.phpt b/tests/expressions/list/list_keyed_undefined.phpt new file mode 100644 index 00000000..a18e3b4d --- /dev/null +++ b/tests/expressions/list/list_keyed_undefined.phpt @@ -0,0 +1,22 @@ +--TEST-- +list() with undefined keys +--FILE-- + "the best PHP version", + "elePHPant" => "the cutest mascot" +]; + +list(5 => $five, "duke" => $duke) = $contrivedMixedKeyTypesExample; + +var_dump($five, $duke); + +?> +--EXPECTF-- + +Notice: Undefined offset: 5 in %s on line %d + +Notice: Undefined index: duke in %s on line %d +NULL +NULL diff --git a/tests/expressions/list/list_mixed_keyed_unkeyed.phpt b/tests/expressions/list/list_mixed_keyed_unkeyed.phpt new file mode 100644 index 00000000..5562479f --- /dev/null +++ b/tests/expressions/list/list_mixed_keyed_unkeyed.phpt @@ -0,0 +1,16 @@ +--TEST-- +list() with both keyed and unkeyed elements +--FILE-- + 1, + "foo" => "bar" +]; + +list($zero, 1 => $one, "foo" => $foo) = $contrivedKeyedAndUnkeyedArrayExample; + +?> +--EXPECTF-- +Parse error: syntax error, unexpected %s in %s on line %d diff --git a/tests/expressions/list/list_mixed_nested_keyed_unkeyed.phpt b/tests/expressions/list/list_mixed_nested_keyed_unkeyed.phpt new file mode 100644 index 00000000..3087775b --- /dev/null +++ b/tests/expressions/list/list_mixed_nested_keyed_unkeyed.phpt @@ -0,0 +1,34 @@ +--TEST-- +list() with nested unkeyed and keyed list() +--FILE-- + 1, "y" => 2], + ["x" => 2, "y" => 1] +]; + +list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = $points; +var_dump($x1, $y1, $x2, $y2); + +echo PHP_EOL; + +$invertedPoints = [ + "x" => [1, 2], + "y" => [2, 1] +]; + +list("x" => list($x1, $x2), "y" => list($y1, $y2)) = $invertedPoints; +var_dump($x1, $y1, $x2, $y2); + +?> +--EXPECT-- +int(1) +int(2) +int(2) +int(1) + +int(1) +int(2) +int(2) +int(1) diff --git a/tests/expressions/list/list_self_assign.phpt b/tests/expressions/list/list_self_assign.phpt new file mode 100644 index 00000000..46409126 --- /dev/null +++ b/tests/expressions/list/list_self_assign.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test variable occuring on both LHS and RHS of list() +--FILE-- + +--EXPECT-- +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) From a3ea4e992f43ea9083c3fe3738a5ded03412f6e1 Mon Sep 17 00:00:00 2001 From: Andrea Faulds Date: Wed, 30 Mar 2016 01:46:51 +0100 Subject: [PATCH 005/146] Warn about invalid strings in arithmetic Squashed commit of the following: commit 4bc40d91788a983a99aac8ff337509f53ec1000a Author: Andrea Faulds Date: Sun Mar 20 02:20:28 2016 +0000 Update spec for invalid numeric strings commit 2461e4f7387741b176a9aa9a5d32b92a2903ed85 Author: Andrea Faulds Date: Wed Feb 24 16:53:26 2016 +0000 Updated tests for invalid numeric strings --- spec/10-expressions.md | 90 ++-- .../assignment_operators/add_assignment.phpt | 236 ++++++-- .../assignment_operators/and_assignment.phpt | 196 +++++-- .../assignment_operators/div_assignment.phpt | 84 ++- .../assignment_operators/mod_assignment.phpt | 78 ++- .../assignment_operators/mul_assignment.phpt | 236 ++++++-- .../assignment_operators/or_assignment.phpt | 216 +++++--- .../assignment_operators/sl_assignment.phpt | 248 ++++++--- .../assignment_operators/sr_assignment.phpt | 508 +++++++++++------- .../assignment_operators/sub_assignment.phpt | 236 ++++++-- .../assignment_operators/xor_assignment.phpt | Bin 9260 -> 11942 bytes .../bitwise_shift.phpt | 10 +- .../multiplication_division_modulus.phpt | 432 ++++++++++----- .../pre-increment_and_decrement.phpt | 102 +++- .../unary_arithmetic_operators.phpt | 10 +- tests/types/string/numeric_like_strings.phpt | 18 +- 16 files changed, 1929 insertions(+), 771 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 12ab39f3..ba628bb1 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -1528,12 +1528,12 @@ left-hand operand to the power of the right-hand one. If either of the operands have an object type supporting `**` operation, then the object semantics defines the result. The left operand is checked first. -If either or both operands have non-numeric types, their values are converted to type `int` -or `float`, as appropriate. If both operands have non-negative integer -values and the result can be represented as an `int`, the result has type -`int`; otherwise, the result has type `float`. - -**Examples** +If either or both operands have non-numeric types, their values are converted +to type `int` or `float`, as appropriate. If both operands have non-negative +integer values and the result can be represented as an `int`, the result has +type `int`; otherwise, the result has type `float`. If either or both operands +were leading-numeric or non-numeric strings, a non-fatal error must be produced +for each. **Examples** ```PHP 2**3; // int with value 8 @@ -1752,7 +1752,8 @@ leading-numeric string, the string is first converted to an `int` or `float`, as appropriate, after which it is handled as an arithmetic operand. The trailing non-numeric characters in leading-numeric strings are ignored. With a non-numeric string, the result has type `int` and -value 0. +value 0. If the string was leading-numeric or non-numeric, a non-fatal error +MUST be produced. For a unary `~` operator used with a string, the result is the string with each byte being bitwise complement of the corresponding byte of the source string. @@ -2080,28 +2081,33 @@ The right-hand operand of operator `/` and operator `%` must not be zero. If either of the operands is an object supporting the operation, the result is defined by that object's semantics, with the left operand checked first. -The binary `*` operator produces the product of its operands. If either -or both operands have non-numeric types, their values are converted to -type `int` or `float`, as appropriate. Then if either operand has type -`float`, the other is converted to that type, and the result has type -`float`. Otherwise, both operands have type `int`, in which case, if the -resulting value can be represented in type `int` that is the result type. -Otherwise, the result would have type `float`. +The binary `*` operator produces the product of its operands. If either or both +operands have non-numeric types, their values are converted to type `int` or +`float`, as appropriate. If either or both operands were leading-numeric or +non-numeric strings, a non-fatal error MUST be produced for each. Then if +either operand has type `float`, the other is converted to that type, and the +result has type `float`. Otherwise, both operands have type `int`, in which +case, if the resulting value can be represented in type `int` that is the +result type. Otherwise, the result would have type `float`. Division by zero results in a non-fatal error. If the value of the numerator is positive, the result value is `INF`. If the value of the numerator is negative, the result value is `-INF`. If the value of the numerator is zero, the result value is `NAN`. The binary `/` operator produces the quotient from dividing the left-hand -operand by the right-hand one. If either or both operands have -non-numeric types, their values are converted to type `int` or `float`, as -appropriate. Then if either operand has type `float`, the other is -converted to that type, and the result has type `float`. Otherwise, both -operands have type `int`, in which case, if the mathematical value of the -computation can be preserved using type `int`, that is the result type; -otherwise, the type of the result is `float`. +operand by the right-hand one. If either or both operands have non-numeric +types, their values are converted to type `int` or `float`, as appropriate. If +either or both operands were leading-numeric or non-numeric strings, a +non-fatal error must be produced for each. Then if either operand has type +`float`, the other is converted to that type, and the result has type `float`. +Otherwise, both operands have type `int`, in which case, if the mathematical +value of the computation can be preserved using type `int`, that is the result +type; otherwise, the type of the result is `float`. The binary `%` operator produces the remainder from dividing the left-hand -operand by the right-hand one. If the type of both operands is not `int`, -their values are converted to that type. The result has type `int`. If the right-hand operand has value zero, an exception of type `DivisionByZeroError` is thrown. +operand by the right-hand one. If the type of both operands is not `int`, their +values are converted to that type. If either or both operands were +leading-numeric or non-numeric strings, a non-fatal error MUST be produced for +each. The result has type `int`. If the right-hand operand has value zero, an +exception of type `DivisionByZeroError` is thrown. These operators associate left-to-right. @@ -2150,15 +2156,15 @@ If either of the operands is an object supporting the operation, the result is defined by that object's semantics, with the left operand checked first. For non-array operands, the binary `+` operator produces the sum of those -operands, while the binary `-` operator produces the difference of its -operands when subtracting the right-hand operand from the left-hand one. -If either or both operands have non-array, non-numeric types, their -values are converted to type `int` or `float`, as appropriate. Then if -either operand has type `float`, the other is converted to that type, and -the result has type `float`. Otherwise, both operands have type `int`, in -which case, if the resulting value can be represented in type `int` that -is the result type. -Otherwise, the result would have type `float`. +operands, while the binary `-` operator produces the difference of its operands +when subtracting the right-hand operand from the left-hand one. If either or +both operands have non-array, non-numeric types, their values are converted to +type `int` or `float`, as appropriate. If either or both operands were +leading-numeric or non-numeric strings, a non-fatal error MUST be produced for +each. Then if either operand has type `float`, the other is converted to that +type, and the result has type `float`. Otherwise, both operands have type +`int`, in which case, if the resulting value can be represented in type `int` +that is the result type. Otherwise, the result would have type `float`. If both operands have array type, the binary `+` operator produces a new array that is the union of the two operands. The result is a copy of the @@ -2226,8 +2232,9 @@ zero bits are shifted on from the right end. Given the expression `e2` positions. Bits shifted off the right end are discarded, and the sign bit is propagated from the left end. -If either operand does not have type `int`, its value is first converted -to that type. +If either operand does not have type `int`, its value is first converted to +that type. If either or both operands were leading-numeric or non-numeric +strings, a non-fatal error MUST be produced for each. The type of the result is `int`, and the value of the result is that after the shifting is complete. The values of `e1` and `e2` are unchanged. @@ -2465,8 +2472,9 @@ Each of the operands must have scalar-compatible type. If either of the operands is an object supporting the operation, the result is defined by that object's semantics, with the left operand checked first. -If either operand does not have type `int`, its value is first converted -to that type. +If either operand does not have type `int`, its value is first converted to +that type. If either or both operands were leading-numeric or non-numeric +strings, a non-fatal error MUST be produced for each. The result of this operator is the bitwise-AND of the two operands, and the type of that result is `int`. @@ -2509,8 +2517,9 @@ Each of the operands must have scalar-compatible type. If either of the operands is an object supporting the operation, the result is defined by that object's semantics, with the left operand checked first. -If either operand does not have type `int`, its value is first converted -to that type. +If either operand does not have type `int`, its value is first converted to +that type. If either or both operands were leading-numeric or non-numeric +strings, a non-fatal error MUST be produced for each. The result of this operator is the bitwise exclusive-OR of the two operands, and the type of that result is `int`. @@ -2555,8 +2564,9 @@ Each of the operands must have scalar-compatible type. If either of the operands is an object supporting the operation, the result is defined by that object's semantics, with the left operand checked first. -If either operand does not have type `int`, its value is first converted -to that type. +If either operand does not have type `int`, its value is first converted to +that type. If either or both operands were leading-numeric or non-numeric +strings, a non-fatal error MUST be produced for each. The result of this operator is the bitwise inclusive-OR of the two operands, and the type of that result is `int`. diff --git a/tests/expressions/assignment_operators/add_assignment.phpt b/tests/expressions/assignment_operators/add_assignment.phpt index 622e9146..bfec7698 100644 --- a/tests/expressions/assignment_operators/add_assignment.phpt +++ b/tests/expressions/assignment_operators/add_assignment.phpt @@ -16,7 +16,7 @@ foreach ($oper as $t) } ?> ---EXPECT-- +--EXPECTF-- >0< += >0<, result: int(0) >0< += >-10<, result: int(-10) >0< += >100<, result: int(100) @@ -29,8 +29,12 @@ foreach ($oper as $t) >0< += ><, result: int(0) >0< += >123<, result: int(123) >0< += >2e+5<, result: float(200000) ->0< += ><, result: int(0) ->0< += >abc<, result: int(0) +>0< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >0< += >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >-10< += >0<, result: int(-10) @@ -45,8 +49,12 @@ foreach ($oper as $t) >-10< += ><, result: int(-10) >-10< += >123<, result: int(113) >-10< += >2e+5<, result: float(199990) ->-10< += ><, result: int(-10) ->-10< += >abc<, result: int(-10) +>-10< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) >-10< += >9223372036854775807<, result: int(9223372036854775797) ------------------------------------- >100< += >0<, result: int(100) @@ -61,8 +69,12 @@ foreach ($oper as $t) >100< += ><, result: int(100) >100< += >123<, result: int(223) >100< += >2e+5<, result: float(200100) ->100< += ><, result: int(100) ->100< += >abc<, result: int(100) +>100< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) >100< += >9223372036854775807<, result: float(9.2233720368548E+18) ------------------------------------- >-34000000000< += >0<, result: float(-34000000000) @@ -77,8 +89,12 @@ foreach ($oper as $t) >-34000000000< += ><, result: float(-34000000000) >-34000000000< += >123<, result: float(-33999999877) >-34000000000< += >2e+5<, result: float(-33999800000) ->-34000000000< += ><, result: float(-34000000000) ->-34000000000< += >abc<, result: float(-34000000000) +>-34000000000< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(-34000000000) +>-34000000000< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-34000000000) >-34000000000< += >9223372036854775807<, result: float(9.2233720028548E+18) ------------------------------------- >INF< += >0<, result: float(INF) @@ -93,8 +109,12 @@ foreach ($oper as $t) >INF< += ><, result: float(INF) >INF< += >123<, result: float(INF) >INF< += >2e+5<, result: float(INF) ->INF< += ><, result: float(INF) ->INF< += >abc<, result: float(INF) +>INF< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>INF< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) >INF< += >9223372036854775807<, result: float(INF) ------------------------------------- >-INF< += >0<, result: float(-INF) @@ -109,8 +129,12 @@ foreach ($oper as $t) >-INF< += ><, result: float(-INF) >-INF< += >123<, result: float(-INF) >-INF< += >2e+5<, result: float(-INF) ->-INF< += ><, result: float(-INF) ->-INF< += >abc<, result: float(-INF) +>-INF< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>-INF< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) >-INF< += >9223372036854775807<, result: float(-INF) ------------------------------------- >NAN< += >0<, result: float(NAN) @@ -125,8 +149,12 @@ foreach ($oper as $t) >NAN< += ><, result: float(NAN) >NAN< += >123<, result: float(NAN) >NAN< += >2e+5<, result: float(NAN) ->NAN< += ><, result: float(NAN) ->NAN< += >abc<, result: float(NAN) +>NAN< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>NAN< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) >NAN< += >9223372036854775807<, result: float(NAN) ------------------------------------- >1< += >0<, result: int(1) @@ -141,8 +169,12 @@ foreach ($oper as $t) >1< += ><, result: int(1) >1< += >123<, result: int(124) >1< += >2e+5<, result: float(200001) ->1< += ><, result: int(1) ->1< += >abc<, result: int(1) +>1< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) >1< += >9223372036854775807<, result: float(9.2233720368548E+18) ------------------------------------- >< += >0<, result: int(0) @@ -157,8 +189,12 @@ foreach ($oper as $t) >< += ><, result: int(0) >< += >123<, result: int(123) >< += >2e+5<, result: float(200000) ->< += ><, result: int(0) ->< += >abc<, result: int(0) +>< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< += >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >< += >0<, result: int(0) @@ -173,8 +209,12 @@ foreach ($oper as $t) >< += ><, result: int(0) >< += >123<, result: int(123) >< += >2e+5<, result: float(200000) ->< += ><, result: int(0) ->< += >abc<, result: int(0) +>< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< += >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >123< += >0<, result: int(123) @@ -189,8 +229,12 @@ foreach ($oper as $t) >123< += ><, result: int(123) >123< += >123<, result: int(246) >123< += >2e+5<, result: float(200123) ->123< += ><, result: int(123) ->123< += >abc<, result: int(123) +>123< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) >123< += >9223372036854775807<, result: float(9.2233720368548E+18) ------------------------------------- >2e+5< += >0<, result: float(200000) @@ -205,41 +249,113 @@ foreach ($oper as $t) >2e+5< += ><, result: float(200000) >2e+5< += >123<, result: float(200123) >2e+5< += >2e+5<, result: float(400000) ->2e+5< += ><, result: float(200000) ->2e+5< += >abc<, result: float(200000) +>2e+5< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(200000) +>2e+5< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(200000) >2e+5< += >9223372036854775807<, result: float(9.223372036855E+18) ------------------------------------- ->< += >0<, result: int(0) ->< += >-10<, result: int(-10) ->< += >100<, result: int(100) ->< += >-34000000000<, result: float(-34000000000) ->< += >INF<, result: float(INF) ->< += >-INF<, result: float(-INF) ->< += >NAN<, result: float(NAN) ->< += >1<, result: int(1) ->< += ><, result: int(0) ->< += ><, result: int(0) ->< += >123<, result: int(123) ->< += >2e+5<, result: float(200000) ->< += ><, result: int(0) ->< += >abc<, result: int(0) ->< += >9223372036854775807<, result: int(9223372036854775807) +>< += >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>< += >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>< += >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-34000000000) +>< += >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>< += >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>< += >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< += >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>< += >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(200000) +>< += ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< += >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) ------------------------------------- ->abc< += >0<, result: int(0) ->abc< += >-10<, result: int(-10) ->abc< += >100<, result: int(100) ->abc< += >-34000000000<, result: float(-34000000000) ->abc< += >INF<, result: float(INF) ->abc< += >-INF<, result: float(-INF) ->abc< += >NAN<, result: float(NAN) ->abc< += >1<, result: int(1) ->abc< += ><, result: int(0) ->abc< += ><, result: int(0) ->abc< += >123<, result: int(123) ->abc< += >2e+5<, result: float(200000) ->abc< += ><, result: int(0) ->abc< += >abc<, result: int(0) ->abc< += >9223372036854775807<, result: int(9223372036854775807) +>abc< += >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< += >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>abc< += >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>abc< += >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-34000000000) +>abc< += >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>abc< += >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>abc< += >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< += >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>abc< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< += >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>abc< += >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(200000) +>abc< += ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< += >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) ------------------------------------- >9223372036854775807< += >0<, result: int(9223372036854775807) >9223372036854775807< += >-10<, result: int(9223372036854775797) @@ -253,7 +369,11 @@ foreach ($oper as $t) >9223372036854775807< += ><, result: int(9223372036854775807) >9223372036854775807< += >123<, result: float(9.2233720368548E+18) >9223372036854775807< += >2e+5<, result: float(9.223372036855E+18) ->9223372036854775807< += ><, result: int(9223372036854775807) ->9223372036854775807< += >abc<, result: int(9223372036854775807) +>9223372036854775807< += ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< += >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) >9223372036854775807< += >9223372036854775807<, result: float(1.844674407371E+19) -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/assignment_operators/and_assignment.phpt b/tests/expressions/assignment_operators/and_assignment.phpt index 4a8259f5..e32149bb 100644 --- a/tests/expressions/assignment_operators/and_assignment.phpt +++ b/tests/expressions/assignment_operators/and_assignment.phpt @@ -16,7 +16,7 @@ foreach ($oper as $t) } ?> ---EXPECT-- +--EXPECTF-- >0< &= >0<, result: int(0) >0< &= >-10<, result: int(0) >0< &= >100<, result: int(0) @@ -29,8 +29,12 @@ foreach ($oper as $t) >0< &= ><, result: int(0) >0< &= >123<, result: int(0) >0< &= >2e+5<, result: int(0) ->0< &= ><, result: int(0) ->0< &= >abc<, result: int(0) +>0< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >0< &= >9223372036854775807<, result: int(0) ------------------------------------- >-10< &= >0<, result: int(0) @@ -44,9 +48,13 @@ foreach ($oper as $t) >-10< &= ><, result: int(0) >-10< &= ><, result: int(0) >-10< &= >123<, result: int(114) ->-10< &= >2e+5<, result: int(2) ->-10< &= ><, result: int(0) ->-10< &= >abc<, result: int(0) +>-10< &= >2e+5<, result: int(200000) +>-10< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-10< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >-10< &= >9223372036854775807<, result: int(9223372036854775798) ------------------------------------- >100< &= >0<, result: int(0) @@ -60,9 +68,13 @@ foreach ($oper as $t) >100< &= ><, result: int(0) >100< &= ><, result: int(0) >100< &= >123<, result: int(96) ->100< &= >2e+5<, result: int(0) ->100< &= ><, result: int(0) ->100< &= >abc<, result: int(0) +>100< &= >2e+5<, result: int(64) +>100< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>100< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >100< &= >9223372036854775807<, result: int(100) ------------------------------------- >-34000000000< &= >0<, result: int(0) @@ -76,9 +88,13 @@ foreach ($oper as $t) >-34000000000< &= ><, result: int(0) >-34000000000< &= ><, result: int(0) >-34000000000< &= >123<, result: int(0) ->-34000000000< &= >2e+5<, result: int(0) ->-34000000000< &= ><, result: int(0) ->-34000000000< &= >abc<, result: int(0) +>-34000000000< &= >2e+5<, result: int(68608) +>-34000000000< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-34000000000< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >-34000000000< &= >9223372036854775807<, result: int(9223372002854775808) ------------------------------------- >INF< &= >0<, result: int(0) @@ -93,8 +109,12 @@ foreach ($oper as $t) >INF< &= ><, result: int(0) >INF< &= >123<, result: int(0) >INF< &= >2e+5<, result: int(0) ->INF< &= ><, result: int(0) ->INF< &= >abc<, result: int(0) +>INF< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >INF< &= >9223372036854775807<, result: int(0) ------------------------------------- >-INF< &= >0<, result: int(0) @@ -109,8 +129,12 @@ foreach ($oper as $t) >-INF< &= ><, result: int(0) >-INF< &= >123<, result: int(0) >-INF< &= >2e+5<, result: int(0) ->-INF< &= ><, result: int(0) ->-INF< &= >abc<, result: int(0) +>-INF< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >-INF< &= >9223372036854775807<, result: int(0) ------------------------------------- >NAN< &= >0<, result: int(0) @@ -125,8 +149,12 @@ foreach ($oper as $t) >NAN< &= ><, result: int(0) >NAN< &= >123<, result: int(0) >NAN< &= >2e+5<, result: int(0) ->NAN< &= ><, result: int(0) ->NAN< &= >abc<, result: int(0) +>NAN< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >NAN< &= >9223372036854775807<, result: int(0) ------------------------------------- >1< &= >0<, result: int(0) @@ -141,8 +169,12 @@ foreach ($oper as $t) >1< &= ><, result: int(0) >1< &= >123<, result: int(1) >1< &= >2e+5<, result: int(0) ->1< &= ><, result: int(0) ->1< &= >abc<, result: int(0) +>1< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>1< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >1< &= >9223372036854775807<, result: int(1) ------------------------------------- >< &= >0<, result: int(0) @@ -157,8 +189,12 @@ foreach ($oper as $t) >< &= ><, result: int(0) >< &= >123<, result: int(0) >< &= >2e+5<, result: int(0) ->< &= ><, result: int(0) ->< &= >abc<, result: int(0) +>< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< &= >9223372036854775807<, result: int(0) ------------------------------------- >< &= >0<, result: int(0) @@ -173,8 +209,12 @@ foreach ($oper as $t) >< &= ><, result: int(0) >< &= >123<, result: int(0) >< &= >2e+5<, result: int(0) ->< &= ><, result: int(0) ->< &= >abc<, result: int(0) +>< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< &= >9223372036854775807<, result: int(0) ------------------------------------- >123< &= >0<, result: int(0) @@ -194,9 +234,9 @@ foreach ($oper as $t) >123< &= >9223372036854775807<, result: int(123) ------------------------------------- >2e+5< &= >0<, result: int(0) ->2e+5< &= >-10<, result: int(2) ->2e+5< &= >100<, result: int(0) ->2e+5< &= >-34000000000<, result: int(0) +>2e+5< &= >-10<, result: int(200000) +>2e+5< &= >100<, result: int(64) +>2e+5< &= >-34000000000<, result: int(68608) >2e+5< &= >INF<, result: int(0) >2e+5< &= >-INF<, result: int(0) >2e+5< &= >NAN<, result: int(0) @@ -207,39 +247,83 @@ foreach ($oper as $t) >2e+5< &= >2e+5<, result: string(4) "2e+5" >2e+5< &= ><, result: string(0) "" >2e+5< &= >abc<, result: string(3) " `#" ->2e+5< &= >9223372036854775807<, result: int(2) +>2e+5< &= >9223372036854775807<, result: int(200000) ------------------------------------- ->< &= >0<, result: int(0) ->< &= >-10<, result: int(0) ->< &= >100<, result: int(0) ->< &= >-34000000000<, result: int(0) ->< &= >INF<, result: int(0) ->< &= >-INF<, result: int(0) ->< &= >NAN<, result: int(0) ->< &= >1<, result: int(0) ->< &= ><, result: int(0) ->< &= ><, result: int(0) +>< &= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< &= >123<, result: string(0) "" >< &= >2e+5<, result: string(0) "" >< &= ><, result: string(0) "" >< &= >abc<, result: string(0) "" ->< &= >9223372036854775807<, result: int(0) +>< &= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- ->abc< &= >0<, result: int(0) ->abc< &= >-10<, result: int(0) ->abc< &= >100<, result: int(0) ->abc< &= >-34000000000<, result: int(0) ->abc< &= >INF<, result: int(0) ->abc< &= >-INF<, result: int(0) ->abc< &= >NAN<, result: int(0) ->abc< &= >1<, result: int(0) ->abc< &= ><, result: int(0) ->abc< &= ><, result: int(0) +>abc< &= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >abc< &= >123<, result: string(3) "!"#" >abc< &= >2e+5<, result: string(3) " `#" >abc< &= ><, result: string(0) "" >abc< &= >abc<, result: string(3) "abc" ->abc< &= >9223372036854775807<, result: int(0) +>abc< &= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- >9223372036854775807< &= >0<, result: int(0) >9223372036854775807< &= >-10<, result: int(9223372036854775798) @@ -252,8 +336,12 @@ foreach ($oper as $t) >9223372036854775807< &= ><, result: int(0) >9223372036854775807< &= ><, result: int(0) >9223372036854775807< &= >123<, result: int(123) ->9223372036854775807< &= >2e+5<, result: int(2) ->9223372036854775807< &= ><, result: int(0) ->9223372036854775807< &= >abc<, result: int(0) +>9223372036854775807< &= >2e+5<, result: int(200000) +>9223372036854775807< &= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>9223372036854775807< &= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >9223372036854775807< &= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/assignment_operators/div_assignment.phpt b/tests/expressions/assignment_operators/div_assignment.phpt index baa6471b..ddb2c315 100644 --- a/tests/expressions/assignment_operators/div_assignment.phpt +++ b/tests/expressions/assignment_operators/div_assignment.phpt @@ -18,7 +18,7 @@ foreach ($oper as $t) } ?> ---EXPECT-- +--EXPECTF-- >0< /= >-10<, result: int(0) >0< /= >100<, result: int(0) >0< /= >-34000000000<, result: float(-0) @@ -151,27 +151,67 @@ foreach ($oper as $t) >2e+5< /= >2e+5<, result: float(1) >2e+5< /= >9223372036854775807<, result: float(2.168404344971E-14) ------------------------------------- ->< /= >-10<, result: int(0) ->< /= >100<, result: int(0) ->< /= >-34000000000<, result: float(-0) ->< /= >INF<, result: float(0) ->< /= >-INF<, result: float(-0) ->< /= >NAN<, result: float(NAN) ->< /= >1<, result: int(0) ->< /= >123<, result: int(0) ->< /= >2e+5<, result: float(0) ->< /= >9223372036854775807<, result: int(0) +>< /= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< /= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< /= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>< /= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>< /= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>< /= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< /= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< /= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< /= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>< /= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- ->abc< /= >-10<, result: int(0) ->abc< /= >100<, result: int(0) ->abc< /= >-34000000000<, result: float(-0) ->abc< /= >INF<, result: float(0) ->abc< /= >-INF<, result: float(-0) ->abc< /= >NAN<, result: float(NAN) ->abc< /= >1<, result: int(0) ->abc< /= >123<, result: int(0) ->abc< /= >2e+5<, result: float(0) ->abc< /= >9223372036854775807<, result: int(0) +>abc< /= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< /= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< /= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>abc< /= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>abc< /= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>abc< /= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< /= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< /= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< /= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>abc< /= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- >9223372036854775807< /= >-10<, result: float(-9.2233720368548E+17) >9223372036854775807< /= >100<, result: float(9.2233720368548E+16) @@ -183,4 +223,4 @@ foreach ($oper as $t) >9223372036854775807< /= >123<, result: float(7.4986764527275E+16) >9223372036854775807< /= >2e+5<, result: float(46116860184274) >9223372036854775807< /= >9223372036854775807<, result: int(1) -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/assignment_operators/mod_assignment.phpt b/tests/expressions/assignment_operators/mod_assignment.phpt index 87681300..252fdbb2 100644 --- a/tests/expressions/assignment_operators/mod_assignment.phpt +++ b/tests/expressions/assignment_operators/mod_assignment.phpt @@ -1,5 +1,5 @@ --TEST-- -/= operator +%= operator --FILE-- ---EXPECT-- +--EXPECTF-- >0< %= >-10<, result: int(0) >0< %= >100<, result: int(0) >0< %= >-34000000000<, result: int(0) @@ -32,7 +32,7 @@ foreach ($oper as $t) >-10< %= >-34000000000<, result: int(-10) >-10< %= >1<, result: int(0) >-10< %= >123<, result: int(-10) ->-10< %= >2e+5<, result: int(0) +>-10< %= >2e+5<, result: int(-10) >-10< %= >9223372036854775807<, result: int(-10) ------------------------------------- >100< %= >-10<, result: int(0) @@ -40,7 +40,7 @@ foreach ($oper as $t) >100< %= >-34000000000<, result: int(100) >100< %= >1<, result: int(0) >100< %= >123<, result: int(100) ->100< %= >2e+5<, result: int(0) +>100< %= >2e+5<, result: int(100) >100< %= >9223372036854775807<, result: int(100) ------------------------------------- >-34000000000< %= >-10<, result: int(0) @@ -104,38 +104,66 @@ foreach ($oper as $t) >123< %= >-34000000000<, result: int(123) >123< %= >1<, result: int(0) >123< %= >123<, result: int(0) ->123< %= >2e+5<, result: int(1) +>123< %= >2e+5<, result: int(123) >123< %= >9223372036854775807<, result: int(123) ------------------------------------- ->2e+5< %= >-10<, result: int(2) ->2e+5< %= >100<, result: int(2) ->2e+5< %= >-34000000000<, result: int(2) +>2e+5< %= >-10<, result: int(0) +>2e+5< %= >100<, result: int(0) +>2e+5< %= >-34000000000<, result: int(200000) >2e+5< %= >1<, result: int(0) >2e+5< %= >123<, result: int(2) >2e+5< %= >2e+5<, result: int(0) ->2e+5< %= >9223372036854775807<, result: int(2) +>2e+5< %= >9223372036854775807<, result: int(200000) ------------------------------------- ->< %= >-10<, result: int(0) ->< %= >100<, result: int(0) ->< %= >-34000000000<, result: int(0) ->< %= >1<, result: int(0) ->< %= >123<, result: int(0) ->< %= >2e+5<, result: int(0) ->< %= >9223372036854775807<, result: int(0) +>< %= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< %= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< %= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< %= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< %= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< %= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< %= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- ->abc< %= >-10<, result: int(0) ->abc< %= >100<, result: int(0) ->abc< %= >-34000000000<, result: int(0) ->abc< %= >1<, result: int(0) ->abc< %= >123<, result: int(0) ->abc< %= >2e+5<, result: int(0) ->abc< %= >9223372036854775807<, result: int(0) +>abc< %= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< %= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< %= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< %= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< %= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< %= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< %= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- >9223372036854775807< %= >-10<, result: int(7) >9223372036854775807< %= >100<, result: int(7) >9223372036854775807< %= >-34000000000<, result: int(4854775807) >9223372036854775807< %= >1<, result: int(0) >9223372036854775807< %= >123<, result: int(7) ->9223372036854775807< %= >2e+5<, result: int(1) +>9223372036854775807< %= >2e+5<, result: int(175807) >9223372036854775807< %= >9223372036854775807<, result: int(0) -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/assignment_operators/mul_assignment.phpt b/tests/expressions/assignment_operators/mul_assignment.phpt index 833066de..ab33ab36 100644 --- a/tests/expressions/assignment_operators/mul_assignment.phpt +++ b/tests/expressions/assignment_operators/mul_assignment.phpt @@ -16,7 +16,7 @@ foreach ($oper as $t) } ?> ---EXPECT-- +--EXPECTF-- >0< *= >0<, result: int(0) >0< *= >-10<, result: int(0) >0< *= >100<, result: int(0) @@ -29,8 +29,12 @@ foreach ($oper as $t) >0< *= ><, result: int(0) >0< *= >123<, result: int(0) >0< *= >2e+5<, result: float(0) ->0< *= ><, result: int(0) ->0< *= >abc<, result: int(0) +>0< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >0< *= >9223372036854775807<, result: int(0) ------------------------------------- >-10< *= >0<, result: int(0) @@ -45,8 +49,12 @@ foreach ($oper as $t) >-10< *= ><, result: int(0) >-10< *= >123<, result: int(-1230) >-10< *= >2e+5<, result: float(-2000000) ->-10< *= ><, result: int(0) ->-10< *= >abc<, result: int(0) +>-10< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-10< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >-10< *= >9223372036854775807<, result: float(-9.2233720368548E+19) ------------------------------------- >100< *= >0<, result: int(0) @@ -61,8 +69,12 @@ foreach ($oper as $t) >100< *= ><, result: int(0) >100< *= >123<, result: int(12300) >100< *= >2e+5<, result: float(20000000) ->100< *= ><, result: int(0) ->100< *= >abc<, result: int(0) +>100< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>100< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >100< *= >9223372036854775807<, result: float(9.2233720368548E+20) ------------------------------------- >-34000000000< *= >0<, result: float(-0) @@ -77,8 +89,12 @@ foreach ($oper as $t) >-34000000000< *= ><, result: float(-0) >-34000000000< *= >123<, result: float(-4182000000000) >-34000000000< *= >2e+5<, result: float(-6.8E+15) ->-34000000000< *= ><, result: float(-0) ->-34000000000< *= >abc<, result: float(-0) +>-34000000000< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>-34000000000< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) >-34000000000< *= >9223372036854775807<, result: float(-3.1359464925306E+29) ------------------------------------- >INF< *= >0<, result: float(NAN) @@ -93,8 +109,12 @@ foreach ($oper as $t) >INF< *= ><, result: float(NAN) >INF< *= >123<, result: float(INF) >INF< *= >2e+5<, result: float(INF) ->INF< *= ><, result: float(NAN) ->INF< *= >abc<, result: float(NAN) +>INF< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>INF< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) >INF< *= >9223372036854775807<, result: float(INF) ------------------------------------- >-INF< *= >0<, result: float(NAN) @@ -109,8 +129,12 @@ foreach ($oper as $t) >-INF< *= ><, result: float(NAN) >-INF< *= >123<, result: float(-INF) >-INF< *= >2e+5<, result: float(-INF) ->-INF< *= ><, result: float(NAN) ->-INF< *= >abc<, result: float(NAN) +>-INF< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>-INF< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) >-INF< *= >9223372036854775807<, result: float(-INF) ------------------------------------- >NAN< *= >0<, result: float(NAN) @@ -125,8 +149,12 @@ foreach ($oper as $t) >NAN< *= ><, result: float(NAN) >NAN< *= >123<, result: float(NAN) >NAN< *= >2e+5<, result: float(NAN) ->NAN< *= ><, result: float(NAN) ->NAN< *= >abc<, result: float(NAN) +>NAN< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>NAN< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) >NAN< *= >9223372036854775807<, result: float(NAN) ------------------------------------- >1< *= >0<, result: int(0) @@ -141,8 +169,12 @@ foreach ($oper as $t) >1< *= ><, result: int(0) >1< *= >123<, result: int(123) >1< *= >2e+5<, result: float(200000) ->1< *= ><, result: int(0) ->1< *= >abc<, result: int(0) +>1< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>1< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >1< *= >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >< *= >0<, result: int(0) @@ -157,8 +189,12 @@ foreach ($oper as $t) >< *= ><, result: int(0) >< *= >123<, result: int(0) >< *= >2e+5<, result: float(0) ->< *= ><, result: int(0) ->< *= >abc<, result: int(0) +>< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< *= >9223372036854775807<, result: int(0) ------------------------------------- >< *= >0<, result: int(0) @@ -173,8 +209,12 @@ foreach ($oper as $t) >< *= ><, result: int(0) >< *= >123<, result: int(0) >< *= >2e+5<, result: float(0) ->< *= ><, result: int(0) ->< *= >abc<, result: int(0) +>< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< *= >9223372036854775807<, result: int(0) ------------------------------------- >123< *= >0<, result: int(0) @@ -189,8 +229,12 @@ foreach ($oper as $t) >123< *= ><, result: int(0) >123< *= >123<, result: int(15129) >123< *= >2e+5<, result: float(24600000) ->123< *= ><, result: int(0) ->123< *= >abc<, result: int(0) +>123< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>123< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >123< *= >9223372036854775807<, result: float(1.1344747605331E+21) ------------------------------------- >2e+5< *= >0<, result: float(0) @@ -205,41 +249,113 @@ foreach ($oper as $t) >2e+5< *= ><, result: float(0) >2e+5< *= >123<, result: float(24600000) >2e+5< *= >2e+5<, result: float(40000000000) ->2e+5< *= ><, result: float(0) ->2e+5< *= >abc<, result: float(0) +>2e+5< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>2e+5< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) >2e+5< *= >9223372036854775807<, result: float(1.844674407371E+24) ------------------------------------- ->< *= >0<, result: int(0) ->< *= >-10<, result: int(0) ->< *= >100<, result: int(0) ->< *= >-34000000000<, result: float(-0) ->< *= >INF<, result: float(NAN) ->< *= >-INF<, result: float(NAN) ->< *= >NAN<, result: float(NAN) ->< *= >1<, result: int(0) ->< *= ><, result: int(0) ->< *= ><, result: int(0) ->< *= >123<, result: int(0) ->< *= >2e+5<, result: float(0) ->< *= ><, result: int(0) ->< *= >abc<, result: int(0) ->< *= >9223372036854775807<, result: int(0) +>< *= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>< *= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< *= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< *= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< *= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< *= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- ->abc< *= >0<, result: int(0) ->abc< *= >-10<, result: int(0) ->abc< *= >100<, result: int(0) ->abc< *= >-34000000000<, result: float(-0) ->abc< *= >INF<, result: float(NAN) ->abc< *= >-INF<, result: float(NAN) ->abc< *= >NAN<, result: float(NAN) ->abc< *= >1<, result: int(0) ->abc< *= ><, result: int(0) ->abc< *= ><, result: int(0) ->abc< *= >123<, result: int(0) ->abc< *= >2e+5<, result: float(0) ->abc< *= ><, result: int(0) ->abc< *= >abc<, result: int(0) ->abc< *= >9223372036854775807<, result: int(0) +>abc< *= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>abc< *= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< *= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< *= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< *= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>abc< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< *= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- >9223372036854775807< *= >0<, result: int(0) >9223372036854775807< *= >-10<, result: float(-9.2233720368548E+19) @@ -253,7 +369,11 @@ foreach ($oper as $t) >9223372036854775807< *= ><, result: int(0) >9223372036854775807< *= >123<, result: float(1.1344747605331E+21) >9223372036854775807< *= >2e+5<, result: float(1.844674407371E+24) ->9223372036854775807< *= ><, result: int(0) ->9223372036854775807< *= >abc<, result: int(0) +>9223372036854775807< *= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>9223372036854775807< *= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >9223372036854775807< *= >9223372036854775807<, result: float(8.5070591730235E+37) -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/assignment_operators/or_assignment.phpt b/tests/expressions/assignment_operators/or_assignment.phpt index 7479d823..06eebc63 100644 --- a/tests/expressions/assignment_operators/or_assignment.phpt +++ b/tests/expressions/assignment_operators/or_assignment.phpt @@ -16,7 +16,7 @@ foreach ($oper as $t) } ?> ---EXPECT-- +--EXPECTF-- >0< |= >0<, result: int(0) >0< |= >-10<, result: int(-10) >0< |= >100<, result: int(100) @@ -28,9 +28,13 @@ foreach ($oper as $t) >0< |= ><, result: int(0) >0< |= ><, result: int(0) >0< |= >123<, result: int(123) ->0< |= >2e+5<, result: int(2) ->0< |= ><, result: int(0) ->0< |= >abc<, result: int(0) +>0< |= >2e+5<, result: int(200000) +>0< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >0< |= >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >-10< |= >0<, result: int(-10) @@ -45,8 +49,12 @@ foreach ($oper as $t) >-10< |= ><, result: int(-10) >-10< |= >123<, result: int(-1) >-10< |= >2e+5<, result: int(-10) ->-10< |= ><, result: int(-10) ->-10< |= >abc<, result: int(-10) +>-10< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) >-10< |= >9223372036854775807<, result: int(-1) ------------------------------------- >100< |= >0<, result: int(100) @@ -60,9 +68,13 @@ foreach ($oper as $t) >100< |= ><, result: int(100) >100< |= ><, result: int(100) >100< |= >123<, result: int(127) ->100< |= >2e+5<, result: int(102) ->100< |= ><, result: int(100) ->100< |= >abc<, result: int(100) +>100< |= >2e+5<, result: int(200036) +>100< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) >100< |= >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >-34000000000< |= >0<, result: int(-34000000000) @@ -76,9 +88,13 @@ foreach ($oper as $t) >-34000000000< |= ><, result: int(-34000000000) >-34000000000< |= ><, result: int(-34000000000) >-34000000000< |= >123<, result: int(-33999999877) ->-34000000000< |= >2e+5<, result: int(-33999999998) ->-34000000000< |= ><, result: int(-34000000000) ->-34000000000< |= >abc<, result: int(-34000000000) +>-34000000000< |= >2e+5<, result: int(-33999868608) +>-34000000000< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>-34000000000< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) >-34000000000< |= >9223372036854775807<, result: int(-1) ------------------------------------- >INF< |= >0<, result: int(0) @@ -92,9 +108,13 @@ foreach ($oper as $t) >INF< |= ><, result: int(0) >INF< |= ><, result: int(0) >INF< |= >123<, result: int(123) ->INF< |= >2e+5<, result: int(2) ->INF< |= ><, result: int(0) ->INF< |= >abc<, result: int(0) +>INF< |= >2e+5<, result: int(200000) +>INF< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >INF< |= >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >-INF< |= >0<, result: int(0) @@ -108,9 +128,13 @@ foreach ($oper as $t) >-INF< |= ><, result: int(0) >-INF< |= ><, result: int(0) >-INF< |= >123<, result: int(123) ->-INF< |= >2e+5<, result: int(2) ->-INF< |= ><, result: int(0) ->-INF< |= >abc<, result: int(0) +>-INF< |= >2e+5<, result: int(200000) +>-INF< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >-INF< |= >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >NAN< |= >0<, result: int(0) @@ -124,9 +148,13 @@ foreach ($oper as $t) >NAN< |= ><, result: int(0) >NAN< |= ><, result: int(0) >NAN< |= >123<, result: int(123) ->NAN< |= >2e+5<, result: int(2) ->NAN< |= ><, result: int(0) ->NAN< |= >abc<, result: int(0) +>NAN< |= >2e+5<, result: int(200000) +>NAN< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >NAN< |= >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >1< |= >0<, result: int(1) @@ -140,9 +168,13 @@ foreach ($oper as $t) >1< |= ><, result: int(1) >1< |= ><, result: int(1) >1< |= >123<, result: int(123) ->1< |= >2e+5<, result: int(3) ->1< |= ><, result: int(1) ->1< |= >abc<, result: int(1) +>1< |= >2e+5<, result: int(200001) +>1< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) >1< |= >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >< |= >0<, result: int(0) @@ -156,9 +188,13 @@ foreach ($oper as $t) >< |= ><, result: int(0) >< |= ><, result: int(0) >< |= >123<, result: int(123) ->< |= >2e+5<, result: int(2) ->< |= ><, result: int(0) ->< |= >abc<, result: int(0) +>< |= >2e+5<, result: int(200000) +>< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< |= >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >< |= >0<, result: int(0) @@ -172,9 +208,13 @@ foreach ($oper as $t) >< |= ><, result: int(0) >< |= ><, result: int(0) >< |= >123<, result: int(123) ->< |= >2e+5<, result: int(2) ->< |= ><, result: int(0) ->< |= >abc<, result: int(0) +>< |= >2e+5<, result: int(200000) +>< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< |= >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >123< |= >0<, result: int(123) @@ -193,53 +233,97 @@ foreach ($oper as $t) >123< |= >abc<, result: string(3) "qrs" >123< |= >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- ->2e+5< |= >0<, result: int(2) +>2e+5< |= >0<, result: int(200000) >2e+5< |= >-10<, result: int(-10) ->2e+5< |= >100<, result: int(102) ->2e+5< |= >-34000000000<, result: int(-33999999998) ->2e+5< |= >INF<, result: int(2) ->2e+5< |= >-INF<, result: int(2) ->2e+5< |= >NAN<, result: int(2) ->2e+5< |= >1<, result: int(3) ->2e+5< |= ><, result: int(2) ->2e+5< |= ><, result: int(2) +>2e+5< |= >100<, result: int(200036) +>2e+5< |= >-34000000000<, result: int(-33999868608) +>2e+5< |= >INF<, result: int(200000) +>2e+5< |= >-INF<, result: int(200000) +>2e+5< |= >NAN<, result: int(200000) +>2e+5< |= >1<, result: int(200001) +>2e+5< |= ><, result: int(200000) +>2e+5< |= ><, result: int(200000) >2e+5< |= >123<, result: string(4) "3w;5" >2e+5< |= >2e+5<, result: string(4) "2e+5" >2e+5< |= ><, result: string(4) "2e+5" >2e+5< |= >abc<, result: string(4) "sgk5" >2e+5< |= >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- ->< |= >0<, result: int(0) ->< |= >-10<, result: int(-10) ->< |= >100<, result: int(100) ->< |= >-34000000000<, result: int(-34000000000) ->< |= >INF<, result: int(0) ->< |= >-INF<, result: int(0) ->< |= >NAN<, result: int(0) ->< |= >1<, result: int(1) ->< |= ><, result: int(0) ->< |= ><, result: int(0) +>< |= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>< |= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>< |= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>< |= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< |= >123<, result: string(3) "123" >< |= >2e+5<, result: string(4) "2e+5" >< |= ><, result: string(0) "" >< |= >abc<, result: string(3) "abc" ->< |= >9223372036854775807<, result: int(9223372036854775807) +>< |= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) ------------------------------------- ->abc< |= >0<, result: int(0) ->abc< |= >-10<, result: int(-10) ->abc< |= >100<, result: int(100) ->abc< |= >-34000000000<, result: int(-34000000000) ->abc< |= >INF<, result: int(0) ->abc< |= >-INF<, result: int(0) ->abc< |= >NAN<, result: int(0) ->abc< |= >1<, result: int(1) ->abc< |= ><, result: int(0) ->abc< |= ><, result: int(0) +>abc< |= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< |= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>abc< |= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>abc< |= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>abc< |= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< |= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< |= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< |= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>abc< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >abc< |= >123<, result: string(3) "qrs" >abc< |= >2e+5<, result: string(4) "sgk5" >abc< |= ><, result: string(3) "abc" >abc< |= >abc<, result: string(3) "abc" ->abc< |= >9223372036854775807<, result: int(9223372036854775807) +>abc< |= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) ------------------------------------- >9223372036854775807< |= >0<, result: int(9223372036854775807) >9223372036854775807< |= >-10<, result: int(-1) @@ -253,7 +337,11 @@ foreach ($oper as $t) >9223372036854775807< |= ><, result: int(9223372036854775807) >9223372036854775807< |= >123<, result: int(9223372036854775807) >9223372036854775807< |= >2e+5<, result: int(9223372036854775807) ->9223372036854775807< |= ><, result: int(9223372036854775807) ->9223372036854775807< |= >abc<, result: int(9223372036854775807) +>9223372036854775807< |= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< |= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) >9223372036854775807< |= >9223372036854775807<, result: int(9223372036854775807) -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/assignment_operators/sl_assignment.phpt b/tests/expressions/assignment_operators/sl_assignment.phpt index 69cb1017..2d6fc1ae 100644 --- a/tests/expressions/assignment_operators/sl_assignment.phpt +++ b/tests/expressions/assignment_operators/sl_assignment.phpt @@ -18,7 +18,7 @@ foreach ($oper as $t) } ?> ---EXPECT-- +--EXPECTF-- >0< <<= >0<, result: int(0) >0< <<= >100<, result: int(0) >0< <<= >INF<, result: int(0) @@ -29,8 +29,12 @@ foreach ($oper as $t) >0< <<= ><, result: int(0) >0< <<= >123<, result: int(0) >0< <<= >2e+5<, result: int(0) ->0< <<= ><, result: int(0) ->0< <<= >abc<, result: int(0) +>0< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >0< <<= >9223372036854775807<, result: int(0) ------------------------------------- >-10< <<= >0<, result: int(-10) @@ -42,9 +46,13 @@ foreach ($oper as $t) >-10< <<= ><, result: int(-10) >-10< <<= ><, result: int(-10) >-10< <<= >123<, result: int(0) ->-10< <<= >2e+5<, result: int(-40) ->-10< <<= ><, result: int(-10) ->-10< <<= >abc<, result: int(-10) +>-10< <<= >2e+5<, result: int(0) +>-10< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) >-10< <<= >9223372036854775807<, result: int(0) ------------------------------------- >100< <<= >0<, result: int(100) @@ -56,9 +64,13 @@ foreach ($oper as $t) >100< <<= ><, result: int(100) >100< <<= ><, result: int(100) >100< <<= >123<, result: int(0) ->100< <<= >2e+5<, result: int(400) ->100< <<= ><, result: int(100) ->100< <<= >abc<, result: int(100) +>100< <<= >2e+5<, result: int(0) +>100< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) >100< <<= >9223372036854775807<, result: int(0) ------------------------------------- >-34000000000< <<= >0<, result: int(-34000000000) @@ -70,9 +82,13 @@ foreach ($oper as $t) >-34000000000< <<= ><, result: int(-34000000000) >-34000000000< <<= ><, result: int(-34000000000) >-34000000000< <<= >123<, result: int(0) ->-34000000000< <<= >2e+5<, result: int(-136000000000) ->-34000000000< <<= ><, result: int(-34000000000) ->-34000000000< <<= >abc<, result: int(-34000000000) +>-34000000000< <<= >2e+5<, result: int(0) +>-34000000000< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>-34000000000< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) >-34000000000< <<= >9223372036854775807<, result: int(0) ------------------------------------- >INF< <<= >0<, result: int(0) @@ -85,8 +101,12 @@ foreach ($oper as $t) >INF< <<= ><, result: int(0) >INF< <<= >123<, result: int(0) >INF< <<= >2e+5<, result: int(0) ->INF< <<= ><, result: int(0) ->INF< <<= >abc<, result: int(0) +>INF< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >INF< <<= >9223372036854775807<, result: int(0) ------------------------------------- >-INF< <<= >0<, result: int(0) @@ -99,8 +119,12 @@ foreach ($oper as $t) >-INF< <<= ><, result: int(0) >-INF< <<= >123<, result: int(0) >-INF< <<= >2e+5<, result: int(0) ->-INF< <<= ><, result: int(0) ->-INF< <<= >abc<, result: int(0) +>-INF< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >-INF< <<= >9223372036854775807<, result: int(0) ------------------------------------- >NAN< <<= >0<, result: int(0) @@ -113,8 +137,12 @@ foreach ($oper as $t) >NAN< <<= ><, result: int(0) >NAN< <<= >123<, result: int(0) >NAN< <<= >2e+5<, result: int(0) ->NAN< <<= ><, result: int(0) ->NAN< <<= >abc<, result: int(0) +>NAN< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >NAN< <<= >9223372036854775807<, result: int(0) ------------------------------------- >1< <<= >0<, result: int(1) @@ -126,9 +154,13 @@ foreach ($oper as $t) >1< <<= ><, result: int(1) >1< <<= ><, result: int(1) >1< <<= >123<, result: int(0) ->1< <<= >2e+5<, result: int(4) ->1< <<= ><, result: int(1) ->1< <<= >abc<, result: int(1) +>1< <<= >2e+5<, result: int(0) +>1< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) >1< <<= >9223372036854775807<, result: int(0) ------------------------------------- >< <<= >0<, result: int(0) @@ -141,8 +173,12 @@ foreach ($oper as $t) >< <<= ><, result: int(0) >< <<= >123<, result: int(0) >< <<= >2e+5<, result: int(0) ->< <<= ><, result: int(0) ->< <<= >abc<, result: int(0) +>< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< <<= >9223372036854775807<, result: int(0) ------------------------------------- >< <<= >0<, result: int(0) @@ -155,8 +191,12 @@ foreach ($oper as $t) >< <<= ><, result: int(0) >< <<= >123<, result: int(0) >< <<= >2e+5<, result: int(0) ->< <<= ><, result: int(0) ->< <<= >abc<, result: int(0) +>< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< <<= >9223372036854775807<, result: int(0) ------------------------------------- >123< <<= >0<, result: int(123) @@ -168,52 +208,120 @@ foreach ($oper as $t) >123< <<= ><, result: int(123) >123< <<= ><, result: int(123) >123< <<= >123<, result: int(0) ->123< <<= >2e+5<, result: int(492) ->123< <<= ><, result: int(123) ->123< <<= >abc<, result: int(123) +>123< <<= >2e+5<, result: int(0) +>123< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) >123< <<= >9223372036854775807<, result: int(0) ------------------------------------- ->2e+5< <<= >0<, result: int(2) +>2e+5< <<= >0<, result: int(200000) >2e+5< <<= >100<, result: int(0) ->2e+5< <<= >INF<, result: int(2) ->2e+5< <<= >-INF<, result: int(2) ->2e+5< <<= >NAN<, result: int(2) ->2e+5< <<= >1<, result: int(4) ->2e+5< <<= ><, result: int(2) ->2e+5< <<= ><, result: int(2) +>2e+5< <<= >INF<, result: int(200000) +>2e+5< <<= >-INF<, result: int(200000) +>2e+5< <<= >NAN<, result: int(200000) +>2e+5< <<= >1<, result: int(400000) +>2e+5< <<= ><, result: int(200000) +>2e+5< <<= ><, result: int(200000) >2e+5< <<= >123<, result: int(0) ->2e+5< <<= >2e+5<, result: int(8) ->2e+5< <<= ><, result: int(2) ->2e+5< <<= >abc<, result: int(2) +>2e+5< <<= >2e+5<, result: int(0) +>2e+5< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(200000) +>2e+5< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(200000) >2e+5< <<= >9223372036854775807<, result: int(0) ------------------------------------- ->< <<= >0<, result: int(0) ->< <<= >100<, result: int(0) ->< <<= >INF<, result: int(0) ->< <<= >-INF<, result: int(0) ->< <<= >NAN<, result: int(0) ->< <<= >1<, result: int(0) ->< <<= ><, result: int(0) ->< <<= ><, result: int(0) ->< <<= >123<, result: int(0) ->< <<= >2e+5<, result: int(0) ->< <<= ><, result: int(0) ->< <<= >abc<, result: int(0) ->< <<= >9223372036854775807<, result: int(0) +>< <<= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< <<= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- ->abc< <<= >0<, result: int(0) ->abc< <<= >100<, result: int(0) ->abc< <<= >INF<, result: int(0) ->abc< <<= >-INF<, result: int(0) ->abc< <<= >NAN<, result: int(0) ->abc< <<= >1<, result: int(0) ->abc< <<= ><, result: int(0) ->abc< <<= ><, result: int(0) ->abc< <<= >123<, result: int(0) ->abc< <<= >2e+5<, result: int(0) ->abc< <<= ><, result: int(0) ->abc< <<= >abc<, result: int(0) ->abc< <<= >9223372036854775807<, result: int(0) +>abc< <<= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< <<= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- >9223372036854775807< <<= >0<, result: int(9223372036854775807) >9223372036854775807< <<= >100<, result: int(0) @@ -224,8 +332,12 @@ foreach ($oper as $t) >9223372036854775807< <<= ><, result: int(9223372036854775807) >9223372036854775807< <<= ><, result: int(9223372036854775807) >9223372036854775807< <<= >123<, result: int(0) ->9223372036854775807< <<= >2e+5<, result: int(-4) ->9223372036854775807< <<= ><, result: int(9223372036854775807) ->9223372036854775807< <<= >abc<, result: int(9223372036854775807) +>9223372036854775807< <<= >2e+5<, result: int(0) +>9223372036854775807< <<= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< <<= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) >9223372036854775807< <<= >9223372036854775807<, result: int(0) -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/assignment_operators/sr_assignment.phpt b/tests/expressions/assignment_operators/sr_assignment.phpt index 7d80e7b0..43c08968 100644 --- a/tests/expressions/assignment_operators/sr_assignment.phpt +++ b/tests/expressions/assignment_operators/sr_assignment.phpt @@ -12,220 +12,332 @@ foreach ($oper as $t) if ((int)($e2) < 0) continue; // skip negative shifts $e1 = $t; - echo ">$e1< <<= >$e2<, result: "; var_dump($e1 <<= $e2); + echo ">$e1< >>= >$e2<, result: "; var_dump($e1 <<= $e2); } echo "-------------------------------------\n"; } ?> ---EXPECT-- ->0< <<= >0<, result: int(0) ->0< <<= >100<, result: int(0) ->0< <<= >INF<, result: int(0) ->0< <<= >-INF<, result: int(0) ->0< <<= >NAN<, result: int(0) ->0< <<= >1<, result: int(0) ->0< <<= ><, result: int(0) ->0< <<= ><, result: int(0) ->0< <<= >123<, result: int(0) ->0< <<= >2e+5<, result: int(0) ->0< <<= ><, result: int(0) ->0< <<= >abc<, result: int(0) ->0< <<= >9223372036854775807<, result: int(0) +--EXPECTF-- +>0< >>= >0<, result: int(0) +>0< >>= >100<, result: int(0) +>0< >>= >INF<, result: int(0) +>0< >>= >-INF<, result: int(0) +>0< >>= >NAN<, result: int(0) +>0< >>= >1<, result: int(0) +>0< >>= ><, result: int(0) +>0< >>= ><, result: int(0) +>0< >>= >123<, result: int(0) +>0< >>= >2e+5<, result: int(0) +>0< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->-10< <<= >0<, result: int(-10) ->-10< <<= >100<, result: int(0) ->-10< <<= >INF<, result: int(-10) ->-10< <<= >-INF<, result: int(-10) ->-10< <<= >NAN<, result: int(-10) ->-10< <<= >1<, result: int(-20) ->-10< <<= ><, result: int(-10) ->-10< <<= ><, result: int(-10) ->-10< <<= >123<, result: int(0) ->-10< <<= >2e+5<, result: int(-40) ->-10< <<= ><, result: int(-10) ->-10< <<= >abc<, result: int(-10) ->-10< <<= >9223372036854775807<, result: int(0) +>-10< >>= >0<, result: int(-10) +>-10< >>= >100<, result: int(0) +>-10< >>= >INF<, result: int(-10) +>-10< >>= >-INF<, result: int(-10) +>-10< >>= >NAN<, result: int(-10) +>-10< >>= >1<, result: int(-20) +>-10< >>= ><, result: int(-10) +>-10< >>= ><, result: int(-10) +>-10< >>= >123<, result: int(0) +>-10< >>= >2e+5<, result: int(0) +>-10< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->100< <<= >0<, result: int(100) ->100< <<= >100<, result: int(0) ->100< <<= >INF<, result: int(100) ->100< <<= >-INF<, result: int(100) ->100< <<= >NAN<, result: int(100) ->100< <<= >1<, result: int(200) ->100< <<= ><, result: int(100) ->100< <<= ><, result: int(100) ->100< <<= >123<, result: int(0) ->100< <<= >2e+5<, result: int(400) ->100< <<= ><, result: int(100) ->100< <<= >abc<, result: int(100) ->100< <<= >9223372036854775807<, result: int(0) +>100< >>= >0<, result: int(100) +>100< >>= >100<, result: int(0) +>100< >>= >INF<, result: int(100) +>100< >>= >-INF<, result: int(100) +>100< >>= >NAN<, result: int(100) +>100< >>= >1<, result: int(200) +>100< >>= ><, result: int(100) +>100< >>= ><, result: int(100) +>100< >>= >123<, result: int(0) +>100< >>= >2e+5<, result: int(0) +>100< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->-34000000000< <<= >0<, result: int(-34000000000) ->-34000000000< <<= >100<, result: int(0) ->-34000000000< <<= >INF<, result: int(-34000000000) ->-34000000000< <<= >-INF<, result: int(-34000000000) ->-34000000000< <<= >NAN<, result: int(-34000000000) ->-34000000000< <<= >1<, result: int(-68000000000) ->-34000000000< <<= ><, result: int(-34000000000) ->-34000000000< <<= ><, result: int(-34000000000) ->-34000000000< <<= >123<, result: int(0) ->-34000000000< <<= >2e+5<, result: int(-136000000000) ->-34000000000< <<= ><, result: int(-34000000000) ->-34000000000< <<= >abc<, result: int(-34000000000) ->-34000000000< <<= >9223372036854775807<, result: int(0) +>-34000000000< >>= >0<, result: int(-34000000000) +>-34000000000< >>= >100<, result: int(0) +>-34000000000< >>= >INF<, result: int(-34000000000) +>-34000000000< >>= >-INF<, result: int(-34000000000) +>-34000000000< >>= >NAN<, result: int(-34000000000) +>-34000000000< >>= >1<, result: int(-68000000000) +>-34000000000< >>= ><, result: int(-34000000000) +>-34000000000< >>= ><, result: int(-34000000000) +>-34000000000< >>= >123<, result: int(0) +>-34000000000< >>= >2e+5<, result: int(0) +>-34000000000< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>-34000000000< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-34000000000) +>-34000000000< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->INF< <<= >0<, result: int(0) ->INF< <<= >100<, result: int(0) ->INF< <<= >INF<, result: int(0) ->INF< <<= >-INF<, result: int(0) ->INF< <<= >NAN<, result: int(0) ->INF< <<= >1<, result: int(0) ->INF< <<= ><, result: int(0) ->INF< <<= ><, result: int(0) ->INF< <<= >123<, result: int(0) ->INF< <<= >2e+5<, result: int(0) ->INF< <<= ><, result: int(0) ->INF< <<= >abc<, result: int(0) ->INF< <<= >9223372036854775807<, result: int(0) +>INF< >>= >0<, result: int(0) +>INF< >>= >100<, result: int(0) +>INF< >>= >INF<, result: int(0) +>INF< >>= >-INF<, result: int(0) +>INF< >>= >NAN<, result: int(0) +>INF< >>= >1<, result: int(0) +>INF< >>= ><, result: int(0) +>INF< >>= ><, result: int(0) +>INF< >>= >123<, result: int(0) +>INF< >>= >2e+5<, result: int(0) +>INF< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>INF< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->-INF< <<= >0<, result: int(0) ->-INF< <<= >100<, result: int(0) ->-INF< <<= >INF<, result: int(0) ->-INF< <<= >-INF<, result: int(0) ->-INF< <<= >NAN<, result: int(0) ->-INF< <<= >1<, result: int(0) ->-INF< <<= ><, result: int(0) ->-INF< <<= ><, result: int(0) ->-INF< <<= >123<, result: int(0) ->-INF< <<= >2e+5<, result: int(0) ->-INF< <<= ><, result: int(0) ->-INF< <<= >abc<, result: int(0) ->-INF< <<= >9223372036854775807<, result: int(0) +>-INF< >>= >0<, result: int(0) +>-INF< >>= >100<, result: int(0) +>-INF< >>= >INF<, result: int(0) +>-INF< >>= >-INF<, result: int(0) +>-INF< >>= >NAN<, result: int(0) +>-INF< >>= >1<, result: int(0) +>-INF< >>= ><, result: int(0) +>-INF< >>= ><, result: int(0) +>-INF< >>= >123<, result: int(0) +>-INF< >>= >2e+5<, result: int(0) +>-INF< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-INF< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->NAN< <<= >0<, result: int(0) ->NAN< <<= >100<, result: int(0) ->NAN< <<= >INF<, result: int(0) ->NAN< <<= >-INF<, result: int(0) ->NAN< <<= >NAN<, result: int(0) ->NAN< <<= >1<, result: int(0) ->NAN< <<= ><, result: int(0) ->NAN< <<= ><, result: int(0) ->NAN< <<= >123<, result: int(0) ->NAN< <<= >2e+5<, result: int(0) ->NAN< <<= ><, result: int(0) ->NAN< <<= >abc<, result: int(0) ->NAN< <<= >9223372036854775807<, result: int(0) +>NAN< >>= >0<, result: int(0) +>NAN< >>= >100<, result: int(0) +>NAN< >>= >INF<, result: int(0) +>NAN< >>= >-INF<, result: int(0) +>NAN< >>= >NAN<, result: int(0) +>NAN< >>= >1<, result: int(0) +>NAN< >>= ><, result: int(0) +>NAN< >>= ><, result: int(0) +>NAN< >>= >123<, result: int(0) +>NAN< >>= >2e+5<, result: int(0) +>NAN< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>NAN< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->1< <<= >0<, result: int(1) ->1< <<= >100<, result: int(0) ->1< <<= >INF<, result: int(1) ->1< <<= >-INF<, result: int(1) ->1< <<= >NAN<, result: int(1) ->1< <<= >1<, result: int(2) ->1< <<= ><, result: int(1) ->1< <<= ><, result: int(1) ->1< <<= >123<, result: int(0) ->1< <<= >2e+5<, result: int(4) ->1< <<= ><, result: int(1) ->1< <<= >abc<, result: int(1) ->1< <<= >9223372036854775807<, result: int(0) +>1< >>= >0<, result: int(1) +>1< >>= >100<, result: int(0) +>1< >>= >INF<, result: int(1) +>1< >>= >-INF<, result: int(1) +>1< >>= >NAN<, result: int(1) +>1< >>= >1<, result: int(2) +>1< >>= ><, result: int(1) +>1< >>= ><, result: int(1) +>1< >>= >123<, result: int(0) +>1< >>= >2e+5<, result: int(0) +>1< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->< <<= >0<, result: int(0) ->< <<= >100<, result: int(0) ->< <<= >INF<, result: int(0) ->< <<= >-INF<, result: int(0) ->< <<= >NAN<, result: int(0) ->< <<= >1<, result: int(0) ->< <<= ><, result: int(0) ->< <<= ><, result: int(0) ->< <<= >123<, result: int(0) ->< <<= >2e+5<, result: int(0) ->< <<= ><, result: int(0) ->< <<= >abc<, result: int(0) ->< <<= >9223372036854775807<, result: int(0) +>< >>= >0<, result: int(0) +>< >>= >100<, result: int(0) +>< >>= >INF<, result: int(0) +>< >>= >-INF<, result: int(0) +>< >>= >NAN<, result: int(0) +>< >>= >1<, result: int(0) +>< >>= ><, result: int(0) +>< >>= ><, result: int(0) +>< >>= >123<, result: int(0) +>< >>= >2e+5<, result: int(0) +>< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->< <<= >0<, result: int(0) ->< <<= >100<, result: int(0) ->< <<= >INF<, result: int(0) ->< <<= >-INF<, result: int(0) ->< <<= >NAN<, result: int(0) ->< <<= >1<, result: int(0) ->< <<= ><, result: int(0) ->< <<= ><, result: int(0) ->< <<= >123<, result: int(0) ->< <<= >2e+5<, result: int(0) ->< <<= ><, result: int(0) ->< <<= >abc<, result: int(0) ->< <<= >9223372036854775807<, result: int(0) +>< >>= >0<, result: int(0) +>< >>= >100<, result: int(0) +>< >>= >INF<, result: int(0) +>< >>= >-INF<, result: int(0) +>< >>= >NAN<, result: int(0) +>< >>= >1<, result: int(0) +>< >>= ><, result: int(0) +>< >>= ><, result: int(0) +>< >>= >123<, result: int(0) +>< >>= >2e+5<, result: int(0) +>< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->123< <<= >0<, result: int(123) ->123< <<= >100<, result: int(0) ->123< <<= >INF<, result: int(123) ->123< <<= >-INF<, result: int(123) ->123< <<= >NAN<, result: int(123) ->123< <<= >1<, result: int(246) ->123< <<= ><, result: int(123) ->123< <<= ><, result: int(123) ->123< <<= >123<, result: int(0) ->123< <<= >2e+5<, result: int(492) ->123< <<= ><, result: int(123) ->123< <<= >abc<, result: int(123) ->123< <<= >9223372036854775807<, result: int(0) +>123< >>= >0<, result: int(123) +>123< >>= >100<, result: int(0) +>123< >>= >INF<, result: int(123) +>123< >>= >-INF<, result: int(123) +>123< >>= >NAN<, result: int(123) +>123< >>= >1<, result: int(246) +>123< >>= ><, result: int(123) +>123< >>= ><, result: int(123) +>123< >>= >123<, result: int(0) +>123< >>= >2e+5<, result: int(0) +>123< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->2e+5< <<= >0<, result: int(2) ->2e+5< <<= >100<, result: int(0) ->2e+5< <<= >INF<, result: int(2) ->2e+5< <<= >-INF<, result: int(2) ->2e+5< <<= >NAN<, result: int(2) ->2e+5< <<= >1<, result: int(4) ->2e+5< <<= ><, result: int(2) ->2e+5< <<= ><, result: int(2) ->2e+5< <<= >123<, result: int(0) ->2e+5< <<= >2e+5<, result: int(8) ->2e+5< <<= ><, result: int(2) ->2e+5< <<= >abc<, result: int(2) ->2e+5< <<= >9223372036854775807<, result: int(0) +>2e+5< >>= >0<, result: int(200000) +>2e+5< >>= >100<, result: int(0) +>2e+5< >>= >INF<, result: int(200000) +>2e+5< >>= >-INF<, result: int(200000) +>2e+5< >>= >NAN<, result: int(200000) +>2e+5< >>= >1<, result: int(400000) +>2e+5< >>= ><, result: int(200000) +>2e+5< >>= ><, result: int(200000) +>2e+5< >>= >123<, result: int(0) +>2e+5< >>= >2e+5<, result: int(0) +>2e+5< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(200000) +>2e+5< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(200000) +>2e+5< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->< <<= >0<, result: int(0) ->< <<= >100<, result: int(0) ->< <<= >INF<, result: int(0) ->< <<= >-INF<, result: int(0) ->< <<= >NAN<, result: int(0) ->< <<= >1<, result: int(0) ->< <<= ><, result: int(0) ->< <<= ><, result: int(0) ->< <<= >123<, result: int(0) ->< <<= >2e+5<, result: int(0) ->< <<= ><, result: int(0) ->< <<= >abc<, result: int(0) ->< <<= >9223372036854775807<, result: int(0) +>< >>= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< >>= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>abc< >>= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< >>= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- ->abc< <<= >0<, result: int(0) ->abc< <<= >100<, result: int(0) ->abc< <<= >INF<, result: int(0) ->abc< <<= >-INF<, result: int(0) ->abc< <<= >NAN<, result: int(0) ->abc< <<= >1<, result: int(0) ->abc< <<= ><, result: int(0) ->abc< <<= ><, result: int(0) ->abc< <<= >123<, result: int(0) ->abc< <<= >2e+5<, result: int(0) ->abc< <<= ><, result: int(0) ->abc< <<= >abc<, result: int(0) ->abc< <<= >9223372036854775807<, result: int(0) +>9223372036854775807< >>= >0<, result: int(9223372036854775807) +>9223372036854775807< >>= >100<, result: int(0) +>9223372036854775807< >>= >INF<, result: int(9223372036854775807) +>9223372036854775807< >>= >-INF<, result: int(9223372036854775807) +>9223372036854775807< >>= >NAN<, result: int(9223372036854775807) +>9223372036854775807< >>= >1<, result: int(-2) +>9223372036854775807< >>= ><, result: int(9223372036854775807) +>9223372036854775807< >>= ><, result: int(9223372036854775807) +>9223372036854775807< >>= >123<, result: int(0) +>9223372036854775807< >>= >2e+5<, result: int(0) +>9223372036854775807< >>= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< >>= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< >>= >9223372036854775807<, result: int(0) ------------------------------------- ->9223372036854775807< <<= >0<, result: int(9223372036854775807) ->9223372036854775807< <<= >100<, result: int(0) ->9223372036854775807< <<= >INF<, result: int(9223372036854775807) ->9223372036854775807< <<= >-INF<, result: int(9223372036854775807) ->9223372036854775807< <<= >NAN<, result: int(9223372036854775807) ->9223372036854775807< <<= >1<, result: int(-2) ->9223372036854775807< <<= ><, result: int(9223372036854775807) ->9223372036854775807< <<= ><, result: int(9223372036854775807) ->9223372036854775807< <<= >123<, result: int(0) ->9223372036854775807< <<= >2e+5<, result: int(-4) ->9223372036854775807< <<= ><, result: int(9223372036854775807) ->9223372036854775807< <<= >abc<, result: int(9223372036854775807) ->9223372036854775807< <<= >9223372036854775807<, result: int(0) -------------------------------------- \ No newline at end of file diff --git a/tests/expressions/assignment_operators/sub_assignment.phpt b/tests/expressions/assignment_operators/sub_assignment.phpt index 4460d014..345d695c 100644 --- a/tests/expressions/assignment_operators/sub_assignment.phpt +++ b/tests/expressions/assignment_operators/sub_assignment.phpt @@ -16,7 +16,7 @@ foreach ($oper as $t) } ?> ---EXPECT-- +--EXPECTF-- >0< -= >0<, result: int(0) >0< -= >-10<, result: int(10) >0< -= >100<, result: int(-100) @@ -29,8 +29,12 @@ foreach ($oper as $t) >0< -= ><, result: int(0) >0< -= >123<, result: int(-123) >0< -= >2e+5<, result: float(-200000) ->0< -= ><, result: int(0) ->0< -= >abc<, result: int(0) +>0< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >0< -= >9223372036854775807<, result: int(-9223372036854775807) ------------------------------------- >-10< -= >0<, result: int(-10) @@ -45,8 +49,12 @@ foreach ($oper as $t) >-10< -= ><, result: int(-10) >-10< -= >123<, result: int(-133) >-10< -= >2e+5<, result: float(-200010) ->-10< -= ><, result: int(-10) ->-10< -= >abc<, result: int(-10) +>-10< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) +>-10< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-10) >-10< -= >9223372036854775807<, result: float(-9.2233720368548E+18) ------------------------------------- >100< -= >0<, result: int(100) @@ -61,8 +69,12 @@ foreach ($oper as $t) >100< -= ><, result: int(100) >100< -= >123<, result: int(-23) >100< -= >2e+5<, result: float(-199900) ->100< -= ><, result: int(100) ->100< -= >abc<, result: int(100) +>100< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) +>100< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(100) >100< -= >9223372036854775807<, result: int(-9223372036854775707) ------------------------------------- >-34000000000< -= >0<, result: float(-34000000000) @@ -77,8 +89,12 @@ foreach ($oper as $t) >-34000000000< -= ><, result: float(-34000000000) >-34000000000< -= >123<, result: float(-34000000123) >-34000000000< -= >2e+5<, result: float(-34000200000) ->-34000000000< -= ><, result: float(-34000000000) ->-34000000000< -= >abc<, result: float(-34000000000) +>-34000000000< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(-34000000000) +>-34000000000< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-34000000000) >-34000000000< -= >9223372036854775807<, result: float(-9.2233720708548E+18) ------------------------------------- >INF< -= >0<, result: float(INF) @@ -93,8 +109,12 @@ foreach ($oper as $t) >INF< -= ><, result: float(INF) >INF< -= >123<, result: float(INF) >INF< -= >2e+5<, result: float(INF) ->INF< -= ><, result: float(INF) ->INF< -= >abc<, result: float(INF) +>INF< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>INF< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) >INF< -= >9223372036854775807<, result: float(INF) ------------------------------------- >-INF< -= >0<, result: float(-INF) @@ -109,8 +129,12 @@ foreach ($oper as $t) >-INF< -= ><, result: float(-INF) >-INF< -= >123<, result: float(-INF) >-INF< -= >2e+5<, result: float(-INF) ->-INF< -= ><, result: float(-INF) ->-INF< -= >abc<, result: float(-INF) +>-INF< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>-INF< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) >-INF< -= >9223372036854775807<, result: float(-INF) ------------------------------------- >NAN< -= >0<, result: float(NAN) @@ -125,8 +149,12 @@ foreach ($oper as $t) >NAN< -= ><, result: float(NAN) >NAN< -= >123<, result: float(NAN) >NAN< -= >2e+5<, result: float(NAN) ->NAN< -= ><, result: float(NAN) ->NAN< -= >abc<, result: float(NAN) +>NAN< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>NAN< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) >NAN< -= >9223372036854775807<, result: float(NAN) ------------------------------------- >1< -= >0<, result: int(1) @@ -141,8 +169,12 @@ foreach ($oper as $t) >1< -= ><, result: int(1) >1< -= >123<, result: int(-122) >1< -= >2e+5<, result: float(-199999) ->1< -= ><, result: int(1) ->1< -= >abc<, result: int(1) +>1< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) +>1< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(1) >1< -= >9223372036854775807<, result: int(-9223372036854775806) ------------------------------------- >< -= >0<, result: int(0) @@ -157,8 +189,12 @@ foreach ($oper as $t) >< -= ><, result: int(0) >< -= >123<, result: int(-123) >< -= >2e+5<, result: float(-200000) ->< -= ><, result: int(0) ->< -= >abc<, result: int(0) +>< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< -= >9223372036854775807<, result: int(-9223372036854775807) ------------------------------------- >< -= >0<, result: int(0) @@ -173,8 +209,12 @@ foreach ($oper as $t) >< -= ><, result: int(0) >< -= >123<, result: int(-123) >< -= >2e+5<, result: float(-200000) ->< -= ><, result: int(0) ->< -= >abc<, result: int(0) +>< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< -= >9223372036854775807<, result: int(-9223372036854775807) ------------------------------------- >123< -= >0<, result: int(123) @@ -189,8 +229,12 @@ foreach ($oper as $t) >123< -= ><, result: int(123) >123< -= >123<, result: int(0) >123< -= >2e+5<, result: float(-199877) ->123< -= ><, result: int(123) ->123< -= >abc<, result: int(123) +>123< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) +>123< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(123) >123< -= >9223372036854775807<, result: int(-9223372036854775684) ------------------------------------- >2e+5< -= >0<, result: float(200000) @@ -205,41 +249,113 @@ foreach ($oper as $t) >2e+5< -= ><, result: float(200000) >2e+5< -= >123<, result: float(199877) >2e+5< -= >2e+5<, result: float(0) ->2e+5< -= ><, result: float(200000) ->2e+5< -= >abc<, result: float(200000) +>2e+5< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(200000) +>2e+5< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(200000) >2e+5< -= >9223372036854775807<, result: float(-9.2233720368546E+18) ------------------------------------- ->< -= >0<, result: int(0) ->< -= >-10<, result: int(10) ->< -= >100<, result: int(-100) ->< -= >-34000000000<, result: float(34000000000) ->< -= >INF<, result: float(-INF) ->< -= >-INF<, result: float(INF) ->< -= >NAN<, result: float(NAN) ->< -= >1<, result: int(-1) ->< -= ><, result: int(0) ->< -= ><, result: int(0) ->< -= >123<, result: int(-123) ->< -= >2e+5<, result: float(-200000) ->< -= ><, result: int(0) ->< -= >abc<, result: int(0) ->< -= >9223372036854775807<, result: int(-9223372036854775807) +>< -= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(10) +>< -= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-100) +>< -= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(34000000000) +>< -= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>< -= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>< -= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< -= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-1) +>< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-123) +>< -= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-200000) +>< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< -= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-9223372036854775807) ------------------------------------- ->abc< -= >0<, result: int(0) ->abc< -= >-10<, result: int(10) ->abc< -= >100<, result: int(-100) ->abc< -= >-34000000000<, result: float(34000000000) ->abc< -= >INF<, result: float(-INF) ->abc< -= >-INF<, result: float(INF) ->abc< -= >NAN<, result: float(NAN) ->abc< -= >1<, result: int(-1) ->abc< -= ><, result: int(0) ->abc< -= ><, result: int(0) ->abc< -= >123<, result: int(-123) ->abc< -= >2e+5<, result: float(-200000) ->abc< -= ><, result: int(0) ->abc< -= >abc<, result: int(0) ->abc< -= >9223372036854775807<, result: int(-9223372036854775807) +>abc< -= >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< -= >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(10) +>abc< -= >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-100) +>abc< -= >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(34000000000) +>abc< -= >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-INF) +>abc< -= >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(INF) +>abc< -= >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< -= >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-1) +>abc< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< -= >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-123) +>abc< -= >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-200000) +>abc< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< -= >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(-9223372036854775807) ------------------------------------- >9223372036854775807< -= >0<, result: int(9223372036854775807) >9223372036854775807< -= >-10<, result: float(9.2233720368548E+18) @@ -253,7 +369,11 @@ foreach ($oper as $t) >9223372036854775807< -= ><, result: int(9223372036854775807) >9223372036854775807< -= >123<, result: int(9223372036854775684) >9223372036854775807< -= >2e+5<, result: float(9.2233720368546E+18) ->9223372036854775807< -= ><, result: int(9223372036854775807) ->9223372036854775807< -= >abc<, result: int(9223372036854775807) +>9223372036854775807< -= ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) +>9223372036854775807< -= >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(9223372036854775807) >9223372036854775807< -= >9223372036854775807<, result: int(0) -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/assignment_operators/xor_assignment.phpt b/tests/expressions/assignment_operators/xor_assignment.phpt index 357f92a12d87dd6004aea2553ab93b80bdf6512a..904d585328535c795d3e5588a7cd7d49e2abdc26 100644 GIT binary patch literal 11942 zcmeI2QE%He5XS@TVTeA#9*H1DV{GbVJBgE~O;KzK7GMa1H9+?;Ebts{F_6faV((?> zcOQ?GkH_OtQX_d!^^@Sc``?lJ@kq%|)9bSj*J+yk{#Gp>^K!aelu4SNU;KQgzkKuV z@$NB6%KY!uyv)_j&5swq+}x;F>gD&d#lyp*cr`C(FHe%>&qbL}XLo9E7ev(bN$oBN z$-l|AV8};&)f=Tt(HEmP->EWxTHP;StDO_|&$PU` zT|GSRL6r8;4g($dDXBu!HlN>$os;BKlDs?BV?6uy>gb3M${%qGo9%6YNe%LZsl zhuo;Yapqyh&H5W>PRIM%`onTilMA@GJZFAXt=4+^{xTjqWTv4@$t)ya+%g=EnNfe^ zBuDwT2h2V))8Jf)Ir%s(i+S7OP^Jm-(%l7wW~6 zS`_MjUgYYXH4Lf)yUJdkI^glnQP4PPa0?9gh22@dAUou7K~57!o!bTrW@2_*^3t%}h{g5jYU zLx$0D^)*g$uj{cfTk{IVT_qc>4@>QL6`)dFnE*Z-!&PYaK6D5doozJeK*ve$mDv@^ z>Z3^^He8HOvB4fL9&bo|p+Lh&?Yg{mwh(sx4HXv9#&f!qy(7!sh%gMP#e6kUEbTrOu;0rY=V2(AmvZ2(ojKNp*G!Rc94=Y-xcZ=AbzY=` z9(Z-Sy#wo{1s=&Lx;|gR4UINcG{%}LI>c~AhxW8$hzu*5%?yRCq8%=3%o3>>TNhYo zi(!hwb(EqL$2rY`KA2gXj!*z=!i7W)5_xd6w0be{MB$Fy zIn7?NbF$B&uKi01J7K)>x$HvU`$C=laR^Y=9Dbp0{hZyNI#|Bqk#AAbW5M-S7>7FmJS|K8)7IX2 zpmw&lws!P(zs|v$Bys%e<2TeXRLis)_3%3%QM$UiqJE#>$_|hATW_FdKq6K6Qo*?h zWZ@4l&MTw~-*h{tX2jMn>Re1nkW^zUuaGrCit}b%U;}m~k=qQNO%Q4Jh_Yvqa>>k9 zKRGsN3I-^cdfetk}BXylxNAI4b$b1djHUgN~$5zm1^>Tm*+N_lSUgLdzj> z9T$lp-nyR&v0;CMQ>@^q7o_m54fop^2;k4j>;K-FKPkl({AMMUVE!@^7ofd^Otx2x z_tSP<%I^tME&2~GwbRjA!EYYVD1r6}IUN205xt>o1_i&(Mf(d|D&9QZ#*1ewK2TUc gp2QW%@Heqq5Lp6y+wFx;8AANzM?7dQ8fx3{fe-Lr230OUH(0<~{E%p5v}HD=hsjDQSj# zMjMMv>J1lNYXVnPM;x;IN@-EP(-=2>tPKt2RtFUaKh0|1{;J~jvFKV~3D3$i#SE{@ zrubwZlNR${f^plE(pph<94?+zzYwbKKvET{cStmk9lwR^bsHVOaxzIxe5*euRXSmd z``8OOE{xdN4Q$a4_y1c!J6sdLNA4fbZy=B~)^tWpa z?o_vY_#wHaGQ;`l;XLk42RI_8Zr->FIRsK)!_}GoL0J(g he$%%Xy|%8Ne7!W+#O+QGpA#FG)DU*3fopRY{{ZFPqHh2I diff --git a/tests/expressions/bitwise_shift_operators/bitwise_shift.phpt b/tests/expressions/bitwise_shift_operators/bitwise_shift.phpt index d58309d7..d271a633 100644 --- a/tests/expressions/bitwise_shift_operators/bitwise_shift.phpt +++ b/tests/expressions/bitwise_shift_operators/bitwise_shift.phpt @@ -37,7 +37,7 @@ foreach ($scalarValueList as $v) { printf("%d(%08X): >> %2d = %08X\t<< %2d = %08X\n", $v, $v, 3, $v >> 3, 5, $v << 5); } ---EXPECT-- +--EXPECTF-- 1000(000003E8): >> 0 = 000003E8 << 0 = 000003E8 1000(000003E8): >> 1 = 000001F4 << 1 = 000007D0 1000(000003E8): >> 2 = 000000FA << 2 = 00000FA0 @@ -179,5 +179,13 @@ foreach ($scalarValueList as $v) 0(00000000): >> 3 = 00000000 << 5 = 00000000 0(00000000): >> 3 = 00000000 << 5 = 00000000 123(0000007B): >> 3 = 0000000F << 5 = 00000F60 + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d 0(00000000): >> 3 = 00000000 << 5 = 00000000 + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d 0(00000000): >> 3 = 00000000 << 5 = 00000000 diff --git a/tests/expressions/multiplicative_operators/multiplication_division_modulus.phpt b/tests/expressions/multiplicative_operators/multiplication_division_modulus.phpt index b1efcbce..5ab91c30 100644 --- a/tests/expressions/multiplicative_operators/multiplication_division_modulus.phpt +++ b/tests/expressions/multiplicative_operators/multiplication_division_modulus.phpt @@ -63,8 +63,12 @@ foreach ($oper as $e1) >0< * ><, result: int(0) >0< * >123<, result: int(0) >0< * >2e+5<, result: float(0) ->0< * ><, result: int(0) ->0< * >abc<, result: int(0) +>0< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>0< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >0< * >9223372036854775807<, result: int(0) ------------------------------------- >-10< * >0<, result: int(0) @@ -79,8 +83,12 @@ foreach ($oper as $e1) >-10< * ><, result: int(0) >-10< * >123<, result: int(-1230) >-10< * >2e+5<, result: float(-2000000) ->-10< * ><, result: int(0) ->-10< * >abc<, result: int(0) +>-10< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>-10< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >-10< * >9223372036854775807<, result: float(-9.2233720368548E+19) ------------------------------------- >100< * >0<, result: int(0) @@ -95,8 +103,12 @@ foreach ($oper as $e1) >100< * ><, result: int(0) >100< * >123<, result: int(12300) >100< * >2e+5<, result: float(20000000) ->100< * ><, result: int(0) ->100< * >abc<, result: int(0) +>100< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>100< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >100< * >9223372036854775807<, result: float(9.2233720368548E+20) ------------------------------------- >-34000000000< * >0<, result: float(-0) @@ -111,8 +123,12 @@ foreach ($oper as $e1) >-34000000000< * ><, result: float(-0) >-34000000000< * >123<, result: float(-4182000000000) >-34000000000< * >2e+5<, result: float(-6.8E+15) ->-34000000000< * ><, result: float(-0) ->-34000000000< * >abc<, result: float(-0) +>-34000000000< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>-34000000000< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) >-34000000000< * >9223372036854775807<, result: float(-3.1359464925306E+29) ------------------------------------- >INF< * >0<, result: float(NAN) @@ -127,8 +143,12 @@ foreach ($oper as $e1) >INF< * ><, result: float(NAN) >INF< * >123<, result: float(INF) >INF< * >2e+5<, result: float(INF) ->INF< * ><, result: float(NAN) ->INF< * >abc<, result: float(NAN) +>INF< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>INF< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) >INF< * >9223372036854775807<, result: float(INF) ------------------------------------- >-INF< * >0<, result: float(NAN) @@ -143,8 +163,12 @@ foreach ($oper as $e1) >-INF< * ><, result: float(NAN) >-INF< * >123<, result: float(-INF) >-INF< * >2e+5<, result: float(-INF) ->-INF< * ><, result: float(NAN) ->-INF< * >abc<, result: float(NAN) +>-INF< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>-INF< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) >-INF< * >9223372036854775807<, result: float(-INF) ------------------------------------- >NAN< * >0<, result: float(NAN) @@ -159,8 +183,12 @@ foreach ($oper as $e1) >NAN< * ><, result: float(NAN) >NAN< * >123<, result: float(NAN) >NAN< * >2e+5<, result: float(NAN) ->NAN< * ><, result: float(NAN) ->NAN< * >abc<, result: float(NAN) +>NAN< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>NAN< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) >NAN< * >9223372036854775807<, result: float(NAN) ------------------------------------- >1< * >0<, result: int(0) @@ -175,8 +203,12 @@ foreach ($oper as $e1) >1< * ><, result: int(0) >1< * >123<, result: int(123) >1< * >2e+5<, result: float(200000) ->1< * ><, result: int(0) ->1< * >abc<, result: int(0) +>1< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>1< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >1< * >9223372036854775807<, result: int(9223372036854775807) ------------------------------------- >< * >0<, result: int(0) @@ -191,8 +223,12 @@ foreach ($oper as $e1) >< * ><, result: int(0) >< * >123<, result: int(0) >< * >2e+5<, result: float(0) ->< * ><, result: int(0) ->< * >abc<, result: int(0) +>< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< * >9223372036854775807<, result: int(0) ------------------------------------- >< * >0<, result: int(0) @@ -207,8 +243,12 @@ foreach ($oper as $e1) >< * ><, result: int(0) >< * >123<, result: int(0) >< * >2e+5<, result: float(0) ->< * ><, result: int(0) ->< * >abc<, result: int(0) +>< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >< * >9223372036854775807<, result: int(0) ------------------------------------- >123< * >0<, result: int(0) @@ -223,8 +263,12 @@ foreach ($oper as $e1) >123< * ><, result: int(0) >123< * >123<, result: int(15129) >123< * >2e+5<, result: float(24600000) ->123< * ><, result: int(0) ->123< * >abc<, result: int(0) +>123< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>123< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >123< * >9223372036854775807<, result: float(1.1344747605331E+21) ------------------------------------- >2e+5< * >0<, result: float(0) @@ -239,41 +283,113 @@ foreach ($oper as $e1) >2e+5< * ><, result: float(0) >2e+5< * >123<, result: float(24600000) >2e+5< * >2e+5<, result: float(40000000000) ->2e+5< * ><, result: float(0) ->2e+5< * >abc<, result: float(0) +>2e+5< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>2e+5< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) >2e+5< * >9223372036854775807<, result: float(1.844674407371E+24) ------------------------------------- ->< * >0<, result: int(0) ->< * >-10<, result: int(0) ->< * >100<, result: int(0) ->< * >-34000000000<, result: float(-0) ->< * >INF<, result: float(NAN) ->< * >-INF<, result: float(NAN) ->< * >NAN<, result: float(NAN) ->< * >1<, result: int(0) ->< * ><, result: int(0) ->< * ><, result: int(0) ->< * >123<, result: int(0) ->< * >2e+5<, result: float(0) ->< * ><, result: int(0) ->< * >abc<, result: int(0) ->< * >9223372036854775807<, result: int(0) -------------------------------------- ->abc< * >0<, result: int(0) ->abc< * >-10<, result: int(0) ->abc< * >100<, result: int(0) ->abc< * >-34000000000<, result: float(-0) ->abc< * >INF<, result: float(NAN) ->abc< * >-INF<, result: float(NAN) ->abc< * >NAN<, result: float(NAN) ->abc< * >1<, result: int(0) ->abc< * ><, result: int(0) ->abc< * ><, result: int(0) ->abc< * >123<, result: int(0) ->abc< * >2e+5<, result: float(0) ->abc< * ><, result: int(0) ->abc< * >abc<, result: int(0) ->abc< * >9223372036854775807<, result: int(0) +>< * >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>< * >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< * >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< * >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< * >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>< * ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< * >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>abc< * >0<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>abc< * >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< * >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< * >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< * >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>abc< * ><, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< * >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- >9223372036854775807< * >0<, result: int(0) >9223372036854775807< * >-10<, result: float(-9.2233720368548E+19) @@ -287,8 +403,12 @@ foreach ($oper as $e1) >9223372036854775807< * ><, result: int(0) >9223372036854775807< * >123<, result: float(1.1344747605331E+21) >9223372036854775807< * >2e+5<, result: float(1.844674407371E+24) ->9223372036854775807< * ><, result: int(0) ->9223372036854775807< * >abc<, result: int(0) +>9223372036854775807< * ><, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>9223372036854775807< * >abc<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) >9223372036854775807< * >9223372036854775807<, result: float(8.5070591730235E+37) ------------------------------------- >0< / >-10<, result: int(0) @@ -423,27 +543,67 @@ foreach ($oper as $e1) >2e+5< / >2e+5<, result: float(1) >2e+5< / >9223372036854775807<, result: float(2.168404344971E-14) ------------------------------------- ->< / >-10<, result: int(0) ->< / >100<, result: int(0) ->< / >-34000000000<, result: float(-0) ->< / >INF<, result: float(0) ->< / >-INF<, result: float(-0) ->< / >NAN<, result: float(NAN) ->< / >1<, result: int(0) ->< / >123<, result: int(0) ->< / >2e+5<, result: float(0) ->< / >9223372036854775807<, result: int(0) -------------------------------------- ->abc< / >-10<, result: int(0) ->abc< / >100<, result: int(0) ->abc< / >-34000000000<, result: float(-0) ->abc< / >INF<, result: float(0) ->abc< / >-INF<, result: float(-0) ->abc< / >NAN<, result: float(NAN) ->abc< / >1<, result: int(0) ->abc< / >123<, result: int(0) ->abc< / >2e+5<, result: float(0) ->abc< / >9223372036854775807<, result: int(0) +>< / >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< / >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< / >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>< / >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>< / >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>< / >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>< / >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< / >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>< / >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>< / >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +------------------------------------- +>abc< / >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< / >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< / >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>abc< / >INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>abc< / >-INF<, result: +Warning: A non-numeric value encountered in %s on line %d +float(-0) +>abc< / >NAN<, result: +Warning: A non-numeric value encountered in %s on line %d +float(NAN) +>abc< / >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< / >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +>abc< / >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +float(0) +>abc< / >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) ------------------------------------- >9223372036854775807< / >-10<, result: float(-9.2233720368548E+17) >9223372036854775807< / >100<, result: float(9.2233720368548E+16) @@ -467,7 +627,7 @@ foreach ($oper as $e1) >0< % >123<, result: int(0) (int) >0< % >(int) >123<, result: int(0) >0< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) +(int) >0< % >(int) >200000<, result: int(0) >0< % >9223372036854775807<, result: int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- @@ -481,8 +641,8 @@ foreach ($oper as $e1) (int) >-10< % >(int) >1<, result: int(0) >-10< % >123<, result: int(-10) (int) >-10< % >(int) >123<, result: int(-10) - >-10< % >2e+5<, result: int(0) -(int) >-10< % >(int) >2<, result: int(0) + >-10< % >2e+5<, result: int(-10) +(int) >-10< % >(int) >200000<, result: int(-10) >-10< % >9223372036854775807<, result: int(-10) (int) >-10< % >(int) >9223372036854775807<, result: int(-10) ------------------------------------- @@ -496,8 +656,8 @@ foreach ($oper as $e1) (int) >100< % >(int) >1<, result: int(0) >100< % >123<, result: int(100) (int) >100< % >(int) >123<, result: int(100) - >100< % >2e+5<, result: int(0) -(int) >100< % >(int) >2<, result: int(0) + >100< % >2e+5<, result: int(100) +(int) >100< % >(int) >200000<, result: int(100) >100< % >9223372036854775807<, result: int(100) (int) >100< % >(int) >9223372036854775807<, result: int(100) ------------------------------------- @@ -512,7 +672,7 @@ foreach ($oper as $e1) >-34000000000< % >123<, result: int(-28) (int) >-34000000000< % >(int) >123<, result: int(-28) >-34000000000< % >2e+5<, result: int(0) -(int) >-34000000000< % >(int) >2<, result: int(0) +(int) >-34000000000< % >(int) >200000<, result: int(0) >-34000000000< % >9223372036854775807<, result: int(-34000000000) (int) >-34000000000< % >(int) >9223372036854775807<, result: int(-34000000000) ------------------------------------- @@ -527,7 +687,7 @@ foreach ($oper as $e1) >INF< % >123<, result: int(0) (int) >0< % >(int) >123<, result: int(0) >INF< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) +(int) >0< % >(int) >200000<, result: int(0) >INF< % >9223372036854775807<, result: int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- @@ -542,7 +702,7 @@ foreach ($oper as $e1) >-INF< % >123<, result: int(0) (int) >0< % >(int) >123<, result: int(0) >-INF< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) +(int) >0< % >(int) >200000<, result: int(0) >-INF< % >9223372036854775807<, result: int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- @@ -557,7 +717,7 @@ foreach ($oper as $e1) >NAN< % >123<, result: int(0) (int) >0< % >(int) >123<, result: int(0) >NAN< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) +(int) >0< % >(int) >200000<, result: int(0) >NAN< % >9223372036854775807<, result: int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- @@ -572,7 +732,7 @@ foreach ($oper as $e1) >1< % >123<, result: int(1) (int) >1< % >(int) >123<, result: int(1) >1< % >2e+5<, result: int(1) -(int) >1< % >(int) >2<, result: int(1) +(int) >1< % >(int) >200000<, result: int(1) >1< % >9223372036854775807<, result: int(1) (int) >1< % >(int) >9223372036854775807<, result: int(1) ------------------------------------- @@ -587,7 +747,7 @@ foreach ($oper as $e1) >< % >123<, result: int(0) (int) >0< % >(int) >123<, result: int(0) >< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) +(int) >0< % >(int) >200000<, result: int(0) >< % >9223372036854775807<, result: int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- @@ -602,7 +762,7 @@ foreach ($oper as $e1) >< % >123<, result: int(0) (int) >0< % >(int) >123<, result: int(0) >< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) +(int) >0< % >(int) >200000<, result: int(0) >< % >9223372036854775807<, result: int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- @@ -616,54 +776,82 @@ foreach ($oper as $e1) (int) >123< % >(int) >1<, result: int(0) >123< % >123<, result: int(0) (int) >123< % >(int) >123<, result: int(0) - >123< % >2e+5<, result: int(1) -(int) >123< % >(int) >2<, result: int(1) + >123< % >2e+5<, result: int(123) +(int) >123< % >(int) >200000<, result: int(123) >123< % >9223372036854775807<, result: int(123) (int) >123< % >(int) >9223372036854775807<, result: int(123) ------------------------------------- - >2e+5< % >-10<, result: int(2) -(int) >2< % >(int) >-10<, result: int(2) - >2e+5< % >100<, result: int(2) -(int) >2< % >(int) >100<, result: int(2) - >2e+5< % >-34000000000<, result: int(2) -(int) >2< % >(int) >-34000000000<, result: int(2) + >2e+5< % >-10<, result: int(0) +(int) >200000< % >(int) >-10<, result: int(0) + >2e+5< % >100<, result: int(0) +(int) >200000< % >(int) >100<, result: int(0) + >2e+5< % >-34000000000<, result: int(200000) +(int) >200000< % >(int) >-34000000000<, result: int(200000) >2e+5< % >1<, result: int(0) -(int) >2< % >(int) >1<, result: int(0) +(int) >200000< % >(int) >1<, result: int(0) >2e+5< % >123<, result: int(2) -(int) >2< % >(int) >123<, result: int(2) +(int) >200000< % >(int) >123<, result: int(2) >2e+5< % >2e+5<, result: int(0) -(int) >2< % >(int) >2<, result: int(0) - >2e+5< % >9223372036854775807<, result: int(2) -(int) >2< % >(int) >9223372036854775807<, result: int(2) +(int) >200000< % >(int) >200000<, result: int(0) + >2e+5< % >9223372036854775807<, result: int(200000) +(int) >200000< % >(int) >9223372036854775807<, result: int(200000) ------------------------------------- - >< % >-10<, result: int(0) + >< % >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >-10<, result: int(0) - >< % >100<, result: int(0) + >< % >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >100<, result: int(0) - >< % >-34000000000<, result: int(0) + >< % >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >-34000000000<, result: int(0) - >< % >1<, result: int(0) + >< % >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >1<, result: int(0) - >< % >123<, result: int(0) + >< % >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >123<, result: int(0) - >< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) - >< % >9223372036854775807<, result: int(0) + >< % >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +(int) >0< % >(int) >200000<, result: int(0) + >< % >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- - >abc< % >-10<, result: int(0) + >abc< % >-10<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >-10<, result: int(0) - >abc< % >100<, result: int(0) + >abc< % >100<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >100<, result: int(0) - >abc< % >-34000000000<, result: int(0) + >abc< % >-34000000000<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >-34000000000<, result: int(0) - >abc< % >1<, result: int(0) + >abc< % >1<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >1<, result: int(0) - >abc< % >123<, result: int(0) + >abc< % >123<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >123<, result: int(0) - >abc< % >2e+5<, result: int(0) -(int) >0< % >(int) >2<, result: int(0) - >abc< % >9223372036854775807<, result: int(0) + >abc< % >2e+5<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) +(int) >0< % >(int) >200000<, result: int(0) + >abc< % >9223372036854775807<, result: +Warning: A non-numeric value encountered in %s on line %d +int(0) (int) >0< % >(int) >9223372036854775807<, result: int(0) ------------------------------------- >9223372036854775807< % >-10<, result: int(7) @@ -676,8 +864,8 @@ foreach ($oper as $e1) (int) >9223372036854775807< % >(int) >1<, result: int(0) >9223372036854775807< % >123<, result: int(7) (int) >9223372036854775807< % >(int) >123<, result: int(7) - >9223372036854775807< % >2e+5<, result: int(1) -(int) >9223372036854775807< % >(int) >2<, result: int(1) + >9223372036854775807< % >2e+5<, result: int(175807) +(int) >9223372036854775807< % >(int) >200000<, result: int(175807) >9223372036854775807< % >9223372036854775807<, result: int(0) (int) >9223372036854775807< % >(int) >9223372036854775807<, result: int(0) -------------------------------------- \ No newline at end of file +------------------------------------- diff --git a/tests/expressions/unary_operators/pre-increment_and_decrement.phpt b/tests/expressions/unary_operators/pre-increment_and_decrement.phpt index c111f7fb..c417cc14 100644 --- a/tests/expressions/unary_operators/pre-increment_and_decrement.phpt +++ b/tests/expressions/unary_operators/pre-increment_and_decrement.phpt @@ -257,7 +257,7 @@ $x = "zza"; var_dump($x); var_dump(--$x); var_dump(--$x); ---EXPECT-- +--EXPECTF-- --------------------------------------- start incdec --- $a = 5 <---> int(5) $a = 4 <---> int(4) @@ -389,6 +389,8 @@ $a = <---> bool(false) --------------------------------------- start incdec --- $a = <---> string(0) "" $a = -1 <---> int(-1) + +Warning: A non-numeric value encountered in %s on line %d $a = -2 <---> int(-2) $a = -1 <---> int(-1) $a = 0 @@ -397,6 +399,8 @@ $a = 0 <---> int(0) --------------------------------------- start incdecrev --- $a = <---> string(0) "" $a = 1 <---> string(1) "1" + +Warning: A non-numeric value encountered in %s on line %d $a = 2 <---> int(2) $a = 1 <---> int(1) $a = 2 @@ -501,6 +505,8 @@ $a = 14 <---> int(14) --------------------------------------- start incdec --- $a = 0x12 <---> string(4) "0x12" $a = 0x12 <---> string(4) "0x12" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0x12 <---> string(4) "0x12" $a = 0x13 <---> string(4) "0x13" $a = 0x14 @@ -509,6 +515,8 @@ $a = 0x14 <---> string(4) "0x14" --------------------------------------- start incdecrev --- $a = 0x12 <---> string(4) "0x12" $a = 0x13 <---> string(4) "0x13" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0x14 <---> string(4) "0x14" $a = 0x14 <---> string(4) "0x14" $a = 0x15 @@ -517,6 +525,8 @@ $a = 0x15 <---> string(4) "0x15" --------------------------------------- start incdec --- $a = 0X12 <---> string(4) "0X12" $a = 0X12 <---> string(4) "0X12" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0X12 <---> string(4) "0X12" $a = 0X13 <---> string(4) "0X13" $a = 0X14 @@ -525,6 +535,8 @@ $a = 0X14 <---> string(4) "0X14" --------------------------------------- start incdecrev --- $a = 0X12 <---> string(4) "0X12" $a = 0X13 <---> string(4) "0X13" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0X14 <---> string(4) "0X14" $a = 0X14 <---> string(4) "0X14" $a = 0X15 @@ -533,6 +545,8 @@ $a = 0X15 <---> string(4) "0X15" --------------------------------------- start incdec --- $a = 0b101 <---> string(5) "0b101" $a = 0b101 <---> string(5) "0b101" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0b101 <---> string(5) "0b101" $a = 0b102 <---> string(5) "0b102" $a = 0b103 @@ -541,6 +555,8 @@ $a = 0b103 <---> string(5) "0b103" --------------------------------------- start incdecrev --- $a = 0b101 <---> string(5) "0b101" $a = 0b102 <---> string(5) "0b102" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0b103 <---> string(5) "0b103" $a = 0b103 <---> string(5) "0b103" $a = 0b104 @@ -549,6 +565,8 @@ $a = 0b104 <---> string(5) "0b104" --------------------------------------- start incdec --- $a = 0B101 <---> string(5) "0B101" $a = 0B101 <---> string(5) "0B101" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0B101 <---> string(5) "0B101" $a = 0B102 <---> string(5) "0B102" $a = 0B103 @@ -557,6 +575,8 @@ $a = 0B103 <---> string(5) "0B103" --------------------------------------- start incdecrev --- $a = 0B101 <---> string(5) "0B101" $a = 0B102 <---> string(5) "0B102" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0B103 <---> string(5) "0B103" $a = 0B103 <---> string(5) "0B103" $a = 0B104 @@ -565,6 +585,8 @@ $a = 0B104 <---> string(5) "0B104" --------------------------------------- start incdec --- $a = 0Q101 <---> string(5) "0Q101" $a = 0Q101 <---> string(5) "0Q101" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0Q101 <---> string(5) "0Q101" $a = 0Q102 <---> string(5) "0Q102" $a = 0Q103 @@ -573,6 +595,8 @@ $a = 0Q103 <---> string(5) "0Q103" --------------------------------------- start incdecrev --- $a = 0Q101 <---> string(5) "0Q101" $a = 0Q102 <---> string(5) "0Q102" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 0Q103 <---> string(5) "0Q103" $a = 0Q103 <---> string(5) "0Q103" $a = 0Q104 @@ -665,6 +689,8 @@ $a = 96 <---> int(96) --------------------------------------- start incdec --- $a = 987 <---> string(4) "987 " $a = 987 <---> string(4) "987 " + +Notice: A non well formed numeric value encountered in %s on line %d $a = 987 <---> string(4) "987 " $a = 987 <---> string(4) "987 " $a = 987 @@ -673,6 +699,8 @@ $a = 987 <---> string(4) "987 " --------------------------------------- start incdecrev --- $a = 987 <---> string(4) "987 " $a = 987 <---> string(4) "987 " + +Notice: A non well formed numeric value encountered in %s on line %d $a = 987 <---> string(4) "987 " $a = 987 <---> string(4) "987 " $a = 987 @@ -685,6 +713,8 @@ $a = 15 $a = 15 <---> string(9) "15 " + +Notice: A non well formed numeric value encountered in %s on line %d $a = 15 <---> string(9) "15 " @@ -704,6 +734,8 @@ $a = 15 $a = 15 <---> string(9) "15 " + +Notice: A non well formed numeric value encountered in %s on line %d $a = 15 <---> string(9) "15 " @@ -815,6 +847,8 @@ $a = 11.87 <---> float(11.87) --------------------------------------- start incdec --- $a = a <---> string(1) "a" $a = a <---> string(1) "a" + +Warning: A non-numeric value encountered in %s on line %d $a = a <---> string(1) "a" $a = b <---> string(1) "b" $a = c @@ -823,6 +857,8 @@ $a = c <---> string(1) "c" --------------------------------------- start incdecrev --- $a = a <---> string(1) "a" $a = b <---> string(1) "b" + +Warning: A non-numeric value encountered in %s on line %d $a = c <---> string(1) "c" $a = c <---> string(1) "c" $a = d @@ -831,6 +867,8 @@ $a = d <---> string(1) "d" --------------------------------------- start incdec --- $a = z <---> string(1) "z" $a = z <---> string(1) "z" + +Warning: A non-numeric value encountered in %s on line %d $a = z <---> string(1) "z" $a = aa <---> string(2) "aa" $a = ab @@ -839,6 +877,8 @@ $a = ab <---> string(2) "ab" --------------------------------------- start incdecrev --- $a = z <---> string(1) "z" $a = aa <---> string(2) "aa" + +Warning: A non-numeric value encountered in %s on line %d $a = ab <---> string(2) "ab" $a = ab <---> string(2) "ab" $a = ac @@ -847,6 +887,8 @@ $a = ac <---> string(2) "ac" --------------------------------------- start incdec --- $a = A <---> string(1) "A" $a = A <---> string(1) "A" + +Warning: A non-numeric value encountered in %s on line %d $a = A <---> string(1) "A" $a = B <---> string(1) "B" $a = C @@ -855,6 +897,8 @@ $a = C <---> string(1) "C" --------------------------------------- start incdecrev --- $a = A <---> string(1) "A" $a = B <---> string(1) "B" + +Warning: A non-numeric value encountered in %s on line %d $a = C <---> string(1) "C" $a = C <---> string(1) "C" $a = D @@ -863,6 +907,8 @@ $a = D <---> string(1) "D" --------------------------------------- start incdec --- $a = Z <---> string(1) "Z" $a = Z <---> string(1) "Z" + +Warning: A non-numeric value encountered in %s on line %d $a = Z <---> string(1) "Z" $a = AA <---> string(2) "AA" $a = AB @@ -871,6 +917,8 @@ $a = AB <---> string(2) "AB" --------------------------------------- start incdecrev --- $a = Z <---> string(1) "Z" $a = AA <---> string(2) "AA" + +Warning: A non-numeric value encountered in %s on line %d $a = AB <---> string(2) "AB" $a = AB <---> string(2) "AB" $a = AC @@ -879,6 +927,8 @@ $a = AC <---> string(2) "AC" --------------------------------------- start incdec --- $a = F28 <---> string(3) "F28" $a = F28 <---> string(3) "F28" + +Warning: A non-numeric value encountered in %s on line %d $a = F28 <---> string(3) "F28" $a = F29 <---> string(3) "F29" $a = F30 @@ -887,6 +937,8 @@ $a = F30 <---> string(3) "F30" --------------------------------------- start incdecrev --- $a = F28 <---> string(3) "F28" $a = F29 <---> string(3) "F29" + +Warning: A non-numeric value encountered in %s on line %d $a = F30 <---> string(3) "F30" $a = F30 <---> string(3) "F30" $a = F31 @@ -895,6 +947,8 @@ $a = F31 <---> string(3) "F31" --------------------------------------- start incdec --- $a = F28 <---> string(3) "F28" $a = F28 <---> string(3) "F28" + +Warning: A non-numeric value encountered in %s on line %d $a = F28 <---> string(3) "F28" $a = F29 <---> string(3) "F29" $a = F30 @@ -903,6 +957,8 @@ $a = F30 <---> string(3) "F30" --------------------------------------- start incdecrev --- $a = F98 <---> string(3) "F98" $a = F99 <---> string(3) "F99" + +Warning: A non-numeric value encountered in %s on line %d $a = G00 <---> string(3) "G00" $a = G00 <---> string(3) "G00" $a = G01 @@ -911,6 +967,8 @@ $a = G01 <---> string(3) "G01" --------------------------------------- start incdec --- $a = F98 <---> string(3) "F98" $a = F98 <---> string(3) "F98" + +Warning: A non-numeric value encountered in %s on line %d $a = F98 <---> string(3) "F98" $a = F99 <---> string(3) "F99" $a = G00 @@ -919,6 +977,8 @@ $a = G00 <---> string(3) "G00" --------------------------------------- start incdecrev --- $a = FZ8 <---> string(3) "FZ8" $a = FZ9 <---> string(3) "FZ9" + +Warning: A non-numeric value encountered in %s on line %d $a = GA0 <---> string(3) "GA0" $a = GA0 <---> string(3) "GA0" $a = GA1 @@ -927,6 +987,8 @@ $a = GA1 <---> string(3) "GA1" --------------------------------------- start incdec --- $a = ZZ8 <---> string(3) "ZZ8" $a = ZZ8 <---> string(3) "ZZ8" + +Warning: A non-numeric value encountered in %s on line %d $a = ZZ8 <---> string(3) "ZZ8" $a = ZZ9 <---> string(3) "ZZ9" $a = AAA0 @@ -935,6 +997,8 @@ $a = AAA0 <---> string(4) "AAA0" --------------------------------------- start incdecrev --- $a = ZZ8 <---> string(3) "ZZ8" $a = ZZ9 <---> string(3) "ZZ9" + +Warning: A non-numeric value encountered in %s on line %d $a = AAA0 <---> string(4) "AAA0" $a = AAA0 <---> string(4) "AAA0" $a = AAA1 @@ -943,6 +1007,8 @@ $a = AAA1 <---> string(4) "AAA1" --------------------------------------- start incdecrev --- $a = 543J <---> string(4) "543J" $a = 543K <---> string(4) "543K" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 543L <---> string(4) "543L" $a = 543L <---> string(4) "543L" $a = 543M @@ -951,6 +1017,8 @@ $a = 543M <---> string(4) "543M" --------------------------------------- start incdec --- $a = 543J <---> string(4) "543J" $a = 543J <---> string(4) "543J" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 543J <---> string(4) "543J" $a = 543K <---> string(4) "543K" $a = 543L @@ -959,6 +1027,8 @@ $a = 543L <---> string(4) "543L" --------------------------------------- start incdecrev --- $a = 543J9 <---> string(5) "543J9" $a = 543K0 <---> string(5) "543K0" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 543K1 <---> string(5) "543K1" $a = 543K1 <---> string(5) "543K1" $a = 543K2 @@ -967,6 +1037,8 @@ $a = 543K2 <---> string(5) "543K2" --------------------------------------- start incdec --- $a = 543J9 <---> string(5) "543J9" $a = 543J9 <---> string(5) "543J9" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 543J9 <---> string(5) "543J9" $a = 543K0 <---> string(5) "543K0" $a = 543K1 @@ -975,6 +1047,8 @@ $a = 543K1 <---> string(5) "543K1" --------------------------------------- start incdec --- $a = & <---> string(1) "&" $a = & <---> string(1) "&" + +Warning: A non-numeric value encountered in %s on line %d $a = & <---> string(1) "&" $a = & <---> string(1) "&" $a = & @@ -983,6 +1057,8 @@ $a = & <---> string(1) "&" --------------------------------------- start incdecrev --- $a = & <---> string(1) "&" $a = & <---> string(1) "&" + +Warning: A non-numeric value encountered in %s on line %d $a = & <---> string(1) "&" $a = & <---> string(1) "&" $a = & @@ -991,6 +1067,8 @@ $a = & <---> string(1) "&" --------------------------------------- start incdec --- $a = 83& <---> string(3) "83&" $a = 83& <---> string(3) "83&" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83& <---> string(3) "83&" $a = 83& <---> string(3) "83&" $a = 83& @@ -999,6 +1077,8 @@ $a = 83& <---> string(3) "83&" --------------------------------------- start incdecrev --- $a = 83& <---> string(3) "83&" $a = 83& <---> string(3) "83&" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83& <---> string(3) "83&" $a = 83& <---> string(3) "83&" $a = 83& @@ -1007,6 +1087,8 @@ $a = 83& <---> string(3) "83&" --------------------------------------- start incdec --- $a = 83&8 <---> string(4) "83&8" $a = 83&8 <---> string(4) "83&8" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83&8 <---> string(4) "83&8" $a = 83&9 <---> string(4) "83&9" $a = 83&0 @@ -1015,6 +1097,8 @@ $a = 83&0 <---> string(4) "83&0" --------------------------------------- start incdecrev --- $a = 83&8 <---> string(4) "83&8" $a = 83&9 <---> string(4) "83&9" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83&0 <---> string(4) "83&0" $a = 83&0 <---> string(4) "83&0" $a = 83&1 @@ -1023,6 +1107,8 @@ $a = 83&1 <---> string(4) "83&1" --------------------------------------- start incdec --- $a = 83&Z8 <---> string(5) "83&Z8" $a = 83&Z8 <---> string(5) "83&Z8" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83&Z8 <---> string(5) "83&Z8" $a = 83&Z9 <---> string(5) "83&Z9" $a = 83&A0 @@ -1031,6 +1117,8 @@ $a = 83&A0 <---> string(5) "83&A0" --------------------------------------- start incdecrev --- $a = 83&Z8 <---> string(5) "83&Z8" $a = 83&Z9 <---> string(5) "83&Z9" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83&A0 <---> string(5) "83&A0" $a = 83&A0 <---> string(5) "83&A0" $a = 83&A1 @@ -1039,6 +1127,8 @@ $a = 83&A1 <---> string(5) "83&A1" --------------------------------------- start incdec --- $a = 83&z8 <---> string(5) "83&z8" $a = 83&z8 <---> string(5) "83&z8" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83&z8 <---> string(5) "83&z8" $a = 83&z9 <---> string(5) "83&z9" $a = 83&a0 @@ -1047,6 +1137,8 @@ $a = 83&a0 <---> string(5) "83&a0" --------------------------------------- start incdecrev --- $a = 83&z8 <---> string(5) "83&z8" $a = 83&z9 <---> string(5) "83&z9" + +Notice: A non well formed numeric value encountered in %s on line %d $a = 83&a0 <---> string(5) "83&a0" $a = 83&a0 <---> string(5) "83&a0" $a = 83&a1 @@ -1055,6 +1147,8 @@ $a = 83&a1 <---> string(5) "83&a1" --------------------------------------- start incdec --- $a = &28 <---> string(3) "&28" $a = &28 <---> string(3) "&28" + +Warning: A non-numeric value encountered in %s on line %d $a = &28 <---> string(3) "&28" $a = &29 <---> string(3) "&29" $a = &30 @@ -1063,6 +1157,8 @@ $a = &30 <---> string(3) "&30" --------------------------------------- start incdecrev --- $a = &28 <---> string(3) "&28" $a = &29 <---> string(3) "&29" + +Warning: A non-numeric value encountered in %s on line %d $a = &30 <---> string(3) "&30" $a = &30 <---> string(3) "&30" $a = &31 @@ -1071,6 +1167,8 @@ $a = &31 <---> string(3) "&31" --------------------------------------- start incdec --- $a = &98 <---> string(3) "&98" $a = &98 <---> string(3) "&98" + +Warning: A non-numeric value encountered in %s on line %d $a = &98 <---> string(3) "&98" $a = &99 <---> string(3) "&99" $a = &00 @@ -1079,6 +1177,8 @@ $a = &00 <---> string(3) "&00" --------------------------------------- start incdecrev --- $a = &98 <---> string(3) "&98" $a = &99 <---> string(3) "&99" + +Warning: A non-numeric value encountered in %s on line %d $a = &00 <---> string(3) "&00" $a = &00 <---> string(3) "&00" $a = &01 diff --git a/tests/expressions/unary_operators/unary_arithmetic_operators.phpt b/tests/expressions/unary_operators/unary_arithmetic_operators.phpt index c795a625..88055f61 100644 --- a/tests/expressions/unary_operators/unary_arithmetic_operators.phpt +++ b/tests/expressions/unary_operators/unary_arithmetic_operators.phpt @@ -80,7 +80,7 @@ DoIt("-25.5e-10"); DoIt(""); DoIt("ABC"); //*/ ---EXPECT-- +--EXPECTF-- --- start DoIt ------------------------- original: int(0) @@ -229,10 +229,18 @@ DoIt("ABC"); original: string(0) "" +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d + --- end DoIt ------------------------- --- start DoIt ------------------------- original: string(3) "ABC" +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d + --- end DoIt ------------------------- diff --git a/tests/types/string/numeric_like_strings.phpt b/tests/types/string/numeric_like_strings.phpt index f1621b42..51aa0327 100644 --- a/tests/types/string/numeric_like_strings.phpt +++ b/tests/types/string/numeric_like_strings.phpt @@ -94,7 +94,7 @@ var_dump($s1--); var_dump($s2--); var_dump($s3--); var_dump($s4--); ---EXPECT-- +--EXPECTF-- ============== var_dump(numeric_like_string) =================== string(8) "12345xxx" @@ -118,13 +118,29 @@ float(12345.6) ============== +/- numeric_like_string =================== + +Notice: A non well formed numeric value encountered in %s on line %d int(12345) + +Notice: A non well formed numeric value encountered in %s on line %d int(12345) + +Notice: A non well formed numeric value encountered in %s on line %d float(12345.6) + +Notice: A non well formed numeric value encountered in %s on line %d float(12345.6) + +Notice: A non well formed numeric value encountered in %s on line %d int(-12345) + +Notice: A non well formed numeric value encountered in %s on line %d int(-12345) + +Notice: A non well formed numeric value encountered in %s on line %d float(-12345.6) + +Notice: A non well formed numeric value encountered in %s on line %d float(-12345.6) ============== relational/equality ops with numeric_like_string =================== From 1bec75b6abf752c2a7888b6f0589a59c7eaabfd4 Mon Sep 17 00:00:00 2001 From: Francois Laupretre Date: Mon, 7 Mar 2016 12:46:06 +0100 Subject: [PATCH 006/146] Add support of negative string offsets Additional fix: string are extended padding with spaces, not '\0'. bugfix #71572: Assignment from empty string does not insert null byte anymore. --- spec/10-expressions.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 447e08e3..134caecc 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -1058,14 +1058,15 @@ The result is the added new element, or `NULL` if the element was not added. **postfix-expression designates a string** The *expression* is converted to `int` and the result is the character of the -string at the position equal to that integer. If the integer is negative or refers +string at the position corresponding to that integer. If the integer is negative, +the position is counted backwards from the end of the string. If the position refers to a non-existing offset, the result is an empty string. If the operator is used as the left-hand side of a [*simple-assignment-expression*](#simple-assignment), -the value being assigned is converted to string and the character in the specified offset will be -replaced by the first character of the string. If the assigned string is empty, the `'\0'` character is used. -If the string before the assignment had no such offset, the string is extended to include the offset -with `'\0'` characters. + +- If the assigned string is empty, or in case of non-existing negative offset (absolute value larger than string length), a warning is raised and no assignment is performed. +- If the offset is larger than the current string length, the string is extended to a length equal to the offset value, using space (0x20) padding characters. +- The value being assigned is converted to string and the character in the specified offset is replaced by the first character of the string. The subscript operator can not be used on a string value in a byRef context or as the operand of the [postfix- or prefix-increment or decrement operators](#postfix-increment-and-decrement-operators) or on the left @@ -1135,6 +1136,7 @@ $v["red"] = TRUE; // insert a new element with string key "red" function f() { return [1000, 2000, 3000]; } f()[2]; // designates element with value 3000 "red"[1.9]; // designates "e" +"red"[-2]; // designates "e" "red"[0][0][0]; // designates "r" // ----------------------------------------- class MyVector implements ArrayAccess { /* ... */ } From f75930f6f08b1ec21cf3a16872f8c17b961f1062 Mon Sep 17 00:00:00 2001 From: Andrea Faulds Date: Fri, 25 Mar 2016 14:09:51 +0000 Subject: [PATCH 007/146] Fix bug #71897 --- spec/09-lexical-structure.md | 4 ++-- spec/19-grammar.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index aac648d0..d506d437 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -234,7 +234,7 @@ There are several kinds of source *tokens*: name-nondigit:: nondigit - one of the characters U+007f–U+00ff + one of the characters U+0080–U+00ff nondigit:: one of _ @@ -258,7 +258,7 @@ Names are used to identify the following: [constants](06-constants.md#general), and names in [heredoc](#heredoc-string-literals) and [nowdoc comments](#nowdoc-string-literals). A *name* begins with an underscore (_), *name-nondigit*, or extended -name character in the range U+007f–-U+00ff. Subsequent characters can +name character in the range U+0080–-U+00ff. Subsequent characters can also include *digits*. A *variable name* is a name with a leading dollar ($). diff --git a/spec/19-grammar.md b/spec/19-grammar.md index b194416f..d484fc7d 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -97,7 +97,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# name-nondigit:: nondigit - one of the characters U+007f–U+00ff + one of the characters U+0080–U+00ff nondigit:: one of _ From 2d5cc6f08c3cd3abfcc718f42c9341939d8c91f5 Mon Sep 17 00:00:00 2001 From: Reeze Xia Date: Sat, 27 Feb 2016 18:41:13 +0800 Subject: [PATCH 008/146] Add the accepted RFC: class constant visibility to spec RFC: https://wiki.php.net/rfc/class_const_visibility --- spec/14-classes.md | 23 +++++++++++++++-------- spec/15-interfaces.md | 6 +++++- spec/19-grammar.md | 7 +++++-- tests/classes/visibility.phpt | 10 ++++++---- tests/constants/constants.phpt | 15 +++++++++++---- tests/interfaces/interfaces.phpt | 9 +++++++-- 6 files changed, 49 insertions(+), 21 deletions(-) diff --git a/spec/14-classes.md b/spec/14-classes.md index 95019155..443b7136 100644 --- a/spec/14-classes.md +++ b/spec/14-classes.md @@ -203,7 +203,7 @@ class MyList implements MyCollection class-member-declarations class-member-declaration class-member-declaration: - const-declaration + class-const-declaration property-declaration method-declaration constructor-declaration @@ -213,7 +213,7 @@ class MyList implements MyCollection **Defined elsewhere** -* [*const-declaration*](#constants) +* [*class-const-declaration*](#constants) * [*property-declaration*](#properties) * [*method-declaration*](#methods) * [*constructor-declaration*](#constructors) @@ -387,28 +387,32 @@ Widget::__callStatic('sMethod', array(NULL, 1.234))
   const-declaration:
     const  name  =  constant-expression   ;
+
+  class-const-declaration:
+    visibility-modifieropt  const  name  =  constant-expression   ;
 
**Defined elsewhere** * [*name*](09-lexical-structure.md#names) * [*constant-expression*](10-expressions.md#constant-expressions) +* [*visibility-modifier*](#properties) **Constraints:** -A *const-declaration* must only appear at the top level of a script, be -a *class constant* (inside a [*class-definition*](#class-members) or be an -[*interface constant*](15-interfaces.md#interface-members). +A *const-declaration* must only appear at the top level of a script, and +must not redefine an existing [c-constant](06-constants.md#general). -A *const-declaration* must not redefine an existing [c-constant](06-constants.md#general). +A *class-const-declaration* must be inside a [*class-definition*](#class-members) or be an +[*interface constant*](15-interfaces.md#interface-members). -A class constant must not have visibility specifier or `static` specifier. +A class constant must not have a `static` specifier. **Semantics:** A *const-declaration* defines a c-constant. -All class constants have public visibility. +If *visibility-modifier* for a class constant is omitted, `public` is assumed. All constants are implicitly `static`. @@ -421,6 +425,9 @@ const LOWER = MIN_VAL; class Automobile { const DEFAULT_COLOR = "white"; + public DEFAULT_BRAND = 'benz'; + protected WHEEL_NUM = 4; + private PRIVATE_CONST = 'const'; ... } $col = Automobile::DEFAULT_COLOR; diff --git a/spec/15-interfaces.md b/spec/15-interfaces.md index 2bc6566f..e11ec348 100644 --- a/spec/15-interfaces.md +++ b/spec/15-interfaces.md @@ -88,7 +88,7 @@ processCollection(new MyQueue(...)); interface-member-declarations interface-member-declaration interface-member-declaration: - const-declaration + class-const-declaration method-declaration @@ -109,6 +109,10 @@ An interface may contain the following members: ##Constants +**Constraints** + +All constants declared in an interface must be implicitly or explicitly public. + **Semantics** An interface constant is just like a class [constant](14-classes.md#constants), except that diff --git a/spec/19-grammar.md b/spec/19-grammar.md index d484fc7d..b4d4d9e0 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -1097,7 +1097,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# class-member-declarations class-member-declaration class-member-declaration: - const-declaration + class-const-declaration property-declaration method-declaration constructor-declaration @@ -1107,6 +1107,9 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# const-declaration: const name = constant-expression ; + class-const-declaration: + visibility-modifieropt const name = constant-expression ; + property-declaration: property-modifier variable-name property-initializeropt ; @@ -1163,7 +1166,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# interface-member-declarations interface-member-declaration interface-member-declaration: - const-declaration + class-const-declaration method-declaration diff --git a/tests/classes/visibility.phpt b/tests/classes/visibility.phpt index 49f5cae3..4b483652 100644 --- a/tests/classes/visibility.phpt +++ b/tests/classes/visibility.phpt @@ -15,10 +15,12 @@ class C { // constants - const CON1 = 123; // implicitly static, and can't say so explicitly -// public const CON2 = 123; // class constants are implicitly public; can't say explicitly -// protected const CON3 = 123; // class constants are implicitly public -// private const CON4 = 123; // class constants are implicitly public + const CON1 = 123; // implicitly static and can't say so explicitly + // implicitly public + + public const CON2 = 123; // explicitly public + protected const CON3 = 123; // protected constant + private const CON4 = 123; // private constant // properties diff --git a/tests/constants/constants.phpt b/tests/constants/constants.phpt index 66e1c079..323a5215 100644 --- a/tests/constants/constants.phpt +++ b/tests/constants/constants.phpt @@ -165,14 +165,21 @@ trace("FOR", 100); // succeeded class C3 { - const CON1 = 123; // implicitly static, and can't say so explicitly -// public const CON2 = 123; // all class constants are implicitly public; can't say explicitly -// protected const CON3 = 123; // all class constants are implicitly public -// private const CON4 = 123; // all class constants are implicitly public + + const CON1 = 123; // implicitly static and can't say so explicitly + // implicitly public + + public const CON2 = 123; // explicitly public + protected const CON3 = 123; // protected constant + private const CON4 = 123; // private constant } echo "CON1: " . C3::CON1 . "\n"; // use :: notation, as a const is implicitly static +// public const CON80 = 80; // top level const can not have visibility modifier +// protected const CON81 = 81; // top level const can not have visibility modifier +// private const CON82 = 82; // top level const can not have visibility modifier + //print_r(get_defined_constants()); --EXPECTF-- define STATUS1 succeeded; value is >1< diff --git a/tests/interfaces/interfaces.phpt b/tests/interfaces/interfaces.phpt index a7470c75..99f5b6c0 100644 --- a/tests/interfaces/interfaces.phpt +++ b/tests/interfaces/interfaces.phpt @@ -13,8 +13,11 @@ error_reporting(-1); interface iX { - const C1 = 123; -// const C2 = "green"; + const C1 = 123; // implicitly public +// const C2 = "green"; + public const C3 = 234; // explicitly public +// protected const C4 = 'C4'; // protected not permitted +// private const C5 = 'C5'; // private not permitted function f0 (); // implicitly public public function f1 ($p1); // explicitly public @@ -56,6 +59,7 @@ class D implements iZ var_dump(D::C1); var_dump(D::C2); +var_dump(D::C3); echo "------------------------------------\n"; @@ -96,6 +100,7 @@ var_dump(MyQueue::MAX_NUMBER_ITEMS); --EXPECT-- int(123) string(5) "green" +int(234) ------------------------------------ object(MyList)#1 (0) { } From 19e44137fe0bb8cde8f52a9780524e6eec916164 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Mon, 11 Jul 2016 19:16:09 +0200 Subject: [PATCH 009/146] Describe static/global variable shadowing --- spec/07-variables.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/spec/07-variables.md b/spec/07-variables.md index f2dae215..064c8219 100644 --- a/spec/07-variables.md +++ b/spec/07-variables.md @@ -183,6 +183,28 @@ Unlike the [local variable equivalent](#local-variables), function `f` outputs " = 1`", "`$fs = 2`", and "`$fs = 3`", as `$fs` retains its value across calls. + +Be also aware that declaring a function static can hide a local variable and/or a global variable withe the same name. The value of the local or global variable is not taken over as initial value of the function static. Subsequent modifications of the variable only modify the function static and do not affect the local nor the global variable. An example: + +```PHP +function f(){ + $fs = 10; // assign 10 to the local variable $fs + static $fs; // define a function static with name $fs + echo "\$fs = $fs\n"; // $fs = + $fs = 5; // assign 5 to the function static $fs (local variable is not modified) + echo "\$fs = $fs\n"; // $fs = 5 + global $fs; // define a global variabel with name $fs + echo "\$fs = $fs\n"; // $fs = + $fs = 3; // assign 3 to the global variable $fs (function static and local variabel is not modified + echo "\$fs = $fs\n"; // $fs = 3 + static $fs; + ++$fs; // increment function static $fs + echo "\$fs = $fs\n"; // $fs = 6 +} +f(); +echo "\$fs = $fs\n"; // $fs = 3 +``` + ###Global Variables **Syntax** @@ -272,6 +294,8 @@ function f() } ``` +Be also aware that declaring a variable global can hide a local variable and/or a function static with the same name. See [static variables section](#hidingNotice) for an example. + ###Instance Properties These are described in [class instance properties section](14-classes.md#properties). From 2ab435e7445d212aeee66f3d7e0d9708980e8faf Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 11 Jul 2016 20:32:38 +0200 Subject: [PATCH 010/146] Multiple constants can be defined at once --- spec/14-classes.md | 16 ++++++++++++---- spec/19-grammar.md | 11 +++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/spec/14-classes.md b/spec/14-classes.md index 443b7136..281a85a2 100644 --- a/spec/14-classes.md +++ b/spec/14-classes.md @@ -386,10 +386,17 @@ Widget::__callStatic('sMethod', array(NULL, 1.234))
   const-declaration:
-    const  name  =  constant-expression   ;
+    const   const-elements   ;
 
   class-const-declaration:
-    visibility-modifieropt  const  name  =  constant-expression   ;
+    visibility-modifieropt   const   const-elements   ;
+
+  const-elements:
+    const-element
+    const-elements   const-element
+
+  const-element:
+    name   =   constant-expression
 
**Defined elsewhere** @@ -403,8 +410,8 @@ Widget::__callStatic('sMethod', array(NULL, 1.234)) A *const-declaration* must only appear at the top level of a script, and must not redefine an existing [c-constant](06-constants.md#general). -A *class-const-declaration* must be inside a [*class-definition*](#class-members) or be an -[*interface constant*](15-interfaces.md#interface-members). +A *class-const-declaration* must be inside a [*class-declaration*](#class-members) or +[*interface-declaration*](15-interfaces.md#interface-members). A class constant must not have a `static` specifier. @@ -413,6 +420,7 @@ A class constant must not have a `static` specifier. A *const-declaration* defines a c-constant. If *visibility-modifier* for a class constant is omitted, `public` is assumed. +The *visibility-modifier* applies to all constants defined in the *const-elements* list. All constants are implicitly `static`. diff --git a/spec/19-grammar.md b/spec/19-grammar.md index b4d4d9e0..3010829d 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -1105,10 +1105,17 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# trait-use-clause const-declaration: - const name = constant-expression ; + const const-elements ; class-const-declaration: - visibility-modifieropt const name = constant-expression ; + visibility-modifieropt const const-elements ; + + const-elements: + const-element + const-elements const-element + + const-element: + name = constant-expression property-declaration: property-modifier variable-name property-initializeropt ; From f57050faed1a0ce39fb0c662e9e9fc40a277e3f1 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 11 Jul 2016 20:37:40 +0200 Subject: [PATCH 011/146] Can also defined multiple properties at once --- spec/14-classes.md | 13 ++++++++++--- spec/19-grammar.md | 9 ++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/spec/14-classes.md b/spec/14-classes.md index 281a85a2..f23bb9ca 100644 --- a/spec/14-classes.md +++ b/spec/14-classes.md @@ -447,7 +447,7 @@ $col = Automobile::DEFAULT_COLOR;
   property-declaration:
-    property-modifier   variable-name   property-initializeropt  ;
+    property-modifier   property-elements   ;
 
   property-modifier:
     var
@@ -462,6 +462,13 @@ $col = Automobile::DEFAULT_COLOR;
   static-modifier:
     static
 
+  property-elements:
+    property-element
+    property-elements   property-element
+
+  property-element:
+    variable-name   property-initializeropt   ;
+
   property-initializer:
     =  constant-expression
 
@@ -473,10 +480,10 @@ $col = Automobile::DEFAULT_COLOR; **Semantics** -A *property-declaration* defines an instance or static property. +A *property-declaration* defines one or more instance or static properties. If [*visibility-modifier*](#general) is omitted, `public` is assumed. The `var` modifier -implies public visibility. The `static` modifier defines the member as [static member](#class-members). +implies public visibility. The `static` modifier defines the member as a [static member](#class-members). The *property-initializer* for instance properties is applied prior to the class's [constructor](#constructors) being called. diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 3010829d..f58f716a 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -1118,7 +1118,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# name = constant-expression property-declaration: - property-modifier variable-name property-initializeropt ; + property-modifier property-elements ; property-modifier: var @@ -1133,6 +1133,13 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# static-modifier: static + property-elements: + property-element + property-elements property-element + + property-element: + variable-name property-initializeropt ; + property-initializer: = constant-expression From 854b2d1d01e5c3d3feec16eebf94f5481611a875 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 11 Jul 2016 20:47:45 +0200 Subject: [PATCH 012/146] Remove =& from list of operators =& is actually = followed by &. --- spec/09-lexical-structure.md | 2 +- spec/19-grammar.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index d506d437..25f95437 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -864,7 +864,7 @@ echo ">$s<\n\n"; [ ] ( ) { } . -> ++ -- ** * + - ~ ! $ / % << >> < > <= >= == === != !== ^ | & && || ? : ; = **= *= /= %= += -= .= <<= - >>= &= ^= |= =& , ?? <=> ... + >>= &= ^= |= , ?? <=> ... **Semantics** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index f58f716a..2e3682f4 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -319,7 +319,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# [ ] ( ) { } . -> ++ -- ** * + - ~ ! $ / % << >> < > <= >= == === != !== ^ | & && || ? : ; = **= *= /= %= += -= .= <<= - >>= &= ^= |= =& , ?? <=> ... + >>= &= ^= |= , ?? <=> ... ##Syntactic Grammar From 4a0bcfb3c75f08320a05596d3658f6976890c5b9 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 12 Jul 2016 08:37:43 +0200 Subject: [PATCH 013/146] Punctuators: Fix spacing, add namespace separator --- spec/09-lexical-structure.md | 4 ++-- spec/19-grammar.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index 25f95437..9951bc96 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -861,10 +861,10 @@ echo ">$s<\n\n";
   operator-or-punctuator:: one of
-    [   ]    (   )   {    }   .   ->   ++   --   **   *   +   -   ~   !
+    [   ]   (   )   {   }   .   ->   ++   --   **   *   +   -   ~   !
     $   /   %   <<    >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
     &   &&   ||   ?   :   ;   =   **=   *=   /=   %=   +=   -=   .=   <<=
-    >>=   &=   ^=   |=   ,   ??   <=>   ...
+    >>=   &=   ^=   |=   ,   ??   <=>   ...   \
 
**Semantics** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 2e3682f4..c3440c3a 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -316,10 +316,10 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
   operator-or-punctuator:: one of
-    [   ]    (   )   {    }   .   ->   ++   --   **   *   +   -   ~   !
+    [   ]   (   )   {   }   .   ->   ++   --   **   *   +   -   ~   !
     $   /   %   <<    >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
     &   &&   ||   ?   :   ;   =   **=   *=   /=   %=   +=   -=   .=   <<=
-    >>=   &=   ^=   |=   ,   ??   <=>   ...
+    >>=   &=   ^=   |=   ,   ??   <=>   ...   \
 
##Syntactic Grammar From 48bf751fd190b83cb44d9033b4f56eb8ecf4474b Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Wed, 13 Jul 2016 13:46:09 +0200 Subject: [PATCH 014/146] Specify handling of undefined variables, constants, etc. --- spec/07-variables.md | 144 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 143 insertions(+), 1 deletion(-) diff --git a/spec/07-variables.md b/spec/07-variables.md index 064c8219..0ed53d01 100644 --- a/spec/07-variables.md +++ b/spec/07-variables.md @@ -3,7 +3,8 @@ ##General A *variable* is a named area of data storage that contains a PHP value. A variable is represented by a [VSlot](04-basic-concepts.md#general). A variable is created by [assigning a value](04-basic-concepts.md#assignment) to it. -A variable is destroyed by *unsetting* it, either by an explicit call to the intrinsic [`unset`](10-expressions.md#unset), or by the Engine. The intrinsic [`isset`](10-expressions.md#isset) tests if a given variable exists and is not set to `NULL`. A variable that somehow becomes defined, but is not initialized starts out with the value `NULL`. +A variable is destroyed by *unsetting* it, either by an explicit call to the intrinsic [`unset`](10-expressions.md#unset), or by the Engine. The intrinsic [`isset`](10-expressions.md#isset) tests if a given variable exists and is not set to `NULL`. +If a variable, which is not defined so far, is used in an expression, then different strategies are applied which determine whether the variable is defined implicitly or a substitution value is used instead and whether a notice is emitted or not. The strategies depend on the kind of the variable as well as on the context where the undefined variable is being used. The strategies are elaborated in the sub-sections of the different [kinds of variables](#kinds-of-variables) below. Variables have [names](09-lexical-structure.md#names). Distinct variables may have the same name provided they are in different [scopes](04-basic-concepts.md#scope). @@ -47,6 +48,14 @@ See [constants](06-constants.md#general) and [class constants](14-classes.md#con A constant defined outside of a class or interface is a [superglobal](#general). A constant has static [storage duration](04-basic-concepts.md#storage-duration) and is a non-modifiable lvalue. +**Undefined Constants** + +Undefined constants are not defined implicitly -- forward usages of constants are also classified as undefined constants here. A distinction between class/interface constants and top level constants is made. + +For top level constants: the name of the undefined constant (as string) is used as substitution value. Moreover, a notice is emitted stating that the corresponding constant was undefined. + +For class/interface constants: a fatal error is produced stating that the corresponding constant was undefined. + **Examples** ```PHP @@ -54,6 +63,27 @@ const MAX_HEIGHT = 10.5; // define two c-constants const UPPER_LIMIT = MAX_HEIGHT; define('COEFFICIENT_1', 2.345); // define two d-constants define('FAILURE', TRUE); + +//examples of undefined constants +echo NON_EXISTING_CONSTANT; // uses 'NON_EXISTING_CONSTANT' as substitution + // value and emits a notice stating that the + // constant was undefined. + +echo NON_EXISTING_CONSTANT; // same here, the constant is still undefined + // and 'NON_EXISTING_CONSTANT' is used as + // substitution value and a notice is emitted + // again. + +echo MAX_LENGTH; // same here due to a forward usage + // (MAX_LENGTH is defined further below). + // 'MAX_LENGTH' is used as substitution + // value and an notice is emitted. + +const MAX_LENGTH = 7.5; + +echo Exception::MESSAGE; // undefined class constant. Emits a fatal + // error and stops execution. + ``` ###Local Variables @@ -71,6 +101,10 @@ variable can be assigned to as a parameter in the parameter list of a has function [scope](04-basic-concepts.md#scope) and automatic [storage duration](04-basic-concepts.md#storage-duration). A local variable is a modifiable lvalue. +**Undefined Local Variables** + +The same rules as for [undefined global variables](#undefined-global-variables) apply. + **Examples** ```PHP @@ -118,11 +152,38 @@ removed by calling the [`unset` intrinsic](10-expressions.md#unset). The [scope](04-basic-concepts.md#scope) of an array element is the same as the scope of that array's name. An array element has allocated [storage duration](04-basic-concepts.md#storage-duration). +**Undefined Array Elements** + +Similar to [undefined global variables](#undefined-global-variables), a distinction is made based on the context where an undefined array element is used. + +*byValue Context* + +If one tries to access an undefined array element, then `NULL` is used as substitution value and a notice is emitted, stating that an undefined offset was used. The undefined offset is not created implicitly and a subsequent access results in another notice. + +*byRef Context* + +PHP defines implicitly an undefined array element when it is accessed byRef, a VSlot for the corresponding undefined offset is created and `NULL` is assigned to it. A notice is *not* emitted in this case. + **Examples** ```PHP $colors = ["red", "white", "blue"]; // create array with 3 elements $colors[] = "green"; // insert a new element + +echo $colors[100]; // element with offset 100 is undefined and NULL is + // used as substitution value. Moreover, a notice is + // emitted stating that an undefined offset was used. + +echo $colors[100]; // element with offset 100 is still undefined and NULL + // is used as substitution value instead. Another + // notice is emitted. + +$b = &colors[100]; // a VSlot for $b is created which points to the array + // element with the offset 100. An array element with + // offset 100 was undefined but implicitly defined + // because the assignment is byRef. Thus a VSlot for + // the array element with offset 100 is created and + // NULL is assigned to it. A notice is *not* emitted. ``` ###Function Statics @@ -166,6 +227,10 @@ declaration is called, that execution is dealing with an [alias](04-basic-concep to that static variable. If that alias is passed to the [`unset` intrinsic](10-expressions.md#unset), only that alias is destroyed. The next time that function is called, a new alias is created. +**Undefined Function Statics** + +Function statics are explicitly defined and thus cannot be undefined. + **Examples** ```PHP @@ -261,6 +326,83 @@ global variable. If that alias is passed to the [`unset` intrinsic](10-expressio only that alias is destroyed. The next time that function is called, a new alias is created with the current value of the global variable. + +**Undefined Global Variables** +A distinction is made based on the context where an undefined global variable is used. + +*byVal Context* + +PHP does not implicitly define an undefined global variable and uses `NULL` as substitution value instead. Furthermore, a notice is emitted, stating that the corresponding variable was undefined, unless the variable is used + +1. as the single expression in a statement. +2. as argument of [isset](10-expressions.md#isset). +3. as argument of [empty](10-expressions.md#empty). +4. as the left hand side of the [coalesce operator `??`](10-expressions.md#coalesce-operator). + +Since undefined global variables are not defined implicitly, they stay undefined. In general, a VSlot is not created for undefined variables used in a byValue context. + +*byRef Context* + +If the undefined variable is used in a [byRef context](04-basic-concepts#byRef) then PHP defines the variable implicitly. Hence, a VSlot is created for it and `NULL` is stored in it. A notice is *not* emitted in such a case. + +*Examples of Undefined Variables* + +Following some examples which outlines the behaviour with undefined global variables. + +```PHP +// The following 4 cases outline the exceptions of undefined variables +// used in byValue context where no notice is emitted. +$a; +isset($a); +empty($a); +$a ?? 'default Value'; + +$a = 1; // a VSlot for $a was created and 1 was assigned. + +$b = $c; // a VSlot for $b was created and the value of $c was assigned to + // it. But because $c in turn was undefined, NULL was used as + // substitution value instead. In addition, a notice was + // emitted stating that $c was undefined. + +$d = $c; // a VSlot for $d was created and the value of $c was assigned to + // it. But since $c is still undefined, NULL was used as + // substitution value instead and another notice was emitted + // stating $c was undefined. + +$d + $e; // $e was undefined and `NULL` was used as substitution value + // instead. In addition, a notice was emitted stating that + // $e was undefined. + +$f = &$g; // a VSlot for $f was created which points to the VSlot of $g. + // $g in turn was undefined but was defined implicitly because the + // assignment was byRef. Thus a VSlot for $g was created and `NULL` + // was assigned to it. A notice was *not* emitted. + +$h = $g; // a VSlot for $h was created and the value of $g (which is NULL) + // was assigned to it. + +function foo($x){} + +foo($i); // $i was undefined and NULL was used as substitution value + // instead. In addition, a notice was emitted stating that $i + // was undefined. + +$j = $i; // a VSlot for $j was created and the value of $i was assigned to + // it. But because $i in turn was still undefined, NULL was used + // as substitution value instead. Another notice was emitted + // stating that $i was undefined. + +function bar(&$x){} + +bar($k); // $k was undefined but implicitly defined because it was passed to + // the function bar byRef. Thus a VSlot for $k was created and + // NULL was assigned to it. A notice was *not* emitted. + +$l = $k; // a VSlot for $l was created and the value of $k (which is NULL) + // was assigned to it. + +``` + **Examples** ```PHP From ba380138b88e51321352fdfa43ff47ca0f7d8109 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 13 Jul 2016 13:54:16 +0200 Subject: [PATCH 015/146] Specify that qualified constant uses throw Error --- spec/07-variables.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/spec/07-variables.md b/spec/07-variables.md index 0ed53d01..a4c52045 100644 --- a/spec/07-variables.md +++ b/spec/07-variables.md @@ -52,9 +52,9 @@ and is a non-modifiable lvalue. Undefined constants are not defined implicitly -- forward usages of constants are also classified as undefined constants here. A distinction between class/interface constants and top level constants is made. -For top level constants: the name of the undefined constant (as string) is used as substitution value. Moreover, a notice is emitted stating that the corresponding constant was undefined. +For top level constants: For unqualified usages, the name of the undefined constant (as string) is used as substitution value. Moreover, a notice is emitted stating that the corresponding constant was undefined. For qualified usages, an exception of type [`Error`](14-classes.md#class-error) is thrown. -For class/interface constants: a fatal error is produced stating that the corresponding constant was undefined. +For class/interface constants: An exception of type [`Error`](14-classes.md#class-error) is thrown, stating that the corresponding constant was undefined. **Examples** @@ -64,7 +64,7 @@ const UPPER_LIMIT = MAX_HEIGHT; define('COEFFICIENT_1', 2.345); // define two d-constants define('FAILURE', TRUE); -//examples of undefined constants +// Examples of undefined constants echo NON_EXISTING_CONSTANT; // uses 'NON_EXISTING_CONSTANT' as substitution // value and emits a notice stating that the // constant was undefined. @@ -79,10 +79,13 @@ echo MAX_LENGTH; // same here due to a forward usage // 'MAX_LENGTH' is used as substitution // value and an notice is emitted. +echo \NON_EXISTING_CONSTANT; // qualified use of undefined constant. Throws + // an exception of type Error. + const MAX_LENGTH = 7.5; -echo Exception::MESSAGE; // undefined class constant. Emits a fatal - // error and stops execution. +echo Exception::MESSAGE; // undefined class constant. Throws an exception + // of type Error. ``` From f3b5af920462d440aa29b9080366fec3cb655ffd Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 13 Jul 2016 21:25:41 +0200 Subject: [PATCH 016/146] Move undefined var description to locals --- spec/07-variables.md | 159 ++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 79 deletions(-) diff --git a/spec/07-variables.md b/spec/07-variables.md index a4c52045..6da9f0b1 100644 --- a/spec/07-variables.md +++ b/spec/07-variables.md @@ -104,10 +104,6 @@ variable can be assigned to as a parameter in the parameter list of a has function [scope](04-basic-concepts.md#scope) and automatic [storage duration](04-basic-concepts.md#storage-duration). A local variable is a modifiable lvalue. -**Undefined Local Variables** - -The same rules as for [undefined global variables](#undefined-global-variables) apply. - **Examples** ```PHP @@ -139,6 +135,84 @@ Unlike the [function static equivalent](#function-statics), function `f` outputs See the recursive function example in [storage duration section](04-basic-concepts.md#storage-duration). + +**Undefined Local Variables** + +A distinction is made based on the context where an undefined local variable is used. + +*byVal Context* + +PHP does not implicitly define an undefined local variable and uses `NULL` as substitution value instead. Furthermore, a notice is emitted, stating that the corresponding variable was undefined, unless the variable is used + +1. as the single expression in a statement. +2. as argument of [isset](10-expressions.md#isset). +3. as argument of [empty](10-expressions.md#empty). +4. as the left hand side of the [coalesce operator `??`](10-expressions.md#coalesce-operator). + +Since undefined local variables are not defined implicitly, they stay undefined. In general, a VSlot is not created for undefined variables used in a byValue context. + +*byRef Context* + +If the undefined variable is used in a [byRef context](04-basic-concepts#byRef) then PHP defines the variable implicitly. Hence, a VSlot is created for it and `NULL` is stored in it. A notice is *not* emitted in such a case. + +*Examples of Undefined Variables* + +Following some examples which outlines the behaviour with undefined local variables. + +```PHP +// The following 4 cases outline the exceptions of undefined variables +// used in byValue context where no notice is emitted. +$a; +isset($a); +empty($a); +$a ?? 'default Value'; + +$a = 1; // a VSlot for $a was created and 1 was assigned. + +$b = $c; // a VSlot for $b was created and the value of $c was assigned to + // it. But because $c in turn was undefined, NULL was used as + // substitution value instead. In addition, a notice was + // emitted stating that $c was undefined. + +$d = $c; // a VSlot for $d was created and the value of $c was assigned to + // it. But since $c is still undefined, NULL was used as + // substitution value instead and another notice was emitted + // stating $c was undefined. + +$d + $e; // $e was undefined and `NULL` was used as substitution value + // instead. In addition, a notice was emitted stating that + // $e was undefined. + +$f = &$g; // a VSlot for $f was created which points to the VSlot of $g. + // $g in turn was undefined but was defined implicitly because the + // assignment was byRef. Thus a VSlot for $g was created and `NULL` + // was assigned to it. A notice was *not* emitted. + +$h = $g; // a VSlot for $h was created and the value of $g (which is NULL) + // was assigned to it. + +function foo($x){} + +foo($i); // $i was undefined and NULL was used as substitution value + // instead. In addition, a notice was emitted stating that $i + // was undefined. + +$j = $i; // a VSlot for $j was created and the value of $i was assigned to + // it. But because $i in turn was still undefined, NULL was used + // as substitution value instead. Another notice was emitted + // stating that $i was undefined. + +function bar(&$x){} + +bar($k); // $k was undefined but implicitly defined because it was passed to + // the function bar byRef. Thus a VSlot for $k was created and + // NULL was assigned to it. A notice was *not* emitted. + +$l = $k; // a VSlot for $l was created and the value of $k (which is NULL) + // was assigned to it. + +``` + ###Array Elements **Syntax** @@ -157,7 +231,7 @@ array's name. An array element has allocated [storage duration](04-basic-concept **Undefined Array Elements** -Similar to [undefined global variables](#undefined-global-variables), a distinction is made based on the context where an undefined array element is used. +Similar to [undefined local variables](#undefined-local-variables), a distinction is made based on the context where an undefined array element is used. *byValue Context* @@ -329,82 +403,9 @@ global variable. If that alias is passed to the [`unset` intrinsic](10-expressio only that alias is destroyed. The next time that function is called, a new alias is created with the current value of the global variable. - **Undefined Global Variables** -A distinction is made based on the context where an undefined global variable is used. - -*byVal Context* - -PHP does not implicitly define an undefined global variable and uses `NULL` as substitution value instead. Furthermore, a notice is emitted, stating that the corresponding variable was undefined, unless the variable is used - -1. as the single expression in a statement. -2. as argument of [isset](10-expressions.md#isset). -3. as argument of [empty](10-expressions.md#empty). -4. as the left hand side of the [coalesce operator `??`](10-expressions.md#coalesce-operator). - -Since undefined global variables are not defined implicitly, they stay undefined. In general, a VSlot is not created for undefined variables used in a byValue context. - -*byRef Context* - -If the undefined variable is used in a [byRef context](04-basic-concepts#byRef) then PHP defines the variable implicitly. Hence, a VSlot is created for it and `NULL` is stored in it. A notice is *not* emitted in such a case. - -*Examples of Undefined Variables* - -Following some examples which outlines the behaviour with undefined global variables. - -```PHP -// The following 4 cases outline the exceptions of undefined variables -// used in byValue context where no notice is emitted. -$a; -isset($a); -empty($a); -$a ?? 'default Value'; - -$a = 1; // a VSlot for $a was created and 1 was assigned. - -$b = $c; // a VSlot for $b was created and the value of $c was assigned to - // it. But because $c in turn was undefined, NULL was used as - // substitution value instead. In addition, a notice was - // emitted stating that $c was undefined. - -$d = $c; // a VSlot for $d was created and the value of $c was assigned to - // it. But since $c is still undefined, NULL was used as - // substitution value instead and another notice was emitted - // stating $c was undefined. - -$d + $e; // $e was undefined and `NULL` was used as substitution value - // instead. In addition, a notice was emitted stating that - // $e was undefined. - -$f = &$g; // a VSlot for $f was created which points to the VSlot of $g. - // $g in turn was undefined but was defined implicitly because the - // assignment was byRef. Thus a VSlot for $g was created and `NULL` - // was assigned to it. A notice was *not* emitted. - -$h = $g; // a VSlot for $h was created and the value of $g (which is NULL) - // was assigned to it. - -function foo($x){} - -foo($i); // $i was undefined and NULL was used as substitution value - // instead. In addition, a notice was emitted stating that $i - // was undefined. - -$j = $i; // a VSlot for $j was created and the value of $i was assigned to - // it. But because $i in turn was still undefined, NULL was used - // as substitution value instead. Another notice was emitted - // stating that $i was undefined. - -function bar(&$x){} - -bar($k); // $k was undefined but implicitly defined because it was passed to - // the function bar byRef. Thus a VSlot for $k was created and - // NULL was assigned to it. A notice was *not* emitted. -$l = $k; // a VSlot for $l was created and the value of $k (which is NULL) - // was assigned to it. - -``` +The same rules as for [undefined local variables](#undefined-local-variables) apply. **Examples** From 599963eccd8d5f940195800302844f2e9a8e6e76 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 26 Jul 2016 10:26:31 +0200 Subject: [PATCH 017/146] Fix spaces between keywords --- spec/09-lexical-structure.md | 2 +- spec/19-grammar.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index 9951bc96..bf8ddec4 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -311,7 +311,7 @@ cannot be used as a name. 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 + protected public require require_once return static switch throw trait try unset use var while xor yield yield from diff --git a/spec/19-grammar.md b/spec/19-grammar.md index c3440c3a..f57ddf1d 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -117,7 +117,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# 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 + protected public require require_once return static switch throw trait try unset use var while xor yield yield from From 39cb8bede53e51929700fd2fae66ae3790306d7b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 9 Aug 2016 23:15:53 +0200 Subject: [PATCH 018/146] b-prefix is case-insensitive and applies to doc strings --- spec/09-lexical-structure.md | 28 +++++++++++++++++++--------- spec/19-grammar.md | 13 ++++++++----- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index bf8ddec4..a3b3665c 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -519,7 +519,7 @@ The type of a string literal is `string`.
   single-quoted-string-literal::
-    bopt  ' sq-char-sequenceopt  '
+    b-prefixopt  ' sq-char-sequenceopt  '
 
   sq-char-sequence::
     sq-char
@@ -530,7 +530,10 @@ The type of a string literal is `string`.
     \opt   any member of the source character set except single-quote (') or backslash (\)
 
   sq-escape-sequence:: one of
-    \'  \\
+    \'   \\
+
+  b-prefix:: one of
+    b   B
 
**Semantics** @@ -540,9 +543,9 @@ single-quotes (`'`, U+0027). The literal can contain any source character except single-quote (`'`) and backslash (`\\`), which can only be represented by their corresponding escape sequence. -The optional `b` prefix is reserved for future use in dealing with +The optional *b-prefix* is reserved for future use in dealing with so-called *binary strings*. For now, a *single-quoted-string-literal* -with a `b` prefix is equivalent to one without. +with a *b-prefix* is equivalent to one without. A single-quoted string literal is always a constant expression. @@ -560,7 +563,7 @@ A single-quoted string literal is always a constant expression.
   double-quoted-string-literal::
-    bopt  " dq-char-sequenceopt  "
+    b-prefixopt  " dq-char-sequenceopt  "
 
   dq-char-sequence::
     dq-char
@@ -601,6 +604,7 @@ A single-quoted string literal is always a constant expression.
 
 * [*octal-digit*](#integer-literals)
 * [*hexadecimal-digit*](#integer-literals)
+* [*b-prefix*](#single-quoted-string-literals)
 
 **Semantics**
 
@@ -610,9 +614,9 @@ double-quote (`"`) and backslash (`\\`), which can only be represented by
 their corresponding escape sequence. Certain other (and sometimes
 non-printable) characters can also be expressed as escape sequences.
 
-The optional `b` prefix is reserved for future use in dealing with
+The optional *b-prefix* is reserved for future use in dealing with
 so-called *binary strings*. For now, a *double-quoted-string-literal*
-with a `b` prefix is equivalent to one without.
+with a *b-prefix* is equivalent to one without.
 
 An escape sequence represents a single-character encoding, as described
 in the table below:
@@ -741,7 +745,7 @@ echo "\$myC->p1 = >$myC->p1<\n";  // → $myC->p1 = >2<
 
 
   heredoc-string-literal::
-    <<<  hd-start-identifier   new-line   hd-char-sequenceopt  new-line hd-end-identifier  ;opt   new-line
+    b-prefixopt <<<  hd-start-identifier   new-line   hd-char-sequenceopt  new-line hd-end-identifier  ;opt   new-line
 
   hd-start-identifier::
     name
@@ -775,6 +779,7 @@ echo "\$myC->p1 = >$myC->p1<\n";  // → $myC->p1 = >2<
 * [*new-line*](#comments)
 * [*dq-octal-escape-sequence*](#double-quoted-string-literals)
 * [*dq-hexadecimal-escape-sequence*](#double-quoted-string-literals)
+* [*b-prefix*](#single-quoted-string-literals)
 
 **Constraints**
 
@@ -799,6 +804,8 @@ A heredoc literal supports variable substitution as defined for
 A heredoc string literal is a constant expression if it does not contain
 any variable substitution.
 
+The optional *b-prefix* has no effect.
+
 **Examples**
 
 ```PHP
@@ -818,13 +825,14 @@ echo ">$s<";
 
 
   nowdoc-string-literal::
-    <<<  '  name  '  new-line  hd-char-sequenceopt   new-line name  ;opt   new-line
+    b-prefixopt <<<  '  name  '  new-line  hd-char-sequenceopt   new-line name  ;opt   new-line
 
**Defined elsewhere** * [*hd-char-sequence*](#heredoc-string-literals) * [*new-line*](#comments) +* [*b-prefix*](#single-quoted-string-literals) **Constraints** @@ -842,6 +850,8 @@ not subject to variable substitution (like the single-quoted string). A nowdoc string literal is a constant expression. +The optional *b-prefix* has no effect. + **Examples** ```PHP diff --git a/spec/19-grammar.md b/spec/19-grammar.md index f57ddf1d..e426ea10 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -214,7 +214,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# nowdoc-string-literal single-quoted-string-literal:: - bopt ' sq-char-sequenceopt ' + b-prefixopt ' sq-char-sequenceopt ' sq-char-sequence:: sq-char @@ -225,10 +225,13 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# \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:: - bopt " dq-char-sequenceopt " + b-prefixopt " dq-char-sequenceopt " dq-char-sequence:: dq-char @@ -281,7 +284,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# -> name heredoc-string-literal:: - <<< hd-start-identifier new-line hd-char-sequenceopt new-line hd-end-identifier ;opt new-line + b-prefixopt <<< hd-start-identifier new-line hd-char-sequenceopt new-line hd-end-identifier ;opt new-line hd-start-identifier:: name @@ -309,7 +312,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# \\ \$ \e \f \n \r \t \v nowdoc-string-literal:: - <<< ' name ' new-line hd-char-sequenceopt new-line name ;opt new-line + b-prefixopt <<< ' name ' new-line hd-char-sequenceopt new-line name ;opt new-line
###Operators and Punctuators From 8e8df911b732cc08ca0ae45f788c918147b9d007 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 9 Aug 2016 23:39:02 +0200 Subject: [PATCH 019/146] <<p1 = >$myC->p1<\n"; // → $myC->p1 = >2<
   heredoc-string-literal::
-    b-prefixopt <<<  hd-start-identifier   new-line   hd-char-sequenceopt  new-line hd-end-identifier  ;opt   new-line
+    b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
 
   hd-start-identifier::
     name
@@ -754,6 +754,9 @@ echo "\$myC->p1 = >$myC->p1<\n";  // → $myC->p1 = >2<
   hd-end-identifier::
     name
 
+  hd-body::
+    hd-char-sequenceopt   new-line
+
   hd-char-sequence::
     hd-char
     hd-char-sequence   hd-char
@@ -825,12 +828,12 @@ echo ">$s<";
 
 
   nowdoc-string-literal::
-    b-prefixopt <<<  '  name  '  new-line  hd-char-sequenceopt   new-line name  ;opt   new-line
+    b-prefixopt  <<<  '  name  '  new-line  hd-bodyopt   name  ;opt   new-line
 
**Defined elsewhere** -* [*hd-char-sequence*](#heredoc-string-literals) +* [*hd-body*](#heredoc-string-literals) * [*new-line*](#comments) * [*b-prefix*](#single-quoted-string-literals) diff --git a/spec/19-grammar.md b/spec/19-grammar.md index e426ea10..97c272f8 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -284,7 +284,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# -> name heredoc-string-literal:: - b-prefixopt <<< hd-start-identifier new-line hd-char-sequenceopt new-line hd-end-identifier ;opt new-line + b-prefixopt <<< hd-start-identifier new-line hd-bodyopt hd-end-identifier
;opt new-line hd-start-identifier:: name @@ -293,6 +293,9 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# hd-end-identifier:: name + hd-body:: + hd-char-sequenceopt new-line + hd-char-sequence:: hd-char hd-char-sequence hd-char @@ -312,7 +315,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# \\ \$ \e \f \n \r \t \v nowdoc-string-literal:: - b-prefixopt <<< ' name ' new-line hd-char-sequenceopt new-line name ;opt new-line + b-prefixopt <<< ' name ' new-line hd-bodyopt name ;opt new-line
###Operators and Punctuators From dbb78b15a468c7138c8b0fda1adb1c31cc6f86d2 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 24 Aug 2016 16:32:33 +0200 Subject: [PATCH 020/146] Fix markup for comment delimiters --- spec/09-lexical-structure.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index f8dcd747..b892222d 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -136,9 +136,9 @@ Two forms of comments are supported: *delimited comments* and **Semantics** -Except within a string literal or a comment, the characters /\* start a -delimited comment, which ends with the characters \*/. Except within a -string literal or a comment, the characters // or \# start a single-line +Except within a string literal or a comment, the characters `/*` start a +delimited comment, which ends with the characters `*/`. Except within a +string literal or a comment, the characters `//` or `#` start a single-line comment, which ends with a new line. That new line is not part of the comment. However, if the single-line comment is the last source element in an embedded script, the trailing new line can be omitted. (Note: this From 73662663cadc68f0b334fb174de0d1964f5c7b01 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 24 Aug 2016 16:41:50 +0200 Subject: [PATCH 021/146] Fix the whitespace definition. The vertical tab and the form-feed character are not part of the whitespaces. --- spec/09-lexical-structure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index b892222d..7705424c 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -157,7 +157,7 @@ though it was white space. ###White Space White space consists of an arbitrary combination of one or more -new-line, space, horizontal tab, vertical tab, and form-feed characters. +new-line, space and horizontal tab characters. **Syntax** From a1cc12b6a7fa3e6e779d09de8101ece489b7d911 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 24 Aug 2016 16:55:13 +0200 Subject: [PATCH 022/146] Fix markup of the `hd-body` rule. --- spec/09-lexical-structure.md | 2 +- spec/19-grammar.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index 7705424c..678e502c 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -755,7 +755,7 @@ echo "\$myC->p1 = >$myC->p1<\n"; // → $myC->p1 = >2< name hd-body:: - hd-char-sequenceopt new-line + hd-char-sequenceopt new-line hd-char-sequence:: hd-char diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 97c272f8..17898db6 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -294,7 +294,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# name hd-body:: - hd-char-sequenceopt new-line + hd-char-sequenceopt new-line hd-char-sequence:: hd-char From b2b8ac599733be8ca8d1a99d4e01876049b5f861 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 31 Aug 2016 19:13:05 +0200 Subject: [PATCH 023/146] Move literal production to syntactic grammar Not all literals are supported everywhere. Move to syntactic grammar to allow the distinction. --- spec/09-lexical-structure.md | 17 ----------------- spec/10-expressions.md | 24 +++++++++++++++++++++++- spec/19-grammar.md | 14 +++++--------- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index 678e502c..d4cea2b5 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -325,25 +325,8 @@ Also, all [*magic constants*](06-constants.md#context-dependent-constants) are a ####Literals -#####General - The source code representation of a value is called a *literal*. -**Syntax** - -
-  literal::
-    integer-literal
-    floating-literal
-    string-literal
-
- -**Defined elsewhere** - -* [*integer-literal*](#integer-literals) -* [*floating-literal*](#floating-point-literals) -* [*string-literal*](#string-literals) - #####Integer Literals **Syntax** diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 134caecc..f6b58e0a 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -105,7 +105,7 @@ function, `$a` need not actually be incremented. * [*variable-name*](09-lexical-structure.md#names) * [*qualified-name*](09-lexical-structure.md#names) -* [*literal*](09-lexical-structure.md#general-2) +* [*literal*](#literals) * [*constant-expression*](#constant-expressions) * [*intrinsic*](#general-2) * [*anonymous-function-creation-expression*](#anonymous-function-creation) @@ -120,6 +120,28 @@ The variable `$this` is predefined inside any non-static instance method (includ constructor) when that method is called from within an object context. The value of `$this` is the calling object or the object being constructed. +###Literals + +**Syntax** + +
+  literal:
+    integer-literal
+    floating-literal
+    string-literal
+
+ +**Defined elsewhere** + +* [*integer-literal*](09-lexical-structure.md#integer-literals) +* [*floating-literal*](09-lexical-structure.md#floating-point-literals) +* [*string-literal*](09-lexical-structure.md#string-literals) + +**Semantics** + +A literal evaluates to its value, as specified in the lexical specification for +[literals](09-lexical-structure.md#literals). + ###Intrinsics ####General diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 17898db6..2c29b272 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -123,15 +123,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# ###Literals -####General - -
-  literal::
-    integer-literal
-    floating-literal
-    string-literal
-
- ####Integer Literals
@@ -390,6 +381,11 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     (  expression  )
     $this
 
+  literal:
+    integer-literal
+    floating-literal
+    string-literal
+
   intrinsic:
     intrisic-construct
     intrisic-operator

From 50857c9737aa38332bef4dc69684c20958412253 Mon Sep 17 00:00:00 2001
From: Ivan Enderlin 
Date: Wed, 2 Nov 2016 07:59:24 +0100
Subject: [PATCH 024/146] =?UTF-8?q?Fix=20=E2=80=9Cintrisic=E2=80=9D=20typo?=
 =?UTF-8?q?=20(renamed=20to=20=E2=80=9Cintrinsic=E2=80=9D).?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 spec/10-expressions.md | 8 ++++----
 spec/19-grammar.md     | 6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/spec/10-expressions.md b/spec/10-expressions.md
index f6b58e0a..e92b5758 100644
--- a/spec/10-expressions.md
+++ b/spec/10-expressions.md
@@ -149,10 +149,10 @@ A literal evaluates to its value, as specified in the lexical specification for
 **Syntax**
 
   intrinsic:
-    intrisic-construct
-    intrisic-operator
+    intrinsic-construct
+    intrinsic-operator
 
-  intrisic-construct:
+  intrinsic-construct:
     echo-intrinsic
     list-intrinsic
     unset-intrinsic
@@ -187,7 +187,7 @@ are language constructs that are interpreted by the Engine.
 *intrinsic-operator* can be used as part of an expression, in any place
 other values or expressions could be used.
 
-*intrisic-construct* can be used only as stand-alone [statement](11-statements.md#statements).
+*intrinsic-construct* can be used only as stand-alone [statement](11-statements.md#statements).
 
 ####array
 
diff --git a/spec/19-grammar.md b/spec/19-grammar.md
index 2c29b272..e9dfa042 100644
--- a/spec/19-grammar.md
+++ b/spec/19-grammar.md
@@ -387,10 +387,10 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     string-literal
 
   intrinsic:
-    intrisic-construct
-    intrisic-operator
+    intrinsic-construct
+    intrinsic-operator
 
-  intrisic-construct:
+  intrinsic-construct:
     echo-intrinsic
     list-intrinsic
     unset-intrinsic

From fc4db11f8c3351d167b11e08ae189e7863367b5a Mon Sep 17 00:00:00 2001
From: Ivan Enderlin 
Date: Wed, 2 Nov 2016 07:58:23 +0100
Subject: [PATCH 025/146] Add missing backticks that break the markup.

---
 spec/10-expressions.md | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/spec/10-expressions.md b/spec/10-expressions.md
index e92b5758..89092d52 100644
--- a/spec/10-expressions.md
+++ b/spec/10-expressions.md
@@ -34,14 +34,14 @@ is a sequence point at the end of each full expression. The [logical and](#logic
 operators each contain a sequence point. (For example, in the
 following series of expression statements, `$a = 10; ++$a; $b = $a;`,
 there is sequence point at the end of each full expression, so the
-assignment to $a is completed before `$a` is incremented, and the
+assignment to `$a` is completed before `$a` is incremented, and the
 increment is completed before the assignment to `$b`).
 
 When an expression contains multiple operators, the *precedence* of
 those operators controls the order in which those operators are applied.
 (For example, the expression `$a - $b / $c` is evaluated as
-`$a - ($b / $c)` because the / operator has higher precedence than the
-binary - operator). The precedence of an operator is determined by the
+`$a - ($b / $c)` because the `/` operator has higher precedence than the
+binary `-` operator). The precedence of an operator is determined by the
 definition of its associated grammar production.
 
 If an operand occurs between two operators having the same precedence,
@@ -74,7 +74,7 @@ called, is unspecified).
 
 An expression that contains no side effects and whose resulting value is
 not used need not be evaluated. For example, the expression statements
-`6;, $i + 6;`, and `$i/$j`; are well formed, but they contain no side
+`6;`, `$i + 6;`, and `$i/$j`; are well formed, but they contain no side
 effects and their results are not used.
 
 A side effect need not be executed if it can be determined that no other

From 9c176451d86ce4bc3f10ecba510df769e41c9932 Mon Sep 17 00:00:00 2001
From: Ivan Enderlin 
Date: Wed, 9 Nov 2016 15:36:27 +0100
Subject: [PATCH 026/146] Fix markup (`s/ii/i/`).

---
 spec/10-expressions.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spec/10-expressions.md b/spec/10-expressions.md
index 89092d52..dfc6133f 100644
--- a/spec/10-expressions.md
+++ b/spec/10-expressions.md
@@ -442,7 +442,7 @@ isset($v1, $v2, $v3);  // results in FALSE
   unkeyed-list-expression-list:
     list-or-variable
     ,
-    unkeyed-list-expression-list  ,  list-or-variableopt
+    unkeyed-list-expression-list  ,  list-or-variableopt
 
   keyed-list-expression-list:
     expression  =>  list-or-variable

From 676257512edc3bd92a78300105d9f2fef569b864 Mon Sep 17 00:00:00 2001
From: Sara Itani 
Date: Mon, 7 Nov 2016 15:04:40 -0800
Subject: [PATCH 027/146] fix orphaned try-statement in `19-grammar.md`

`statement` should point to `try-statement`. This now matches the
definition in `11-statements.md`
---
 spec/19-grammar.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/spec/19-grammar.md b/spec/19-grammar.md
index e9dfa042..d616407f 100644
--- a/spec/19-grammar.md
+++ b/spec/19-grammar.md
@@ -829,6 +829,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     selection-statement
     iteration-statement
     jump-statement
+    try-statement
     declare-statement
     const-declaration
     function-definition

From a050aef11c681bbf53c0f8d708e10dc12a107e4a Mon Sep 17 00:00:00 2001
From: Sara Itani 
Date: Mon, 7 Nov 2016 18:01:56 -0800
Subject: [PATCH 028/146] Make switch-statement definition more precise

`case-statement` and `default-statement` usages must occur inside a `switch-statement`. Update the spec to represent this behavior more precisely in the grammar, rather than as an additional constraint.
---
 spec/11-statements.md | 31 +++++++++++--------------------
 spec/19-grammar.md    | 26 ++++++++++----------------
 2 files changed, 21 insertions(+), 36 deletions(-)

diff --git a/spec/11-statements.md b/spec/11-statements.md
index 36557317..7a969f2f 100644
--- a/spec/11-statements.md
+++ b/spec/11-statements.md
@@ -8,7 +8,7 @@
 
   statement:
     compound-statement
-    labeled-statement
+    named-label-statement
     expression-statement
     selection-statement
     iteration-statement
@@ -91,23 +91,8 @@ while (condition)
 **Syntax**
 
 
-  labeled-statement:
-    named-label-statement
-    case-statement
-    default-statement
-
   named-label-statement:
     name  :  statement
-
-  case-statement:
-    case   expression   case-default-label-terminator   statement
-
-  default-statement:
-    default  case-default-label-terminator   statement
-
-  case-default-label-terminator:
-    :
-    ;
 
**Defined elsewhere** @@ -122,8 +107,6 @@ A named label can be used as the target of a [`goto` statement](#the-goto-statem Named labels must be unique within a function. -A case and default labeled statements must only occur inside a [`switch` statement](#the-switch-statement). - **Semantics** Any statement may be preceded by a token sequence that declares a name @@ -308,13 +291,21 @@ else // this else does go with the outer if case-statements: case-statement statement-listopt case-statementsopt default-statement statement-listopt case-statementsopt + + case-statement: + case expression case-default-label-terminator statement + + default-statement: + default case-default-label-terminator statement + + case-default-label-terminator: + : + ;
**Defined elsewhere** * [*expression*](10-expressions.md#general-6) -* [*case-statement*](#labeled-statements) -* [*default-statement*](#labeled-statements) * [*compound-statement*](#compound-statements) * [*statement-list*](#compound-statements) diff --git a/spec/19-grammar.md b/spec/19-grammar.md index d616407f..1acdd679 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -824,7 +824,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# statement: compound-statement - labeled-statement + named-label-statement expression-statement selection-statement iteration-statement @@ -856,23 +856,8 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# ####Labeled Statements
-  labeled-statement:
-    named-label-statement
-    case-statement
-    default-statement
-
   named-label-statement:
     name  :  statement
-
-  case-statement:
-    case   expression   case-default-label-terminator   statement
-
-  default-statement:
-    default  case-default-label-terminator   statement
-
-  case-default-label-terminator:
-    :
-    ;
 
####Expression Statements @@ -917,6 +902,15 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# case-statement statement-listopt case-statementsopt default-statement statement-listopt case-statementsopt + case-statement: + case expression case-default-label-terminator statement + + default-statement: + default case-default-label-terminator statement + + case-default-label-terminator: + : + ;
####Iteration Statements From 04a14128a28b1e8a4c4b56ebf84f8caebfd67bf0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 9 Nov 2016 21:45:11 +0100 Subject: [PATCH 029/146] Fix case-statements definition --- spec/11-statements.md | 8 ++++---- spec/19-grammar.md | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/11-statements.md b/spec/11-statements.md index 7a969f2f..d1c10bbc 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -289,14 +289,14 @@ else // this else does go with the outer if switch ( expression ) : case-statementsopt endswitch; case-statements: - case-statement statement-listopt case-statementsopt - default-statement statement-listopt case-statementsopt + case-statement case-statementsopt + default-statement case-statementsopt case-statement: - case expression case-default-label-terminator statement + case expression case-default-label-terminator statement-listopt default-statement: - default case-default-label-terminator statement + default case-default-label-terminator statement-listopt case-default-label-terminator: : diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 1acdd679..8fa14f9a 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -899,14 +899,14 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# switch ( expression ) : case-statementsopt endswitch; case-statements: - case-statement statement-listopt case-statementsopt - default-statement statement-listopt case-statementsopt + case-statement case-statementsopt + default-statement case-statementsopt case-statement: - case expression case-default-label-terminator statement + case expression case-default-label-terminator statement-listopt default-statement: - default case-default-label-terminator statement + default case-default-label-terminator statement-listopt case-default-label-terminator: : From 13ef090cd9eed4c3f9ca2b139aceff977fac4dad Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 11 Nov 2016 10:17:20 +0100 Subject: [PATCH 030/146] `exit` with no parenthesis does have an opt. expr. `exit` is valid, `exit(42)` is valid, but `exit 42` is invalid. The optional expression must be surrounded by parenthesis. --- spec/10-expressions.md | 8 ++++---- spec/19-grammar.md | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index dfc6133f..5408f5a3 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -340,10 +340,10 @@ eval("echo \$str . \"\\n\";"); // → echo $str . "\n"; → prints Hello
   exit-intrinsic:
-    exit  expressionopt
-    exit  (  expressionopt  )
-    die   expressionopt
-    die   (   expressionopt )
+    exit
+    exit   (   expressionopt   )
+    die
+    die   (   expressionopt   )
 
**Defined elsewhere** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 8fa14f9a..9aa00091 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -421,10 +421,10 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# eval ( expression ) exit-intrinsic: - exit expressionopt - exit ( expressionopt ) - die expressionopt - die ( expressionopt ) + exit + exit ( expressionopt ) + die + die ( expressionopt ) isset-intrinsic: isset ( expression-list-one-or-more ) From 65ef21d1bc30cffd9bcd137a8509d39178e5c0c8 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 31 Aug 2016 19:05:45 +0200 Subject: [PATCH 031/146] Make description of variable syntax more correct --- spec/10-expressions.md | 402 +++++++++++++++++++++++++---------------- spec/14-classes.md | 2 +- spec/19-grammar.md | 81 ++++++--- 3 files changed, 302 insertions(+), 183 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 5408f5a3..cf4412db 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -91,35 +91,159 @@ function, `$a` need not actually be incremented.
   primary-expression:
-    variable-name
+    variable
+    class-constant-access-expression
     qualified-name
     literal
-    constant-expression
+    array-creation-expression
     intrinsic
     anonymous-function-creation-expression
     (  expression  )
-    $this
 
**Defined elsewhere** -* [*variable-name*](09-lexical-structure.md#names) +* [*variable*](#variables) * [*qualified-name*](09-lexical-structure.md#names) * [*literal*](#literals) -* [*constant-expression*](#constant-expressions) +* [*array-creation-expression*](#array-creation-operator) * [*intrinsic*](#general-2) * [*anonymous-function-creation-expression*](#anonymous-function-creation) * [*expression*](#script-inclusion-operators) +* [*class-constant-access-expression*](#scope-resolution-operator) **Semantics** The type and value of parenthesized expression are identical to those of the un-parenthesized expression. +###Simple Variable + +**Syntax** + +
+  simple-variable:
+    variable-name
+    $   simple-variable
+    $   {   expression   }
+
+ +**Defined elsewhere** + +* [*variable-name*](09-lexical-structure.md#names) +* [*expression*](#general-6) + +**Constraints** + +The *simple-variable* or *expression* in the last two variants +must designate a scalar value or object convertible to string. + +**Semantics** + +A *simple-variable* expression designates a variable with the name determined by either +the *variable-name* or the string representation of the result of the *simple-variable* or +*expression*, depending on which case is applicable. In the latter two cases the variable +name may contain characters that are not allowed in a lexical +[variable-name](09-lexical-structure.md#names). + +The behavior of a *simple-variable* in different contexts and for different types of +variables is as specified in the [variables](07-variables.md) section. + The variable `$this` is predefined inside any non-static instance method (including constructor) when that method is called from within an object context. The value of `$this` is the calling object or the object being constructed. +**Examples** + +```PHP +$color = "red"; +$$color = 123; // equivalent to $red = 123 +// ----------------------------------------- +$x = 'ab'; $ab = 'fg'; $fg = 'xy'; +$$ $ $x = 'Hello'; // equivalent to $xy = Hello +// ----------------------------------------- +$v1 = 3; +$$v1 = 22; // equivalent to ${3} = 22, variable name is "3" +$v2 = 9.543; +$$v2 = TRUE; // equivalent to ${9.543} = TRUE +$v3 = NULL; +$$v3 = "abc"; // equivalent to ${NULL} = "abc", here we create a variable with empty name +// ----------------------------------------- +function f1 () { return 2.5; } +${1 + f1()} = 1000; // equivalent to ${3.5} = 1000 +``` + +###Dereferencable expression + +**Syntax** + +
+  dereferencable-expression:
+    variable
+    (   expression   )
+    array-creation-expression
+    string-literal
+
+  callable-expression:
+    callable-variable
+    (   expression   )
+    array-creation-expression
+    string-literal
+
+ +**Defined elsewhere** + +* [*array-creation-expression*](#array-creation-operator) +* [*callable-variable*](#variables) +* [*expression*](#general-6) +* [*variable*](#variables) +* [*string-literal*](09-lexical-structure.md#string-literals) + +**Constraints** + +The *string-literal* must not use variable interpolation and must not be a heredoc +or nowdoc string literal. + +**Semantics** + +A *dereferencable-expression* can be used as the left hand side of dereferencing operators, such +as `[]`, `->` and `::`. A *callable-expression* can be used as the left hand side of the [function +call operator](#function-call-operator). + +###Variables + +**Syntax** + +
+  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
+
+ +**Defined elsewhere** + +* [*function-call-expression*](#function-call-operator) +* [*member-access-expression*](#member-access) +* [*member-call-expression*](#member-call) +* [*scoped-call-expresssion*](#scope-resolution-operator) +* [*scoped-property-access-expresssion*](#scope-resolution-operator) +* [*simple-variable*](#simple-variable) +* [*subscript-expression*](#subscript-operator) + +**Semantics** + +A *variable* is an expression that can *in principle* be used as an lvalue. However, the +individual possible expressions may further restrict whether they can behave as lvalues. +An expression that is not a *variable* can never act as an lvalue. + ###Literals **Syntax** @@ -732,13 +856,8 @@ class C primary-expression clone-expression object-creation-expression - array-creation-expression - subscript-expression - function-call-expression - member-selection-expression postfix-increment-expression postfix-decrement-expression - scope-resolution-expression exponentiation-expression
@@ -747,13 +866,8 @@ class C * [*primary-expression*](#general-1) * [*clone-expression*](#the-clone-operator) * [*object-creation-expression*](#the-new-operator) -* [*array-creation-expression*](#array-creation-operator) -* [*subscript-expression*](#subscript-operator) -* [*function-call-expression*](#function-call-operator) -* [*member-selection-expression*](#member-selection-operator) * [*postfix-increment-expression*](#postfix-increment-and-decrement-operators) * [*postfix-decrement-expression*](#postfix-increment-and-decrement-operators) -* [*scope-resolution-expression*](#scope-resolution-operator) * [*exponentiation-expression*](#exponentiation-operator) **Semantics** @@ -1010,23 +1124,23 @@ for ($i = -1; $i <= 2; ++$i) { echo $v[$i]; } // retrieves via keys -1, 0, 1, 2
   subscript-expression:
-    postfix-expression  [  expressionopt  ]
-    postfix-expression  {  expression  }   [Deprecated form]
+    dereferencable-expression  [  expressionopt  ]
+    dereferencable-expression  {  expression  }   [Deprecated form]
 
**Defined elsewhere** -* [*postfix-expression*](#general-3) +* [*dereferencable-expression*](#dereferencable-expression) * [*expression*](#general-6) **Constraints** -If *postfix-expression* designates a string, *expression* must not +If *dereferencable-expression* designates a string, *expression* must not designate a string. *expression* can be omitted only if *subscript-expression* is used in a -modifiable-lvalue context and *postfix-expression* does not designate a string. -Exception from this is when *postfix-expression* is an empty string - then it is +modifiable-lvalue context and *dereferencable-expression* does not designate a string. +Exception from this is when *dereferencable-expression* is an empty string - then it is converted to an empty array. If *subscript-expression* is used in a non-lvalue context, the element @@ -1045,14 +1159,14 @@ or `bool` values, or strings whose contents match exactly the pattern of [*decimal-literal*](09-lexical-structure.md#integer-literals), are [converted to integer](08-conversions.md#converting-to-integer-type), and key values of all other types are [converted to string](08-conversions.md#converting-to-string-type). -If both *postfix-expression* and *expression* designate strings, +If both *dereferencable-expression* and *expression* designate strings, *expression* is treated as if it specified the `int` key zero instead and a non-fatal error is produces. A *subscript-expression* designates a modifiable lvalue if and only if -*postfix-expression* designates a modifiable lvalue. +*dereferencable-expression* designates a modifiable lvalue. -**postfix-expression designates an array** +**dereferencable-expression designates an array** If *expression* is present, if the designated element exists, the type and value of the result is the type and value of that element; @@ -1077,7 +1191,7 @@ The result is the added new element, or `NULL` if the element was not added. [postfix- or prefix-increment or decrement operator](#postfix-increment-and-decrement-operators), the value of the new element is considered to be `NULL`. -**postfix-expression designates a string** +**dereferencable-expression designates a string** The *expression* is converted to `int` and the result is the character of the string at the position corresponding to that integer. If the integer is negative, @@ -1095,7 +1209,7 @@ The subscript operator can not be used on a string value in a byRef context or a side of [*compound-assignment-expression*](#compound-assignment), doing so will result in a fatal error. -**postfix-expression designates an object of a type that implements `ArrayAccess`** +**dereferencable-expression designates an object of a type that implements `ArrayAccess`** If *expression* is present, @@ -1175,7 +1289,7 @@ $x = $vect1[1]; // calls Vector::offsetGet(1)
   function-call-expression:
     qualified-name  (  argument-expression-listopt  )
-    postfix-expression  (  argument-expression-listopt  )
+    callable-expression  (  argument-expression-listopt  )
 
   argument-expression-list:
     argument-expression
@@ -1192,15 +1306,15 @@ $x = $vect1[1];   // calls Vector::offsetGet(1)
 
 **Defined elsewhere**
 
-* [*postfix-expression*](#general-3)
+* [*callable-expression*](#dereferencable-expression)
 * [*assignment-expression*](#general-5)
 
 **Constraints**
 
-*postfix-expression* must designate a function, either by being its
-*name*, by being a value of type string (but not a string literal) that
-contains the function's name, or by being an object of a type that implements
-[`__invoke`](14-classes.md#method-__invoke) method (including [`Closure`](14-classes.md#class-closure) objects).
+*callable-expression* must designate a function, by being a value of type string
+that contains the function's name, or by being an object of a type that implements
+[`__invoke`](14-classes.md#method-__invoke) method (including
+[`Closure`](14-classes.md#class-closure) objects).
 
 The number of arguments present in a function call must be at least as
 many as the number of non-optional parameters defined for that function.
@@ -1220,18 +1334,12 @@ An expression of the form *function-call-expression* is a *function
 call*. The expression designates the *called function*, and
 *argument-expression-list* specifies the arguments to be passed to that
 function. An argument can be any value. In a function call,
-*postfix-expression* is evaluated first, followed by each
+*callable-expression* is evaluated first, followed by each
 *assignment-expression* in the order left-to-right. There is
 a [sequence point](#general) after each argument is evaluated and right before the function is called.
 For details of the result of a function call see [`return` statement](11-statements.md#the-return-statement).
 The value of a function call is a modifiable lvalue only if the function returns a modifiable value byRef.
 
-When *postfix-expression* designates an instance method or constructor,
-the instance used in that designation is used as the value of `$this` in
-the invoked method or constructor. However, if no instance was used in
-that designation (for example, in the call `C::instance_method()`) the
-invoked instance has no `$this` defined.
-
 When a function is called, the value of each argument passed to it is
 assigned to the corresponding parameter in that function's definition,
 if such a parameter exists. The assignment of argument values to
@@ -1253,7 +1361,7 @@ defined, with an initial value of `NULL`.
 
 Direct and indirect recursive function calls are permitted.
 
-If *postfix-expression* is a string, this is
+If *callable-expression* is a string, this is
 a [variable function call](13-functions.md#variable-functions).
 
 If *variadic-unpacking* operation is used, the operand is considered to be a parameter list.
@@ -1298,32 +1406,31 @@ $anon = function () { ... };  // store a Closure in $anon
 $anon();  // call the anonymous function encapsulated by that object
 ```
 
-###Member-Selection Operator
+###Member Access
 
 **Syntax**
 
 
-  member-selection-expression:
-    postfix-expression  ->  member-selection-designator
+  member-access-expression:
+    dereferencable-expression   ->   member-name
 
-  member-selection-designator:
+  member-name:
     name
-    expression
+    simple-variable
+    {   expression   }
 
**Defined elsewhere** -* [*postfix-expression*](#general-3) +* [*dereferencable-expression*](#dereferencable-expression) * [*name*](09-lexical-structure.md#names) +* [*simple-variable*](#simple-variable) * [*expression*](#general-6) **Constraints** -*postfix-expression* must designate an object or be `NULL`, `FALSE`, or an -empty string. - -*name* must designate an instance property, or an instance or static -method of *postfix-expression*'s class type. +The *dereferencable-expression* must designate an object or be `NULL`, `FALSE`, +or an empty string. *expression* must be a value of type `string` (but not a string literal) that contains the name of an instance property (**without** the @@ -1332,25 +1439,24 @@ type. **Semantics** -A *member-selection-expression* designates an instance property or an -instance or static method of the object designated by -*postfix-expression*. For a property, the value is that of the property, -and is a modifiable lvalue if *postfix-expression* is a modifiable -lvalue. +A *member-access-expression* designates an instance property of the object +designated by *dereferencable-expression* with the name given by the string +representation of *member-name*. The value is that of the property, and is a +modifiable lvalue if *dereferencable-expression* is a modifiable lvalue. -When the `->` operator is used in a modifiable lvalue context and *name* -or *expression* designate a property that is not visible, the property -is treated as a [dynamic property](14-classes.md#dynamic-members). If *postfix-expression*'s class +When the `->` operator is used in a modifiable lvalue context and *member-name* +designate a property that is not visible, the property is treated as a +[dynamic property](14-classes.md#dynamic-members). If *dereferencable-expression*'s class type defines a [`__set` method](14-classes.md#method-__set), it is called to store the property's value. When the `->` operator is used in a non-lvalue context -and *name* or *expression* designate a property that is not visible, the -property is treated as a dynamic property. If *postfix-expression*'s -class type defines a [`__get` method](14-classes.md#method-__get), it is called to retrieve -the property's value. - -If *postfix-expression* is `NULL`, `FALSE`, or an empty string, an expression -of the form `$p->x = 10` causes an instance of [`stdClass`](14-classes.md#class-stdclass) to be -created with a dynamic property x having a value of 10. `$p` is then made +and *member-name* designate a property that is not visible, the property +is treated as a dynamic property. If *dereferencable-expression*'s +class type defines a [`__get` method](14-classes.md#method-__get), +it is called to retrieve the property's value. + +If *dereferencable-expression* is `NULL`, `FALSE`, or an empty string, an expression +of the form `$p->x = 10` causes an instance of [`stdClass`](14-classes.md#class-stdclass) +to be created with a dynamic property `x` having a value of 10. `$p` is then made to refer to this instance. **Examples** @@ -1380,21 +1486,62 @@ $p1->color = "red"; // turned into $p1->__set("color", "red"); $c = $p1->color; // turned into $c = $p1->__get("color"); ``` +###Member Call + +**Syntax** + +
+  member-call-expression:
+    dereferencable-expression   ->   member-name   (   argument-expression-listopt   )
+
+ +**Defined elsewhere** + +* [*dereferencable-expression*](#dereferencable-expression) +* [*member-name*](#member-access) +* [*argument-expression-list*](#function-call-operator) + +**Constraints** + +The *dereferencable-expression* must designate an object. + +Additionally the general [function call constraints](#function-call-operator) +apply. + +**Semantics** + +A *member-call-expression* calls an instance or static method of the +object designated by *dereferencable-expression*, with the method +name given by the string representation of *member-name* and the +arguments given by *argument-expression-list*. The value of +*dereferencable-expression* is used as the value of `$this` in the +invoked method. + +The general [function call semantics](#function-call-operator) apply. + +If the called method does not exist or is not visible from the current +scope an exception is thrown, unless a [`__call` method](14-classes.md#method-__call) +exists, in which case it will be called instead. + +**Examples** + +See [member access examples](#member-access). + ###Postfix Increment and Decrement Operators **Syntax**
   postfix-increment-expression:
-    unary-expression  ++
+    variable  ++
 
   postfix-decrement-expression:
-    unary-expression  --
+    variable  --
 
**Defined elsewhere** -* [*unary-expression*](#general-4) +* [*variable*](#variables) **Constraints** @@ -1419,14 +1566,19 @@ $a = array(100, 200); $v = $a[1]++; // old value of $ia[1] (200) is assigned **Syntax**
-  scope-resolution-expression:
-    scope-resolution-qualifier  ::  member-selection-designator
-    scope-resolution-qualifier  ::  class
+  scoped-property-access-expression:
+    scope-resolution-qualifier   ::   simple-variable
+
+  scoped-call-expression:
+    scope-resolution-qualifier   ::   member-name    (   argument-expression-listopt   )
+
+  class-constant-access-expression:
+    scope-resolution-qualifier   ::   name
 
   scope-resolution-qualifier:
     relative-scope
     qualified-name
-    expression
+    dereferencable-expression
 
   relative-scope:
     self
@@ -1436,14 +1588,17 @@ $a = array(100, 200); $v = $a[1]++; // old value of $ia[1] (200) is assigned
 
 **Defined elsewhere**
 
-* [*member-selection-designator*](#member-selection-operator)
+* [*argument-expression-list*](#function-call-operator)
+* [*dereferencable-expression*](#dereferencable-expression)
+* [*member-name*](#member-access)
+* [*simple-variable*](#simple-variable)
 
 **Constraints**
 
 *qualified-name* must be the name of a class or interface type.
 
-*expression* must be a value of type string (but not a string literal)
-that contains the name of a class or interface type.
+*expression* must be a value of type string that contains the name
+of a class or interface type.
 
 **Semantics**
 
@@ -1451,23 +1606,24 @@ From inside or outside a class or interface, operator `::` allows the
 selection of a constant. From inside or outside a class, this operator
 allows the selection of a static property, static method, or instance
 method. From within a class, it also allows the selection of an
-overridden property or method. For a property, the value is that of the
-property, and is a modifiable lvalue if *member-selection-designator* is
-a modifiable lvalue.
+overridden property or method.
 
-If *member-selection-designator* is a [*name*](09-lexical-structure.md#names), this operator is accessing
-a class constant. This form can not be used as an lvalue.
+If the *scoped-property-access-expression* form is used, this operator
+is accessing a static property given by *simple-variable* and can be
+used as an lvalue.
 
-If the operator is used as a *postfix-expression* for *function-call-expression*
-then the operator is accessing the method - which, outside of the object context,
+If the *class-constant-access-expression* form is used, this operator is
+is accessing a class constant given by *name*. This form can not be used
+as an lvalue.
+
+If the *scoped-call-expression* form is used, the operator is calling the
+method given by *member-anem*, which, outside of the object context,
 is treated as static method call.
 
 Inside of the object context when `$this` is defined and the called method is not `static` and
-the called class is the same of a parent of the class of `$this`, then the method is
+the called class is the same as a parent of the class of `$this`, then the method call is
 non-static with the same `$this`. Otherwise it is a static method call.
 
-Otherwise, the operator is accessing a static property.
-
 *relative-scope* designates the class with relation to the current class scope.
 From within a class, `self` refers to the same class, `parent` refers to the
 class the current class extends from. From within a method, `static` refers
@@ -1580,7 +1736,6 @@ for each.  **Examples**
     error-control-expression
     shell-command-expression
     cast-expression
-    variable-name-creation-expression
 
**Defined elsewhere** @@ -1592,7 +1747,6 @@ for each. **Examples** * [*error-control-expression*](#error-control-operator) * [*shell-command-expression*](#shell-command-operator) * [*cast-expression*](#cast-operator) -* [*variable-name-creation-expression*](#variable-name-creation-operator) **Semantics** @@ -1604,15 +1758,15 @@ These operators associate right-to-left.
   prefix-increment-expression:
-    ++ unary-expression
+    ++ variable
 
   prefix-decrement-expression:
-    -- unary-expression
+    -- variable
 
**Defined elsewhere** -* [*unary-expression*](#general-4) +* [*variable*](#variables) **Constraints** @@ -1947,70 +2101,6 @@ A *cast-type* of `unset` always results in a value of `NULL`. (This use of (int)(float)"123.87E3" // results in the int 123870 ``` -###Variable-Name Creation Operator - -**Syntax** - -
-  variable-name-creation-expression:
-    $   expression
-    $  {  expression  }
-
- -**Defined elsewhere** - -* [*expression*](#general-6) - -**Constraints** - -In the non-brace form, *expression* must be a -*variable-name-creation-expression* or a *variable-name* that designates -a scalar value or an object convertible to string. - -In the brace form, *expression* must be a -*variable-name-creation-expression* or an expression that designates a -scalar value or an object convertible to string. - -**Semantics** - -The result of this operator is a variable name spelled using the string -representation of the value of *expression* even though such a name -might not be permitted as a [variable-name](09-lexical-structure.md#names) source code token. - -The operator will consume the following *variable-name-creation-expression* and *variable-name* tokens, and -also tokens representing [subscript operator](#subscript-operator). - -In the absense of braces, the variable is parsed with left-to-right semantics, i.e., in example `$$o->pr` -the expression is treated as `${$o}->pr`, i.e. it is parsed as "take the value of $o, consider it a variable name, -and assuming the variable with this name is an object take the property 'pr' of it". - -**Examples** - -```PHP -$color = "red"; -$$color = 123; // equivalent to $red = 123 -// ----------------------------------------- -$x = 'ab'; $ab = 'fg'; $fg = 'xy'; -$$ $ $x = 'Hello'; // equivalent to $xy = Hello -// ----------------------------------------- -$v1 = 3; -$$v1 = 22; // equivalent to ${3} = 22, variable name is "3" -$v2 = 9.543; -$$v2 = TRUE; // equivalent to ${9.543} = TRUE -$v3 = NULL; -$$v3 = "abc"; // equivalent to ${NULL} = "abc", here we create a variable with empty name -// ----------------------------------------- -function f1 () { return 2.5; } -${1 + f1()} = 1000; // equivalent to ${3.5} = 1000 -// ----------------------------------------- -$v = array(10, 20); $a = 'v'; -$$a[0] = 5; // $v is [5, 20], since $$a is on the left of [] so it gets the first shot -$v = array(10, 20); $a = 'v'; -${$a[0]} = 5; // $v is 5 -$v = array(10, 20); $a = 'v'; -${$a}[0] = 5; // $ gets first shot at $a, $v is [5, 20] -``` - ##`instanceof` Operator **Syntax** diff --git a/spec/14-classes.md b/spec/14-classes.md index f23bb9ca..e95c5397 100644 --- a/spec/14-classes.md +++ b/spec/14-classes.md @@ -772,7 +772,7 @@ designated by `$name` using the arguments specified by the elements of the array designated by `$arguments`. It can return any value deemed appropriate. -Typically, `__call` is called implicitly, when the [`->` operator](10-expressions.md#member-selection-operator) +Typically, `__call` is called implicitly, when the [`->` operator](10-expressions.md#member-call) is used to call an instance method that is not visible. While `__call` can be called explicitly, the two scenarios do not diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 9aa00091..ba095893 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -372,14 +372,43 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
   primary-expression:
-    variable-name
+    variable
+    class-constant-access-expression
     qualified-name
     literal
-    constant-expression
+    array-creation-expression
     intrinsic
     anonymous-function-creation-expression
     (  expression  )
-    $this
+
+  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
 
   literal:
     integer-literal
@@ -480,13 +509,8 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     primary-expression
     clone-expression
     object-creation-expression
-    array-creation-expression
-    subscript-expression
-    function-call-expression
-    member-selection-expression
     postfix-increment-expression
     postfix-decrement-expression
-    scope-resolution-expression
     exponentiation-expression
 
   clone-expression:
@@ -527,12 +551,12 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     expression
 
   subscript-expression:
-    postfix-expression  [  expressionopt  ]
-    postfix-expression  {  expression  }   [Deprecated form]
+    dereferencable-expression  [  expressionopt  ]
+    dereferencable-expression  {  expression  }   [Deprecated form]
 
   function-call-expression:
     qualified-name  (  argument-expression-listopt  )
-    postfix-expression  (  argument-expression-listopt  )
+    callable-expression  (  argument-expression-listopt  )
 
   argument-expression-list:
     argument-expression
@@ -545,22 +569,31 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
   variadic-unpacking:
     ... assignment-expression
 
-  member-selection-expression:
-    postfix-expression  ->  member-selection-designator
+  member-access-expression:
+    dereferencable-expression   ->   member-name
 
-  member-selection-designator:
+  member-name:
     name
-    expression
+    simple-variable
+    {   expression   }
+
+  member-call-expression:
+    dereferencable-expression   ->   member-name   (   argument-expression-listopt   )
 
   postfix-increment-expression:
-    unary-expression  ++
+    variable  ++
 
   postfix-decrement-expression:
-    unary-expression  --
+    variable  --
+
+  scoped-property-access-expression:
+    scope-resolution-qualifier   ::   simple-variable
 
-  scope-resolution-expression:
-    scope-resolution-qualifier  ::  member-selection-designator
-    scope-resolution-qualifier  ::  class
+  scoped-call-expression:
+    scope-resolution-qualifier   ::   member-name    (   argument-expression-listopt   )
+
+  class-constant-access-expression:
+    scope-resolution-qualifier   ::   name
 
   scope-resolution-qualifier:
     relative-scope
@@ -590,10 +623,10 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     variable-name-creation-expression
 
   prefix-increment-expression:
-    ++ unary-expression
+    ++ variable
 
   prefix-decrement-expression:
-    -- unary-expression
+    -- variable
 
   unary-op-expression:
     unary-operator cast-expression
@@ -615,10 +648,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     array  binary  bool  boolean  double  int  integer  float  object
     real  string  unset
 
-  variable-name-creation-expression:
-    $   expression
-    $  {  expression  }
-
 
####instanceof Operator From d6e4f5116578f267d7bb79c2bc73a27987289140 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 11 Nov 2016 19:02:01 +0100 Subject: [PATCH 032/146] Add explicit constant-access-expression --- spec/10-expressions.md | 20 ++++++++++++++++++-- spec/19-grammar.md | 5 ++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index cf4412db..9705a180 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -93,7 +93,7 @@ function, `$a` need not actually be incremented. primary-expression: variable class-constant-access-expression - qualified-name + constant-access-expression literal array-creation-expression intrinsic @@ -104,7 +104,7 @@ function, `$a` need not actually be incremented. **Defined elsewhere** * [*variable*](#variables) -* [*qualified-name*](09-lexical-structure.md#names) +* [*constant-access-expression*](#constant-access-expression) * [*literal*](#literals) * [*array-creation-expression*](#array-creation-operator) * [*intrinsic*](#general-2) @@ -244,6 +244,22 @@ A *variable* is an expression that can *in principle* be used as an lvalue. Howe individual possible expressions may further restrict whether they can behave as lvalues. An expression that is not a *variable* can never act as an lvalue. +###Constant Access Expression + +
+ constant-access-expression:
+   qualified-name
+
+ +**Defined elsewhere** + +* [*qualified-name*](09-lexical-structure.md#names) + +**Semantics** + +A *constant-access-expression* evaluates to the value of the [constant](06-constants.md) +with name *qualified-name*. + ###Literals **Syntax** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index ba095893..b28137e3 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -374,7 +374,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# primary-expression: variable class-constant-access-expression - qualified-name + constant-access-expression literal array-creation-expression intrinsic @@ -410,6 +410,9 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# scoped-property-access-expression member-access-expression + constant-access-expression: + qualified-name + literal: integer-literal floating-literal From 84221d7a313f709c732d307f82932397f9a61f5d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 11 Nov 2016 21:42:03 +0100 Subject: [PATCH 033/146] Property specify constant expressions --- spec/10-expressions.md | 20 +++++++++++--------- spec/19-grammar.md | 1 - 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 9705a180..5bff620a 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -3573,25 +3573,27 @@ and relative path) still are considered the same file.
   constant-expression:
-    array-creation-expression
     expression
 
**Defined elsewhere** -* [*array-creation-expression*](#array-creation-operator) * [*expression*](#general-6) **Constraints** -All of the *element-key* and *element-value* elements in -[*array-creation-expression*](#array-creation-operator) must be literals. +The *expression* may only use the following syntactic elements: -*expression* must have a scalar type, and be a literal or the name of a [c-constant](06-constants.md#general). +* [Literals](#literals). String literals must not use interpolation. +* [Array creation expressions](#array-creation-operator). +* Unary operators `+`, `-`, `~`, `!`. +* Binary operators `+`, `-`, `*`, `/`, `%`, `.`, `**`, `^`, `|`, `&`, + `<`, `>`, `<=`, `>=`, `<=>`, `==`, `!=`, `===`, `!==`, `&&`, `||`, `??`. +* [Conditional expressions](#conditional-operator). +* [Subscript expressions](#subscript-operator). +* [Constant access expressions](#constant-access-expression). +* [Class constant access expressions](#scope-resolution-operator). **Semantics** -A *constant-expression* is the value of a c-constant. A *constant-expression* -is required in several contexts, such as in initializer values in a -[*const-declaration*](14-classes.md#constants) and default initial values in a [function -definition](13-functions.md#function-definitions). +A *constant-expression* evaluates to the value of the constituent *expression*. diff --git a/spec/19-grammar.md b/spec/19-grammar.md index b28137e3..f7c10eca 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -844,7 +844,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
   constant-expression:
-    array-creation-expression
     expression
 
From 598034c9f9e6d9f36689e5f8fcd17d5abc3b9e2b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 11 Nov 2016 21:49:28 +0100 Subject: [PATCH 034/146] Regenerate TOC --- spec/00-specification-for-php.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/spec/00-specification-for-php.md b/spec/00-specification-for-php.md index 0016d82c..6d682038 100644 --- a/spec/00-specification-for-php.md +++ b/spec/00-specification-for-php.md @@ -86,7 +86,6 @@ is distributed without any warranty. - [Names](09-lexical-structure.md#names) - [Keywords](09-lexical-structure.md#keywords) - [Literals](09-lexical-structure.md#literals) - - [General](09-lexical-structure.md#general-2) - [Integer Literals](09-lexical-structure.md#integer-literals) - [Floating-Point Literals](09-lexical-structure.md#floating-point-literals) - [String Literals](09-lexical-structure.md#string-literals) @@ -99,6 +98,11 @@ is distributed without any warranty. - [General](10-expressions.md#general) - [Primary Expressions](10-expressions.md#primary-expressions) - [General](10-expressions.md#general-1) + - [Simple Variable](10-expressions.md#simple-variable) + - [Dereferencable expression](10-expressions.md#dereferencable-expression) + - [Variables](10-expressions.md#variables) + - [Constant Access Expression](10-expressions.md#constant-access-expression) + - [Literals](10-expressions.md#literals) - [Intrinsics](10-expressions.md#intrinsics) - [General](10-expressions.md#general-2) - [array](10-expressions.md#array) @@ -118,7 +122,8 @@ is distributed without any warranty. - [Array Creation Operator](10-expressions.md#array-creation-operator) - [Subscript Operator](10-expressions.md#subscript-operator) - [Function Call Operator](10-expressions.md#function-call-operator) - - [Member-Selection Operator](10-expressions.md#member-selection-operator) + - [Member Access](10-expressions.md#member-access) + - [Member Call](10-expressions.md#member-call) - [Postfix Increment and Decrement Operators](10-expressions.md#postfix-increment-and-decrement-operators) - [Scope-Resolution Operator](10-expressions.md#scope-resolution-operator) - [Exponentiation Operator](10-expressions.md#exponentiation-operator) @@ -129,7 +134,6 @@ is distributed without any warranty. - [Error Control Operator](10-expressions.md#error-control-operator) - [Shell Command Operator](10-expressions.md#shell-command-operator) - [Cast Operator](10-expressions.md#cast-operator) - - [Variable-Name Creation Operator](10-expressions.md#variable-name-creation-operator) - [`instanceof` Operator](10-expressions.md#instanceof-operator) - [Multiplicative Operators](10-expressions.md#multiplicative-operators) - [Additive Operators](10-expressions.md#additive-operators) @@ -272,7 +276,6 @@ is distributed without any warranty. - [Names](19-grammar.md#names) - [Keywords](19-grammar.md#keywords) - [Literals](19-grammar.md#literals) - - [General](19-grammar.md#general-3) - [Integer Literals](19-grammar.md#integer-literals) - [Floating-Point Literals](19-grammar.md#floating-point-literals) - [String Literals](19-grammar.md#string-literals) @@ -300,7 +303,7 @@ is distributed without any warranty. - [Script Inclusion Operators](19-grammar.md#script-inclusion-operators) - [Constant Expressions](19-grammar.md#constant-expressions) - [Statements](19-grammar.md#statements) - - [General](19-grammar.md#general-4) + - [General](19-grammar.md#general-3) - [Compound Statements](19-grammar.md#compound-statements) - [Labeled Statements](19-grammar.md#labeled-statements) - [Expression Statements](19-grammar.md#expression-statements) From e07c954abd8f04847eed6884defdf8bd2219e8cc Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 11 Nov 2016 22:00:47 +0100 Subject: [PATCH 035/146] Refactor toc.php for reusability --- tools/toc.php | 42 +++++++++--------------------------------- tools/util.php | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 33 deletions(-) create mode 100644 tools/util.php diff --git a/tools/toc.php b/tools/toc.php index 17b51ce8..276769b6 100644 --- a/tools/toc.php +++ b/tools/toc.php @@ -1,5 +1,7 @@ $path) { + $contents = file_get_contents($path); + foreach (heading_info($contents) as $info) { + $title = $info['title']; + $anchor = $info['anchor']; + $indent = str_repeat(' ', $info['level']); + $output .= "$indent- [$title]($fileName#$anchor)\n"; } } diff --git a/tools/util.php b/tools/util.php new file mode 100644 index 00000000..e6d21e58 --- /dev/null +++ b/tools/util.php @@ -0,0 +1,46 @@ + $path. */ +function spec_files() { + $dir = __DIR__ . '/../spec/'; + $files = scandir($dir); + + foreach ($files as $file) { + if (pathinfo($file, PATHINFO_EXTENSION) != 'md') { + continue; + } + if ($file == '00-specification-for-php.md' || $file == 'php-spec-draft.md') { + continue; + } + + yield $file => $dir . $file; + } +} + +function heading_info($code) { + $anchors = []; + $lines = explode("\n", $code); + foreach ($lines as $line) { + if (!preg_match('/^(#+)\s*(.+)/', $line, $matches)) { + continue; + } + + list(, $hashes, $title) = $matches; + + $anchor = strtr(strtolower($title), ' ', '-'); + $anchor = preg_replace('/[^\w-]/', '', $anchor); + + if (isset($anchors[$anchor])) { + $anchors[$anchor]++; + $anchor .= '-' . $anchors[$anchor]; + } else { + $anchors[$anchor] = 0; + } + + yield [ + 'title' => $title, + 'anchor' => $anchor, + 'level' => strlen($hashes) - 1 + ]; + } +} From 61641e09508d3588e02aa85f542e8702318597f3 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 11 Nov 2016 22:10:47 +0100 Subject: [PATCH 036/146] Add check_refs tool --- tools/check_refs.php | 36 ++++++++++++++++++++++++++++++++++++ tools/util.php | 2 ++ 2 files changed, 38 insertions(+) create mode 100644 tools/check_refs.php diff --git a/tools/check_refs.php b/tools/check_refs.php new file mode 100644 index 00000000..f76e7356 --- /dev/null +++ b/tools/check_refs.php @@ -0,0 +1,36 @@ + $path) { + $contents = file_get_contents($path); + foreach (heading_info($contents) as $info) { + $fullAnchor = $fileName . '#' . $info['anchor']; + $anchors[$fullAnchor] = true; + } +} + +// Find unknown anchor references +foreach (spec_files() as $fileName => $path) { + $contents = file_get_contents($path); + + if (!preg_match_all('/\]\(([^)]+)\)/', $contents, $matches)) { + continue; + } + + foreach ($matches[1] as $anchor) { + if (!preg_match('/^(#|\d{2})/', $anchor)) { + continue; + } + + if ('#' === $anchor[0]) { + $anchor = $fileName . $anchor; + } + + if (!isset($anchors[$anchor])) { + echo "Unknown anchor $anchor in $fileName\n"; + } + } +} diff --git a/tools/util.php b/tools/util.php index e6d21e58..52a8a999 100644 --- a/tools/util.php +++ b/tools/util.php @@ -17,6 +17,8 @@ function spec_files() { } } +/* Iterator of heading information. + * Assoc array with title, anchor, level. */ function heading_info($code) { $anchors = []; $lines = explode("\n", $code); From 547f723ae305479ddc6f642223868b3aaf07e518 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 11 Nov 2016 22:33:43 +0100 Subject: [PATCH 037/146] Fix invalid references --- spec/04-basic-concepts.md | 10 +++++----- spec/05-types.md | 2 +- spec/06-constants.md | 2 +- spec/07-variables.md | 16 +++------------- spec/09-lexical-structure.md | 16 ++++++++++------ spec/10-expressions.md | 16 ++++++++-------- spec/14-classes.md | 28 +++++++++++++++++----------- spec/19-grammar.md | 8 +++++--- tools/check_refs.php | 3 +++ 9 files changed, 53 insertions(+), 48 deletions(-) diff --git a/spec/04-basic-concepts.md b/spec/04-basic-concepts.md index 3de18073..7fcb2818 100644 --- a/spec/04-basic-concepts.md +++ b/spec/04-basic-concepts.md @@ -249,7 +249,7 @@ VSlot, they become eligible for reclamation to release the memory they occupy. The engine may reclaim a VStore or HStore at any time between when it becomes eligible for reclamation and the end of the script execution. -Before reclaiming an HStore that represents an [object](05-types.md#object-types), +Before reclaiming an HStore that represents an [object](05-types.md#objects), the Engine should invoke the object's [destructor](14-classes.md#constructors) if one is defined. The Engine must reclaim each VSlot when the [storage duration](#storage-duration) of its @@ -647,7 +647,7 @@ side of byRef assignment. ByRef assignment of non-scalar types works using the same mechanism as byRef assignment for scalar types. Nevertheless, it is worthwhile to describe a few examples to clarify the semantics of byRef assignment. -Recall the [example using the `Point` class](#value-assignment-of-object-and-resource-types-to-a-local-variable): +Recall the [example using the `Point` class](#value-assignment-of-objects-to-a-local-variable): `$a = new Point(1, 3);` @@ -719,7 +719,7 @@ it can be destoyed too. ####Value Assignment of Array Types to Local Variables The semantics of value assignment of array types is different from value -assignment of other types. Recall the `Point` class from [the examples](#value-assignment-of-object-and-resource-types-to-a-local-variable), and consider the following [value assignments](10-expressions.md#simple-assignment) and their abstract implementation: +assignment of other types. Recall the `Point` class from [the examples](#value-assignment-of-objects-to-a-local-variable), and consider the following [value assignments](10-expressions.md#simple-assignment) and their abstract implementation: `$a = array(10, 'B' => new Point(1, 3));` @@ -1231,7 +1231,7 @@ treated as byRef assignments. ###Cloning objects When an object instance is allocated, operator [`new`](10-expressions.md#the-new-operator) returns a handle -that points to that object. As described [above](#value-assignment-of-object-and-resource-types-to-a-local-variable), +that points to that object. As described [above](#value-assignment-of-objects-to-a-local-variable), value assignment of a handle to an object does not copy the object HStore itself. Instead, it creates a copy of the handle. The copying of the HStore itself is performed via [operator `clone`](10-expressions.md#the-clone-operator). @@ -1324,7 +1324,7 @@ The class scope of an [interface member m](14-classes.md#class-members) that is an interface type I is the body of I. When a [trait](16-traits.md#general) is used by a class or an interface, the [trait's -members](16-traits.md#trait-members) take on the class scope of a member of that class or +members](16-traits.md#trait-declarations) take on the class scope of a member of that class or interface. ##Storage Duration diff --git a/spec/05-types.md b/spec/05-types.md index bc5f4ea6..87c553db 100644 --- a/spec/05-types.md +++ b/spec/05-types.md @@ -95,7 +95,7 @@ function [`is_nan`](http://www.php.net/is_nan) indicates if a given floating-poi A string is a set of contiguous bytes that represents a sequence of zero or more characters. -Conceptually, a string can be considered as an [array](#array-types) of +Conceptually, a string can be considered as an [array](#the-array-type) of bytes—the *elements*—whose keys are the `int` values starting at zero. The type of each element is `string`. However, a string is *not* considered a collection, so it cannot be iterated over. diff --git a/spec/06-constants.md b/spec/06-constants.md index 7b8532f5..ca8b84cf 100644 --- a/spec/06-constants.md +++ b/spec/06-constants.md @@ -18,7 +18,7 @@ Specifically: - If `define` is able to define the given name, it returns `TRUE`; otherwise, it returns `FALSE`. -The constants can only hold a value of a [scalar type](05-types.md#scalar-types), an array or a [resource](05-types.md#resource-types). +The constants can only hold a value of a [scalar type](05-types.md#scalar-types), an array or a [resource](05-types.md#resources). The library function [`defined`](http://www.php.net/defined) reports if a given name (specified as a string) is defined as a constant. The library function [`constant`](http://www.php.net/constant) diff --git a/spec/07-variables.md b/spec/07-variables.md index 6da9f0b1..7d23251e 100644 --- a/spec/07-variables.md +++ b/spec/07-variables.md @@ -356,24 +356,14 @@ echo "\$fs = $fs\n"; // $fs = 3 global variable-name-list ; variable-name-list: - global-variable - variable-name-list , global-variable - - global-variable: - variable-name - variable-name-creation-expression + simple-variable + variable-name-list , simple-variable
**Defined elsewhere** * [*expression*](10-expressions.md#general-6) -* [*variable-name*](09-lexical-structure.md#names) -* [*variable-name-creation-expression*](10-expressions.md#variable-name-creation-operator) - -**Constraints** - -Each *variable-name-creation-expression* must designate a simple variable name, i.e. it can not include array elements, -property accesses, etc. that are not inside braced expression. +* [*simple-variable*](10-expressions.md#simple-variable) **Semantics** diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index d4cea2b5..e038bb95 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -194,7 +194,9 @@ There are several kinds of source *tokens*: variable-name name keyword - literal + integer-literal + floating-literal + string-literal operator-or-punctuator @@ -203,7 +205,9 @@ There are several kinds of source *tokens*: * [*variable-name*](#names) * [*name*](#names) * [*keyword*](#keywords) -* [*literal*](#general-2) +* [*integer-literal*](#integer-literals) +* [*floating-literal*](#floating-point-literals) +* [*string-literal*](#string-literals) * [*operator-or-punctuator*](#operators-and-punctuators) ####Names @@ -273,11 +277,11 @@ The following names cannot be used as the names of classes, interfaces, or trait The following names are reserved for future use and should not be used as the names of classes, interfaces, or traits: `mixed`, `numeric`, `object`, and `resource`. -With the exception of `class`, all [keywords](09-lexical-structures#keywords) can be used as names for the members of a class, interface, or trait. However, `class` can be used as the name of a property or method. +With the exception of `class`, all [keywords](#keywords) can be used as names for the members of a class, interface, or trait. However, `class` can be used as the name of a property or method. Variable names and function names (when used in a function-call context) need not be defined as source tokens; they can also be created at -runtime using the [variable name-creation operator](10-expressions.md#variable-name-creation-operator). (For +runtime using [simple variable expressions](10-expressions.md#simple-variable). (For example, given `$a = "Total"; $b = 3; $c = $b + 5;`, `${$a.$b.$c} = TRUE;` is equivalent to `$Total38 = TRUE;`, and `${$a.$b.$c}()` is equivalent to `Total38()`). @@ -674,7 +678,7 @@ The variable substitution accepts the following syntax: * [*integer-literal*](#integer-literals) * [*expression*](10-expressions.md#general-6) -*expression* works the same way as in [variable name creation operator](10-expressions.md#variable-name-creation-operator). +*expression* works the same way as in [simple variable expressions](10-expressions.md#simple-variable). After the variable defined by the syntax above is evaluated, its value is converted to string according to the rules of [string conversion](08-conversions.md#converting-to-string-type) @@ -682,7 +686,7 @@ and is substituted into the string in place of the variable substitution express Subscript or property access defined by *offset-in-string* and *property-in-string* is resolved according to the rules of the [subscript operator](10-expressions.md#subscript-operator) -and [member selection operator](10-expressions.md#member-selection-operator) respectively. +and [member access operator](10-expressions.md#member-access-operator) respectively. The exception is that *name* inside *offset-in-string* is interpreted as a string literal even if it is not quoted. diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 5bff620a..0082e24f 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -231,8 +231,8 @@ call operator](#function-call-operator). **Defined elsewhere** * [*function-call-expression*](#function-call-operator) -* [*member-access-expression*](#member-access) -* [*member-call-expression*](#member-call) +* [*member-access-expression*](#member-access-operator) +* [*member-call-expression*](#member-call-operator) * [*scoped-call-expresssion*](#scope-resolution-operator) * [*scoped-property-access-expresssion*](#scope-resolution-operator) * [*simple-variable*](#simple-variable) @@ -1422,7 +1422,7 @@ $anon = function () { ... }; // store a Closure in $anon $anon(); // call the anonymous function encapsulated by that object ``` -###Member Access +###Member Access Operator **Syntax** @@ -1502,7 +1502,7 @@ $p1->color = "red"; // turned into $p1->__set("color", "red"); $c = $p1->color; // turned into $c = $p1->__get("color"); ``` -###Member Call +###Member Call Operator **Syntax** @@ -1514,7 +1514,7 @@ $c = $p1->color; // turned into $c = $p1->__get("color"); **Defined elsewhere** * [*dereferencable-expression*](#dereferencable-expression) -* [*member-name*](#member-access) +* [*member-name*](#member-access-operator) * [*argument-expression-list*](#function-call-operator) **Constraints** @@ -1541,7 +1541,7 @@ exists, in which case it will be called instead. **Examples** -See [member access examples](#member-access). +See [member access examples](#member-access-operator). ###Postfix Increment and Decrement Operators @@ -1606,7 +1606,7 @@ $a = array(100, 200); $v = $a[1]++; // old value of $ia[1] (200) is assigned * [*argument-expression-list*](#function-call-operator) * [*dereferencable-expression*](#dereferencable-expression) -* [*member-name*](#member-access) +* [*member-name*](#member-access-operator) * [*simple-variable*](#simple-variable) **Constraints** @@ -2921,7 +2921,7 @@ must have type `string`. If *assignment-expression* designates an expression having value type, see [assignment for scalar types](04-basic-concepts.md#byref-assignment-for-scalar-types-with-local-variables) -If *assignment-expression* designates an expression having handle type, see [assignment for object and resource types](04-basic-concepts.md#value-assignment-of-object-and-resource-types-to-a-local-variable). +If *assignment-expression* designates an expression having handle type, see [assignment for object and resource types](04-basic-concepts.md#value-assignment-of-objects-to-a-local-variable). If *assignment-expression* designates an expression having array type, see [assignment of array types](04-basic-concepts.md#value-assignment-of-array-types-to-local-variables). diff --git a/spec/14-classes.md b/spec/14-classes.md index e95c5397..cee4237f 100644 --- a/spec/14-classes.md +++ b/spec/14-classes.md @@ -248,14 +248,16 @@ Methods and properties can either be *static* or *instance* members. A static member is declared using `static`. An instance member is one that is not static. The name of a static or instance member can never be used on its own; it must always be used as the right-hand operand of the -[scope resolution operator](10-expressions.md#scope-resolution-operator) or the [member selection operator](10-expressions.md#member-selection-operator). +[scope resolution operator](10-expressions.md#scope-resolution-operator) +or the [member access operator](10-expressions.md#member-access-operator). Each instance of a class contains its own, unique set of instance properties of that class. An instance member is accessed via the -[`->` operator](10-expressions.md#member-selection-operator). In contrast, a static property designates -exactly one VSlot for its class, which does not belong to any instance, -per se. A static property exists whether or not any instances of that -class exist. A static member is accessed via the [`::` operator](10-expressions.md#scope-resolution-operator). +[`->` operator](10-expressions.md#member-access-operator). In contrast, +a static property designates exactly one VSlot for its class, which does +not belong to any instance, per se. A static property exists whether or +not any instances of that class exist. A static member is accessed via +the [`::` operator](10-expressions.md#scope-resolution-operator). When any instance method operates on a given instance of a class, within that method that object can be accessed via [`$this`](10-expressions.md#general-1). As a @@ -772,7 +774,8 @@ designated by `$name` using the arguments specified by the elements of the array designated by `$arguments`. It can return any value deemed appropriate. -Typically, `__call` is called implicitly, when the [`->` operator](10-expressions.md#member-call) +Typically, `__call` is called implicitly, when the +[`->` operator](10-expressions.md#member-call-operator) is used to call an instance method that is not visible. While `__call` can be called explicitly, the two scenarios do not @@ -1038,7 +1041,8 @@ The *method-modifiers* must not contain `static` and must define public visibili This instance method gets the value of the [dynamic property](#dynamic-members) designated by `$name`. It is up to the implementor to define the return value. -Typically, `__get` is called implicitly, when the [`->` operator](10-expressions.md#member-selection-operator) +Typically, `__get` is called implicitly, when the +[`->` operator](10-expressions.md#member-access-operator) is used in a non-lvalue context and the named property is not visible. While `__get` can be called explicitly, the two scenarios do not @@ -1244,7 +1248,8 @@ The *method-modifiers* must not contain `static` and must define public visibili This instance method sets the value of the [dynamic property](#dynamic-members) designated by `$name` to `$value`. No value is expected to be returned. -Typically, `__set` is called implicitly, when the [`->` operator](10-expressions.md#member-selection-operator) +Typically, `__set` is called implicitly, when the +[`->` operator](10-expressions.md#member-access-operator) is used in a modifiable lvalue context and the named property is not visible. @@ -1826,7 +1831,7 @@ $s = serialize($cp); $v = unserialize($s); ``` -Function `unserialize` takes an optional second argument, which specifies an array of trusted class names as strings. Objects found in the data stream whose type name is not in this trusted name list are converted to objects of type [`__PHP_Incomplete_Class`](#class-__PHP_Incomplete_Class). +Function `unserialize` takes an optional second argument, which specifies an array of trusted class names as strings. Objects found in the data stream whose type name is not in this trusted name list are converted to objects of type [`__PHP_Incomplete_Class`](#class-__php_incomplete_class). Any attempt to serialize an object having an anonymous class type results in an instance of type `Exception` being thrown. @@ -2024,8 +2029,9 @@ for any other operation except serialization will result in a fatal error. This class contains no members. It can be instantiated and used as a base class. An instance of this type is automatically created when a -non-object is [converted to an object](08-conversions.md#converting-to-object-type), or the [member selection -operator](10-expressions.md#member-selection-operator) is applied to `NULL`, `FALSE`, or an empty string. +non-object is [converted to an object](08-conversions.md#converting-to-object-type), +or the [member selection operator](10-expressions.md#member-access-operator) +is applied to `NULL`, `FALSE`, or an empty string. ###Predefined Error Classes diff --git a/spec/19-grammar.md b/spec/19-grammar.md index f7c10eca..78dbd5c5 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -67,7 +67,9 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# variable-name name keyword - literal + integer-literal + floating-literal + string-literal operator-or-punctuator @@ -362,8 +364,8 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# global variable-name-list ; variable-name-list: - expression - variable-name-list , expression + simple-variable + variable-name-list , simple-variable ###Expressions diff --git a/tools/check_refs.php b/tools/check_refs.php index f76e7356..eab817c4 100644 --- a/tools/check_refs.php +++ b/tools/check_refs.php @@ -21,6 +21,9 @@ } foreach ($matches[1] as $anchor) { + if (false === strpos($anchor, '#')) { + continue; + } if (!preg_match('/^(#|\d{2})/', $anchor)) { continue; } From d049fb8af5187cf7039fceca8b3d2866344948e1 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 12 Nov 2016 12:37:34 +0100 Subject: [PATCH 038/146] Fix markup --- spec/10-expressions.md | 2 +- spec/19-grammar.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 0082e24f..2a902691 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -1586,7 +1586,7 @@ $a = array(100, 200); $v = $a[1]++; // old value of $ia[1] (200) is assigned scope-resolution-qualifier :: simple-variable scoped-call-expression: - scope-resolution-qualifier :: member-name ( argument-expression-listopt ) + scope-resolution-qualifier :: member-name ( argument-expression-listopt ) class-constant-access-expression: scope-resolution-qualifier :: name diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 78dbd5c5..76ca4345 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -595,7 +595,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# scope-resolution-qualifier :: simple-variable scoped-call-expression: - scope-resolution-qualifier :: member-name ( argument-expression-listopt ) + scope-resolution-qualifier :: member-name ( argument-expression-listopt ) class-constant-access-expression: scope-resolution-qualifier :: name From 7a778c1db355c2e8f3d4c54ce0be2e2fa8646978 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 12 Nov 2016 12:40:13 +0100 Subject: [PATCH 039/146] Add redundant include/require productions The parenthesized forms are part of expression. --- spec/10-expressions.md | 12 ++++-------- spec/19-grammar.md | 12 ++++-------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 2a902691..278793fa 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -3426,8 +3426,7 @@ echo $x; // hello
   include-expression:
-    include  (  expression  )
-    include  expression
+    include   expression
 
**Defined elsewhere** @@ -3478,8 +3477,7 @@ If ((include 'Positions.php') == 1) ...
   include-once-expression:
-    include_once  (  expression  )
-    include_once  expression
+    include_once   expression
 
**Defined elsewhere** @@ -3526,8 +3524,7 @@ $c1 = new Circle(9, 7, 2.4);
   require-expression:
-    require  (  expression  )
-    require  expression
+    require   expression
 
**Defined elsewhere** @@ -3546,8 +3543,7 @@ produces a fatal error.
   require-once-expression:
-    require_once  (  expression  )
-    require_once  expression
+    require_once   expression
 
**Defined elsewhere** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 76ca4345..4071e92e 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -826,20 +826,16 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# require-once-expression include-expression: - include ( expression ) - include expression + include expression include-once-expression: - include_once ( expression ) - include_once expression + include_once expression require-expression: - require ( expression ) - require expression + require expression require-once-expression: - require_once ( expression ) - require_once expression + require_once expression ####Constant Expressions From 0ff2c672deb3b0f73478e56c490a195943e98bbe Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 12 Nov 2016 12:47:36 +0100 Subject: [PATCH 040/146] Remove sub-headings from grammar These don't provide a lot of value for an overview grammar listing, but make automatic regeneration of the grammar hard (because they do not correspond to the headings in the actual spec -- some headings are left out, others aren't and none of this follows any obvious rule). --- spec/11-statements.md | 4 +- spec/19-grammar.md | 152 +----------------------------------------- 2 files changed, 4 insertions(+), 152 deletions(-) diff --git a/spec/11-statements.md b/spec/11-statements.md index d1c10bbc..423c972b 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -118,8 +118,8 @@ execution. **Syntax**
-   expression-statement:
-     expressionopt  ;
+  expression-statement:
+    expressionopt  ;
 
**Defined elsewhere** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 4071e92e..e99c586f 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -6,8 +6,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# ##Lexical Grammar -###General -
   input-file::
     input-element
@@ -16,11 +14,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     comment
     white-space
     token
-
-###Comments - -
   comment::
     single-line-comment
     delimited-comment
@@ -43,11 +37,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 
   delimited-comment::
     /*   No characters or any source character sequence except */   */
-
- -###White Space -
   white-space::
     white-space-character
     white-space   white-space-character
@@ -56,13 +46,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     new-line
     Space character (U+0020)
     Horizontal-tab character (U+0009)
-
- -###Tokens -####General - -
   token::
     variable-name
     name
@@ -71,11 +55,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     floating-literal
     string-literal
     operator-or-punctuator
-
- -####Names -
   variable-name::
     $   name
 
@@ -107,11 +87,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     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
-
- -###Keywords -
   keyword:: one of
     abstract   and   array   as   break   callable   case   catch   class   clone
     const   continue   declare   default   die   do   echo   else   elseif   empty
@@ -121,13 +97,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     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
-
-###Literals - -####Integer Literals - -
   integer-literal::
     decimal-literal
     octal-literal
@@ -172,11 +142,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 
     binary-digit:: one of
         0  1
-
- -####Floating-Point Literals -
   floating-literal::
     fractional-literal   exponent-partopt
     digit-sequence   exponent-part
@@ -195,11 +161,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
   digit-sequence::
     digit
     digit-sequence   digit
-
-####String Literals - -
   string-literal::
     single-quoted-string-literal
     double-quoted-string-literal
@@ -309,11 +271,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 
   nowdoc-string-literal::
     b-prefixopt  <<<  '  name  '  new-line  hd-bodyopt   name  ;opt   new-line
-
-###Operators and Punctuators - -
   operator-or-punctuator:: one of
     [   ]   (   )   {   }   .   ->   ++   --   **   *   +   -   ~   !
     $   /   %   <<    >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
@@ -370,8 +328,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 
 ###Expressions
 
-####Primary Expressions
-
 
   primary-expression:
     variable
@@ -505,11 +461,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     &opt   variable-name
     use-variable-name-list  ,  &opt  variable-name
 
-
- -####Postfix Operators - -
   postfix-expression:
     primary-expression
     clone-expression
@@ -612,11 +563,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 
   exponentiation-expression:
     expression  **  expression
-
- -####Unary Operators -
   unary-expression:
     postfix-expression
     prefix-increment-expression
@@ -653,11 +600,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     array  binary  bool  boolean  double  int  integer  float  object
     real  string  unset
 
-
- -####instanceof Operator - -
   instanceof-expression:
     unary-expression
     instanceof-subject  instanceof   instanceof-type-designator
@@ -668,40 +610,24 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
   instanceof-type-designator:
     qualified-name
     expression
-
- -####Multiplicative Operators -
   multiplicative-expression:
     instanceof-expression
     multiplicative-expression  *  instanceof-expression
     multiplicative-expression  /  instanceof-expression
     multiplicative-expression  %  instanceof-expression
-
-####Additive Operators - -
   additive-expression:
     multiplicative-expression
     additive-expression  +  multiplicative-expression
     additive-expression  -  multiplicative-expression
     additive-expression  .  multiplicative-expression
-
-####Bitwise Shift Operators - -
   shift-expression:
     additive-expression
     shift-expression  <<  additive-expression
     shift-expression  >>  additive-expression
-
-####Relational Operators - -
   relational-expression:
     shift-expression
     relational-expression  <   shift-expression
@@ -709,11 +635,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     relational-expression  <=  shift-expression
     relational-expression  >=  shift-expression
     relational-expression  <=> shift-expression
-
-####Equality Operators - -
   equality-expression:
     relational-expression
     equality-expression  ==  relational-expression
@@ -721,11 +643,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     equality-expression  <>  relational-expression
     equality-expression  ===  relational-expression
     equality-expression  !==  relational-expression
-
- -####Bitwise Logical Operators -
   bitwise-AND-expression:
     equality-expression
     bit-wise-AND-expression  &  equality-expression
@@ -737,11 +655,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
   bitwise-inc-OR-expression:
     bitwise-exc-OR-expression
     bitwise-inc-OR-expression  |  bitwise-exc-OR-expression
-
- -####Logical Operators (form 1) -
   logical-AND-expression-1:
     bitwise-incl-OR-expression
     logical-AND-expression-1  &&  bitwise-inc-OR-expression
@@ -749,26 +663,14 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
   logical-inc-OR-expression-1:
     logical-AND-expression-1
     logical-inc-OR-expression-1  ||  logical-AND-expression-1
-
-####Conditional Operator - -
   conditional-expression:
     logical-inc-OR-expression-1
     logical-inc-OR-expression-1  ?  expressionopt  :  conditional-expression
-
- -####Coalesce Operator -
   coalesce-expression:
     logical-inc-OR-expression  ??  expression
-
- -####Assignment Operators -
   assignment-expression:
     conditional-expression
     coalesce-expression
@@ -787,11 +689,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 
   compound-assignment-operator: one of
     **=  *=  /=  %=  +=  -=  .=  <<=  >>=  &=  ^=  |=
-
-####Logical Operators (form 2) - -
   logical-AND-expression-2:
     assignment-expression
     logical-AND-expression-2  and  assignment-expression
@@ -804,20 +702,10 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     logical-exc-OR-expression
     logical-inc-OR-expression-2  or  logical-exc-OR-expression
 
-
- - -####yield Operator - -
   yield-expression:
     logical-inc-OR-expression-2
     yield  array-element-initializer
-
- -####Script Inclusion Operators -
   expression:
     yield-expression
     include-expression
@@ -836,21 +724,14 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 
   require-once-expression:
     require_once   expression
-
- -####Constant Expressions -
   constant-expression:
     expression
 
###Statements -####General -
-
   statement:
     compound-statement
     named-label-statement
@@ -869,31 +750,19 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     namespace-use-declaration
     global-declaration
     function-static-declaration
-
- -####Compound Statements -
   compound-statement:
     {   statement-listopt  }
 
   statement-list:
     statement
     statement-list   statement
-
-####Labeled Statements - -
   named-label-statement:
     name  :  statement
-
- -####Expression Statements -
-   expression-statement:
-     expressionopt  ;
+  expression-statement:
+    expressionopt  ;
 
   selection-statement:
     if-statement
@@ -940,11 +809,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
   case-default-label-terminator:
     :
     ;
-
- -####Iteration Statements -
   iteration-statement:
     while-statement
     do-statement
@@ -989,11 +854,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     &opt   expression
     list-intrinsic
 
-
- -####Jump Statements - -
   jump-statement:
     goto-statement
     continue-statement
@@ -1018,11 +878,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 
   throw-statement:
     throw  expression  ;
-
- -####The try Statement -
   try-statement:
     try  compound-statement   catch-clauses
     try  compound-statement   finally-clause
@@ -1037,11 +893,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 
   finally-clause:
     finally   compound-statement
-
- -####The declare Statement -
   declare-statement:
     declare  (  declare-directive  )  statement
     declare  (  declare-directive  )  :  statement-list  enddeclare  ;

From 7cd2faa0f81851a7f8891834bb4dc069a1e4f277 Mon Sep 17 00:00:00 2001
From: Nikita Popov 
Date: Sat, 12 Nov 2016 13:15:27 +0100
Subject: [PATCH 041/146] Fix formatting errors in grammar blocks

---
 spec/04-basic-concepts.md    | 24 ++++++++++++------------
 spec/07-variables.md         |  4 ++--
 spec/09-lexical-structure.md | 25 ++++++++++++-------------
 spec/10-expressions.md       |  4 ++--
 4 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/spec/04-basic-concepts.md b/spec/04-basic-concepts.md
index 7fcb2818..3c7ee1b0 100644
--- a/spec/04-basic-concepts.md
+++ b/spec/04-basic-concepts.md
@@ -4,22 +4,22 @@ A PHP *program* consists of one or more source files, known formally as
 *scripts*.
 
 
-script:
- script-section
- script   script-section
+  script:
+    script-section
+    script   script-section
 
-script-section:
-   textopt start-tag statement-listopt end-tagopt textopt
+  script-section:
+     textopt start-tag statement-listopt end-tagopt textopt
 
-start-tag:
-  <?php
-  <?=
+  start-tag:
+    <?php
+    <?=
 
-end-tag:
-  ?>
+  end-tag:
+    ?>
 
-text:
-  arbitrary text not containing any of start-tag sequences
+  text:
+    arbitrary text not containing any of start-tag sequences
 
All of the sections in a script are treated as though they belonged to diff --git a/spec/07-variables.md b/spec/07-variables.md index 7d23251e..1a2d332c 100644 --- a/spec/07-variables.md +++ b/spec/07-variables.md @@ -273,10 +273,10 @@ $b = &colors[100]; // a VSlot for $b is created which points to the array static-variable-name-list: static-variable-declaration - static-variable-name-list , static-variable-declaration + static-variable-name-list , static-variable-declaration static-variable-declaration: - variable-name function-static-initializeropt + variable-name function-static-initializeropt function-static-initializer: = constant-expression diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index e038bb95..5ea95f29 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -653,22 +653,21 @@ ill-formed Unicode escape sequences. The variable substitution accepts the following syntax:
-    string-variable::
-        variable-name   offset-or-propertyopt
-        ${   expression   }
+  string-variable::
+    variable-name   offset-or-propertyopt
+    ${   expression   }
 
-    offset-or-property::
-        offset-in-string
-        property-in-string
+  offset-or-property::
+    offset-in-string
+    property-in-string
 
-    offset-in-string::
-        [   name   ]
-        [   variable-name   ]
-        [   integer-literal   ]
-
-    property-in-string::
-        ->   name
+  offset-in-string::
+    [   name   ]
+    [   variable-name   ]
+    [   integer-literal   ]
 
+  property-in-string::
+    ->   name
 
**Defined elsewhere** diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 278793fa..bd1ac0bc 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -247,8 +247,8 @@ An expression that is not a *variable* can never act as an lvalue. ###Constant Access Expression
- constant-access-expression:
-   qualified-name
+  constant-access-expression:
+    qualified-name
 
**Defined elsewhere** From c9f5fd0cdd19a1ebc1c0571662e85e0e2385b1c0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 12 Nov 2016 12:48:53 +0100 Subject: [PATCH 042/146] Add grammar regeneration tool --- tools/grammar.php | 68 +++++++++++++++++++++++++++++++++++++++++++++++ tools/util.php | 4 ++- 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 tools/grammar.php diff --git a/tools/grammar.php b/tools/grammar.php new file mode 100644 index 00000000..81e8c487 --- /dev/null +++ b/tools/grammar.php @@ -0,0 +1,68 @@ + $path) { + if ($fileName === '05-types.md' || $fileName === '09-lexical-structure.md') { + continue; + } + + $code = file_get_contents($path); + $grammar = extract_grammar($code); + if (null === $grammar) { + continue; + } + + $heading = extract_heading($code); + $output .= "\n\n###$heading\n\n" . $grammar; +} + +$output .= "\n"; + +file_put_contents($grammarFile, $output); + +function extract_heading($code) { + if (!preg_match('/#\s*(.*)/', $code, $matches)) { + throw new Exception('No heading found'); + } + + return $matches[1]; +} + +function extract_grammar($code) { + if (!preg_match_all('(
(.*?)
)s', $code, $matches)) { + return null; + } + + $parts = []; + foreach ($matches[1] as $match) { + if (!preg_match('/^\s*.*:.*<\/i>/', $match)) { + continue; + } + $parts[] = ' ' . trim($match); + } + + $rawGrammar = implode("\n\n", $parts); + return "
\n$rawGrammar\n
"; +} diff --git a/tools/util.php b/tools/util.php index 52a8a999..2a5d426a 100644 --- a/tools/util.php +++ b/tools/util.php @@ -9,7 +9,9 @@ function spec_files() { if (pathinfo($file, PATHINFO_EXTENSION) != 'md') { continue; } - if ($file == '00-specification-for-php.md' || $file == 'php-spec-draft.md') { + if ($file == '00-specification-for-php.md' + || $file == '19-grammar.md' + || $file == 'php-spec-draft.md') { continue; } From 8a5e4a5238b32c890ddf887baea3614fa4168d3d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 12 Nov 2016 13:24:23 +0100 Subject: [PATCH 043/146] Regenerate grammar --- spec/19-grammar.md | 61 ++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/spec/19-grammar.md b/spec/19-grammar.md index e99c586f..7b3eab1d 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -222,21 +222,21 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# hexadecimal-digit hexadecimal-digit codepoint-digits - string-variable:: - variable-name offset-or-propertyopt - ${ expression } + string-variable:: + variable-name offset-or-propertyopt + ${ expression } - offset-or-property:: - offset-in-string - property-in-string + offset-or-property:: + offset-in-string + property-in-string - offset-in-string:: - [ name ] - [ variable-name ] - [ integer-literal ] + offset-in-string:: + [ name ] + [ variable-name ] + [ integer-literal ] - property-in-string:: - -> name + property-in-string:: + -> name heredoc-string-literal:: b-prefixopt <<< hd-start-identifier new-line hd-bodyopt hd-end-identifier
;opt new-line @@ -281,25 +281,25 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# ##Syntactic Grammar -###Program Structure +###Basic Concepts
-script:
- script-section
- script   script-section
+  script:
+    script-section
+    script   script-section
 
-script-section:
-   textopt start-tag statement-listopt end-tagopt textopt
+  script-section:
+     textopt start-tag statement-listopt end-tagopt textopt
 
-start-tag:
-  <?php
-  <?=
+  start-tag:
+    <?php
+    <?=
 
-end-tag:
-  ?>
+  end-tag:
+    ?>
 
-text:
-  arbitrary text not containing any of start-tag sequences
+  text:
+    arbitrary text not containing any of start-tag sequences
 
###Variables @@ -368,8 +368,8 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# scoped-property-access-expression member-access-expression - constant-access-expression: - qualified-name + constant-access-expression: + qualified-name literal: integer-literal @@ -554,7 +554,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# scope-resolution-qualifier: relative-scope qualified-name - expression + dereferencable-expression relative-scope: self @@ -572,7 +572,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# error-control-expression shell-command-expression cast-expression - variable-name-creation-expression prefix-increment-expression: ++ variable @@ -705,6 +704,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# yield-expression: logical-inc-OR-expression-2 yield array-element-initializer + yield from expression expression: yield-expression @@ -903,7 +903,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# ticks = literal encoding = literal strict_types = literal -
###Functions @@ -1036,11 +1035,9 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# constructor-declaration: method-modifiers function &opt __construct ( parameter-declaration-listopt ) compound-statement - method-modifiers function &opt name ( parameter-declaration-listopt ) compound-statement [Deprecated form] destructor-declaration: method-modifiers function &opt __destruct ( ) compound-statement -
###Interfaces From 6539c1979c7924f9418381c57eb14fe33f7073ae Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 12 Nov 2016 13:29:06 +0100 Subject: [PATCH 044/146] Regenerate TOC --- spec/00-specification-for-php.md | 44 +++----------------------------- tools/grammar.php | 4 ++- tools/util.php | 1 - 3 files changed, 6 insertions(+), 43 deletions(-) diff --git a/spec/00-specification-for-php.md b/spec/00-specification-for-php.md index 6d682038..52be9c9c 100644 --- a/spec/00-specification-for-php.md +++ b/spec/00-specification-for-php.md @@ -122,8 +122,8 @@ is distributed without any warranty. - [Array Creation Operator](10-expressions.md#array-creation-operator) - [Subscript Operator](10-expressions.md#subscript-operator) - [Function Call Operator](10-expressions.md#function-call-operator) - - [Member Access](10-expressions.md#member-access) - - [Member Call](10-expressions.md#member-call) + - [Member Access Operator](10-expressions.md#member-access-operator) + - [Member Call Operator](10-expressions.md#member-call-operator) - [Postfix Increment and Decrement Operators](10-expressions.md#postfix-increment-and-decrement-operators) - [Scope-Resolution Operator](10-expressions.md#scope-resolution-operator) - [Exponentiation Operator](10-expressions.md#exponentiation-operator) @@ -268,49 +268,11 @@ is distributed without any warranty. - [Grammar](19-grammar.md#grammar) - [General](19-grammar.md#general) - [Lexical Grammar](19-grammar.md#lexical-grammar) - - [General](19-grammar.md#general-1) - - [Comments](19-grammar.md#comments) - - [White Space](19-grammar.md#white-space) - - [Tokens](19-grammar.md#tokens) - - [General](19-grammar.md#general-2) - - [Names](19-grammar.md#names) - - [Keywords](19-grammar.md#keywords) - - [Literals](19-grammar.md#literals) - - [Integer Literals](19-grammar.md#integer-literals) - - [Floating-Point Literals](19-grammar.md#floating-point-literals) - - [String Literals](19-grammar.md#string-literals) - - [Operators and Punctuators](19-grammar.md#operators-and-punctuators) - [Syntactic Grammar](19-grammar.md#syntactic-grammar) - - [Program Structure](19-grammar.md#program-structure) + - [Basic Concepts](19-grammar.md#basic-concepts) - [Variables](19-grammar.md#variables) - [Expressions](19-grammar.md#expressions) - - [Primary Expressions](19-grammar.md#primary-expressions) - - [Postfix Operators](19-grammar.md#postfix-operators) - - [Unary Operators](19-grammar.md#unary-operators) - - [instanceof Operator](19-grammar.md#instanceof-operator) - - [Multiplicative Operators](19-grammar.md#multiplicative-operators) - - [Additive Operators](19-grammar.md#additive-operators) - - [Bitwise Shift Operators](19-grammar.md#bitwise-shift-operators) - - [Relational Operators](19-grammar.md#relational-operators) - - [Equality Operators](19-grammar.md#equality-operators) - - [Bitwise Logical Operators](19-grammar.md#bitwise-logical-operators) - - [Logical Operators (form 1)](19-grammar.md#logical-operators-form-1) - - [Conditional Operator](19-grammar.md#conditional-operator) - - [Coalesce Operator](19-grammar.md#coalesce-operator) - - [Assignment Operators](19-grammar.md#assignment-operators) - - [Logical Operators (form 2)](19-grammar.md#logical-operators-form-2) - - [yield Operator](19-grammar.md#yield-operator) - - [Script Inclusion Operators](19-grammar.md#script-inclusion-operators) - - [Constant Expressions](19-grammar.md#constant-expressions) - [Statements](19-grammar.md#statements) - - [General](19-grammar.md#general-3) - - [Compound Statements](19-grammar.md#compound-statements) - - [Labeled Statements](19-grammar.md#labeled-statements) - - [Expression Statements](19-grammar.md#expression-statements) - - [Iteration Statements](19-grammar.md#iteration-statements) - - [Jump Statements](19-grammar.md#jump-statements) - - [The try Statement](19-grammar.md#the-try-statement) - - [The declare Statement](19-grammar.md#the-declare-statement) - [Functions](19-grammar.md#functions) - [Classes](19-grammar.md#classes) - [Interfaces](19-grammar.md#interfaces) diff --git a/tools/grammar.php b/tools/grammar.php index 81e8c487..2ba0186e 100644 --- a/tools/grammar.php +++ b/tools/grammar.php @@ -24,7 +24,9 @@ $output .= "\n\n##Syntactic Grammar"; foreach (spec_files() as $fileName => $path) { - if ($fileName === '05-types.md' || $fileName === '09-lexical-structure.md') { + if ($fileName === '05-types.md' + || $fileName === '09-lexical-structure.md' + || $fileName === '19-grammar.md') { continue; } diff --git a/tools/util.php b/tools/util.php index 2a5d426a..6860c942 100644 --- a/tools/util.php +++ b/tools/util.php @@ -10,7 +10,6 @@ function spec_files() { continue; } if ($file == '00-specification-for-php.md' - || $file == '19-grammar.md' || $file == 'php-spec-draft.md') { continue; } From 7c85acc7b051a340814d0da590e4ca266bbb0c96 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 12 Nov 2016 13:34:52 +0100 Subject: [PATCH 045/146] Update README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fc277f19..7ff1b0bc 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # PHP Language Specifications -This repo will contain the WIP PHP Language Specifications. +This repo contains the WIP PHP Language Specifications. -To join the conversation, send blank email to: +To join the conversation, send a blank email to: > [standards-subscribe@lists.php.net](mailto:standards-subscribe@lists.php.net) @@ -26,4 +26,4 @@ It is also mirrored on GitHub: The PHP specification is community-owned and open-source. Pull requests, issue filings and comments are extremely welcome. -Make sure you understand the [*contribution process*](CONTRIBUTING.md). \ No newline at end of file +Make sure you understand the [*contribution process*](CONTRIBUTING.md). From a6ae806a1f4f6ade361d4ffc80b8a4bc1b5d61b7 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 12 Nov 2016 13:36:30 +0100 Subject: [PATCH 046/146] Remove php-spec-draft file GitHub doesn't redirect symlinks, so this isn't really useful to keep around. --- spec/php-spec-draft.md | 1 - tools/util.php | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 120000 spec/php-spec-draft.md diff --git a/spec/php-spec-draft.md b/spec/php-spec-draft.md deleted file mode 120000 index a7c2f5e4..00000000 --- a/spec/php-spec-draft.md +++ /dev/null @@ -1 +0,0 @@ -00-specification-for-php.md \ No newline at end of file diff --git a/tools/util.php b/tools/util.php index 6860c942..fa1a8cb5 100644 --- a/tools/util.php +++ b/tools/util.php @@ -9,8 +9,7 @@ function spec_files() { if (pathinfo($file, PATHINFO_EXTENSION) != 'md') { continue; } - if ($file == '00-specification-for-php.md' - || $file == 'php-spec-draft.md') { + if ($file == '00-specification-for-php.md') { continue; } From e85e5508ca29872b60a59c7f37684f13d07e4533 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Sat, 12 Nov 2016 14:18:04 +0100 Subject: [PATCH 047/146] Simplify `print` rule. `print 42` is the same than `print(42)`, which is the same than `print (42)`. Just like `echo`, it is possible to consider that parenthesis belong to the expression instead of to the `print` intrinsic. --- spec/10-expressions.md | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index bd1ac0bc..5e8af86a 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -688,7 +688,6 @@ list(0 => list($x1, $x2), 1 => list($x2, $y2)) = [[1, 2], [3, 4]];
   print-intrinsic:
     print  expression
-    print  (  expression  )
 
**Defined elsewhere** From ec2d46f8ae91c0006c8969baf320eaf4d5518d6a Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Sat, 12 Nov 2016 14:13:51 +0100 Subject: [PATCH 048/146] =?UTF-8?q?Fix=20=E2=80=9Cdouble=20quoted=20string?= =?UTF-8?q?s=E2=80=9D=20link.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/10-expressions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 5e8af86a..1fb081ae 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -378,7 +378,7 @@ necessary, `echo` concatenates them in order given, and writes the resulting string to [`STDOUT`](06-constants.md#core-predefined-constants). Unlike [`print`](#print), it does not produce a result. -See also: [double quioted strings](09-lexical-structure.md#double-quoted-string-literals) and +See also: [double quoted strings](09-lexical-structure.md#double-quoted-string-literals) and [heredoc documents](09-lexical-structure.md#heredoc-string-literals), [conversion to string](08-conversions.md#converting-to-string-type). **Examples** @@ -707,7 +707,7 @@ After converting its *expression*'s value to a string, if necessary, Unlike [`echo`](#echo), `print` can be used in any context allowing an expression. It always returns the value 1. -See also: [double quioted strings](09-lexical-structure.md#double-quoted-string-literals) and +See also: [double quoted strings](09-lexical-structure.md#double-quoted-string-literals) and [heredoc documents](09-lexical-structure.md#heredoc-string-literals), [conversion to string](08-conversions.md#converting-to-string-type). **Examples** From 3db4044d36ae4267abf90f7c086e063225c2772d Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Sat, 12 Nov 2016 14:18:04 +0100 Subject: [PATCH 049/146] Regenerate grammar --- spec/19-grammar.md | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 7b3eab1d..90698eb2 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -445,7 +445,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# print-intrinsic: print expression - print ( expression ) unset-intrinsic: unset ( expression-list-one-or-more ) From 4bc7c825be72d52b3b4ecace46828d16c69ce7b1 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 12 Nov 2016 17:35:30 +0100 Subject: [PATCH 050/146] Remove array-intrinsic This is already covered by array-creation-operator. --- spec/00-specification-for-php.md | 1 - spec/10-expressions.md | 20 -------------------- spec/19-grammar.md | 4 ---- 3 files changed, 25 deletions(-) diff --git a/spec/00-specification-for-php.md b/spec/00-specification-for-php.md index 52be9c9c..a40f29d2 100644 --- a/spec/00-specification-for-php.md +++ b/spec/00-specification-for-php.md @@ -105,7 +105,6 @@ is distributed without any warranty. - [Literals](10-expressions.md#literals) - [Intrinsics](10-expressions.md#intrinsics) - [General](10-expressions.md#general-2) - - [array](10-expressions.md#array) - [echo](10-expressions.md#echo) - [empty](10-expressions.md#empty) - [eval](10-expressions.md#eval) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 1fb081ae..bd022a43 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -298,7 +298,6 @@ A literal evaluates to its value, as specified in the lexical specification for unset-intrinsic intrinsic-operator: - array-intrinsic empty-intrinsic eval-intrinsic exit-intrinsic @@ -308,7 +307,6 @@ A literal evaluates to its value, as specified in the lexical specification for **Defined elsewhere** -* [*array-intrinsic*](#array) * [*echo-intrinsic*](#echo) * [*empty-intrinsic*](#empty) * [*eval-intrinsic*](#eval) @@ -329,24 +327,6 @@ other values or expressions could be used. *intrinsic-construct* can be used only as stand-alone [statement](11-statements.md#statements). -####array - -**Syntax** - -
-  array-intrinsic:
-    array ( array-initializeropt  )
-
- -**Defined elsewhere** - -* [*array-initializer*](#array-creation-operator) - -**Semantics** - -This intrinsic creates and initializes an array. It is equivalent to the -array-creation operator [`[]`](#array-creation-operator). - ####echo **Syntax** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 90698eb2..493f3642 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -386,16 +386,12 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# unset-intrinsic intrinsic-operator: - array-intrinsic empty-intrinsic eval-intrinsic exit-intrinsic isset-intrinsic print-intrinsic - array-intrinsic: - array ( array-initializeropt ) - echo-intrinsic: echo expression echo expression-list-two-or-more From 9c1e9d1aa1de4f1f82498ab210095d3a76e2521d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 15 Nov 2016 22:29:10 +0100 Subject: [PATCH 051/146] Restrict LHS of assignments to variable --- spec/10-expressions.md | 16 ++++++++-------- spec/19-grammar.md | 7 ++++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index bd022a43..55891de6 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -2882,12 +2882,14 @@ These operators associate right-to-left.
   simple-assignment-expression:
-    unary-expression  =  assignment-expression
+    variable  =  assignment-expression
+    list-intrinsic  =  assignment-expression
 
**Defined elsewhere** -* [*unary-expression*](#general-4) +* [*variable*](#variables) +* [*list-intrinsic*](#list) * [*assignment-expression*](#general-5) **Constraints** @@ -2950,18 +2952,16 @@ $a = new C; // make $a point to the allocated object
   byref-assignment-expression:
-    unary-expression  =  &  assignment-expression
+    variable  =  &  assignment-expression
 
**Defined elsewhere** -* [*unary-expression*](#general-4) +* [*variable*](#variables) * [*assignment-expression*](#general-5) **Constraints** -*unary-expression* must designate a variable. - *assignment-expression* must be an lvalue or a call to a function that returns a value byRef. @@ -2994,7 +2994,7 @@ $b =& g2(); // make $b an alias to "xxx"
   compound-assignment-expression:
-    unary-expression   compound-assignment-operator   assignment-expression
+    variable   compound-assignment-operator   assignment-expression
 
   compound-assignment-operator: one of
     **=  *=  /=  %=  +=  -=  .=  <<=  >>=  &=  ^=  |=
@@ -3002,7 +3002,7 @@ $b =& g2();     // make $b an alias to "xxx"
 
 **Defined elsewhere**
 
-* [*unary-expression*](#general-4)
+* [*variable*](#variables)
 * [*assignment-expression*](#general-5)
 
 **Constraints**
diff --git a/spec/19-grammar.md b/spec/19-grammar.md
index 493f3642..beb6cf5b 100644
--- a/spec/19-grammar.md
+++ b/spec/19-grammar.md
@@ -673,13 +673,14 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     compound-assignment-expression
 
   simple-assignment-expression:
-    unary-expression  =  assignment-expression
+    variable  =  assignment-expression
+    list-intrinsic  =  assignment-expression
 
   byref-assignment-expression:
-    unary-expression  =  &  assignment-expression
+    variable  =  &  assignment-expression
 
   compound-assignment-expression:
-    unary-expression   compound-assignment-operator   assignment-expression
+    variable   compound-assignment-operator   assignment-expression
 
   compound-assignment-operator: one of
     **=  *=  /=  %=  +=  -=  .=  <<=  >>=  &=  ^=  |=

From 883396eb050375ad973b25c1142bf015b5e3adb2 Mon Sep 17 00:00:00 2001
From: Nikita Popov 
Date: Tue, 15 Nov 2016 22:33:56 +0100
Subject: [PATCH 052/146] Remove references to #array

---
 spec/07-variables.md   | 3 +--
 spec/10-expressions.md | 4 ----
 spec/12-arrays.md      | 4 ++--
 3 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/spec/07-variables.md b/spec/07-variables.md
index 1a2d332c..6e59bf45 100644
--- a/spec/07-variables.md
+++ b/spec/07-variables.md
@@ -217,8 +217,7 @@ $l = $k;   // a VSlot for $l was created and the value of $k (which is NULL)
 
 **Syntax**
 
-[Arrays](12-arrays.md#arrays) are created via the [array-creation operator](10-expressions.md#array-creation-operator) or
-the intrinsic [`array`](10-expressions.md#array). At the same time, one or more elements
+[Arrays](12-arrays.md#arrays) are created using the [array-creation operator](10-expressions.md#array-creation-operator). At the same time, one or more elements
 may be created for that array. New elements are inserted into an
 existing array via the [simple-assignment operator](10-expressions.md#simple-assignment) in
 conjunction with the subscript [operator `[]`](10-expressions.md#subscript-operator). Elements can be
diff --git a/spec/10-expressions.md b/spec/10-expressions.md
index 55891de6..f45286c0 100644
--- a/spec/10-expressions.md
+++ b/spec/10-expressions.md
@@ -1017,10 +1017,6 @@ $v2 = new class (100) extends C1 implements I1, I2 {
 
 ###Array Creation Operator
 
-An array is created and initialized by one of two equivalent ways: via
-the array-creation operator `[]`, as described below, or the intrinsic
-[`array`](#array).
-
 **Syntax**
 
 
diff --git a/spec/12-arrays.md b/spec/12-arrays.md
index d027f19b..714686bb 100644
--- a/spec/12-arrays.md
+++ b/spec/12-arrays.md
@@ -33,8 +33,8 @@ and there is no concept of consecutive elements of the array occupying physicall
 
 ##Array Creation and Initialization
 
-An array is created and initialized by one of two equivalent ways: via
-the array-creation operator [`[]`](10-expressions.md#array-creation-operator) or the [intrinsic `array`](10-expressions.md#array).
+An array is created and initialized using the
+[array-creation operator](10-expressions.md#array-creation-operator):
 
 ##Element Access and Insertion
 

From 0fd1786650afcdd580d02a8cca535fdf4d33a27e Mon Sep 17 00:00:00 2001
From: Nikita Popov 
Date: Tue, 15 Nov 2016 22:38:27 +0100
Subject: [PATCH 053/146] Improve check_refs

Handle manual anchor. Return exit code.
---
 spec/07-variables.md |  2 +-
 tools/check_refs.php | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/spec/07-variables.md b/spec/07-variables.md
index 6e59bf45..3fa4cb73 100644
--- a/spec/07-variables.md
+++ b/spec/07-variables.md
@@ -153,7 +153,7 @@ Since undefined local variables are not defined implicitly, they stay undefined.
 
 *byRef Context*
 
-If the undefined variable is used in a [byRef context](04-basic-concepts#byRef) then PHP defines the variable implicitly. Hence, a VSlot is created for it and `NULL` is stored in it. A notice is *not* emitted in such a case.
+If the undefined variable is used in a byRef context then PHP defines the variable implicitly. Hence, a VSlot is created for it and `NULL` is stored in it. A notice is *not* emitted in such a case.
 
 *Examples of Undefined Variables*
 
diff --git a/tools/check_refs.php b/tools/check_refs.php
index eab817c4..aede04a8 100644
--- a/tools/check_refs.php
+++ b/tools/check_refs.php
@@ -10,9 +10,18 @@
         $fullAnchor = $fileName . '#' . $info['anchor'];
         $anchors[$fullAnchor] = true;
     }
+
+    // Collect manual anchors as well
+    if (preg_match_all('//', $contents, $matches)) {
+        foreach ($matches[1] as $anchor) {
+            $fullAnchor = $fileName . '#' . $anchor;
+            $anchors[$fullAnchor] = true;
+        }
+    }
 }
 
 // Find unknown anchor references
+$foundUnknown = false;
 foreach (spec_files() as $fileName => $path) {
     $contents = file_get_contents($path);
 
@@ -33,7 +42,10 @@
         }
 
         if (!isset($anchors[$anchor])) {
+            $foundUnknown = true;
             echo "Unknown anchor $anchor in $fileName\n";
         }
     }
 }
+
+exit($foundUnknown ? 1 : 0);

From 256534b60943c0610ccb0f8cde160323bcbd4f7c Mon Sep 17 00:00:00 2001
From: Nikita Popov 
Date: Tue, 15 Nov 2016 23:15:45 +0100
Subject: [PATCH 054/146] Cleanup echo/isset/unset grammar

isset and unset accept only variables.
For echo, merge the single and multiple expression cases.
---
 spec/10-expressions.md | 33 ++++++++++++---------------------
 spec/19-grammar.md     | 17 ++++++++---------
 2 files changed, 20 insertions(+), 30 deletions(-)

diff --git a/spec/10-expressions.md b/spec/10-expressions.md
index f45286c0..39c88cf6 100644
--- a/spec/10-expressions.md
+++ b/spec/10-expressions.md
@@ -333,12 +333,11 @@ other values or expressions could be used.
 
 
   echo-intrinsic:
-    echo  expression
-    echo  expression-list-two-or-more
+    echo  expression-list
 
   expression-list-two-or-more:
-    expression  ,  expression
-    expression-list-two-or-more  ,  expression
+    expression
+    expression-list  ,  expression
 
**Defined elsewhere** @@ -508,25 +507,21 @@ exit;
   isset-intrinsic:
-    isset  (  expression-list-one-or-more  )
+    isset  (  variable-list  )
 
-  expression-list-one-or-more:
-    expression
-    expression-list-one-or-more  ,  expression
+  variable-list:
+    variable
+    variable-list  ,  variable
 
**Defined elsewhere** -* [*expression*](#general-6) - -**Constraints** - -Each *expression* must designate a variable. +* [*variable*](#variables) **Semantics** This intrinsic returns `TRUE` if all the variables designated by -*expression*s are set and their values are not `NULL`. Otherwise, it +*variables*s are set and their values are not `NULL`. Otherwise, it returns `FALSE`. If this intrinsic is used with an expression that designate a [dynamic @@ -708,21 +703,17 @@ $a > $b ? print "..." : print "...";
   unset-intrinsic:
-    unset  (  expression-list-one-or-more  )
+    unset  (  variable-list  )
 
**Defined elsewhere** -* [*expression-list-one-or-more*](#isset) - -**Constraints** - -Each *expression* must designate a variable. +* [*variable-list*](#isset) **Semantics** This intrinsic [unsets](07-variables.md#general) the variables designated by each -*expression* in *expression-list-one-or-more*. No value is returned. An +*variable* in *variable-list*. No value is returned. An attempt to unset a non-existent variable (such as a non-existent element in an array) is ignored. diff --git a/spec/19-grammar.md b/spec/19-grammar.md index beb6cf5b..ce47a26d 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -393,12 +393,11 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# print-intrinsic echo-intrinsic: - echo expression - echo expression-list-two-or-more + echo expression-list expression-list-two-or-more: - expression , expression - expression-list-two-or-more , expression + expression + expression-list , expression empty-intrinsic: empty ( expression ) @@ -413,11 +412,11 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# die ( expressionopt ) isset-intrinsic: - isset ( expression-list-one-or-more ) + isset ( variable-list ) - expression-list-one-or-more: - expression - expression-list-one-or-more , expression + variable-list: + variable + variable-list , variable list-intrinsic: list ( list-expression-listopt ) @@ -443,7 +442,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# print expression unset-intrinsic: - unset ( expression-list-one-or-more ) + unset ( variable-list ) anonymous-function-creation-expression: staticopt function &opt ( parameter-declaration-listopt ) return-typeopt anonymous-function-use-clauseopt From 3447bf5d4df23527c623c58da67b43df665c7ba0 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 16 Nov 2016 07:16:30 +0100 Subject: [PATCH 055/146] A `list` cannot be empty. --- spec/10-expressions.md | 2 +- spec/19-grammar.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 39c88cf6..0ced0f28 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -548,7 +548,7 @@ isset($v1, $v2, $v3); // results in FALSE
   list-intrinsic:
-    list  (  list-expression-listopt  )
+    list  (  list-expression-list  )
 
   list-expression-list:
     unkeyed-list-expression-list
diff --git a/spec/19-grammar.md b/spec/19-grammar.md
index ce47a26d..4042df43 100644
--- a/spec/19-grammar.md
+++ b/spec/19-grammar.md
@@ -419,7 +419,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     variable-list  ,  variable
 
   list-intrinsic:
-    list  (  list-expression-listopt  )
+    list  (  list-expression-list  )
 
   list-expression-list:
     unkeyed-list-expression-list

From bb8f2d45961447e4deb4e730c8a2c0fb3d525bcd Mon Sep 17 00:00:00 2001
From: Nikita Popov 
Date: Sun, 20 Nov 2016 23:15:46 +0100
Subject: [PATCH 056/146] Grammar syntax/typo fixes

---
 spec/09-lexical-structure.md |  2 +-
 spec/10-expressions.md       | 16 ++++++++--------
 spec/11-statements.md        |  2 +-
 spec/19-grammar.md           | 20 ++++++++++----------
 4 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md
index 5ea95f29..cc829170 100644
--- a/spec/09-lexical-structure.md
+++ b/spec/09-lexical-structure.md
@@ -731,7 +731,7 @@ echo "\$myC->p1 = >$myC->p1<\n";  // → $myC->p1 = >2<
 
 
   heredoc-string-literal::
-    b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
+    b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
 
   hd-start-identifier::
     name
diff --git a/spec/10-expressions.md b/spec/10-expressions.md
index 0ced0f28..255a7dd0 100644
--- a/spec/10-expressions.md
+++ b/spec/10-expressions.md
@@ -335,7 +335,7 @@ other values or expressions could be used.
   echo-intrinsic:
     echo  expression-list
 
-  expression-list-two-or-more:
+  expression-list:
     expression
     expression-list  ,  expression
 
@@ -509,7 +509,7 @@ exit; isset-intrinsic: isset ( variable-list ) - variable-list: + variable-list: variable variable-list , variable
@@ -754,7 +754,7 @@ unset($x->m); // if m is a dynamic property, $x->__unset("m") is called
   anonymous-function-creation-expression:
-  staticopt function  &opt (  parameter-declaration-listopt  ) return-typeopt anonymous-function-use-clauseopt
+  staticopt function  &opt (  parameter-declaration-listopt  ) return-typeopt anonymous-function-use-clauseopt
       compound-statement
 
   anonymous-function-use-clause:
@@ -1029,7 +1029,7 @@ $v2 = new class (100) extends C1 implements I1, I2 {
   element-key:
     expression
 
-  element-value
+  element-value:
     expression
 
@@ -1562,7 +1562,7 @@ $a = array(100, 200); $v = $a[1]++; // old value of $ia[1] (200) is assigned qualified-name dereferencable-expression - relative-scope: + relative-scope: self parent static @@ -2552,7 +2552,7 @@ TRUE !== 100 // result has value TRUE
   bitwise-AND-expression:
     equality-expression
-    bit-wise-AND-expression  &  equality-expression
+    bitwise-AND-expression  &  equality-expression
 
**Defined elsewhere** @@ -2688,7 +2688,7 @@ $lLetter = $upCaseLetter | 0x20; // set the 6th bit to make letter 'a'
   logical-AND-expression-1:
-    bitwise-incl-OR-expression
+    bitwise-inc-OR-expression
     logical-AND-expression-1  &&  bitwise-inc-OR-expression
 
@@ -2789,7 +2789,7 @@ function factorial($int)
   coalesce-expression:
-    logical-inc-OR-expression  ??  expression
+    logical-inc-OR-expression-1  ??  expression
 
**Defined elsewhere** diff --git a/spec/11-statements.md b/spec/11-statements.md index 423c972b..a8ba5f05 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -605,7 +605,7 @@ for ($a = 100, $i = 1; ++$i, $i <= 10; ++$i, $a -= 10) 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: + foreach-collection-name: expression foreach-key: diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 4042df43..6e3e9366 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -239,7 +239,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# -> name heredoc-string-literal:: - b-prefixopt <<< hd-start-identifier new-line hd-bodyopt hd-end-identifier ;opt new-line + b-prefixopt <<< hd-start-identifier new-line hd-bodyopt hd-end-identifier ;opt new-line hd-start-identifier:: name @@ -395,7 +395,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# echo-intrinsic: echo expression-list - expression-list-two-or-more: + expression-list: expression expression-list , expression @@ -414,7 +414,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# isset-intrinsic: isset ( variable-list ) - variable-list: + variable-list: variable variable-list , variable @@ -445,7 +445,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# unset ( variable-list ) anonymous-function-creation-expression: - staticopt function &opt ( parameter-declaration-listopt ) return-typeopt anonymous-function-use-clauseopt + staticopt function &opt ( parameter-declaration-listopt ) return-typeopt anonymous-function-use-clauseopt compound-statement anonymous-function-use-clause: @@ -497,7 +497,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# element-key: expression - element-value + element-value: expression subscript-expression: @@ -550,7 +550,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# qualified-name dereferencable-expression - relative-scope: + relative-scope: self parent static @@ -639,7 +639,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# bitwise-AND-expression: equality-expression - bit-wise-AND-expression & equality-expression + bitwise-AND-expression & equality-expression bitwise-exc-OR-expression: bitwise-AND-expression @@ -650,7 +650,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# bitwise-inc-OR-expression | bitwise-exc-OR-expression logical-AND-expression-1: - bitwise-incl-OR-expression + bitwise-inc-OR-expression logical-AND-expression-1 && bitwise-inc-OR-expression logical-inc-OR-expression-1: @@ -662,7 +662,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# logical-inc-OR-expression-1 ? expressionopt : conditional-expression coalesce-expression: - logical-inc-OR-expression ?? expression + logical-inc-OR-expression-1 ?? expression assignment-expression: conditional-expression @@ -839,7 +839,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# 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: + foreach-collection-name: expression foreach-key: From f550b7423df0afa4583a77d7c1ef130ce8277ecd Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 25 Nov 2016 18:36:40 +0100 Subject: [PATCH 057/146] Add $skipFiles to spec_files() --- tools/grammar.php | 9 ++------- tools/util.php | 5 +++-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/tools/grammar.php b/tools/grammar.php index 2ba0186e..1ad7f71d 100644 --- a/tools/grammar.php +++ b/tools/grammar.php @@ -23,13 +23,8 @@ $output .= "\n\n##Syntactic Grammar"; -foreach (spec_files() as $fileName => $path) { - if ($fileName === '05-types.md' - || $fileName === '09-lexical-structure.md' - || $fileName === '19-grammar.md') { - continue; - } - +$skipFiles = ['05-types.md', '09-lexical-structure.md', '19-grammar.md']; +foreach (spec_files($skipFiles) as $fileName => $path) { $code = file_get_contents($path); $grammar = extract_grammar($code); if (null === $grammar) { diff --git a/tools/util.php b/tools/util.php index fa1a8cb5..8cd521e0 100644 --- a/tools/util.php +++ b/tools/util.php @@ -1,7 +1,7 @@ $path. */ -function spec_files() { +function spec_files($skipFiles = []) { $dir = __DIR__ . '/../spec/'; $files = scandir($dir); @@ -9,7 +9,8 @@ function spec_files() { if (pathinfo($file, PATHINFO_EXTENSION) != 'md') { continue; } - if ($file == '00-specification-for-php.md') { + if ($file == '00-specification-for-php.md' + || in_array($file, $skipFiles)) { continue; } From a1bfc76bee5dbebecadb2b5f0dd90caec55cefe0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 25 Nov 2016 18:49:47 +0100 Subject: [PATCH 058/146] Fix typo --- spec/09-lexical-structure.md | 2 +- spec/19-grammar.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index cc829170..8c33d50c 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -731,7 +731,7 @@ echo "\$myC->p1 = >$myC->p1<\n"; // → $myC->p1 = >2<
   heredoc-string-literal::
-    b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
+    b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
 
   hd-start-identifier::
     name
diff --git a/spec/19-grammar.md b/spec/19-grammar.md
index 6e3e9366..712b337c 100644
--- a/spec/19-grammar.md
+++ b/spec/19-grammar.md
@@ -239,7 +239,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
     ->   name
 
   heredoc-string-literal::
-    b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
+    b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
 
   hd-start-identifier::
     name

From eacc8b33e1ef150b08f29f87d63e206b664cc8c1 Mon Sep 17 00:00:00 2001
From: Nikita Popov 
Date: Fri, 25 Nov 2016 19:05:32 +0100
Subject: [PATCH 059/146] Extract grammar

Grammar is now defined in  blocks. The actually
displayed grammar will be auto-generated.
---
 .gitignore                   |   1 +
 spec/04-basic-concepts.md    |  19 ++
 spec/05-types.md             |  19 ++
 spec/07-variables.md         |  24 ++
 spec/09-lexical-structure.md | 317 +++++++++++++++++++++-
 spec/10-expressions.md       | 510 +++++++++++++++++++++++++++++++++++
 spec/11-statements.md        | 212 +++++++++++++++
 spec/13-functions.md         |  45 ++++
 spec/14-classes.md           |  98 +++++++
 spec/15-interfaces.md        |  19 ++
 spec/16-traits.md            |  48 ++++
 spec/18-namespaces.md        |  41 +++
 12 files changed, 1352 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 999b52e3..10184eb4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 /.commit-template
+*.swp
diff --git a/spec/04-basic-concepts.md b/spec/04-basic-concepts.md
index 3c7ee1b0..d2b2ac24 100644
--- a/spec/04-basic-concepts.md
+++ b/spec/04-basic-concepts.md
@@ -3,6 +3,25 @@
 A PHP *program* consists of one or more source files, known formally as
 *scripts*.
 
+
+
 
   script:
     script-section
diff --git a/spec/05-types.md b/spec/05-types.md
index 87c553db..c83632d6 100644
--- a/spec/05-types.md
+++ b/spec/05-types.md
@@ -119,6 +119,25 @@ the requirements of a numeric string, and whose trailing characters are
 non-numeric. A *non-numeric string* is a string that is not a numeric
 string.
 
+
+
 
   str-numeric::
     str-whitespaceopt   signopt   str-number
diff --git a/spec/07-variables.md b/spec/07-variables.md
index 3fa4cb73..b7098a26 100644
--- a/spec/07-variables.md
+++ b/spec/07-variables.md
@@ -266,6 +266,21 @@ $b = &colors[100];      // a VSlot for $b is created which points to the array
 
 **Syntax**
 
+
+
 
   function-static-declaration:
     static static-variable-name-list  ;
@@ -350,6 +365,15 @@ echo "\$fs = $fs\n";    // $fs = 3
 
 **Syntax**
 
+
+
 
   global-declaration:
     global variable-name-list ;
diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md
index 8c33d50c..ac3d7255 100644
--- a/spec/09-lexical-structure.md
+++ b/spec/09-lexical-structure.md
@@ -43,13 +43,19 @@ successive indented line contains a possible expansion of the
 non-terminal given as a sequence of non-terminal or terminal symbols.
 For example, the production:
 
+
+
 
   single-line-comment::
     // input-charactersopt
     #  input-charactersopt
 
-defines the lexical grammar production *single-line-comment* as being +defines the lexical grammar production *single-line-comment-example* as being the terminals `//` or `#`, followed by an optional *input-characters*. Each expansion is listed on a separate line. @@ -57,6 +63,13 @@ Although alternatives are usually listed on separate lines, when there is a large number, the shorthand phrase “one of” may precede a list of expansions given on a single line. For example, + +
   hexadecimal-digit:: one of
     0   1   2   3   4   5   6   7   8   9
@@ -73,6 +86,17 @@ script. Each script must conform to this production.
 
 **Syntax**
 
+
+
 
   input-file::
     input-element
@@ -109,6 +133,31 @@ Two forms of comments are supported: *delimited comments* and
 
 **Syntax**
 
+
+
 
   comment::
     single-line-comment
@@ -161,6 +210,17 @@ new-line, space and horizontal tab characters.
 
 **Syntax**
 
+
+
 
   white-space::
     white-space-character
@@ -189,6 +249,17 @@ There are several kinds of source *tokens*:
 
 **Syntax**
 
+
+
 
   token::
     variable-name
@@ -214,6 +285,40 @@ There are several kinds of source *tokens*:
 
 **Syntax**
 
+
+
 
   variable-name::
     $   name
@@ -307,6 +412,18 @@ cannot be used as a name.
 
 **Syntax**
 
+
+
 
   keyword:: one of
     abstract   and   array   as   break   callable   case   catch   class   clone
@@ -335,6 +452,53 @@ The source code representation of a value is called a *literal*.
 
 **Syntax**
 
+
+
 
   integer-literal::
     decimal-literal
@@ -429,6 +593,27 @@ On an implementation using 32-bit int representation
 
 **Syntax**
 
+
+
 
   floating-literal::
     fractional-literal   exponent-partopt
@@ -478,6 +663,14 @@ $values = array(1.23, 3e12, 543.678E-23);
 
 **Syntax**
 
+
+
 
   string-literal::
     single-quoted-string-literal
@@ -504,6 +697,25 @@ The type of a string literal is `string`.
 
 **Syntax**
 
+
+
 
   single-quoted-string-literal::
     b-prefixopt  ' sq-char-sequenceopt  '
@@ -548,6 +760,45 @@ A single-quoted string literal is always a constant expression.
 
 **Syntax**
 
+
+
 
   double-quoted-string-literal::
     b-prefixopt  " dq-char-sequenceopt  "
@@ -652,6 +903,24 @@ ill-formed Unicode escape sequences.
 
 The variable substitution accepts the following syntax:
 
+
+
 
   string-variable::
     variable-name   offset-or-propertyopt
@@ -729,6 +998,39 @@ echo "\$myC->p1 = >$myC->p1<\n";  // → $myC->p1 = >2<
 
 **Syntax**
 
+
+
 
   heredoc-string-literal::
     b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
@@ -812,6 +1114,11 @@ echo ">$s<";
 
 **Syntax**
 
+
+
 
   nowdoc-string-literal::
     b-prefixopt  <<<  '  name  '  new-line  hd-bodyopt   name  ;opt   new-line
@@ -858,6 +1165,14 @@ echo ">$s<\n\n";
 
 **Syntax**
 
+
+
 
   operator-or-punctuator:: one of
     [   ]   (   )   {   }   .   ->   ++   --   **   *   +   -   ~   !
diff --git a/spec/10-expressions.md b/spec/10-expressions.md
index 255a7dd0..f5e55613 100644
--- a/spec/10-expressions.md
+++ b/spec/10-expressions.md
@@ -89,6 +89,18 @@ function, `$a` need not actually be incremented.
 
 **Syntax**
 
+
+
 
   primary-expression:
     variable
@@ -121,6 +133,13 @@ the un-parenthesized expression.
 
 **Syntax**
 
+
+
 
   simple-variable:
     variable-name
@@ -177,6 +196,20 @@ ${1 + f1()} = 1000;   // equivalent to ${3.5} = 1000
 
 **Syntax**
 
+
+
 
   dereferencable-expression:
     variable
@@ -214,6 +247,20 @@ call operator](#function-call-operator).
 
 **Syntax**
 
+
+
 
   callable-variable:
     simple-variable
@@ -246,6 +293,11 @@ An expression that is not a *variable* can never act as an lvalue.
 
 ###Constant Access Expression
 
+
+
 
   constant-access-expression:
     qualified-name
@@ -264,6 +316,13 @@ with name *qualified-name*.
 
 **Syntax**
 
+
+
 
   literal:
     integer-literal
@@ -287,6 +346,24 @@ A literal evaluates to its value, as specified in the lexical specification for
 ####General
 
 **Syntax**
+
+
 
   intrinsic:
     intrinsic-construct
@@ -331,6 +408,15 @@ other values or expressions could be used.
 
 **Syntax**
 
+
+
 
   echo-intrinsic:
     echo  expression-list
@@ -376,6 +462,11 @@ echo "$v3\n";
 
 **Syntax**
 
+
+
 
   empty-intrinsic:
     empty ( expression  )
@@ -415,6 +506,11 @@ empty($v);   // results in FALSE
 
 **Syntax**
 
+
+
 
   eval-intrinsic:
     eval (  expression  )
@@ -457,6 +553,14 @@ eval("echo \$str . \"\\n\";");  // → echo $str . "\n"; → prints Hello
 
 **Syntax**
 
+
+
 
   exit-intrinsic:
     exit
@@ -505,6 +609,15 @@ exit;
 
 **Syntax**
 
+
+
 
   isset-intrinsic:
     isset  (  variable-list  )
@@ -546,6 +659,28 @@ isset($v1, $v2, $v3);  // results in FALSE
 
 **Syntax**
 
+
+
 
   list-intrinsic:
     list  (  list-expression-list  )
@@ -660,6 +795,11 @@ list(0 => list($x1, $x2), 1 => list($x2, $y2)) = [[1, 2], [3, 4]];
 
 **Syntax**
 
+
+
 
   print-intrinsic:
     print  expression
@@ -701,6 +841,11 @@ $a > $b ? print "..." : print "...";
 
 **Syntax**
 
+
+
 
   unset-intrinsic:
     unset  (  variable-list  )
@@ -752,6 +897,18 @@ unset($x->m); // if m is a dynamic property, $x->__unset("m") is called
 
 **Syntax**
 
+
+
 
   anonymous-function-creation-expression:
   staticopt function  &opt (  parameter-declaration-listopt  ) return-typeopt anonymous-function-use-clauseopt
@@ -837,6 +994,16 @@ class C
 
 **Syntax**
 
+
+
 
   postfix-expression:
     primary-expression
@@ -864,6 +1031,11 @@ These operators associate left-to-right.
 
 **Syntax**
 
+
+
 
   clone-expression:
     clone  expression
@@ -918,6 +1090,18 @@ $obj2 = clone $obj1;  // creates a new Manager that is a deep copy
 
 **Syntax**
 
+
+
 
   object-creation-expression:
     new  class-type-designator  (  argument-expression-listopt  )
@@ -1010,6 +1194,29 @@ $v2 = new class (100) extends C1 implements I1, I2 {
 
 **Syntax**
 
+
+
 
   array-creation-expression:
     array  (  array-initializeropt  )
@@ -1104,6 +1311,12 @@ for ($i = -1; $i <= 2; ++$i) { echo $v[$i]; } // retrieves via keys -1, 0, 1, 2
 
 **Syntax**
 
+
+
 
   subscript-expression:
     dereferencable-expression  [  expressionopt  ]
@@ -1268,6 +1481,23 @@ $x = $vect1[1];   // calls Vector::offsetGet(1)
 
 **Syntax**
 
+
+
 
   function-call-expression:
     qualified-name  (  argument-expression-listopt  )
@@ -1392,6 +1622,16 @@ $anon();  // call the anonymous function encapsulated by that object
 
 **Syntax**
 
+
+
 
   member-access-expression:
     dereferencable-expression   ->   member-name
@@ -1472,6 +1712,11 @@ $c = $p1->color;  // turned into $c = $p1->__get("color");
 
 **Syntax**
 
+
+
 
   member-call-expression:
     dereferencable-expression   ->   member-name   (   argument-expression-listopt   )
@@ -1513,6 +1758,14 @@ See [member access examples](#member-access-operator).
 
 **Syntax**
 
+
+
 
   postfix-increment-expression:
     variable  ++
@@ -1547,6 +1800,27 @@ $a = array(100, 200); $v = $a[1]++; // old value of $ia[1] (200) is assigned
 
 **Syntax**
 
+
+
 
   scoped-property-access-expression:
     scope-resolution-qualifier   ::   simple-variable
@@ -1673,6 +1947,11 @@ class Point
 
 **Syntax**
 
+
+
 
   exponentiation-expression:
     expression  **  expression
@@ -1709,6 +1988,17 @@ for each.  **Examples**
 
 **Syntax**
 
+
+
 
   unary-expression:
     postfix-expression
@@ -1738,6 +2028,14 @@ These operators associate right-to-left.
 
 **Syntax**
 
+
+
 
   prefix-increment-expression:
     ++ variable
@@ -1848,6 +2146,14 @@ $a = "^^Z^^"; ++$a; // $a is now "^^Z^^"
 
 **Syntax**
 
+
+
 
   unary-op-expression:
     unary-operator cast-expression
@@ -1939,6 +2245,11 @@ $s = "\x86\x97"; $s = ~$s; // $s is "yh"
 
 **Syntax**
 
+
+
 
   error-control-expression:
     @   expression
@@ -1995,6 +2306,11 @@ $x = $tmp;
 
 **Syntax**
 
+
+
 
   shell-command-expression:
     `  dq-char-sequenceopt  `
@@ -2032,6 +2348,16 @@ $result = `$d {$f}`;      // result is the output of command dir *.*
 
 **Syntax**
 
+
+
 
   cast-expression:
     unary-expression
@@ -2087,6 +2413,19 @@ A *cast-type* of `unset` always results in a value of `NULL`. (This use of
 
 **Syntax**
 
+
+
 
   instanceof-expression:
     unary-expression
@@ -2156,6 +2495,14 @@ var_dump($e2 instanceof $e1);      // TRUE
 
 **Syntax**
 
+
+
 
   multiplicative-expression:
     instanceof-expression
@@ -2227,6 +2574,14 @@ These operators associate left-to-right.
 
 **Syntax**
 
+
+
 
   additive-expression:
     multiplicative-expression
@@ -2301,6 +2656,13 @@ TRUE . NULL;      // string with value "1"
 
 **Syntax**
 
+
+
 
   shift-expression:
     additive-expression
@@ -2361,6 +2723,16 @@ These operators associate left-to-right.
 
 **Syntax**
 
+
+
 
   relational-expression:
     shift-expression
@@ -2491,6 +2863,16 @@ function order_func($a, $b) {
 
 **Syntax**
 
+
+
 
   equality-expression:
     relational-expression
@@ -2549,6 +2931,12 @@ TRUE !== 100  // result has value TRUE
 
 **Syntax**
 
+
+
 
   bitwise-AND-expression:
     equality-expression
@@ -2594,6 +2982,12 @@ $uLetter = $lLetter & ~0x20;  // clear the 6th bit to make letter 'S'
 
 **Syntax**
 
+
+
 
   bitwise-exc-OR-expression:
     bitwise-AND-expression
@@ -2641,6 +3035,12 @@ $v1 = $v1 ^ $v2;    // $v1 is now -987, and $v2 is now 1234
 
 **Syntax**
 
+
+
 
   bitwise-inc-OR-expression:
     bitwise-exc-OR-expression
@@ -2686,6 +3086,12 @@ $lLetter = $upCaseLetter | 0x20;  // set the 6th bit to make letter 'a'
 
 **Syntax**
 
+
+
 
   logical-AND-expression-1:
     bitwise-inc-OR-expression
@@ -2715,6 +3121,12 @@ if ($month > 1 && $month <= 12) ...
 
 **Syntax**
 
+
+
 
   logical-inc-OR-expression-1:
     logical-AND-expression-1
@@ -2741,6 +3153,12 @@ if ($month < 1 || $month > 12) ...
 
 **Syntax**
 
+
+
 
   conditional-expression:
     logical-inc-OR-expression-1
@@ -2787,6 +3205,11 @@ function factorial($int)
 
 **Syntax**
 
+
+
 
   coalesce-expression:
     logical-inc-OR-expression-1  ??  expression
@@ -2837,6 +3260,15 @@ var_dump(true ?? foo()); // outputs bool(true), "executed!" does not appear as i
 
 **Syntax**
 
+
+
 
   assignment-expression:
     conditional-expression
@@ -2867,6 +3299,12 @@ These operators associate right-to-left.
 
 **Syntax**
 
+
+
 
   simple-assignment-expression:
     variable  =  assignment-expression
@@ -2937,6 +3375,11 @@ $a = new C; // make $a point to the allocated object
 
 **Syntax**
 
+
+
 
   byref-assignment-expression:
     variable  =  &  assignment-expression
@@ -2979,6 +3422,14 @@ $b =& g2();     // make $b an alias to "xxx"
 
 **Syntax**
 
+
+
 
   compound-assignment-expression:
     variable   compound-assignment-operator   assignment-expression
@@ -3017,6 +3468,12 @@ $a[$i++] += 50; // $a[1] = 250, $i → 2
 
 **Syntax**
 
+
+
 
   logical-AND-expression-2:
     assignment-expression
@@ -3036,6 +3493,12 @@ same semantics as [operator `&&`](#logical-and-operator-form-1).
 
 **Syntax**
 
+
+
 
   logical-exc-OR-expression:
     logical-AND-expression-2
@@ -3068,6 +3531,12 @@ f($i++) xor g($i) // the sequence point makes this well-defined
 
 **Syntax**
 
+
+
 
   logical-inc-OR-expression-2:
     logical-exc-OR-expression
@@ -3087,6 +3556,13 @@ same semantics as [operator `||`](#logical-inclusive-or-operator-form-1).
 
 **Syntax**
 
+
+
 
   yield-expression:
     logical-inc-OR-expression-2
@@ -3216,6 +3692,15 @@ foreach ($g as $yielded) {
 
 **Syntax**
 
+
+
 
   expression:
     yield-expression
@@ -3390,6 +3875,11 @@ echo $x;                  // hello
 
 **Syntax**
 
+
+
 
   include-expression:
     include   expression
@@ -3441,6 +3931,11 @@ If ((include 'Positions.php') == 1) ...
 
 **Syntax**
 
+
+
 
   include-once-expression:
     include_once   expression
@@ -3488,6 +3983,11 @@ $c1 = new Circle(9, 7, 2.4);
 
 **Syntax**
 
+
+
 
   require-expression:
     require   expression
@@ -3507,6 +4007,11 @@ produces a fatal error.
 
 **Syntax**
 
+
+
 
   require-once-expression:
     require_once   expression
@@ -3533,6 +4038,11 @@ and relative path) still are considered the same file.
 
 **Syntax**
 
+
+
 
   constant-expression:
     expression
diff --git a/spec/11-statements.md b/spec/11-statements.md
index a8ba5f05..0ac71684 100644
--- a/spec/11-statements.md
+++ b/spec/11-statements.md
@@ -4,6 +4,27 @@
 
 **Syntax**
 
+
+
 
 
   statement:
@@ -49,6 +70,15 @@
 
 **Syntax**
 
+
+
 
   compound-statement:
     {   statement-listopt  }
@@ -90,6 +120,11 @@ while (condition)
 
 **Syntax**
 
+
+
 
   named-label-statement:
     name  :  statement
@@ -117,6 +152,11 @@ execution.
 
 **Syntax**
 
+
+
 
   expression-statement:
     expressionopt  ;
@@ -170,6 +210,12 @@ done:
 
 **Syntax**
 
+
+
 
   selection-statement:
     if-statement
@@ -190,6 +236,32 @@ selects among a set of statements.
 
 **Syntax**
 
+
+
 
   if-statement:
     if   (   expression   )   statement   elseif-clauses-1opt   else-clause-1opt
@@ -283,6 +355,26 @@ else  // this else does go with the outer if
 
 **Syntax**
 
+
+
 
   switch-statement:
     switch  (  expression  )  { case-statementsopt }
@@ -397,6 +489,14 @@ case $v < $a:   // non-constant expression
 
 **Syntax**
 
+
+
 
   iteration-statement:
     while-statement
@@ -416,6 +516,12 @@ case $v < $a:   // non-constant expression
 
 **Syntax**
 
+
+
 
   while-statement:
     while  (  expression  )  statement
@@ -464,6 +570,11 @@ while (TRUE)
 
 **Syntax**
 
+
+
 
   do-statement:
     do  statement  while  (  expression  )  ;
@@ -508,6 +619,25 @@ while ($i <= 10);
 
 **Syntax**
 
+
+
 
   for-statement:
     for   (   for-initializeropt   ;   for-controlopt   ;   for-end-of-loopopt   )   statement
@@ -600,6 +730,22 @@ for ($a = 100, $i = 1; ++$i, $i <= 10; ++$i, $a -= 10)
 
 **Syntax**
 
+
+
 
   foreach-statement:
     foreach  (  foreach-collection-name  as  foreach-keyopt  foreach-value  )   statement
@@ -685,6 +831,15 @@ foreach ($colors as &$color)  // note the &
 
 **Syntax**
 
+
+
 
   jump-statement:
     goto-statement
@@ -706,6 +861,11 @@ foreach ($colors as &$color)  // note the &
 
 **Syntax**
 
+
+
 
   goto-statement:
     goto  name  ;
@@ -758,6 +918,14 @@ done:
 
 **Syntax**
 
+
+
 
   continue-statement:
     continue   breakout-levelopt  ;
@@ -810,6 +978,11 @@ for ($i = 1; $i <= 5; ++$i)
 
 **Syntax**
 
+
+
 
   break-statement:
     break  breakout-levelopt  ;
@@ -875,6 +1048,11 @@ for ($i = 10; $i <= 40; $i +=10)
 
 **Syntax**
 
+
+
 
   return-statement:
     return  expressionopt  ;
@@ -987,6 +1165,11 @@ enclosing function, `$a` need not actually be incremented.
 
 **Syntax**
 
+
+
 
   throw-statement:
     throw  expression  ;
@@ -1027,6 +1210,23 @@ throw new MyException;
 
 **Syntax**
 
+
+
 
   try-statement:
     try  compound-statement   catch-clauses
@@ -1128,6 +1328,18 @@ finally { ... }
 
 **Syntax**
 
+
+
 
   declare-statement:
     declare  (  declare-directive  )  statement
diff --git a/spec/13-functions.md b/spec/13-functions.md
index d8fdfb19..33f9af0a 100644
--- a/spec/13-functions.md
+++ b/spec/13-functions.md
@@ -47,6 +47,51 @@ A function is called via the function-call operator [`()`](10-expressions.md#fun
 
 **Syntax**
 
+
+
 
   function-definition:
     function-definition-header   compound-statement
diff --git a/spec/14-classes.md b/spec/14-classes.md
index cee4237f..5dc3644b 100644
--- a/spec/14-classes.md
+++ b/spec/14-classes.md
@@ -58,6 +58,22 @@ While PHP supports *anonymous class types*, such a type cannot be declared using
 
 **Syntax**
 
+
+
 
   class-declaration:
     class-modifieropt  class  name   class-base-clauseopt  class-interface-clauseopt   {   class-member-declarationsopt }
@@ -197,6 +213,20 @@ class MyList implements MyCollection
 
 **Syntax**
 
+
+
 
   class-member-declarations:
     class-member-declaration
@@ -386,6 +416,21 @@ Widget::__callStatic('sMethod', array(NULL, 1.234))
 
 **Syntax**
 
+
+
 
   const-declaration:
     const   const-elements   ;
@@ -447,6 +492,34 @@ $col = Automobile::DEFAULT_COLOR;
 
 **Syntax**
 
+
+
 
   property-declaration:
     property-modifier   property-elements   ;
@@ -511,6 +584,21 @@ class Point
 
 **Syntax**
 
+
+
 
   method-declaration:
     method-modifiersopt   function-definition
@@ -569,6 +657,11 @@ examples of abstract methods and their subsequent definitions.
 
 **Syntax**
 
+
+
 
   constructor-declaration:
     method-modifiers  function &opt   __construct  (  parameter-declaration-listopt  )  compound-statement
@@ -657,6 +750,11 @@ class MyRangeException extends Exception
 
 **Syntax**
 
+
+
 
   destructor-declaration:
     method-modifiers  function  &opt  __destruct  ( ) compound-statement
diff --git a/spec/15-interfaces.md b/spec/15-interfaces.md
index e11ec348..0b84876f 100644
--- a/spec/15-interfaces.md
+++ b/spec/15-interfaces.md
@@ -18,6 +18,15 @@ inherits all members from its *base interface(s)*.
 
 **Syntax**
 
+
+
 
   interface-declaration:
     interface   name   interface-base-clauseopt {  interface-member-declarationsopt  }
@@ -82,6 +91,16 @@ processCollection(new MyQueue(...));
 
 **Syntax**
 
+
+
 
   interface-member-declarations:
     interface-member-declaration
diff --git a/spec/16-traits.md b/spec/16-traits.md
index ff7b5801..07cce424 100644
--- a/spec/16-traits.md
+++ b/spec/16-traits.md
@@ -42,6 +42,22 @@ that trait is used.
 
 **Syntax**
 
+
+
 
   trait-declaration:
     trait   name   {   trait-member-declarationsopt   }
@@ -106,6 +122,38 @@ trait T
 
 **Syntax**
 
+
+
 
   trait-use-clauses:
     trait-use-clause
diff --git a/spec/18-namespaces.md b/spec/18-namespaces.md
index 20414058..b27f3ea7 100644
--- a/spec/18-namespaces.md
+++ b/spec/18-namespaces.md
@@ -36,6 +36,12 @@ prefixes are reserved for use by PHP.
 
 **Syntax**
 
+
+
 
   namespace-definition:
     namespace  name  ;
@@ -118,6 +124,41 @@ namespace NS3\Sub1;
 
 **Syntax**
 
+
+
 
   namespace-use-declaration:
     use  namespace-function-or-constopt namespace-use-clauses  ;

From eec8da6b03f99e6987057f7aa4d7d33e0297a965 Mon Sep 17 00:00:00 2001
From: Nikita Popov 
Date: Fri, 25 Nov 2016 23:00:13 +0100
Subject: [PATCH 060/146] Remove "Defined elsewhere" blocks

---
 spec/05-types.md             |   7 -
 spec/07-variables.md         |  10 --
 spec/09-lexical-structure.md |  62 -------
 spec/10-expressions.md       | 314 -----------------------------------
 spec/11-statements.md        | 121 --------------
 spec/13-functions.md         |   5 -
 spec/14-classes.md           | 146 ----------------
 spec/15-interfaces.md        |   5 -
 spec/16-traits.md            |  13 --
 spec/18-namespaces.md        |  11 --
 10 files changed, 694 deletions(-)

diff --git a/spec/05-types.md b/spec/05-types.md
index c83632d6..9a48b5f2 100644
--- a/spec/05-types.md
+++ b/spec/05-types.md
@@ -157,13 +157,6 @@ str-number::
     floating-literal
 
-**Defined elsewhere** - -* [*digit-sequence*](09-lexical-structure.md#floating-point-literals) -* [*floating-literal*](09-lexical-structure.md#floating-point-literals) -* [*new-line*](09-lexical-structure.md#comments) -* [*sign*](09-lexical-structure.md#floating-point-literals) - Note that *digit-sequence* is interpreted as having base-10 (so `"0377"` is treated as 377 decimal with a redundant leading zero, rather than as octal 377). diff --git a/spec/07-variables.md b/spec/07-variables.md index b7098a26..105b7f41 100644 --- a/spec/07-variables.md +++ b/spec/07-variables.md @@ -296,11 +296,6 @@ function-static-initializer: = constant-expression
-**Defined elsewhere** - -* [*variable-name*](09-lexical-structure.md#names) -* [*constant-expression*](10-expressions.md#constant-expressions) - **Constraints** A function static must be defined inside a function. @@ -383,11 +378,6 @@ variable-name-list: variable-name-list , simple-variable
-**Defined elsewhere** - -* [*expression*](10-expressions.md#general-6) -* [*simple-variable*](10-expressions.md#simple-variable) - **Semantics** A global variable is never defined explicitly; instead, it is created diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index ac3d7255..7ce5b360 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -107,12 +107,6 @@ input-element:: token
-**Defined elsewhere** - -* [*comment*](#comments) -* [*white-space*](#white-space) -* [*token*](#tokens) - **Semantics** The basic elements of a script are comments, white space, and tokens. @@ -232,10 +226,6 @@ white-space-character:: Horizontal-tab character (U+0009)
-**Defined elsewhere** - -* [*new-line*](#comments) - **Semantics** The space and horizontal tab characters are considered *horizontal @@ -271,16 +261,6 @@ token:: operator-or-punctuator
-**Defined elsewhere** - -* [*variable-name*](#names) -* [*name*](#names) -* [*keyword*](#keywords) -* [*integer-literal*](#integer-literals) -* [*floating-literal*](#floating-point-literals) -* [*string-literal*](#string-literals) -* [*operator-or-punctuator*](#operators-and-punctuators) - ####Names **Syntax** @@ -353,10 +333,6 @@ nondigit:: one of N O P Q R S T U V W X Y Z
-**Defined elsewhere** - -* [*digit*](#integer-literals) - **Semantics** Names are used to identify the following: [constants](06-constants.md#general), @@ -635,10 +611,6 @@ digit-sequence:: digit-sequence digit
-**Defined elsewhere** - -* [*digit*](#integer-literals) - **Constraints** The value of a floating-point literal must be representable by its type. @@ -679,13 +651,6 @@ string-literal:: nowdoc-string-literal
-**Defined elsewhere** - -* [*single-quoted-string-literal*](#single-quoted-string-literals) -* [*double-quoted-string-literal*](#double-quoted-string-literals) -* [*heredoc-string-literal*](#heredoc-string-literals) -* [*nowdoc-string-literal*](#nowdoc-string-literals) - **Semantics** A string literal is a sequence of zero or more characters delimited in @@ -838,12 +803,6 @@ codepoint-digits:: hexadecimal-digit codepoint-digits
-**Defined elsewhere** - -* [*octal-digit*](#integer-literals) -* [*hexadecimal-digit*](#integer-literals) -* [*b-prefix*](#single-quoted-string-literals) - **Semantics** A double-quoted string literal is a string literal delimited by @@ -939,13 +898,6 @@ property-in-string:: -> name
-**Defined elsewhere** - -* [*variable-name*](#names) -* [*name*](#names) -* [*integer-literal*](#integer-literals) -* [*expression*](10-expressions.md#general-6) - *expression* works the same way as in [simple variable expressions](10-expressions.md#simple-variable). After the variable defined by the syntax above is evaluated, its value is converted @@ -1064,14 +1016,6 @@ hd-simple-escape-sequence:: one of \\ \$ \e \f \n \r \t \v
-**Defined elsewhere** - -* [*name*](#names) -* [*new-line*](#comments) -* [*dq-octal-escape-sequence*](#double-quoted-string-literals) -* [*dq-hexadecimal-escape-sequence*](#double-quoted-string-literals) -* [*b-prefix*](#single-quoted-string-literals) - **Constraints** The start and end identifier names must be the same. Only horizontal white @@ -1124,12 +1068,6 @@ nowdoc-string-literal:: b-prefixopt <<< ' name ' new-line hd-bodyopt name ;opt new-line
-**Defined elsewhere** - -* [*hd-body*](#heredoc-string-literals) -* [*new-line*](#comments) -* [*b-prefix*](#single-quoted-string-literals) - **Constraints** The start and end identifier names must be the same. diff --git a/spec/10-expressions.md b/spec/10-expressions.md index f5e55613..6c5d86c4 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -113,17 +113,6 @@ primary-expression: ( expression )
-**Defined elsewhere** - -* [*variable*](#variables) -* [*constant-access-expression*](#constant-access-expression) -* [*literal*](#literals) -* [*array-creation-expression*](#array-creation-operator) -* [*intrinsic*](#general-2) -* [*anonymous-function-creation-expression*](#anonymous-function-creation) -* [*expression*](#script-inclusion-operators) -* [*class-constant-access-expression*](#scope-resolution-operator) - **Semantics** The type and value of parenthesized expression are identical to those of @@ -147,11 +136,6 @@ simple-variable: $ { expression }
-**Defined elsewhere** - -* [*variable-name*](09-lexical-structure.md#names) -* [*expression*](#general-6) - **Constraints** The *simple-variable* or *expression* in the last two variants @@ -224,14 +208,6 @@ callable-expression: string-literal
-**Defined elsewhere** - -* [*array-creation-expression*](#array-creation-operator) -* [*callable-variable*](#variables) -* [*expression*](#general-6) -* [*variable*](#variables) -* [*string-literal*](09-lexical-structure.md#string-literals) - **Constraints** The *string-literal* must not use variable interpolation and must not be a heredoc @@ -275,16 +251,6 @@ variable: member-access-expression
-**Defined elsewhere** - -* [*function-call-expression*](#function-call-operator) -* [*member-access-expression*](#member-access-operator) -* [*member-call-expression*](#member-call-operator) -* [*scoped-call-expresssion*](#scope-resolution-operator) -* [*scoped-property-access-expresssion*](#scope-resolution-operator) -* [*simple-variable*](#simple-variable) -* [*subscript-expression*](#subscript-operator) - **Semantics** A *variable* is an expression that can *in principle* be used as an lvalue. However, the @@ -303,10 +269,6 @@ constant-access-expression: qualified-name
-**Defined elsewhere** - -* [*qualified-name*](09-lexical-structure.md#names) - **Semantics** A *constant-access-expression* evaluates to the value of the [constant](06-constants.md) @@ -330,12 +292,6 @@ literal: string-literal
-**Defined elsewhere** - -* [*integer-literal*](09-lexical-structure.md#integer-literals) -* [*floating-literal*](09-lexical-structure.md#floating-point-literals) -* [*string-literal*](09-lexical-structure.md#string-literals) - **Semantics** A literal evaluates to its value, as specified in the lexical specification for @@ -382,17 +338,6 @@ intrinsic-operator: print-intrinsic
-**Defined elsewhere** - -* [*echo-intrinsic*](#echo) -* [*empty-intrinsic*](#empty) -* [*eval-intrinsic*](#eval) -* [*exit-intrinsic*](#exitdie) -* [*isset-intrinsic*](#isset) -* [*list-intrinsic*](#list) -* [*print-intrinsic*](#print) -* [*unset-intrinsic*](#unset) - **Semantics** The names in this series of sections have special meaning and are @@ -426,10 +371,6 @@ expression-list: expression-list , expression
-**Defined elsewhere** - -* [*expression*](#general-6) - **Constraints** *expression* value must be [convertable to a string](08-conversions.md#converting-to-string-type). @@ -472,10 +413,6 @@ empty-intrinsic: empty ( expression )
-**Defined elsewhere** - -* [*expression*](#general-6) - **Semantics** This intrinsic returns `TRUE` if the variable or value designated by @@ -516,10 +453,6 @@ eval-intrinsic: eval ( expression )
-**Defined elsewhere** - -* [*expression*](#general-6) - **Constraints** *expression* must designate a string, or be [convertable to a string](08-conversions.md#converting-to-string-type). @@ -569,10 +502,6 @@ exit-intrinsic: die ( expressionopt )
-**Defined elsewhere** - -* [*expression*](#general-6) - **Constraints** When *expression* designates an integer, its value must be in the range @@ -627,10 +556,6 @@ variable-list: variable-list , variable
-**Defined elsewhere** - -* [*variable*](#variables) - **Semantics** This intrinsic returns `TRUE` if all the variables designated by @@ -703,10 +628,6 @@ list-or-variable: expression
-**Defined elsewhere** - -* [*expression*](#general-6) - **Constraints** *list-intrinsic* must be used as the left-hand operand in a @@ -805,10 +726,6 @@ print-intrinsic: print expression
-**Defined elsewhere** - -* [*expression*](#general-6) - **Constraints** *expression* value must be [convertable to a string](08-conversions.md#converting-to-string-type). @@ -851,10 +768,6 @@ unset-intrinsic: unset ( variable-list )
-**Defined elsewhere** - -* [*variable-list*](#isset) - **Semantics** This intrinsic [unsets](07-variables.md#general) the variables designated by each @@ -922,13 +835,6 @@ use-variable-name-list: use-variable-name-list , &opt variable-name
-**Defined elsewhere** - -* [*parameter-declaration-list*](13-functions.md#function-definitions) -* [*return-type*](13-functions.md#function-definitions) -* [*compound-statement*](11-statements.md#compound-statements) -* [*variable-name*](09-lexical-structure.md#names) - **Semantics** This operator returns an object of type [`Closure`](14-classes.md#class-closure), or a derived @@ -1014,15 +920,6 @@ postfix-expression: exponentiation-expression
-**Defined elsewhere** - -* [*primary-expression*](#general-1) -* [*clone-expression*](#the-clone-operator) -* [*object-creation-expression*](#the-new-operator) -* [*postfix-increment-expression*](#postfix-increment-and-decrement-operators) -* [*postfix-decrement-expression*](#postfix-increment-and-decrement-operators) -* [*exponentiation-expression*](#exponentiation-operator) - **Semantics** These operators associate left-to-right. @@ -1041,10 +938,6 @@ clone-expression: clone expression
-**Defined elsewhere** - -* [*expression*](#general-6) - **Constraints** *expression* must designate an object. @@ -1117,15 +1010,6 @@ class-type-designator: expression
-**Defined elsewhere** - -* [*argument-expression-list*](#function-call-operator) -* [*class-base-clause*](14-classes.md#class-declarations) -* [*class-interface-clause*](14-classes.md#class-declarations) -* [*class-member-declarations*](14-classes.md#class-members) -* [*expression*](#general-6) -* [*qualified-name*](09-lexical-structure.md#names) - **Constraints** *qualified-name* must name a class. @@ -1240,10 +1124,6 @@ element-value: expression
-**Defined elsewhere** - -* [*expression*](#general-6) - **Constraints** If *array-element-initializer* contains &, *expression* in *element-value* @@ -1323,11 +1203,6 @@ subscript-expression: dereferencable-expression { expression } [Deprecated form]
-**Defined elsewhere** - -* [*dereferencable-expression*](#dereferencable-expression) -* [*expression*](#general-6) - **Constraints** If *dereferencable-expression* designates a string, *expression* must not @@ -1516,11 +1391,6 @@ variadic-unpacking:
-**Defined elsewhere** - -* [*callable-expression*](#dereferencable-expression) -* [*assignment-expression*](#general-5) - **Constraints** *callable-expression* must designate a function, by being a value of type string @@ -1642,13 +1512,6 @@ member-name: { expression }
-**Defined elsewhere** - -* [*dereferencable-expression*](#dereferencable-expression) -* [*name*](09-lexical-structure.md#names) -* [*simple-variable*](#simple-variable) -* [*expression*](#general-6) - **Constraints** The *dereferencable-expression* must designate an object or be `NULL`, `FALSE`, @@ -1722,12 +1585,6 @@ member-call-expression: dereferencable-expression -> member-name ( argument-expression-listopt )
-**Defined elsewhere** - -* [*dereferencable-expression*](#dereferencable-expression) -* [*member-name*](#member-access-operator) -* [*argument-expression-list*](#function-call-operator) - **Constraints** The *dereferencable-expression* must designate an object. @@ -1774,10 +1631,6 @@ postfix-decrement-expression: variable --
-**Defined elsewhere** - -* [*variable*](#variables) - **Constraints** The operand of the postfix ++ and -- operators must be a modifiable @@ -1842,13 +1695,6 @@ relative-scope: static
-**Defined elsewhere** - -* [*argument-expression-list*](#function-call-operator) -* [*dereferencable-expression*](#dereferencable-expression) -* [*member-name*](#member-access-operator) -* [*simple-variable*](#simple-variable) - **Constraints** *qualified-name* must be the name of a class or interface type. @@ -1957,10 +1803,6 @@ exponentiation-expression: expression ** expression
-**Defined elsewhere** - -* [*expression*](#general-6) - **Semantics** The `**` operator produces the result of raising the value of the @@ -2010,16 +1852,6 @@ unary-expression: cast-expression
-**Defined elsewhere** - -* [*postfix-expression*](#general-3) -* [*prefix-increment-expression*](#prefix-increment-and-decrement-operators) -* [*prefix-decrement-expression*](#prefix-increment-and-decrement-operators) -* [*unary-op-expression*](#unary-arithmetic-operators) -* [*error-control-expression*](#error-control-operator) -* [*shell-command-expression*](#shell-command-operator) -* [*cast-expression*](#cast-operator) - **Semantics** These operators associate right-to-left. @@ -2044,10 +1876,6 @@ prefix-decrement-expression: -- variable
-**Defined elsewhere** - -* [*variable*](#variables) - **Constraints** The operand of the prefix `++` or `--` operator must be a modifiable lvalue @@ -2162,10 +1990,6 @@ unary-operator: one of + - ! ~
-**Defined elsewhere** - -* [*cast-expression*](#cast-operator) - **Constraints** The operand of the unary `+` and unary `-` must have scalar-compatible type. @@ -2255,10 +2079,6 @@ error-control-expression: @ expression
-**Defined elsewhere** - -* [*expression*](#general-6) - **Semantics** Operator `@` suppresses the reporting of any error messages generated by the evaluation of @@ -2319,10 +2139,6 @@ shell-command-expression: where \` is the GRAVE ACCENT character U+0060, commonly referred to as a *backtick*. -**Defined elsewhere** - -* [*dq-char-sequence*](09-lexical-structure.md#double-quoted-string-literals) - **Semantics** This operator passes *dq-char-sequence* to the command shell for @@ -2368,10 +2184,6 @@ cast-type: one of real string unset
-**Defined elsewhere** - -* [*unary-expression*](#general-4) - **Semantics** With the exception of the *cast-type* unset and binary (see below), the @@ -2439,12 +2251,6 @@ instanceof-type-designator: expression
-**Defined elsewhere** - -* [*unary-expression*](#general-4) -* [*expression*](#general-6) -* [*qualified-name*](09-lexical-structure.md#names) - **Constraints** The *expression* in *instanceof-type-designator* and *instanceof-subject* must not be any form of @@ -2511,10 +2317,6 @@ multiplicative-expression: multiplicative-expression % instanceof-expression
-**Defined elsewhere** - -* [*instanceof-expression*](#instanceof-operator) - **Constraints** The right-hand operand of operator `/` and operator `%` must not be zero. @@ -2590,10 +2392,6 @@ additive-expression: additive-expression . multiplicative-expression
-**Defined elsewhere** - -* [*multiplicative-expression*](#multiplicative-operators) - **Constraints** If either operand of `+` has array type, the other operand must also have array @@ -2670,10 +2468,6 @@ shift-expression: shift-expression >> additive-expression
-**Defined elsewhere** - -* [*additive-expression*](#additive-operators) - **Constraints** Each of the operands must have scalar-compatible type. @@ -2743,10 +2537,6 @@ relational-expression: relational-expression <=> shift-expression
-**Defined elsewhere** - -* [*shift-expression*](#bitwise-shift-operators) - **Semantics** Operator `<=>` represents comparison operator between two expressions, with the @@ -2883,10 +2673,6 @@ equality-expression: equality-expression !== relational-expression
-**Defined elsewhere** - -* [*relational-expression*](#relational-operators) - **Semantics** Operator `==` represents *value equality*, operators `!=` and `<>` are @@ -2943,10 +2729,6 @@ bitwise-AND-expression: bitwise-AND-expression & equality-expression
-**Defined elsewhere** - -* [*equality-expression*](#equality-operators) - **Constraints** Each of the operands must have scalar-compatible type. @@ -2994,10 +2776,6 @@ bitwise-exc-OR-expression: bitwise-exc-OR-expression ^ bitwise-AND-expression
-**Defined elsewhere** - -* [*bitwise-AND-expression*](#bitwise-and-operator) - **Constraints** Each of the operands must have scalar-compatible type. @@ -3047,10 +2825,6 @@ bitwise-inc-OR-expression: bitwise-inc-OR-expression | bitwise-exc-OR-expression
-**Defined elsewhere** - -* [*bitwise-exc-OR-expression*](#bitwise-exclusive-or-operator) - **Constraints** Each of the operands must have scalar-compatible type. @@ -3098,10 +2872,6 @@ logical-AND-expression-1: logical-AND-expression-1 && bitwise-inc-OR-expression
-**Defined elsewhere** - -* [*bitwise-incl-OR-expression*](#bitwise-inclusive-or-operator) - **Semantics** Given the expression `e1 && e2`, `e1` is evaluated first. If `e1` [converts to `bool`](08-conversions.md#converting-to-boolean-type) as `FALSE`, `e2` is not evaluated, and the result has type `bool`, value `FALSE`. Otherwise, `e2` is evaluated. If `e2` converts to `bool` as `FALSE`, the result has type `bool`, value `FALSE`; otherwise, it has type `bool`, value `TRUE`. There is a sequence point after the evaluation of `e1`. @@ -3133,10 +2903,6 @@ logical-inc-OR-expression-1: logical-inc-OR-expression-1 || logical-AND-expression-1
-**Defined elsewhere** - -* [*logical-exc-OR-expression*](#bitwise-exclusive-or-operator) - **Semantics** Given the expression `e1 || e2`, `e1` is evaluated first. If `e1` [converts to `bool`](08-conversions.md#converting-to-boolean-type) as `TRUE`, `e2` is not evaluated, and the result has type `bool`, value `TRUE`. Otherwise, `e2` is evaluated. If `e2` converts to `bool` as `TRUE`, the result has type `bool`, value `TRUE`; otherwise, it has type `bool`, value `FALSE`. There is a sequence point after the evaluation of `e1`. @@ -3165,11 +2931,6 @@ conditional-expression: logical-inc-OR-expression-1 ? expressionopt : conditional-expression
-**Defined elsewhere** - -* [*logical-OR-expression*](#logical-inclusive-or-operator-form-1) -* [*expression*](#general-6) - **Semantics** Given the expression `e1 ? e2 : e3`, `e1` is evaluated first and [converted to `bool`](08-conversions.md#converting-to-boolean-type) if it has another type. If the result is `TRUE`, then and only then is `e2` evaluated, and the result and its type become the result and type of @@ -3215,11 +2976,6 @@ coalesce-expression: logical-inc-OR-expression-1 ?? expression
-**Defined elsewhere** - -* [*logical-OR-expression*](#logical-inclusive-or-operator-form-1) -* [*expression*](#general-6) - **Semantics** Given the expression `e1 ?? e2`, if `e1` is set and not `NULL` (i.e. TRUE for @@ -3278,14 +3034,6 @@ assignment-expression: compound-assignment-expression
-**Defined elsewhere** - -* [*conditional-expression*](#conditional-operator) -* [*simple-assignment-expression*](#simple-assignment) -* [*byref-assignment-expression*](#byref-assignment) -* [*compound-assignment-expression*](#compound-assignment) -* [*coalesce-expression*](#coalesce-operator) - **Constraints** The left-hand operand of an assignment operator must be a modifiable @@ -3311,12 +3059,6 @@ simple-assignment-expression: list-intrinsic = assignment-expression
-**Defined elsewhere** - -* [*variable*](#variables) -* [*list-intrinsic*](#list) -* [*assignment-expression*](#general-5) - **Constraints** If the location designated by the left-hand operand is a string element, @@ -3385,11 +3127,6 @@ byref-assignment-expression: variable = & assignment-expression
-**Defined elsewhere** - -* [*variable*](#variables) -* [*assignment-expression*](#general-5) - **Constraints** *assignment-expression* must be an lvalue or a call to a function that @@ -3438,11 +3175,6 @@ compound-assignment-operator: one of **= *= /= %= += -= .= <<= >>= &= ^= |=
-**Defined elsewhere** - -* [*variable*](#variables) -* [*assignment-expression*](#general-5) - **Constraints** Any constraints that apply to the corresponding binary operator apply to the compound-assignment form as well. @@ -3480,10 +3212,6 @@ logical-AND-expression-2: logical-AND-expression-2 and assignment-expression
-**Defined elsewhere** - -* [*assignment-expression*](#general-5) - **Semantics** Except for the difference in precedence, operator and has exactly the @@ -3505,10 +3233,6 @@ logical-exc-OR-expression: logical-exc-OR-expression xor logical-AND-expression-2
-**Defined elsewhere** - -* [*logical-AND-expression*](#logical-and-operator-form-2) - **Semantics** If either operand does not have type `bool`, its value is first converted @@ -3543,10 +3267,6 @@ logical-inc-OR-expression-2: logical-inc-OR-expression-2 or logical-exc-OR-expression
-**Defined elsewhere** - -* [*logical-exc-OR-expression*](#logical-exclusive-or-operator) - **Semantics** Except for the difference in precedence, operator and has exactly the @@ -3570,12 +3290,6 @@ yield-expression: yield from expression
-**Defined elsewhere** - -* [*logical-inc-OR-expression*](#logical-inclusive-or-operator-form-2) -* [*array-element-initializer*](#array-creation-operator) -* [*expression*](#script-inclusion-operators) - **Semantics** Any function containing a *yield-expression* is a *generator function*. @@ -3710,14 +3424,6 @@ expression: require-once-expression
-**Defined elsewhere** - -* [*yield-expression*](#yield-operator) -* [*include-expression*](#the-include-operator) -* [*include-once-expression*](#the-include_once-operator) -* [*require-expression*](#the-require-operator) -* [*require-once-expression*](#the-require_once-operator) - **Semantics** When creating large applications or building component libraries, it is @@ -3885,10 +3591,6 @@ include-expression: include expression
-**Defined elsewhere** - -* [*expression*](#general-6) - **Constraints** *expresssion* must be convertable to a string, which designates @@ -3941,10 +3643,6 @@ include-once-expression: include_once expression
-**Defined elsewhere** - -* [*expression*](#general-6) - **Semantics** This operator is identical to operator [`include`](#the-include-operator) except that in @@ -3993,10 +3691,6 @@ require-expression: require expression
-**Defined elsewhere** - -* [*expression*](#general-6) - **Semantics** This operator is identical to operator [`include`](#the-include-operator) except that in @@ -4017,10 +3711,6 @@ require-once-expression: require_once expression
-**Defined elsewhere** - -* [*expression*](#general-6) - **Semantics** This operator is identical to operator [`require`](#the-require-operator) except that in @@ -4048,10 +3738,6 @@ constant-expression: expression
-**Defined elsewhere** - -* [*expression*](#general-6) - **Constraints** The *expression* may only use the following syntactic elements: diff --git a/spec/11-statements.md b/spec/11-statements.md index 0ac71684..bda56e0d 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -47,25 +47,6 @@ statement: function-static-declaration
-**Defined elsewhere** - -* [*compound-statement*](#compound-statements) -* [*labeled-statement*](#labeled-statements) -* [*expression-statement*](#expression-statements) -* [*selection-statement*](#general-1) -* [*iteration-statement*](#general-2) -* [*jump-statement*](#general-3) -* [*declare-statement*](#the-declare-statement) -* [*const-declaration*](14-classes.md#constants) -* [*function-definition*](13-functions.md#function-definitions) -* [*class-declaration*](14-classes.md#class-declarations) -* [*interface-declaration*](15-interfaces.md#interface-declarations) -* [*trait-declaration*](16-traits.md#trait-declarations) -* [*namespace-definition*](18-namespaces.md#defining-namespaces) -* [*namespace-use-declaration*](18-namespaces.md#namespace-use-declarations) -* [*global-declaration*](07-variables.md#global-variables) -* [*function-static-declaration*](07-variables.md#function-statics) - ##Compound Statements **Syntax** @@ -88,10 +69,6 @@ statement-list: statement-list statement
-**Defined elsewhere** - -* [*statement*](#general) - **Semantics** A *compound statement* allows a group of zero or more statements to be @@ -130,12 +107,6 @@ named-label-statement: name : statement
-**Defined elsewhere** - -* [*name*](09-lexical-structure.md#names) -* [*statement*](#general) -* [*expression*](10-expressions.md#general-6) - **Constraints** A named label can be used as the target of a [`goto` statement](#the-goto-statement). @@ -162,10 +133,6 @@ expression-statement: expressionopt ;
-**Defined elsewhere** - -* [*expression*](10-expressions.md#general-6) - **Semantics** If present, *expression* is evaluated for its side effects, if any, and @@ -222,11 +189,6 @@ selection-statement: switch-statement
-**Defined elsewhere** - -* [*if-statement*](#the-if-statement) -* [*switch-statement*](#the-switch-statement) - **Semantics** Based on the value of a controlling expression, a selection statement @@ -288,12 +250,6 @@ else-clause-2: else : statement-list
-**Defined elsewhere** - -* [*expression*](10-expressions.md#general-6) -* [*statement*](#general) -* [*statement-list*](#compound-statements) - **Semantics** The two forms of the `if` statement are equivalent; they simply provide @@ -395,12 +351,6 @@ case-default-label-terminator: ;
-**Defined elsewhere** - -* [*expression*](10-expressions.md#general-6) -* [*compound-statement*](#compound-statements) -* [*statement-list*](#compound-statements) - **Constraints** There must be at most one default label. @@ -505,13 +455,6 @@ iteration-statement: foreach-statement
-**Defined elsewhere** - -* [*while-statement*](#the-while-statement) -* [*do-statement*](#the-do-statement) -* [*for-statement*](#the-for-statement) -* [*foreach-statement*](#the-foreach-statement) - ##The `while` Statement **Syntax** @@ -528,12 +471,6 @@ while-statement: while ( expression ) : statement-list endwhile ;
-**Defined elsewhere** - -* [*expression*](10-expressions.md#general-6) -* [*statement*](#general) -* [*statement-list*](#compound-statements) - **Semantics** The two forms of the `while` statement are equivalent; they simply provide @@ -582,11 +519,6 @@ do-statement: (Note: There is no alternate syntax). -**Defined elsewhere** - -* [*statement*](#general) -* [*expression*](10-expressions.md#general-6) - **Constraints** The controlling expression *expression* must have type `bool` or be @@ -661,12 +593,6 @@ Note: Unlike C/C++, PHP does not support a comma operator, per se. However, the syntax for the `for` statement has been extended from that of C/C++ to achieve the same results in this context. -**Defined elsewhere** - -* [*statement*](#general) -* [*statement-list*](#compound-statements) -* [*expression*](10-expressions.md#general-6) - **Semantics** The two forms of the `for` statement are equivalent; they simply provide @@ -762,13 +688,6 @@ foreach-value: list-intrinsic
-**Defined elsewhere** - -* [*statement*](#general) -* [*statement-list*](#compound-statements) -* [*list-intrinsic*](10-expressions.md#list) -* [*expression*](10-expressions.md#general-6) - **Constraints** The result of the expression *foreach-collection-name* must be a @@ -849,14 +768,6 @@ jump-statement: throw-statement
-**Defined elsewhere** - -* [*goto-statement*](#the-goto-statement) -* [*continue-statement*](#the-continue-statement) -* [*break-statement*](#the-break-statement) -* [*return-statement*](#the-return-statement) -* [*throw-statement*](#the-throw-statement) - ###The `goto` Statement **Syntax** @@ -871,10 +782,6 @@ goto-statement: goto name ;
-**Defined elsewhere** - -* [*name*](09-lexical-structure.md#names) - **Constraints** The name in a `goto` statement must be that of a [named label](#labeled-statements) located @@ -934,10 +841,6 @@ breakout-level: integer-literal
-**Defined elsewhere** - -* [*integer-literal*](09-lexical-structure.md#integer-literals) - **Constraints** The breakout level must be greater than zero, and it must not exceed the level of @@ -988,10 +891,6 @@ break-statement: break breakout-levelopt ;
-**Defined elsewhere** - -* [*breakout-level*](#the-continue-statement) - **Constraints** The breakout level must be greater than zero, and it must not exceed the level of @@ -1058,10 +957,6 @@ return-statement: return expressionopt ;
-**Defined elsewhere** - -* [*expression*](10-expressions.md#general-6) - **Semantics** A `return` statement from within a function terminates the execution of @@ -1175,10 +1070,6 @@ throw-statement: throw expression ;
-**Defined elsewhere** - -* [*expression*](10-expressions.md#general-6) - **Constraints** The type of *expression* must be [Exception](17-exception-handling.md#class-exception) or a subclass of that @@ -1244,12 +1135,6 @@ finally-clause: finally compound-statement
-**Defined elsewhere** - -* [*compound-statement*](#compound-statements) -* [*variable-name*](09-lexical-structure.md#names) -* [*qualified-name*](09-lexical-structure.md#names) - **Constraints** In a *catch-clause*, *parameter-declaration-list* must contain only one @@ -1353,12 +1238,6 @@ declare-directive:
-**Defined elsewhere** - -* [*statement*](#general) -* [*statement-list*](#compound-statements) -* [*literal*](09-lexical-structure.md#literals) - **Constraints** The literal for *ticks* must designate a value that is, or can be converted, to an diff --git a/spec/13-functions.md b/spec/13-functions.md index 33f9af0a..158c8c91 100644 --- a/spec/13-functions.md +++ b/spec/13-functions.md @@ -137,11 +137,6 @@ default-argument-specifier: = constant-expression
-**Defined elsewhere** - -* [*constant-expression*](10-expressions.md#constant-expressions) -* [*qualified-name*](09-lexical-structure.md#names) - **Constraints** Each parameter name in a *function-definition* must be distinct. diff --git a/spec/14-classes.md b/spec/14-classes.md index 5dc3644b..887dae84 100644 --- a/spec/14-classes.md +++ b/spec/14-classes.md @@ -90,10 +90,6 @@ class-interface-clause: class-interface-clause , qualified-name
-**Defined elsewhere** - -* [*class-member-declarations*](#class-members) - **Constraints** *name* must be a [valid name](09-lexical-structure.md#names), and must not be `self`, `parent`, or a [reserved keyword](09-lexical-structure.md#keywords). @@ -241,15 +237,6 @@ class-member-declaration: trait-use-clause
-**Defined elsewhere** - -* [*class-const-declaration*](#constants) -* [*property-declaration*](#properties) -* [*method-declaration*](#methods) -* [*constructor-declaration*](#constructors) -* [*destructor-declaration*](#destructors) -* [*trait-use-clause*](16-traits.md#trait-uses) - **Semantics** The members of a class are those specified by its @@ -446,12 +433,6 @@ const-element: name = constant-expression
-**Defined elsewhere** - -* [*name*](09-lexical-structure.md#names) -* [*constant-expression*](10-expressions.md#constant-expressions) -* [*visibility-modifier*](#properties) - **Constraints:** A *const-declaration* must only appear at the top level of a script, and @@ -548,11 +529,6 @@ property-initializer: = constant-expression
-**Defined elsewhere** - -* [*variable-name*](09-lexical-structure.md#names) -* [*constant-expression*](10-expressions.md#constant-expressions) - **Semantics** A *property-declaration* defines one or more instance or static properties. @@ -614,13 +590,6 @@ method-modifier: class-modifier
-**Defined elsewhere** - -* [*visibility-modifier*](#properties) -* [*static-modifier*](#properties) -* [*function-definition*](13-functions.md#function-definitions) -* [*function-definition-header*](13-functions.md#function-definitions) - **Constraints** The *method-modifiers* preceding a *function-definition* must not contain @@ -668,12 +637,6 @@ constructor-declaration:
-**Defined elsewhere** - -* [*method-modifiers*](#methods) -* [*parameter-declaration-list*](13-functions.md#function-definitions) -* [*compound-statement*](11-statements.md#compound-statements) - **Constraints** An overriding constructor in a derived class must have the same or a @@ -760,11 +723,6 @@ destructor-declaration: method-modifiers function &opt __destruct ( ) compound-statement
-**Defined elsewhere** - -* [*method-modifiers*](#methods) -* [*compound-statement*](11-statements.md#compound-statements) - **Constraints** *method-modifiers* can not contain `static`. @@ -852,13 +810,6 @@ an overriding concrete class must declare one. Nevertheless, the constraints on method-modifiers function __call ( $name , $arguments ) return-typeopt compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) -* [*return-type*](13-functions.md#function-definitions) -* [*return-type*](13-functions.md#function-definitions) - **Constraints** The method can not be static and must have public visibility. @@ -916,13 +867,6 @@ $obj->iMethod(10, TRUE, "abc"); // $obj->__call('iMethod', array(...)) method-modifiers function __callStatic ( $name , $arguments ) return-typeopt compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) -* [*return-type*](13-functions.md#function-definitions) -* [*return-type*](13-functions.md#function-definitions) - **Constraints** The *method-modifiers* must contain `static` and must define public visibility. @@ -979,11 +923,6 @@ Widget::sMethod(NULL, 1.234); // Widget::__callStatic('sMethod', array(...)) method-modifiers function __clone ( ) compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1069,11 +1008,6 @@ $p2 = clone $p1; // created by cloning method-modifiers function __debugInfo ( ) compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1123,13 +1057,6 @@ object(File)#1 { method-modifiers function &opt __get ( $name ) return-typeopt compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) -* [*return-type*](13-functions.md#function-definitions) -* [*return-type*](13-functions.md#function-definitions) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1222,13 +1149,6 @@ restrictions on the spelling of the dynamic property name designated by method-modifiers function __invoke ( parameter-declaration-listopt ) return-typeopt compound-statement
-**Defined elsewhere** - -* [*parameter-declaration-list*](13-functions.md#function-definitions) -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) -* [*return-type*](13-functions.md#function-definitions) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1268,12 +1188,6 @@ $r = $c(123); // becomes $r = $c->__invoke(123); method-modifiers function __isset ( $name ) return-typeopt compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) -* [*return-type*](13-functions.md#function-definitions) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1331,12 +1245,6 @@ See the Implementation Notes for [`__get`](#method-__get). method-modifiers function __set ( $name , $value ) return-typeopt compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) -* [*return-type*](13-functions.md#function-definitions) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1404,12 +1312,6 @@ See the Implementation Notes for [`__get`](#method-__get). method-modifiers function __set_state ( array $properties ) return-typeopt compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) -* [*return-type*](13-functions.md#function-definitions) - **Constraints** The *method-modifiers* must contain `static` and must define public visibility. @@ -1526,12 +1428,6 @@ var_dump($z); method-modifiers function __sleep ( ) return-typeopt compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) -* [*return-type*](13-functions.md#function-definitions) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1610,12 +1506,6 @@ $v = unserialize($s); // unserialize Point(-1,0) method-modifiers function __toString ( ) return-typeopt compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) -* [*return-type*](13-functions.md#function-definitions) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1676,12 +1566,6 @@ class MyRangeException extends Exception method-modifiers function __unset ( $name ) return-typeopt compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) -* [*return-type*](13-functions.md#function-definitions) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -1739,12 +1623,6 @@ See the Implementation Notes for [`__get`](#method-__get). method-modifiers function __wakeup ( ) return-typeopt compound-statement
-**Defined elsewhere** - -* [*compound-statement*](11-statements.md#compound-statements) -* [*method-modifiers*](#methods) -* [*return-type*](13-functions.md#function-definitions) - **Constraints** The *method-modifiers* must not contain `static` and must define public visibility. @@ -2154,10 +2032,6 @@ class Error implements Throwable } ``` -**Defined elsewhere** - -* [`Throwable`](15-interfaces.md#interface-throwable) - For information about the base interface, see [Throwable](15-interfaces.md#interface-throwable). Note that the methods from Throwable are implemented as `final` in the Error class, which means the extending class can not override them. @@ -2172,10 +2046,6 @@ class ArithmeticError extends Error } ``` -**Defined elsewhere** - -* [`Error`](#class-error) - ####Class `AssertionError` An instance of this class is thrown when an assertion made via the intrinsic `assert` fails. The class type is defined, as follows: @@ -2186,10 +2056,6 @@ class AssertionError extends Error } ``` -**Defined elsewhere** - -* [`Error`](#class-error) - ####Class `DivisionByZeroError` An instance of this class is thrown when an attempt is made to divide a number by zero, e.g. when using the remainder operators ([`%`](10-expressions.md#multiplicative-operators) and [`%=`](10-expressions.md#compound-assignment)). @@ -2202,10 +2068,6 @@ class DivisionByZeroError extends Error } ``` -**Defined elsewhere** - -* [`Error`](#class-error) - ####Class `ParseError` An instance of this class is thrown when an error occurs while parsing PHP code (such as when calling the intrinsic [`eval`](10-expressions.md#eval)). It is defined, as follows: @@ -2216,10 +2078,6 @@ class ParseError extends Error } ``` -**Defined elsewhere** - -* [`Error`](#class-error) - ####Class `TypeError` An instance of this class is thrown when any of the following occurs: @@ -2236,8 +2094,4 @@ class TypeError extends Error } ``` -**Defined elsewhere** - -* [`Error`](#class-error) - See also class [`Exception`](17-exception-handling.md#class-exception). diff --git a/spec/15-interfaces.md b/spec/15-interfaces.md index 0b84876f..d0d5a9f8 100644 --- a/spec/15-interfaces.md +++ b/spec/15-interfaces.md @@ -36,11 +36,6 @@ interface-base-clause: interface-base-clause , qualified-name
-**Defined elsewhere** - -* [*name*](09-lexical-structure.md#names) -* [*interface-member-declarations*](#interface-members) - **Constraints** An interface must not be derived directly or indirectly from itself. diff --git a/spec/16-traits.md b/spec/16-traits.md index 07cce424..294b4f34 100644 --- a/spec/16-traits.md +++ b/spec/16-traits.md @@ -74,14 +74,6 @@ trait-member-declaration: trait-use-clauses
-**Defined elsewhere** - -* [*property-declaration*](14-classes.md#properties) -* [*method-declaration*](14-classes.md#methods) -* [*constructor-declaration*](14-classes.md#constructors) -* [*destructor-declaration*](14-classes.md#destructors) -* [*trait-use-clauses*](#trait-uses) - **Semantics** A *trait-declaration* defines a named set of members, which are made @@ -186,11 +178,6 @@ trait-alias-as-clause: name as visibility-modifier nameopt
-**Defined elsewhere** - -* [*name*](09-lexical-structure.md#names) -* [*visibility-modifier*](14-classes.md#properties) - **Constraints** The *name* items in *trait-name-list* must designate trait names, excluding diff --git a/spec/18-namespaces.md b/spec/18-namespaces.md index b27f3ea7..98136014 100644 --- a/spec/18-namespaces.md +++ b/spec/18-namespaces.md @@ -48,11 +48,6 @@ namespace-definition: namespace nameopt compound-statement
-**Defined elsewhere** - -* [*name*](09-lexical-structure.md#names) -* [*compound-statement*](11-statements.md#compound-statements) - **Constraints** Except for white space and [*declare-statement*](11-statements.md#the-declare-statement), the @@ -195,12 +190,6 @@ namespace-use-group-clause-2: namespace-function-or-constopt namespace-name namespace-aliasing-clauseopt
-**Defined elsewhere** - -* [*name*](09-lexical-structure.md#names) -* [*namespace-name*](09-lexical-structure.md#names) -* [*qualified-name*](09-lexical-structure.md#names) - **Constraints** A *namespace-use-declaration* must not occur except at the top level or directly in the context of a *namespace-definition*. From 512a016a7472f3d170111844699ab89b6578bbd7 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 25 Nov 2016 22:47:55 +0100 Subject: [PATCH 061/146] Implement grammar rendering + render grammar --- spec/04-basic-concepts.md | 24 +- spec/05-types.md | 32 +- spec/07-variables.md | 28 +- spec/09-lexical-structure.md | 459 ++++----- spec/10-expressions.md | 609 ++++++----- spec/11-statements.md | 262 +++-- spec/13-functions.md | 64 +- spec/14-classes.md | 131 ++- spec/15-interfaces.md | 22 +- spec/16-traits.md | 70 +- spec/18-namespaces.md | 55 +- spec/19-grammar.md | 1882 +++++++++++++++++----------------- tools/grammar.php | 63 +- tools/grammar_util.php | 140 +++ 14 files changed, 2001 insertions(+), 1840 deletions(-) create mode 100644 tools/grammar_util.php diff --git a/spec/04-basic-concepts.md b/spec/04-basic-concepts.md index d2b2ac24..a3fe9491 100644 --- a/spec/04-basic-concepts.md +++ b/spec/04-basic-concepts.md @@ -23,22 +23,22 @@ text: -->
-  script:
-    script-section
-    script   script-section
+script:
+   script-section
+   script   script-section
 
-  script-section:
-     textopt start-tag statement-listopt end-tagopt textopt
+script-section:
+   textopt   start-tag   statement-listopt   end-tagopt   textopt
 
-  start-tag:
-    <?php
-    <?=
+start-tag:
+   <?php
+   <?=
 
-  end-tag:
-    ?>
+end-tag:
+   ?>
 
-  text:
-    arbitrary text not containing any of start-tag sequences
+text:
+   arbitrary text not containing any of   start-tag   sequences
 
All of the sections in a script are treated as though they belonged to diff --git a/spec/05-types.md b/spec/05-types.md index 9a48b5f2..0074793c 100644 --- a/spec/05-types.md +++ b/spec/05-types.md @@ -139,22 +139,22 @@ str-number:: -->
-  str-numeric::
-    str-whitespaceopt   signopt   str-number
-
-  str-whitespace::
-    str-whitespaceopt   str-whitespace-char
-
-  str-whitespace-char::
-    new-line
-    Space character (U+0020)
-    Horizontal-tab character (U+0009)
-    Vertical-tab character (U+000B)
-    Form-feed character (U+000C)
-
-  str-number::
-    digit-sequence
-    floating-literal
+str-numeric::
+   str-whitespaceopt   signopt   str-number
+
+str-whitespace::
+   str-whitespaceopt   str-whitespace-char
+
+str-whitespace-char::
+   new-line
+   Space character (U+0020)
+   Horizontal-tab character (U+0009)
+   Vertical-tab character (U+000B)
+   Form-feed character (U+000C)
+
+str-number::
+   digit-sequence
+   floating-literal
 
Note that *digit-sequence* is interpreted as having base-10 (so `"0377"` is treated as 377 decimal with a redundant diff --git a/spec/07-variables.md b/spec/07-variables.md index 105b7f41..9a09e039 100644 --- a/spec/07-variables.md +++ b/spec/07-variables.md @@ -282,18 +282,18 @@ function-static-initializer: -->
-  function-static-declaration:
-    static static-variable-name-list  ;
+function-static-declaration:
+   static   static-variable-name-list   ;
 
-  static-variable-name-list:
-    static-variable-declaration
-    static-variable-name-list  ,  static-variable-declaration
+static-variable-name-list:
+   static-variable-declaration
+   static-variable-name-list   ,   static-variable-declaration
 
-  static-variable-declaration:
-    variable-name function-static-initializeropt
+static-variable-declaration:
+   variable-name   function-static-initializeropt
 
-  function-static-initializer:
-    = constant-expression
+function-static-initializer:
+   =   constant-expression
 
**Constraints** @@ -370,12 +370,12 @@ variable-name-list: -->
-  global-declaration:
-    global variable-name-list ;
+global-declaration:
+   global   variable-name-list   ;
 
-  variable-name-list:
-    simple-variable
-    variable-name-list  ,  simple-variable
+variable-name-list:
+   simple-variable
+   variable-name-list   ,   simple-variable
 
**Semantics** diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index 7ce5b360..ded9eb93 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -50,9 +50,9 @@ single-line-comment-example:: -->
-  single-line-comment::
-    // input-charactersopt
-    #  input-charactersopt
+single-line-comment-example::
+   //   input-charactersopt
+   #   input-charactersopt
 
defines the lexical grammar production *single-line-comment-example* as being @@ -71,10 +71,10 @@ hexadecimal-digit-example:: one of -->
-  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
+hexadecimal-digit-example:: one of
+   0   1   2   3   4   5   6   7   8   9
+   a   b   c   d   e   f
+   A   B   C   D   E   F
 
##Lexical analysis @@ -98,13 +98,14 @@ input-element:: -->
-  input-file::
-    input-element
-    input-file   input-element
-  input-element::
-    comment
-    white-space
-    token
+input-file::
+   input-element
+   input-file   input-element
+
+input-element::
+   comment
+   white-space
+   token
 
**Semantics** @@ -153,28 +154,28 @@ delimited-comment:: -->
-  comment::
-    single-line-comment
-    delimited-comment
+comment::
+   single-line-comment
+   delimited-comment
 
-  single-line-comment::
-    //   input-charactersopt
-    #    input-charactersopt
+single-line-comment::
+   //   input-charactersopt
+   #   input-charactersopt
 
-  input-characters::
-    input-character
-    input-characters   input-character
+input-characters::
+   input-character
+   input-characters   input-character
 
-  input-character::
-    Any source character except new-line
+input-character::
+   Any source character except   new-line
 
-  new-line::
-    Carriage-return character (U+000D)
-    Line-feed character (U+000A)
-    Carriage-return character (U+000D) followed by line-feed character (U+000A)
+new-line::
+   Carriage-return character (U+000D)
+   Line-feed character (U+000A)
+   Carriage-return character (U+000D) followed by line-feed character (U+000A)
 
-  delimited-comment::
-    /*   No characters or any source character sequence except */   */
+delimited-comment::
+   /*   No characters or any source character sequence except */   */
 
**Semantics** @@ -216,14 +217,14 @@ white-space-character:: -->
-  white-space::
-    white-space-character
-    white-space   white-space-character
-
-  white-space-character::
-    new-line
-    Space character (U+0020)
-    Horizontal-tab character (U+0009)
+white-space::
+   white-space-character
+   white-space   white-space-character
+
+white-space-character::
+   new-line
+   Space character (U+0020)
+   Horizontal-tab character (U+0009)
 
**Semantics** @@ -251,14 +252,14 @@ token:: -->
-  token::
-    variable-name
-    name
-    keyword
-    integer-literal
-    floating-literal
-    string-literal
-    operator-or-punctuator
+token::
+   variable-name
+   name
+   keyword
+   integer-literal
+   floating-literal
+   string-literal
+   operator-or-punctuator
 
####Names @@ -300,37 +301,37 @@ nondigit:: one of -->
-  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 U+0080–U+00ff
-
-  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
+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 U+0080–U+00ff
+
+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
 
**Semantics** @@ -401,15 +402,15 @@ keyword:: one of -->
-  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
+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
 
**Semantics** @@ -476,50 +477,50 @@ binary-digit:: one of -->
-  integer-literal::
-    decimal-literal
-    octal-literal
-    hexadecimal-literal
-    binary-literal
+integer-literal::
+   decimal-literal
+   octal-literal
+   hexadecimal-literal
+   binary-literal
 
-    decimal-literal::
-      nonzero-digit
-      decimal-literal   digit
+decimal-literal::
+   nonzero-digit
+   decimal-literal   digit
 
-    octal-literal::
-      0
-      octal-literal   octal-digit
+octal-literal::
+   0
+   octal-literal   octal-digit
 
-    hexadecimal-literal::
-      hexadecimal-prefix   hexadecimal-digit
-      hexadecimal-literal   hexadecimal-digit
+hexadecimal-literal::
+   hexadecimal-prefix   hexadecimal-digit
+   hexadecimal-literal   hexadecimal-digit
 
-    hexadecimal-prefix:: one of
-      0x  0X
+hexadecimal-prefix:: one of
+   0x   0X
 
-    binary-literal::
-      binary-prefix   binary-digit
-      binary-literal   binary-digit
+binary-literal::
+   binary-prefix   binary-digit
+   binary-literal   binary-digit
 
-    binary-prefix:: one of
-      0b  0B
+binary-prefix:: one of
+   0b   0B
 
-    digit:: one of
-      0  1  2  3  4  5  6  7  8  9
+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
+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
+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
+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
+binary-digit:: one of
+   0   1
 
**Semantics** @@ -591,24 +592,24 @@ digit-sequence:: -->
-  floating-literal::
-    fractional-literal   exponent-partopt
-    digit-sequence   exponent-part
+floating-literal::
+   fractional-literal   exponent-partopt
+   digit-sequence   exponent-part
 
-  fractional-literal::
-    digit-sequenceopt . digit-sequence
-    digit-sequence .
+fractional-literal::
+   digit-sequenceopt   .   digit-sequence
+   digit-sequence   .
 
-  exponent-part::
-    e  signopt   digit-sequence
-    E  signopt   digit-sequence
+exponent-part::
+   e   signopt   digit-sequence
+   E   signopt   digit-sequence
 
-  sign:: one of
-    +  -
+sign:: one of
+   +   -
 
-  digit-sequence::
-    digit
-    digit-sequence   digit
+digit-sequence::
+   digit
+   digit-sequence   digit
 
**Constraints** @@ -644,11 +645,11 @@ string-literal:: -->
-  string-literal::
-    single-quoted-string-literal
-    double-quoted-string-literal
-    heredoc-string-literal
-    nowdoc-string-literal
+string-literal::
+   single-quoted-string-literal
+   double-quoted-string-literal
+   heredoc-string-literal
+   nowdoc-string-literal
 
**Semantics** @@ -682,22 +683,22 @@ b-prefix:: one of -->
-  single-quoted-string-literal::
-    b-prefixopt  ' sq-char-sequenceopt  '
+single-quoted-string-literal::
+   b-prefixopt   '   sq-char-sequenceopt   '
 
-  sq-char-sequence::
-    sq-char
-    sq-char-sequence   sq-char
+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-char::
+   sq-escape-sequence
+   \opt   any member of the source character set except single-quote (') or backslash (\)
 
-  sq-escape-sequence:: one of
-    \'   \\
+sq-escape-sequence:: one of
+   \'   \\
 
-  b-prefix:: one of
-    b   B
+b-prefix:: one of
+   b   B
 
**Semantics** @@ -765,42 +766,42 @@ codepoint-digits:: -->
-  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
+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
 
**Semantics** @@ -881,21 +882,21 @@ property-in-string:: -->
-  string-variable::
-    variable-name   offset-or-propertyopt
-    ${   expression   }
+string-variable::
+   variable-name   offset-or-propertyopt
+   ${   expression   }
 
-  offset-or-property::
-    offset-in-string
-    property-in-string
+offset-or-property::
+   offset-in-string
+   property-in-string
 
-  offset-in-string::
-    [   name   ]
-    [   variable-name   ]
-    [   integer-literal   ]
+offset-in-string::
+   [   name   ]
+   [   variable-name   ]
+   [   integer-literal   ]
 
-  property-in-string::
-    ->   name
+property-in-string::
+   ->   name
 
*expression* works the same way as in [simple variable expressions](10-expressions.md#simple-variable). @@ -984,36 +985,36 @@ hd-simple-escape-sequence:: one of -->
-  heredoc-string-literal::
-    b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
+heredoc-string-literal::
+   b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
 
-  hd-start-identifier::
-    name
-    "   name  "
+hd-start-identifier::
+   name
+   "   name   "
 
-  hd-end-identifier::
-    name
+hd-end-identifier::
+   name
 
-  hd-body::
-    hd-char-sequenceopt   new-line
+hd-body::
+   hd-char-sequenceopt   new-line
 
-  hd-char-sequence::
-    hd-char
-    hd-char-sequence   hd-char
+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-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-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
+hd-simple-escape-sequence:: one of
+   \\   \$   \e   \f   \n   \r   \t   \v
 
**Constraints** @@ -1064,8 +1065,8 @@ nowdoc-string-literal:: -->
-  nowdoc-string-literal::
-    b-prefixopt  <<<  '  name  '  new-line  hd-bodyopt   name  ;opt   new-line
+nowdoc-string-literal::
+   b-prefixopt   <<<   '   name   '   new-line   hd-bodyopt   name   ;opt   new-line
 
**Constraints** @@ -1112,11 +1113,11 @@ operator-or-punctuator:: one of -->
-  operator-or-punctuator:: one of
-    [   ]   (   )   {   }   .   ->   ++   --   **   *   +   -   ~   !
-    $   /   %   <<    >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
-    &   &&   ||   ?   :   ;   =   **=   *=   /=   %=   +=   -=   .=   <<=
-    >>=   &=   ^=   |=   ,   ??   <=>   ...   \
+operator-or-punctuator:: one of
+   [   ]   (   )   {   }   .   ->   ++   --   **   *   +   -   ~   !
+   $   /   %   <<   >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
+   &   &&   ||   ?   :   ;   =   **=   *=   /=   %=   +=   -=   .=   <<=
+   >>=   &=   ^=   |=   ,   ??   <=>   ...   \
 
**Semantics** diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 6c5d86c4..f421ba65 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -102,15 +102,15 @@ primary-expression: -->
-  primary-expression:
-    variable
-    class-constant-access-expression
-    constant-access-expression
-    literal
-    array-creation-expression
-    intrinsic
-    anonymous-function-creation-expression
-    (  expression  )
+primary-expression:
+   variable
+   class-constant-access-expression
+   constant-access-expression
+   literal
+   array-creation-expression
+   intrinsic
+   anonymous-function-creation-expression
+   (   expression   )
 
**Semantics** @@ -130,10 +130,10 @@ simple-variable: -->
-  simple-variable:
-    variable-name
-    $   simple-variable
-    $   {   expression   }
+simple-variable:
+   variable-name
+   $   simple-variable
+   $   {   expression   }
 
**Constraints** @@ -195,17 +195,17 @@ callable-expression: -->
-  dereferencable-expression:
-    variable
-    (   expression   )
-    array-creation-expression
-    string-literal
-
-  callable-expression:
-    callable-variable
-    (   expression   )
-    array-creation-expression
-    string-literal
+dereferencable-expression:
+   variable
+   (   expression   )
+   array-creation-expression
+   string-literal
+
+callable-expression:
+   callable-variable
+   (   expression   )
+   array-creation-expression
+   string-literal
 
**Constraints** @@ -238,17 +238,17 @@ variable: -->
-  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
+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
 
**Semantics** @@ -265,8 +265,8 @@ constant-access-expression: -->
-  constant-access-expression:
-    qualified-name
+constant-access-expression:
+   qualified-name
 
**Semantics** @@ -286,10 +286,10 @@ literal: -->
-  literal:
-    integer-literal
-    floating-literal
-    string-literal
+literal:
+   integer-literal
+   floating-literal
+   string-literal
 
**Semantics** @@ -321,21 +321,21 @@ intrinsic-operator: -->
-  intrinsic:
-    intrinsic-construct
-    intrinsic-operator
-
-  intrinsic-construct:
-    echo-intrinsic
-    list-intrinsic
-    unset-intrinsic
-
-  intrinsic-operator:
-    empty-intrinsic
-    eval-intrinsic
-    exit-intrinsic
-    isset-intrinsic
-    print-intrinsic
+intrinsic:
+   intrinsic-construct
+   intrinsic-operator
+
+intrinsic-construct:
+   echo-intrinsic
+   list-intrinsic
+   unset-intrinsic
+
+intrinsic-operator:
+   empty-intrinsic
+   eval-intrinsic
+   exit-intrinsic
+   isset-intrinsic
+   print-intrinsic
 
**Semantics** @@ -363,12 +363,12 @@ expression-list: -->
-  echo-intrinsic:
-    echo  expression-list
+echo-intrinsic:
+   echo   expression-list
 
-  expression-list:
-    expression
-    expression-list  ,  expression
+expression-list:
+   expression
+   expression-list   ,   expression
 
**Constraints** @@ -409,8 +409,8 @@ empty-intrinsic: -->
-  empty-intrinsic:
-    empty ( expression  )
+empty-intrinsic:
+   empty   (   expression   )
 
**Semantics** @@ -449,8 +449,8 @@ eval-intrinsic: -->
-  eval-intrinsic:
-    eval (  expression  )
+eval-intrinsic:
+   eval   (   expression   )
 
**Constraints** @@ -495,11 +495,11 @@ exit-intrinsic: -->
-  exit-intrinsic:
-    exit
-    exit   (   expressionopt   )
-    die
-    die   (   expressionopt   )
+exit-intrinsic:
+   exit
+   exit   (   expressionopt   )
+   die
+   die   (   expressionopt   )
 
**Constraints** @@ -548,12 +548,12 @@ variable-list: -->
-  isset-intrinsic:
-    isset  (  variable-list  )
+isset-intrinsic:
+   isset   (   variable-list   )
 
-  variable-list:
-    variable
-    variable-list  ,  variable
+variable-list:
+   variable
+   variable-list   ,   variable
 
**Semantics** @@ -607,25 +607,25 @@ list-or-variable: -->
-  list-intrinsic:
-    list  (  list-expression-list  )
+list-intrinsic:
+   list   (   list-expression-list   )
 
-  list-expression-list:
-    unkeyed-list-expression-list
-    keyed-list-expression-list ,opt
+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
+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
+keyed-list-expression-list:
+   expression   =>   list-or-variable
+   keyed-list-expression-list   ,   expression   =>   list-or-variable
 
-  list-or-variable:
-    list-intrinsic
-    expression
+list-or-variable:
+   list-intrinsic
+   expression
 
**Constraints** @@ -722,8 +722,8 @@ print-intrinsic: -->
-  print-intrinsic:
-    print  expression
+print-intrinsic:
+   print   expression
 
**Constraints** @@ -764,8 +764,8 @@ unset-intrinsic: -->
-  unset-intrinsic:
-    unset  (  variable-list  )
+unset-intrinsic:
+   unset   (   variable-list   )
 
**Semantics** @@ -823,16 +823,15 @@ use-variable-name-list: -->
-  anonymous-function-creation-expression:
-  staticopt function  &opt (  parameter-declaration-listopt  ) return-typeopt anonymous-function-use-clauseopt
-      compound-statement
+anonymous-function-creation-expression:
+   static?   function   &opt   (   parameter-declaration-listopt   )   return-typeopt   anonymous-function-use-clauseopt   compound-statement
 
-  anonymous-function-use-clause:
-    use  (  use-variable-name-list  )
+anonymous-function-use-clause:
+   use   (   use-variable-name-list   )
 
-  use-variable-name-list:
-    &opt   variable-name
-    use-variable-name-list  ,  &opt  variable-name
+use-variable-name-list:
+   &opt   variable-name
+   use-variable-name-list   ,   &opt   variable-name
 
**Semantics** @@ -911,13 +910,13 @@ postfix-expression: -->
-  postfix-expression:
-    primary-expression
-    clone-expression
-    object-creation-expression
-    postfix-increment-expression
-    postfix-decrement-expression
-    exponentiation-expression
+postfix-expression:
+   primary-expression
+   clone-expression
+   object-creation-expression
+   postfix-increment-expression
+   postfix-decrement-expression
+   exponentiation-expression
 
**Semantics** @@ -934,8 +933,8 @@ clone-expression: -->
-  clone-expression:
-    clone  expression
+clone-expression:
+   clone   expression
 
**Constraints** @@ -996,18 +995,15 @@ class-type-designator: -->
-  object-creation-expression:
-    new  class-type-designator  (  argument-expression-listopt  )
-    new  class-type-designator
-    new  class  (  argument-expression-listopt  )
-        class-base-clauseopt   class-interface-clauseopt
-        {   opt   }
-    new  class class-base-clauseopt  class-interface-clauseopt
-        {   class-member-declarationsopt   }
-
-  class-type-designator:
-    qualified-name
-    expression
+object-creation-expression:
+   new   class-type-designator   (   argument-expression-listopt   )
+   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
+   expression
 
**Constraints** @@ -1102,26 +1098,26 @@ element-value: -->
-  array-creation-expression:
-    array  (  array-initializeropt  )
-    [ array-initializeropt ]
+array-creation-expression:
+   array   (   array-initializeropt   )
+   [   array-initializeropt   ]
 
-  array-initializer:
-    array-initializer-list  ,opt
+array-initializer:
+   array-initializer-list   ,opt
 
-  array-initializer-list:
-    array-element-initializer
-    array-element-initializer  ,  array-initializer-list
+array-initializer-list:
+   array-element-initializer
+   array-element-initializer   ,   array-initializer-list
 
-  array-element-initializer:
-    &opt   element-value
-    element-key  =>  &opt   element-value
+array-element-initializer:
+   &opt   element-value
+   element-key   =>   &opt   element-value
 
-  element-key:
-    expression
+element-key:
+   expression
 
-  element-value:
-    expression
+element-value:
+   expression
 
**Constraints** @@ -1198,9 +1194,9 @@ subscript-expression: -->
-  subscript-expression:
-    dereferencable-expression  [  expressionopt  ]
-    dereferencable-expression  {  expression  }   [Deprecated form]
+subscript-expression:
+   dereferencable-expression   [   expressionopt   ]
+   dereferencable-expression   {   expression   }   <b>[Deprecated form]</b>
 
**Constraints** @@ -1374,21 +1370,20 @@ variadic-unpacking: -->
-  function-call-expression:
-    qualified-name  (  argument-expression-listopt  )
-    callable-expression  (  argument-expression-listopt  )
+function-call-expression:
+   qualified-name   (   argument-expression-listopt   )
+   callable-expression   (   argument-expression-listopt   )
 
-  argument-expression-list:
-    argument-expression
-    argument-expression-list  ,  argument-expression
+argument-expression-list:
+   argument-expression
+   argument-expression-list   ,   argument-expression
 
-  argument-expression:
-    variadic-unpacking
-    assignment-expression
-
-  variadic-unpacking:
-    ... assignment-expression
+argument-expression:
+   variadic-unpacking
+   assignment-expression
 
+variadic-unpacking:
+   ...   assignment-expression
 
**Constraints** @@ -1503,13 +1498,13 @@ member-name: -->
-  member-access-expression:
-    dereferencable-expression   ->   member-name
+member-access-expression:
+   dereferencable-expression   ->   member-name
 
-  member-name:
-    name
-    simple-variable
-    {   expression   }
+member-name:
+   name
+   simple-variable
+   {   expression   }
 
**Constraints** @@ -1581,8 +1576,8 @@ member-call-expression: -->
-  member-call-expression:
-    dereferencable-expression   ->   member-name   (   argument-expression-listopt   )
+member-call-expression:
+   dereferencable-expression   ->   member-name   (   argument-expression-listopt   )
 
**Constraints** @@ -1624,11 +1619,11 @@ postfix-decrement-expression: -->
-  postfix-increment-expression:
-    variable  ++
+postfix-increment-expression:
+   variable   ++
 
-  postfix-decrement-expression:
-    variable  --
+postfix-decrement-expression:
+   variable   --
 
**Constraints** @@ -1675,24 +1670,24 @@ relative-scope: -->
-  scoped-property-access-expression:
-    scope-resolution-qualifier   ::   simple-variable
+scoped-property-access-expression:
+   scope-resolution-qualifier   ::   simple-variable
 
-  scoped-call-expression:
-    scope-resolution-qualifier   ::   member-name    (   argument-expression-listopt   )
+scoped-call-expression:
+   scope-resolution-qualifier   ::   member-name   (   argument-expression-listopt   )
 
-  class-constant-access-expression:
-    scope-resolution-qualifier   ::   name
+class-constant-access-expression:
+   scope-resolution-qualifier   ::   name
 
-  scope-resolution-qualifier:
-    relative-scope
-    qualified-name
-    dereferencable-expression
+scope-resolution-qualifier:
+   relative-scope
+   qualified-name
+   dereferencable-expression
 
-  relative-scope:
-    self
-    parent
-    static
+relative-scope:
+   self
+   parent
+   static
 
**Constraints** @@ -1799,8 +1794,8 @@ exponentiation-expression: -->
-  exponentiation-expression:
-    expression  **  expression
+exponentiation-expression:
+   expression   **   expression
 
**Semantics** @@ -1842,14 +1837,14 @@ unary-expression: -->
-  unary-expression:
-    postfix-expression
-    prefix-increment-expression
-    prefix-decrement-expression
-    unary-op-expression
-    error-control-expression
-    shell-command-expression
-    cast-expression
+unary-expression:
+   postfix-expression
+   prefix-increment-expression
+   prefix-decrement-expression
+   unary-op-expression
+   error-control-expression
+   shell-command-expression
+   cast-expression
 
**Semantics** @@ -1869,11 +1864,11 @@ prefix-decrement-expression: -->
-  prefix-increment-expression:
-    ++ variable
+prefix-increment-expression:
+   ++   variable
 
-  prefix-decrement-expression:
-    -- variable
+prefix-decrement-expression:
+   --   variable
 
**Constraints** @@ -1983,11 +1978,11 @@ unary-operator: one of -->
-  unary-op-expression:
-    unary-operator cast-expression
+unary-op-expression:
+   unary-operator   cast-expression
 
-  unary-operator: one of
-    +  -  !  ~
+unary-operator: one of
+   +   -   !   ~
 
**Constraints** @@ -2075,8 +2070,8 @@ error-control-expression: -->
-  error-control-expression:
-    @   expression
+error-control-expression:
+   @   expression
 
**Semantics** @@ -2132,8 +2127,8 @@ shell-command-expression: -->
-  shell-command-expression:
-    `  dq-char-sequenceopt  `
+shell-command-expression:
+   `   dq-char-sequenceopt   `
 
where \` is the GRAVE ACCENT character U+0060, commonly referred to as a @@ -2175,13 +2170,13 @@ cast-type: one of -->
-  cast-expression:
-    unary-expression
-    (  cast-type  ) expression
+cast-expression:
+   unary-expression
+   (   cast-type   )   expression
 
-  cast-type: one of
-    array  binary  bool  boolean  double  int  integer  float  object
-    real  string  unset
+cast-type: one of
+   array   binary   bool   boolean   double   int   integer   float   object
+   real   string   unset
 
**Semantics** @@ -2239,16 +2234,16 @@ instanceof-type-designator: -->
-  instanceof-expression:
-    unary-expression
-    instanceof-subject  instanceof   instanceof-type-designator
+instanceof-expression:
+   unary-expression
+   instanceof-subject   instanceof   instanceof-type-designator
 
-  instanceof-subject:
-    expression
+instanceof-subject:
+   expression
 
-  instanceof-type-designator:
-    qualified-name
-    expression
+instanceof-type-designator:
+   qualified-name
+   expression
 
**Constraints** @@ -2310,11 +2305,11 @@ multiplicative-expression: -->
-  multiplicative-expression:
-    instanceof-expression
-    multiplicative-expression  *  instanceof-expression
-    multiplicative-expression  /  instanceof-expression
-    multiplicative-expression  %  instanceof-expression
+multiplicative-expression:
+   instanceof-expression
+   multiplicative-expression   *   instanceof-expression
+   multiplicative-expression   /   instanceof-expression
+   multiplicative-expression   %   instanceof-expression
 
**Constraints** @@ -2385,11 +2380,11 @@ additive-expression: -->
-  additive-expression:
-    multiplicative-expression
-    additive-expression  +  multiplicative-expression
-    additive-expression  -  multiplicative-expression
-    additive-expression  .  multiplicative-expression
+additive-expression:
+   multiplicative-expression
+   additive-expression   +   multiplicative-expression
+   additive-expression   -   multiplicative-expression
+   additive-expression   .   multiplicative-expression
 
**Constraints** @@ -2462,10 +2457,10 @@ shift-expression: -->
-  shift-expression:
-    additive-expression
-    shift-expression  <<  additive-expression
-    shift-expression  >>  additive-expression
+shift-expression:
+   additive-expression
+   shift-expression   <<   additive-expression
+   shift-expression   >>   additive-expression
 
**Constraints** @@ -2528,13 +2523,13 @@ relational-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
+relational-expression:
+   shift-expression
+   relational-expression   <   shift-expression
+   relational-expression   >   shift-expression
+   relational-expression   <=   shift-expression
+   relational-expression   >=   shift-expression
+   relational-expression   <=>   shift-expression
 
**Semantics** @@ -2664,13 +2659,13 @@ equality-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
+equality-expression:
+   relational-expression
+   equality-expression   ==   relational-expression
+   equality-expression   !=   relational-expression
+   equality-expression   <>   relational-expression
+   equality-expression   ===   relational-expression
+   equality-expression   !==   relational-expression
 
**Semantics** @@ -2724,9 +2719,9 @@ bitwise-AND-expression: -->
-  bitwise-AND-expression:
-    equality-expression
-    bitwise-AND-expression  &  equality-expression
+bitwise-AND-expression:
+   equality-expression
+   bitwise-AND-expression   &   equality-expression
 
**Constraints** @@ -2771,9 +2766,9 @@ bitwise-exc-OR-expression: -->
-  bitwise-exc-OR-expression:
-    bitwise-AND-expression
-    bitwise-exc-OR-expression  ^  bitwise-AND-expression
+bitwise-exc-OR-expression:
+   bitwise-AND-expression
+   bitwise-exc-OR-expression   ^   bitwise-AND-expression
 
**Constraints** @@ -2820,9 +2815,9 @@ bitwise-inc-OR-expression: -->
-  bitwise-inc-OR-expression:
-    bitwise-exc-OR-expression
-    bitwise-inc-OR-expression  |  bitwise-exc-OR-expression
+bitwise-inc-OR-expression:
+   bitwise-exc-OR-expression
+   bitwise-inc-OR-expression   |   bitwise-exc-OR-expression
 
**Constraints** @@ -2867,9 +2862,9 @@ logical-AND-expression-1: -->
-  logical-AND-expression-1:
-    bitwise-inc-OR-expression
-    logical-AND-expression-1  &&  bitwise-inc-OR-expression
+logical-AND-expression-1:
+   bitwise-inc-OR-expression
+   logical-AND-expression-1   &&   bitwise-inc-OR-expression
 
**Semantics** @@ -2898,9 +2893,9 @@ logical-inc-OR-expression-1: -->
-  logical-inc-OR-expression-1:
-    logical-AND-expression-1
-    logical-inc-OR-expression-1  ||  logical-AND-expression-1
+logical-inc-OR-expression-1:
+   logical-AND-expression-1
+   logical-inc-OR-expression-1   ||   logical-AND-expression-1
 
**Semantics** @@ -2926,9 +2921,9 @@ conditional-expression: -->
-  conditional-expression:
-    logical-inc-OR-expression-1
-    logical-inc-OR-expression-1  ?  expressionopt  :  conditional-expression
+conditional-expression:
+   logical-inc-OR-expression-1
+   logical-inc-OR-expression-1   ?   expressionopt   :   conditional-expression
 
**Semantics** @@ -2972,8 +2967,8 @@ coalesce-expression: -->
-  coalesce-expression:
-    logical-inc-OR-expression-1  ??  expression
+coalesce-expression:
+   logical-inc-OR-expression-1   ??   expression
 
**Semantics** @@ -3026,12 +3021,12 @@ assignment-expression: -->
-  assignment-expression:
-    conditional-expression
-    coalesce-expression
-    simple-assignment-expression
-    byref-assignment-expression
-    compound-assignment-expression
+assignment-expression:
+   conditional-expression
+   coalesce-expression
+   simple-assignment-expression
+   byref-assignment-expression
+   compound-assignment-expression
 
**Constraints** @@ -3054,9 +3049,9 @@ simple-assignment-expression: -->
-  simple-assignment-expression:
-    variable  =  assignment-expression
-    list-intrinsic  =  assignment-expression
+simple-assignment-expression:
+   variable   =   assignment-expression
+   list-intrinsic   =   assignment-expression
 
**Constraints** @@ -3123,8 +3118,8 @@ byref-assignment-expression: -->
-  byref-assignment-expression:
-    variable  =  &  assignment-expression
+byref-assignment-expression:
+   variable   =   &   assignment-expression
 
**Constraints** @@ -3168,11 +3163,11 @@ compound-assignment-operator: one of -->
-  compound-assignment-expression:
-    variable   compound-assignment-operator   assignment-expression
+compound-assignment-expression:
+   variable   compound-assignment-operator   assignment-expression
 
-  compound-assignment-operator: one of
-    **=  *=  /=  %=  +=  -=  .=  <<=  >>=  &=  ^=  |=
+compound-assignment-operator: one of
+   **=   *=   /=   %=   +=   -=   .=   <<=   >>=   &=   ^=   |=
 
**Constraints** @@ -3207,9 +3202,9 @@ logical-AND-expression-2: -->
-  logical-AND-expression-2:
-    assignment-expression
-    logical-AND-expression-2  and  assignment-expression
+logical-AND-expression-2:
+   assignment-expression
+   logical-AND-expression-2   and   assignment-expression
 
**Semantics** @@ -3228,9 +3223,9 @@ logical-exc-OR-expression: -->
-  logical-exc-OR-expression:
-    logical-AND-expression-2
-    logical-exc-OR-expression  xor  logical-AND-expression-2
+logical-exc-OR-expression:
+   logical-AND-expression-2
+   logical-exc-OR-expression   xor   logical-AND-expression-2
 
**Semantics** @@ -3262,9 +3257,9 @@ logical-inc-OR-expression-2: -->
-  logical-inc-OR-expression-2:
-    logical-exc-OR-expression
-    logical-inc-OR-expression-2  or  logical-exc-OR-expression
+logical-inc-OR-expression-2:
+   logical-exc-OR-expression
+   logical-inc-OR-expression-2   or   logical-exc-OR-expression
 
**Semantics** @@ -3284,10 +3279,10 @@ yield-expression: -->
-  yield-expression:
-    logical-inc-OR-expression-2
-    yield  array-element-initializer
-    yield from  expression
+yield-expression:
+   logical-inc-OR-expression-2
+   yield   array-element-initializer
+   yield from   expression
 
**Semantics** @@ -3416,12 +3411,12 @@ expression: -->
-  expression:
-    yield-expression
-    include-expression
-    include-once-expression
-    require-expression
-    require-once-expression
+expression:
+   yield-expression
+   include-expression
+   include-once-expression
+   require-expression
+   require-once-expression
 
**Semantics** @@ -3587,8 +3582,8 @@ include-expression: -->
-  include-expression:
-    include   expression
+include-expression:
+   include   expression
 
**Constraints** @@ -3639,8 +3634,8 @@ include-once-expression: -->
-  include-once-expression:
-    include_once   expression
+include-once-expression:
+   include_once   expression
 
**Semantics** @@ -3687,8 +3682,8 @@ require-expression: -->
-  require-expression:
-    require   expression
+require-expression:
+   require   expression
 
**Semantics** @@ -3707,8 +3702,8 @@ require-once-expression: -->
-  require-once-expression:
-    require_once   expression
+require-once-expression:
+   require_once   expression
 
**Semantics** @@ -3734,8 +3729,8 @@ constant-expression: -->
-  constant-expression:
-    expression
+constant-expression:
+   expression
 
**Constraints** diff --git a/spec/11-statements.md b/spec/11-statements.md index bda56e0d..0df7aa73 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -26,25 +26,24 @@ statement: -->
-
-  statement:
-    compound-statement
-    named-label-statement
-    expression-statement
-    selection-statement
-    iteration-statement
-    jump-statement
-    try-statement
-    declare-statement
-    const-declaration
-    function-definition
-    class-declaration
-    interface-declaration
-    trait-declaration
-    namespace-definition
-    namespace-use-declaration
-    global-declaration
-    function-static-declaration
+statement:
+   compound-statement
+   named-label-statement
+   expression-statement
+   selection-statement
+   iteration-statement
+   jump-statement
+   try-statement
+   declare-statement
+   const-declaration
+   function-definition
+   class-declaration
+   interface-declaration
+   trait-declaration
+   namespace-definition
+   namespace-use-declaration
+   global-declaration
+   function-static-declaration
 
##Compound Statements @@ -61,12 +60,12 @@ statement-list: -->
-  compound-statement:
-    {   statement-listopt  }
+compound-statement:
+   {   statement-listopt   }
 
-  statement-list:
-    statement
-    statement-list   statement
+statement-list:
+   statement
+   statement-list   statement
 
**Semantics** @@ -103,8 +102,8 @@ named-label-statement: -->
-  named-label-statement:
-    name  :  statement
+named-label-statement:
+   name   ;   statement
 
**Constraints** @@ -129,8 +128,8 @@ expression-statement: -->
-  expression-statement:
-    expressionopt  ;
+expression-statement:
+   expressionopt   ;
 
**Semantics** @@ -184,9 +183,9 @@ selection-statement: -->
-  selection-statement:
-    if-statement
-    switch-statement
+selection-statement:
+   if-statement
+   switch-statement
 
**Semantics** @@ -225,29 +224,29 @@ else-clause-2: -->
-  if-statement:
-    if   (   expression   )   statement   elseif-clauses-1opt   else-clause-1opt
-    if   (   expression   )   :   statement-list   elseif-clauses-2opt   else-clause-2opt   endif   ;
+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-clauses-1:
+   elseif-clause-1
+   elseif-clauses-1   elseif-clause-1
 
-  elseif-clause-1:
-    elseif   (   expression   )   statement
+elseif-clause-1:
+   elseif   (   expression   )   statement
 
-  else-clause-1:
-    else   statement
+else-clause-1:
+   else   statement
 
-  elseif-clauses-2:
-    elseif-clause-2
-    elseif-clauses-2   elseif-clause-2
+elseif-clauses-2:
+   elseif-clause-2
+   elseif-clauses-2   elseif-clause-2
 
-  elseif-clause-2:
-    elseif   (   expression   )   :   statement-list
+elseif-clause-2:
+   elseif   (   expression   )   :   statement-list
 
-  else-clause-2:
-    else   :   statement-list
+else-clause-2:
+   else   :   statement-list
 
**Semantics** @@ -332,23 +331,23 @@ case-default-label-terminator: -->
-  switch-statement:
-    switch  (  expression  )  { case-statementsopt }
-    switch  (  expression  )  :   case-statementsopt  endswitch;
+switch-statement:
+   switch   (   expression   )   {   case-statementsopt   }
+   switch   (   expression   )   :   case-statementsopt   endswitch;
 
-  case-statements:
-    case-statement   case-statementsopt
-    default-statement   case-statementsopt
+case-statements:
+   case-statement   case-statementsopt
+   default-statement   case-statementsopt
 
-  case-statement:
-    case   expression   case-default-label-terminator   statement-listopt
+case-statement:
+   case   expression   case-default-label-terminator   statement-listopt
 
-  default-statement:
-    default  case-default-label-terminator   statement-listopt
+default-statement:
+   default   case-default-label-terminator   statement-listopt
 
-  case-default-label-terminator:
-    :
-    ;
+case-default-label-terminator:
+   :
+   ;
 
**Constraints** @@ -448,11 +447,11 @@ iteration-statement: -->
-  iteration-statement:
-    while-statement
-    do-statement
-    for-statement
-    foreach-statement
+iteration-statement:
+   while-statement
+   do-statement
+   for-statement
+   foreach-statement
 
##The `while` Statement @@ -466,9 +465,9 @@ while-statement: -->
-  while-statement:
-    while  (  expression  )  statement
-    while  (  expression  )  :   statement-list  endwhile ;
+while-statement:
+   while   (   expression   )   statement
+   while   (   expression   )   :   statement-list   endwhile   ;
 
**Semantics** @@ -513,8 +512,8 @@ do-statement: -->
-  do-statement:
-    do  statement  while  (  expression  )  ;
+do-statement:
+   do   statement   while   (   expression   )   ;
 
(Note: There is no alternate syntax). @@ -571,22 +570,22 @@ for-expression-group: -->
-  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-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-initializer:
+   for-expression-group
 
-  for-control:
-    for-expression-group
+for-control:
+   for-expression-group
 
-  for-end-of-loop:
-    for-expression-group
+for-end-of-loop:
+   for-expression-group
 
-  for-expression-group:
-    expression
-    for-expression-group   ,   expression
+for-expression-group:
+   expression
+   for-expression-group   ,   expression
 
Note: Unlike C/C++, PHP does not support a comma operator, per se. @@ -673,19 +672,19 @@ foreach-value: -->
-  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-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-collection-name:
+   expression
 
-  foreach-key:
-    expression  =>
+foreach-key:
+   expression   =>
 
-  foreach-value:
-    &opt   expression
-    list-intrinsic
+foreach-value:
+   &opt   expression
+   list-intrinsic
 
**Constraints** @@ -760,12 +759,12 @@ jump-statement: -->
-  jump-statement:
-    goto-statement
-    continue-statement
-    break-statement
-    return-statement
-    throw-statement
+jump-statement:
+   goto-statement
+   continue-statement
+   break-statement
+   return-statement
+   throw-statement
 
###The `goto` Statement @@ -778,8 +777,8 @@ goto-statement: -->
-  goto-statement:
-    goto  name  ;
+goto-statement:
+   goto   name   ;
 
**Constraints** @@ -834,11 +833,11 @@ breakout-level: -->
-  continue-statement:
-    continue   breakout-levelopt  ;
+continue-statement:
+   continue   breakout-levelopt   ;
 
-  breakout-level:
-    integer-literal
+breakout-level:
+   integer-literal
 
**Constraints** @@ -887,8 +886,8 @@ break-statement: -->
-  break-statement:
-    break  breakout-levelopt  ;
+break-statement:
+   break   breakout-levelopt   ;
 
**Constraints** @@ -953,8 +952,8 @@ return-statement: -->
-  return-statement:
-    return  expressionopt  ;
+return-statement:
+   return   expressionopt   ;
 
**Semantics** @@ -1066,8 +1065,8 @@ throw-statement: -->
-  throw-statement:
-    throw  expression  ;
+throw-statement:
+   throw   expression   ;
 
**Constraints** @@ -1119,20 +1118,20 @@ finally-clause: -->
-  try-statement:
-    try  compound-statement   catch-clauses
-    try  compound-statement   finally-clause
-    try  compound-statement   catch-clauses   finally-clause
+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-clauses:
+   catch-clause
+   catch-clauses   catch-clause
 
-  catch-clause:
-    catch  (  qualified-name variable-name )  compound-statement
+catch-clause:
+   catch   (   qualified-name   variable-name   )   compound-statement
 
-  finally-clause:
-    finally   compound-statement
+finally-clause:
+   finally   compound-statement
 
**Constraints** @@ -1226,16 +1225,15 @@ declare-directive: -->
-  declare-statement:
-    declare  (  declare-directive  )  statement
-    declare  (  declare-directive  )  :  statement-list  enddeclare  ;
-    declare  (  declare-directive  )  ;
-
-  declare-directive:
-    ticks  =  literal
-    encoding  =  literal
-    strict_types  =  literal
-
+declare-statement:
+   declare   (   declare-directive   )   statement
+   declare   (   declare-directive   )   :   statement-list   enddeclare   ;
+   declare   (   declare-directive   )   ;
+
+declare-directive:
+   ticks   =   literal
+   encoding   =   literal
+   strict_types   =   literal
 
**Constraints** diff --git a/spec/13-functions.md b/spec/13-functions.md index 158c8c91..f7ee26a9 100644 --- a/spec/13-functions.md +++ b/spec/13-functions.md @@ -93,48 +93,48 @@ default-argument-specifier: -->
-  function-definition:
-    function-definition-header   compound-statement
+function-definition:
+   function-definition-header   compound-statement
 
-  function-definition-header:
-    function  &opt   name  (  parameter-declaration-listopt  )  return-typeopt
+function-definition-header:
+   function   &opt   name   (   parameter-declaration-listopt   )   return-typeopt
 
-  parameter-declaration-list:
-    simple-parameter-declaration-list
-    variadic-declaration-list
+parameter-declaration-list:
+   simple-parameter-declaration-list
+   variadic-declaration-list
 
-  simple-parameter-declaration-list:
-    parameter-declaration
-    parameter-declaration-list  ,  parameter-declaration
+simple-parameter-declaration-list:
+   parameter-declaration
+   parameter-declaration-list   ,   parameter-declaration
 
-  variadic-declaration-list:
-    simple-parameter-declaration-list  ,  variadic-parameter
-    variadic-parameter
+variadic-declaration-list:
+   simple-parameter-declaration-list   ,   variadic-parameter
+   variadic-parameter
 
-  parameter-declaration:
-    type-declarationopt  &opt  variable-name   default-argument-specifieropt
+parameter-declaration:
+   type-declarationopt   &opt   variable-name   default-argument-specifieropt
 
-  variadic-parameter:
-	type-declarationopt  &opt  ...  variable-name
+variadic-parameter:
+   type-declarationopt   &opt   ...   variable-name
 
-  return-type:
-    : type-declaration
-    : void
+return-type:
+   :   type-declaration
+   :   void
 
-  type-declaration:
-    array
-    callable
-    scalar-type
-    qualified-name
+type-declaration:
+   array
+   callable
+   scalar-type
+   qualified-name
 
-  scalar-type:
-    bool
-    float
-    int
-    string
+scalar-type:
+   bool
+   float
+   int
+   string
 
-  default-argument-specifier:
-    =  constant-expression
+default-argument-specifier:
+   =   constant-expression
 
**Constraints** diff --git a/spec/14-classes.md b/spec/14-classes.md index 887dae84..29b6e605 100644 --- a/spec/14-classes.md +++ b/spec/14-classes.md @@ -75,19 +75,19 @@ class-interface-clause: -->
-  class-declaration:
-    class-modifieropt  class  name   class-base-clauseopt  class-interface-clauseopt   {   class-member-declarationsopt }
+class-declaration:
+   class-modifieropt   class   name   class-base-clauseopt   class-interface-clauseopt   {   class-member-declarationsopt   }
 
-  class-modifier:
-    abstract
-    final
+class-modifier:
+   abstract
+   final
 
-  class-base-clause:
-    extends  qualified-name
+class-base-clause:
+   extends   qualified-name
 
-  class-interface-clause:
-    implements  qualified-name
-    class-interface-clause  ,  qualified-name
+class-interface-clause:
+   implements   qualified-name
+   class-interface-clause   ,   qualified-name
 
**Constraints** @@ -224,17 +224,17 @@ class-member-declaration: -->
-  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
+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
 
**Semantics** @@ -419,18 +419,18 @@ const-element: -->
-  const-declaration:
-    const   const-elements   ;
+const-declaration:
+   const   const-elements   ;
 
-  class-const-declaration:
-    visibility-modifieropt   const   const-elements   ;
+class-const-declaration:
+   visibility-modifieropt   const   const-elements   ;
 
-  const-elements:
-    const-element
-    const-elements   const-element
+const-elements:
+   const-element
+   const-elements   const-element
 
-  const-element:
-    name   =   constant-expression
+const-element:
+   name   =   constant-expression
 
**Constraints:** @@ -502,31 +502,31 @@ property-initializer: -->
-  property-declaration:
-    property-modifier   property-elements   ;
+property-declaration:
+   property-modifier   property-elements   ;
 
-  property-modifier:
-    var
-    visibility-modifier   static-modifieropt
-    static-modifier   visibility-modifieropt
+property-modifier:
+   var
+   visibility-modifier   static-modifieropt
+   static-modifier   visibility-modifieropt
 
-  visibility-modifier:
-    public
-    protected
-    private
+visibility-modifier:
+   public
+   protected
+   private
 
-  static-modifier:
-    static
+static-modifier:
+   static
 
-  property-elements:
-    property-element
-    property-elements   property-element
+property-elements:
+   property-element
+   property-elements   property-element
 
-  property-element:
-    variable-name   property-initializeropt   ;
+property-element:
+   variable-name   property-initializeropt   ;
 
-  property-initializer:
-    =  constant-expression
+property-initializer:
+   =   constant-expression
 
**Semantics** @@ -576,18 +576,18 @@ method-modifier: -->
-  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
+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
 
**Constraints** @@ -632,9 +632,8 @@ constructor-declaration: -->
-  constructor-declaration:
-    method-modifiers  function &opt   __construct  (  parameter-declaration-listopt  )  compound-statement
-
+constructor-declaration:
+   method-modifiers   function   &opt   __construct   (   parameter-declaration-listopt   )   compound-statement
 
**Constraints** @@ -719,8 +718,8 @@ destructor-declaration: -->
-  destructor-declaration:
-    method-modifiers  function  &opt  __destruct  ( ) compound-statement
+destructor-declaration:
+   method-modifiers   function   &opt   __destruct   (   )   compound-statement
 
**Constraints** diff --git a/spec/15-interfaces.md b/spec/15-interfaces.md index d0d5a9f8..b4a35532 100644 --- a/spec/15-interfaces.md +++ b/spec/15-interfaces.md @@ -28,12 +28,12 @@ interface-base-clause: -->
-  interface-declaration:
-    interface   name   interface-base-clauseopt {  interface-member-declarationsopt  }
+interface-declaration:
+   interface   name   interface-base-clauseopt   {   interface-member-declarationsopt   }
 
-  interface-base-clause:
-    extends   qualified-name
-    interface-base-clause  ,  qualified-name
+interface-base-clause:
+   extends   qualified-name
+   interface-base-clause   ,   qualified-name
 
**Constraints** @@ -97,13 +97,13 @@ interface-member-declaration: -->
-  interface-member-declarations:
-    interface-member-declaration
-    interface-member-declarations   interface-member-declaration
+interface-member-declarations:
+   interface-member-declaration
+   interface-member-declarations   interface-member-declaration
 
-  interface-member-declaration:
-    class-const-declaration
-    method-declaration
+interface-member-declaration:
+   class-const-declaration
+   method-declaration
 
* [*const-declaration*](14-classes.md#constants) diff --git a/spec/16-traits.md b/spec/16-traits.md index 294b4f34..84f96755 100644 --- a/spec/16-traits.md +++ b/spec/16-traits.md @@ -59,19 +59,19 @@ trait-member-declaration: -->
-  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-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
 
**Semantics** @@ -147,35 +147,35 @@ trait-alias-as-clause: -->
-  trait-use-clauses:
-    trait-use-clause
-    trait-use-clauses   trait-use-clause
+trait-use-clauses:
+   trait-use-clause
+   trait-use-clauses   trait-use-clause
 
-  trait-use-clause:
-    use   trait-name-list   trait-use-specification
+trait-use-clause:
+   use   trait-name-list   trait-use-specification
 
-  trait-name-list:
-    qualified-name
-    trait-name-list   ,   qualified-name
+trait-name-list:
+   qualified-name
+   trait-name-list   ,   qualified-name
 
-  trait-use-specification:
-    ;
-    {   trait-select-and-alias-clausesopt   }
+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-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-and-alias-clause:
+   trait-select-insteadof-clause   ;
+   trait-alias-as-clause   ;
 
-  trait-select-insteadof-clause:
-    name   insteadof   name
+trait-select-insteadof-clause:
+   name   insteadof   name
 
-  trait-alias-as-clause:
-    name   as   visibility-modifieropt   name
-    name   as   visibility-modifier   nameopt
+trait-alias-as-clause:
+   name   as   visibility-modifieropt   name
+   name   as   visibility-modifier   nameopt
 
**Constraints** diff --git a/spec/18-namespaces.md b/spec/18-namespaces.md index 98136014..d3334cb1 100644 --- a/spec/18-namespaces.md +++ b/spec/18-namespaces.md @@ -43,9 +43,9 @@ namespace-definition: -->
-  namespace-definition:
-    namespace  name  ;
-    namespace  nameopt   compound-statement
+namespace-definition:
+   namespace   name   ;
+   namespace   nameopt   compound-statement
 
**Constraints** @@ -155,39 +155,38 @@ namespace-use-group-clause-2: -->
-  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-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-clauses:
+   namespace-use-clause
+   namespace-use-clauses   ,   namespace-use-clause
 
-  namespace-use-clause:
-    qualified-name   namespace-aliasing-clauseopt
+namespace-use-clause:
+   qualified-name   namespace-aliasing-clauseopt
 
-  namespace-aliasing-clause:
-    as  name
+namespace-aliasing-clause:
+   as   name
 
-  namespace-function-or-const:
-    function
-    const
+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-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-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-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
+namespace-use-group-clause-2:
+   namespace-function-or-constopt   namespace-name   namespace-aliasing-clauseopt
 
**Constraints** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 712b337c..9482c24d 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -7,276 +7,277 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# ##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 (U+000D)
-    Line-feed character (U+000A)
-    Carriage-return character (U+000D) followed by line-feed character (U+000A)
-
-  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 (U+0020)
-    Horizontal-tab character (U+0009)
-
-  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 U+0080–U+00ff
-
-  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
+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 (U+000D)
+   Line-feed character (U+000A)
+   Carriage-return character (U+000D) followed by line-feed character (U+000A)
+
+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 (U+0020)
+   Horizontal-tab character (U+0009)
+
+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 U+0080–U+00ff
+
+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  "
+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-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-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-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-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-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-hexadecimal-escape-sequence::
+   \x   hexadecimal-digit   hexadecimal-digitopt
+   \X   hexadecimal-digit   hexadecimal-digitopt
 
-  dq-unicode-escape-sequence::
-    \u{  codepoint-digits  }
+dq-unicode-escape-sequence::
+   \u{   codepoint-digits   }
 
-  codepoint-digits::
-     hexadecimal-digit
-     hexadecimal-digit   codepoint-digits
+codepoint-digits::
+   hexadecimal-digit
+   hexadecimal-digit   codepoint-digits
 
-  string-variable::
-    variable-name   offset-or-propertyopt
-    ${   expression   }
+string-variable::
+   variable-name   offset-or-propertyopt
+   ${   expression   }
 
-  offset-or-property::
-    offset-in-string
-    property-in-string
+offset-or-property::
+   offset-in-string
+   property-in-string
 
-  offset-in-string::
-    [   name   ]
-    [   variable-name   ]
-    [   integer-literal   ]
+offset-in-string::
+   [   name   ]
+   [   variable-name   ]
+   [   integer-literal   ]
 
-  property-in-string::
-    ->   name
+property-in-string::
+   ->   name
 
-  heredoc-string-literal::
-    b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
+heredoc-string-literal::
+   b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
 
-  hd-start-identifier::
-    name
-    "   name  "
+hd-start-identifier::
+   name
+   "   name   "
 
-  hd-end-identifier::
-    name
+hd-end-identifier::
+   name
 
-  hd-body::
-    hd-char-sequenceopt   new-line
+hd-body::
+   hd-char-sequenceopt   new-line
 
-  hd-char-sequence::
-    hd-char
-    hd-char-sequence   hd-char
+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-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-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
+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
+nowdoc-string-literal::
+   b-prefixopt   <<<   '   name   '   new-line   hd-bodyopt   name   ;opt   new-line
 
-  operator-or-punctuator:: one of
-    [   ]   (   )   {   }   .   ->   ++   --   **   *   +   -   ~   !
-    $   /   %   <<    >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
-    &   &&   ||   ?   :   ;   =   **=   *=   /=   %=   +=   -=   .=   <<=
-    >>=   &=   ^=   |=   ,   ??   <=>   ...   \
+operator-or-punctuator:: one of
+   [   ]   (   )   {   }   .   ->   ++   --   **   *   +   -   ~   !
+   $   /   %   <<   >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
+   &   &&   ||   ?   :   ;   =   **=   *=   /=   %=   +=   -=   .=   <<=
+   >>=   &=   ^=   |=   ,   ??   <=>   ...   \
 
##Syntactic Grammar @@ -284,862 +285,857 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# ###Basic Concepts
-  script:
-    script-section
-    script   script-section
+script:
+   script-section
+   script   script-section
 
-  script-section:
-     textopt start-tag statement-listopt end-tagopt textopt
+script-section:
+   textopt   start-tag   statement-listopt   end-tagopt   textopt
 
-  start-tag:
-    <?php
-    <?=
+start-tag:
+   <?php
+   <?=
 
-  end-tag:
-    ?>
+end-tag:
+   ?>
 
-  text:
-    arbitrary text not containing any of start-tag sequences
+text:
+   arbitrary text not containing any of   start-tag   sequences
 
###Variables
-  function-static-declaration:
-    static static-variable-name-list  ;
+function-static-declaration:
+   static   static-variable-name-list   ;
 
-  static-variable-name-list:
-    static-variable-declaration
-    static-variable-name-list  ,  static-variable-declaration
+static-variable-name-list:
+   static-variable-declaration
+   static-variable-name-list   ,   static-variable-declaration
 
-  static-variable-declaration:
-    variable-name function-static-initializeropt
+static-variable-declaration:
+   variable-name   function-static-initializeropt
 
-  function-static-initializer:
-    = constant-expression
+function-static-initializer:
+   =   constant-expression
 
-  global-declaration:
-    global variable-name-list ;
+global-declaration:
+   global   variable-name-list   ;
 
-  variable-name-list:
-    simple-variable
-    variable-name-list  ,  simple-variable
+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
-    (  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:
-    intrinsic-construct
-    intrinsic-operator
-
-  intrinsic-construct:
-    echo-intrinsic
-    list-intrinsic
-    unset-intrinsic
-
-  intrinsic-operator:
-    empty-intrinsic
-    eval-intrinsic
-    exit-intrinsic
-    isset-intrinsic
-    print-intrinsic
-
-  echo-intrinsic:
-    echo  expression-list
-
-  expression-list:
-    expression
-    expression-list  ,  expression
-
-  empty-intrinsic:
-    empty ( expression  )
-
-  eval-intrinsic:
-    eval (  expression  )
-
-  exit-intrinsic:
-    exit
-    exit   (   expressionopt   )
-    die
-    die   (   expressionopt   )
-
-  isset-intrinsic:
-    isset  (  variable-list  )
-
-  variable-list:
-    variable
-    variable-list  ,  variable
-
-  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
-    expression
-
-  print-intrinsic:
-    print  expression
-
-  unset-intrinsic:
-    unset  (  variable-list  )
-
-  anonymous-function-creation-expression:
-  staticopt function  &opt (  parameter-declaration-listopt  ) return-typeopt anonymous-function-use-clauseopt
-      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
+primary-expression:
+   variable
+   class-constant-access-expression
+   constant-access-expression
+   literal
+   array-creation-expression
+   intrinsic
+   anonymous-function-creation-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:
+   intrinsic-construct
+   intrinsic-operator
+
+intrinsic-construct:
+   echo-intrinsic
+   list-intrinsic
+   unset-intrinsic
+
+intrinsic-operator:
+   empty-intrinsic
+   eval-intrinsic
+   exit-intrinsic
+   isset-intrinsic
+   print-intrinsic
+
+echo-intrinsic:
+   echo   expression-list
+
+expression-list:
+   expression
+   expression-list   ,   expression
+
+empty-intrinsic:
+   empty   (   expression   )
+
+eval-intrinsic:
+   eval   (   expression   )
+
+exit-intrinsic:
+   exit
+   exit   (   expressionopt   )
+   die
+   die   (   expressionopt   )
+
+isset-intrinsic:
+   isset   (   variable-list   )
+
+variable-list:
+   variable
+   variable-list   ,   variable
+
+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
+   expression
 
-  postfix-expression:
-    primary-expression
-    clone-expression
-    object-creation-expression
-    postfix-increment-expression
-    postfix-decrement-expression
-    exponentiation-expression
+print-intrinsic:
+   print   expression
 
-  clone-expression:
-    clone  expression
-
-  object-creation-expression:
-    new  class-type-designator  (  argument-expression-listopt  )
-    new  class-type-designator
-    new  class  (  argument-expression-listopt  )
-        class-base-clauseopt   class-interface-clauseopt
-        {   opt   }
-    new  class class-base-clauseopt  class-interface-clauseopt
-        {   class-member-declarationsopt   }
+unset-intrinsic:
+   unset   (   variable-list   )
 
-  class-type-designator:
-    qualified-name
-    expression
+anonymous-function-creation-expression:
+   static?   function   &opt   (   parameter-declaration-listopt   )   return-typeopt   anonymous-function-use-clauseopt   compound-statement
 
-  array-creation-expression:
-    array  (  array-initializeropt  )
-    [ array-initializeropt ]
+anonymous-function-use-clause:
+   use   (   use-variable-name-list   )
 
-  array-initializer:
-    array-initializer-list  ,opt
+use-variable-name-list:
+   &opt   variable-name
+   use-variable-name-list   ,   &opt   variable-name
 
-  array-initializer-list:
-    array-element-initializer
-    array-element-initializer  ,  array-initializer-list
+postfix-expression:
+   primary-expression
+   clone-expression
+   object-creation-expression
+   postfix-increment-expression
+   postfix-decrement-expression
+   exponentiation-expression
 
-  array-element-initializer:
-    &opt   element-value
-    element-key  =>  &opt   element-value
+clone-expression:
+   clone   expression
 
-  element-key:
-    expression
+object-creation-expression:
+   new   class-type-designator   (   argument-expression-listopt   )
+   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   }
 
-  element-value:
-    expression
+class-type-designator:
+   qualified-name
+   expression
 
-  subscript-expression:
-    dereferencable-expression  [  expressionopt  ]
-    dereferencable-expression  {  expression  }   [Deprecated form]
+array-creation-expression:
+   array   (   array-initializeropt   )
+   [   array-initializeropt   ]
 
-  function-call-expression:
-    qualified-name  (  argument-expression-listopt  )
-    callable-expression  (  argument-expression-listopt  )
+array-initializer:
+   array-initializer-list   ,opt
 
-  argument-expression-list:
-    argument-expression
-    argument-expression-list  ,  argument-expression
+array-initializer-list:
+   array-element-initializer
+   array-element-initializer   ,   array-initializer-list
 
-  argument-expression:
-    variadic-unpacking
-    assignment-expression
+array-element-initializer:
+   &opt   element-value
+   element-key   =>   &opt   element-value
 
-  variadic-unpacking:
-    ... assignment-expression
+element-key:
+   expression
 
-  member-access-expression:
-    dereferencable-expression   ->   member-name
+element-value:
+   expression
 
-  member-name:
-    name
-    simple-variable
-    {   expression   }
-
-  member-call-expression:
-    dereferencable-expression   ->   member-name   (   argument-expression-listopt   )
+subscript-expression:
+   dereferencable-expression   [   expressionopt   ]
+   dereferencable-expression   {   expression   }   <b>[Deprecated form]</b>
 
-  postfix-increment-expression:
-    variable  ++
-
-  postfix-decrement-expression:
-    variable  --
-
-  scoped-property-access-expression:
-    scope-resolution-qualifier   ::   simple-variable
-
-  scoped-call-expression:
-    scope-resolution-qualifier   ::   member-name    (   argument-expression-listopt   )
-
-  class-constant-access-expression:
-    scope-resolution-qualifier   ::   name
-
-  scope-resolution-qualifier:
-    relative-scope
-    qualified-name
-    dereferencable-expression
-
-  relative-scope:
-    self
-    parent
-    static
-
-  exponentiation-expression:
-    expression  **  expression
-
-  unary-expression:
-    postfix-expression
-    prefix-increment-expression
-    prefix-decrement-expression
-    unary-op-expression
-    error-control-expression
-    shell-command-expression
-    cast-expression
-
-  prefix-increment-expression:
-    ++ variable
-
-  prefix-decrement-expression:
-    -- variable
-
-  unary-op-expression:
-    unary-operator cast-expression
-
-  unary-operator: one of
-    +  -  !  ~
+function-call-expression:
+   qualified-name   (   argument-expression-listopt   )
+   callable-expression   (   argument-expression-listopt   )
 
-  error-control-expression:
-    @   expression
+argument-expression-list:
+   argument-expression
+   argument-expression-list   ,   argument-expression
 
-  shell-command-expression:
-    `  dq-char-sequenceopt  `
+argument-expression:
+   variadic-unpacking
+   assignment-expression
 
-  cast-expression:
-    unary-expression
-    (  cast-type  ) expression
+variadic-unpacking:
+   ...   assignment-expression
 
-  cast-type: one of
-    array  binary  bool  boolean  double  int  integer  float  object
-    real  string  unset
+member-access-expression:
+   dereferencable-expression   ->   member-name
 
-  instanceof-expression:
-    unary-expression
-    instanceof-subject  instanceof   instanceof-type-designator
+member-name:
+   name
+   simple-variable
+   {   expression   }
 
-  instanceof-subject:
-    expression
-
-  instanceof-type-designator:
-    qualified-name
-    expression
-
-  multiplicative-expression:
-    instanceof-expression
-    multiplicative-expression  *  instanceof-expression
-    multiplicative-expression  /  instanceof-expression
-    multiplicative-expression  %  instanceof-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
-
-  conditional-expression:
-    logical-inc-OR-expression-1
-    logical-inc-OR-expression-1  ?  expressionopt  :  conditional-expression
-
-  coalesce-expression:
-    logical-inc-OR-expression-1  ??  expression
-
-  assignment-expression:
-    conditional-expression
-    coalesce-expression
-    simple-assignment-expression
-    byref-assignment-expression
-    compound-assignment-expression
-
-  simple-assignment-expression:
-    variable  =  assignment-expression
-    list-intrinsic  =  assignment-expression
-
-  byref-assignment-expression:
-    variable  =  &  assignment-expression
-
-  compound-assignment-expression:
-    variable   compound-assignment-operator   assignment-expression
-
-  compound-assignment-operator: one of
-    **=  *=  /=  %=  +=  -=  .=  <<=  >>=  &=  ^=  |=
-
-  logical-AND-expression-2:
-    assignment-expression
-    logical-AND-expression-2  and  assignment-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
-
-  yield-expression:
-    logical-inc-OR-expression-2
-    yield  array-element-initializer
-    yield from  expression
-
-  expression:
-    yield-expression
-    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
+member-call-expression:
+   dereferencable-expression   ->   member-name   (   argument-expression-listopt   )
+
+postfix-increment-expression:
+   variable   ++
+
+postfix-decrement-expression:
+   variable   --
+
+scoped-property-access-expression:
+   scope-resolution-qualifier   ::   simple-variable
+
+scoped-call-expression:
+   scope-resolution-qualifier   ::   member-name   (   argument-expression-listopt   )
+
+class-constant-access-expression:
+   scope-resolution-qualifier   ::   name
+
+scope-resolution-qualifier:
+   relative-scope
+   qualified-name
+   dereferencable-expression
+
+relative-scope:
+   self
+   parent
+   static
+
+exponentiation-expression:
+   expression   **   expression
+
+unary-expression:
+   postfix-expression
+   prefix-increment-expression
+   prefix-decrement-expression
+   unary-op-expression
+   error-control-expression
+   shell-command-expression
+   cast-expression
+
+prefix-increment-expression:
+   ++   variable
+
+prefix-decrement-expression:
+   --   variable
+
+unary-op-expression:
+   unary-operator   cast-expression
+
+unary-operator: one of
+   +   -   !   ~
+
+error-control-expression:
+   @   expression
+
+shell-command-expression:
+   `   dq-char-sequenceopt   `
+
+cast-expression:
+   unary-expression
+   (   cast-type   )   expression
+
+cast-type: one of
+   array   binary   bool   boolean   double   int   integer   float   object
+   real   string   unset
+
+instanceof-expression:
+   unary-expression
+   instanceof-subject   instanceof   instanceof-type-designator
+
+instanceof-subject:
+   expression
+
+instanceof-type-designator:
+   qualified-name
+   expression
+
+multiplicative-expression:
+   instanceof-expression
+   multiplicative-expression   *   instanceof-expression
+   multiplicative-expression   /   instanceof-expression
+   multiplicative-expression   %   instanceof-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
+
+conditional-expression:
+   logical-inc-OR-expression-1
+   logical-inc-OR-expression-1   ?   expressionopt   :   conditional-expression
+
+coalesce-expression:
+   logical-inc-OR-expression-1   ??   expression
+
+assignment-expression:
+   conditional-expression
+   coalesce-expression
+   simple-assignment-expression
+   byref-assignment-expression
+   compound-assignment-expression
+
+simple-assignment-expression:
+   variable   =   assignment-expression
+   list-intrinsic   =   assignment-expression
+
+byref-assignment-expression:
+   variable   =   &   assignment-expression
+
+compound-assignment-expression:
+   variable   compound-assignment-operator   assignment-expression
+
+compound-assignment-operator: one of
+   **=   *=   /=   %=   +=   -=   .=   <<=   >>=   &=   ^=   |=
+
+logical-AND-expression-2:
+   assignment-expression
+   logical-AND-expression-2   and   assignment-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
+
+yield-expression:
+   logical-inc-OR-expression-2
+   yield   array-element-initializer
+   yield from   expression
+
+expression:
+   yield-expression
+   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
-    const-declaration
-    function-definition
-    class-declaration
-    interface-declaration
-    trait-declaration
-    namespace-definition
-    namespace-use-declaration
-    global-declaration
-    function-static-declaration
+statement:
+   compound-statement
+   named-label-statement
+   expression-statement
+   selection-statement
+   iteration-statement
+   jump-statement
+   try-statement
+   declare-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  }
+compound-statement:
+   {   statement-listopt   }
 
-  statement-list:
-    statement
-    statement-list   statement
-
-  named-label-statement:
-    name  :  statement
-
-  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
+statement-list:
+   statement
+   statement-list   statement
+
+named-label-statement:
+   name   ;   statement
+
+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
+elseif-clause-1:
+   elseif   (   expression   )   statement
 
-  else-clause-1:
-    else   statement
+else-clause-1:
+   else   statement
 
-  elseif-clauses-2:
-    elseif-clause-2
-    elseif-clauses-2   elseif-clause-2
+elseif-clauses-2:
+   elseif-clause-2
+   elseif-clauses-2   elseif-clause-2
 
-  elseif-clause-2:
-    elseif   (   expression   )   :   statement-list
+elseif-clause-2:
+   elseif   (   expression   )   :   statement-list
 
-  else-clause-2:
-    else   :   statement-list
+else-clause-2:
+   else   :   statement-list
 
-  switch-statement:
-    switch  (  expression  )  { case-statementsopt }
-    switch  (  expression  )  :   case-statementsopt  endswitch;
+switch-statement:
+   switch   (   expression   )   {   case-statementsopt   }
+   switch   (   expression   )   :   case-statementsopt   endswitch;
 
-  case-statements:
-    case-statement   case-statementsopt
-    default-statement   case-statementsopt
+case-statements:
+   case-statement   case-statementsopt
+   default-statement   case-statementsopt
 
-  case-statement:
-    case   expression   case-default-label-terminator   statement-listopt
+case-statement:
+   case   expression   case-default-label-terminator   statement-listopt
 
-  default-statement:
-    default  case-default-label-terminator   statement-listopt
+default-statement:
+   default   case-default-label-terminator   statement-listopt
 
-  case-default-label-terminator:
-    :
-    ;
+case-default-label-terminator:
+   :
+   ;
 
-  iteration-statement:
-    while-statement
-    do-statement
-    for-statement
-    foreach-statement
+iteration-statement:
+   while-statement
+   do-statement
+   for-statement
+   foreach-statement
 
-  while-statement:
-    while  (  expression  )  statement
-    while  (  expression  )  :   statement-list  endwhile ;
+while-statement:
+   while   (   expression   )   statement
+   while   (   expression   )   :   statement-list   endwhile   ;
 
-  do-statement:
-    do  statement  while  (  expression  )  ;
+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-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-initializer:
+   for-expression-group
 
-  for-control:
-    for-expression-group
+for-control:
+   for-expression-group
 
-  for-end-of-loop:
-    for-expression-group
+for-end-of-loop:
+   for-expression-group
 
-  for-expression-group:
-    expression
-    for-expression-group   ,   expression
+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-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-collection-name:
+   expression
 
-  foreach-key:
-    expression  =>
+foreach-key:
+   expression   =>
 
-  foreach-value:
-    &opt   expression
-    list-intrinsic
+foreach-value:
+   &opt   expression
+   list-intrinsic
 
-  jump-statement:
-    goto-statement
-    continue-statement
-    break-statement
-    return-statement
-    throw-statement
+jump-statement:
+   goto-statement
+   continue-statement
+   break-statement
+   return-statement
+   throw-statement
 
-  goto-statement:
-    goto  name  ;
+goto-statement:
+   goto   name   ;
 
-  continue-statement:
-    continue   breakout-levelopt  ;
+continue-statement:
+   continue   breakout-levelopt   ;
 
-  breakout-level:
-    integer-literal
+breakout-level:
+   integer-literal
 
-  break-statement:
-    break  breakout-levelopt  ;
+break-statement:
+   break   breakout-levelopt   ;
 
-  return-statement:
-    return  expressionopt  ;
+return-statement:
+   return   expressionopt   ;
 
-  throw-statement:
-    throw  expression  ;
+throw-statement:
+   throw   expression   ;
 
-  try-statement:
-    try  compound-statement   catch-clauses
-    try  compound-statement   finally-clause
-    try  compound-statement   catch-clauses   finally-clause
+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-clauses:
+   catch-clause
+   catch-clauses   catch-clause
 
-  catch-clause:
-    catch  (  qualified-name variable-name )  compound-statement
+catch-clause:
+   catch   (   qualified-name   variable-name   )   compound-statement
 
-  finally-clause:
-    finally   compound-statement
+finally-clause:
+   finally   compound-statement
 
-  declare-statement:
-    declare  (  declare-directive  )  statement
-    declare  (  declare-directive  )  :  statement-list  enddeclare  ;
-    declare  (  declare-directive  )  ;
+declare-statement:
+   declare   (   declare-directive   )   statement
+   declare   (   declare-directive   )   :   statement-list   enddeclare   ;
+   declare   (   declare-directive   )   ;
 
-  declare-directive:
-    ticks  =  literal
-    encoding  =  literal
-    strict_types  =  literal
+declare-directive:
+   ticks   =   literal
+   encoding   =   literal
+   strict_types   =   literal
 
###Functions
-  function-definition:
-    function-definition-header   compound-statement
+function-definition:
+   function-definition-header   compound-statement
 
-  function-definition-header:
-    function  &opt   name  (  parameter-declaration-listopt  )  return-typeopt
+function-definition-header:
+   function   &opt   name   (   parameter-declaration-listopt   )   return-typeopt
 
-  parameter-declaration-list:
-    simple-parameter-declaration-list
-    variadic-declaration-list
+parameter-declaration-list:
+   simple-parameter-declaration-list
+   variadic-declaration-list
 
-  simple-parameter-declaration-list:
-    parameter-declaration
-    parameter-declaration-list  ,  parameter-declaration
+simple-parameter-declaration-list:
+   parameter-declaration
+   parameter-declaration-list   ,   parameter-declaration
 
-  variadic-declaration-list:
-    simple-parameter-declaration-list  ,  variadic-parameter
-    variadic-parameter
+variadic-declaration-list:
+   simple-parameter-declaration-list   ,   variadic-parameter
+   variadic-parameter
 
-  parameter-declaration:
-    type-declarationopt  &opt  variable-name   default-argument-specifieropt
+parameter-declaration:
+   type-declarationopt   &opt   variable-name   default-argument-specifieropt
 
-  variadic-parameter:
-	type-declarationopt  &opt  ...  variable-name
+variadic-parameter:
+   type-declarationopt   &opt   ...   variable-name
 
-  return-type:
-    : type-declaration
-    : void
+return-type:
+   :   type-declaration
+   :   void
 
-  type-declaration:
-    array
-    callable
-    scalar-type
-    qualified-name
+type-declaration:
+   array
+   callable
+   scalar-type
+   qualified-name
 
-  scalar-type:
-    bool
-    float
-    int
-    string
+scalar-type:
+   bool
+   float
+   int
+   string
 
-  default-argument-specifier:
-    =  constant-expression
+default-argument-specifier:
+   =   constant-expression
 
###Classes
-  class-declaration:
-    class-modifieropt  class  name   class-base-clauseopt  class-interface-clauseopt   {   class-member-declarationsopt }
+class-declaration:
+   class-modifieropt   class   name   class-base-clauseopt   class-interface-clauseopt   {   class-member-declarationsopt   }
 
-  class-modifier:
-    abstract
-    final
+class-modifier:
+   abstract
+   final
 
-  class-base-clause:
-    extends  qualified-name
+class-base-clause:
+   extends   qualified-name
 
-  class-interface-clause:
-    implements  qualified-name
-    class-interface-clause  ,  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-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
+class-member-declaration:
+   class-const-declaration
+   property-declaration
+   method-declaration
+   constructor-declaration
+   destructor-declaration
+   trait-use-clause
 
-  const-declaration:
-    const   const-elements   ;
+const-declaration:
+   const   const-elements   ;
 
-  class-const-declaration:
-    visibility-modifieropt   const   const-elements   ;
+class-const-declaration:
+   visibility-modifieropt   const   const-elements   ;
 
-  const-elements:
-    const-element
-    const-elements   const-element
+const-elements:
+   const-element
+   const-elements   const-element
 
-  const-element:
-    name   =   constant-expression
+const-element:
+   name   =   constant-expression
 
-  property-declaration:
-    property-modifier   property-elements   ;
+property-declaration:
+   property-modifier   property-elements   ;
 
-  property-modifier:
-    var
-    visibility-modifier   static-modifieropt
-    static-modifier   visibility-modifieropt
+property-modifier:
+   var
+   visibility-modifier   static-modifieropt
+   static-modifier   visibility-modifieropt
 
-  visibility-modifier:
-    public
-    protected
-    private
+visibility-modifier:
+   public
+   protected
+   private
 
-  static-modifier:
-    static
+static-modifier:
+   static
 
-  property-elements:
-    property-element
-    property-elements   property-element
+property-elements:
+   property-element
+   property-elements   property-element
 
-  property-element:
-    variable-name   property-initializeropt   ;
+property-element:
+   variable-name   property-initializeropt   ;
 
-  property-initializer:
-    =  constant-expression
+property-initializer:
+   =   constant-expression
 
-  method-declaration:
-    method-modifiersopt   function-definition
-    method-modifiers   function-definition-header  ;
+method-declaration:
+   method-modifiersopt   function-definition
+   method-modifiers   function-definition-header   ;
 
-  method-modifiers:
-    method-modifier
-    method-modifiers   method-modifier
+method-modifiers:
+   method-modifier
+   method-modifiers   method-modifier
 
-  method-modifier:
-    visibility-modifier
-    static-modifier
-    class-modifier
+method-modifier:
+   visibility-modifier
+   static-modifier
+   class-modifier
 
-  constructor-declaration:
-    method-modifiers  function &opt   __construct  (  parameter-declaration-listopt  )  compound-statement
+constructor-declaration:
+   method-modifiers   function   &opt   __construct   (   parameter-declaration-listopt   )   compound-statement
 
-  destructor-declaration:
-    method-modifiers  function  &opt  __destruct  ( ) compound-statement
+destructor-declaration:
+   method-modifiers   function   &opt   __destruct   (   )   compound-statement
 
###Interfaces
-  interface-declaration:
-    interface   name   interface-base-clauseopt {  interface-member-declarationsopt  }
+interface-declaration:
+   interface   name   interface-base-clauseopt   {   interface-member-declarationsopt   }
 
-  interface-base-clause:
-    extends   qualified-name
-    interface-base-clause  ,  qualified-name
+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-declarations:
+   interface-member-declaration
+   interface-member-declarations   interface-member-declaration
 
-  interface-member-declaration:
-    class-const-declaration
-    method-declaration
+interface-member-declaration:
+   class-const-declaration
+   method-declaration
 
###Traits
-  trait-declaration:
-    trait   name   {   trait-member-declarationsopt   }
+trait-declaration:
+   trait   name   {   trait-member-declarationsopt   }
 
-  trait-member-declarations:
-    trait-member-declaration
-    trait-member-declarations   trait-member-declaration
+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-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-clauses:
+   trait-use-clause
+   trait-use-clauses   trait-use-clause
 
-  trait-use-clause:
-    use   trait-name-list   trait-use-specification
+trait-use-clause:
+   use   trait-name-list   trait-use-specification
 
-  trait-name-list:
-    qualified-name
-    trait-name-list   ,   qualified-name
+trait-name-list:
+   qualified-name
+   trait-name-list   ,   qualified-name
 
-  trait-use-specification:
-    ;
-    {   trait-select-and-alias-clausesopt   }
+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-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-and-alias-clause:
+   trait-select-insteadof-clause   ;
+   trait-alias-as-clause   ;
 
-  trait-select-insteadof-clause:
-    name   insteadof   name
+trait-select-insteadof-clause:
+   name   insteadof   name
 
-  trait-alias-as-clause:
-    name   as   visibility-modifieropt   name
-    name   as   visibility-modifier   nameopt
+trait-alias-as-clause:
+   name   as   visibility-modifieropt   name
+   name   as   visibility-modifier   nameopt
 
###Namespaces
-  namespace-definition:
-    namespace  name  ;
-    namespace  nameopt   compound-statement
+namespace-definition:
+   namespace   name   ;
+   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-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-clauses:
+   namespace-use-clause
+   namespace-use-clauses   ,   namespace-use-clause
 
-  namespace-use-clause:
-    qualified-name   namespace-aliasing-clauseopt
+namespace-use-clause:
+   qualified-name   namespace-aliasing-clauseopt
 
-  namespace-aliasing-clause:
-    as  name
+namespace-aliasing-clause:
+   as   name
 
-  namespace-function-or-const:
-    function
-    const
+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-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-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-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
+namespace-use-group-clause-2:
+   namespace-function-or-constopt   namespace-name   namespace-aliasing-clauseopt
 
diff --git a/tools/grammar.php b/tools/grammar.php index 1ad7f71d..289aea49 100644 --- a/tools/grammar.php +++ b/tools/grammar.php @@ -1,6 +1,48 @@ $path) { + $code = file_get_contents($path); + $defs = Grammar\get_all_defs($code); + foreach ($defs as $def) { + if (isset($names[$def->name])) { + throw new Exception("Duplicate definition for $def->name"); + } + $names[$def->name] = $fileName; + } +} + +// Render grammars +foreach (spec_files() as $fileName => $path) { + $code = $origCode = file_get_contents($path); + $code = preg_replace_callback( + '/()\s+
.*?<\/pre>/s',
+        function($matches) use($names, $fileName) {
+            $defs = Grammar\parse_grammar($matches[2]);
+            $rendered = Grammar\render_grammar($defs, $names, $fileName);
+            return $matches[1] . "\n\n" . $rendered;
+        },
+        $code
+    );
+    if ($code !== $origCode) {
+        file_put_contents($path, $code);
+    }
+}
+
+/*
+ * Generate summary grammar chapter
+ */
+
+// Pretend that all definitions are inside 19-grammar.md now
+$names = array_fill_keys(array_keys($names), '19-grammar.md');
 
 $dir = __DIR__ . '/../spec/';
 $grammarFile = $dir . '19-grammar.md';
@@ -19,14 +61,14 @@
 
 $lexical = file_get_contents($dir . '09-lexical-structure.md');
 $lexical = strstr($lexical, '##Lexical analysis');
-$output .= extract_grammar($lexical);
+$output .= extract_grammar($lexical, $names);
 
 $output .= "\n\n##Syntactic Grammar";
 
 $skipFiles = ['05-types.md', '09-lexical-structure.md', '19-grammar.md'];
 foreach (spec_files($skipFiles) as $fileName => $path) {
     $code = file_get_contents($path);
-    $grammar = extract_grammar($code);
+    $grammar = extract_grammar($code, $names);
     if (null === $grammar) {
         continue;
     }
@@ -47,19 +89,10 @@ function extract_heading($code) {
     return $matches[1];
 }
 
-function extract_grammar($code) {
-    if (!preg_match_all('(
(.*?)
)s', $code, $matches)) { +function extract_grammar($code, $names) { + $defs = Grammar\get_all_defs($code); + if (empty($defs)) { return null; } - - $parts = []; - foreach ($matches[1] as $match) { - if (!preg_match('/^\s*.*:.*<\/i>/', $match)) { - continue; - } - $parts[] = ' ' . trim($match); - } - - $rawGrammar = implode("\n\n", $parts); - return "
\n$rawGrammar\n
"; + return Grammar\render_grammar($defs, $names, '19-grammar.md'); } diff --git a/tools/grammar_util.php b/tools/grammar_util.php new file mode 100644 index 00000000..14cf44e5 --- /dev/null +++ b/tools/grammar_util.php @@ -0,0 +1,140 @@ +/s', $code, $matches)) { + return []; + } + $defs = []; + foreach ($matches[1] as $grammar) { + $defs = array_merge($defs, parse_grammar($grammar)); + } + return $defs; +} + +function parse_grammar($grammar) { + $defTexts = explode("\n\n", trim($grammar)); + $defs = []; + foreach ($defTexts as $defText) { + if (!preg_match('/^([a-zA-Z0-9-]+)(::?)(\s+one\s+of)?\n(.*?)$/s', $defText, $matches)) { + throw new \Exception('Invalid definition'); + } + + $rules = array_map('Grammar\parse_rule', explode("\n", $matches[4])); + $defs[] = new Definition( + $matches[1], $matches[2] === '::', $matches[3] !== '', $rules + ); + } + return $defs; +} + +function parse_rule($rule) { + $regex = <<<'REGEX' +/(?: + '[^']*(?:''[^']*)*' + | "[^"]*(?:""[^"]*)*" +)(*SKIP)(*F)|\s+/x +REGEX; + $parts = array_map('Grammar\parse_rule_part', preg_split($regex, trim($rule))); + return new Rule($parts); +} + +function parse_rule_part($part) { + if (substr($part, -1) === '?') { + return new Opt(parse_rule_part(substr($part, 0, -1))); + } + if ($part[0] === "'") { + $contents = str_replace("''", "'", substr($part, 1, -1)); + return new Plain($contents); + } + if ($part[0] === '"') { + $contents = str_replace('""', '"', substr($part, 1, -1)); + return new Plain($contents); + } + return new Reference($part); +} + +function render_grammar($defs, $names, $currentFile) { + $ctx = new RenderContext; + $ctx->names = $names; + $ctx->currentFile = $currentFile; + + $result = []; + foreach ($defs as $def) { + $result[] = $def->render($ctx); + } + return "
\n" . implode("\n\n", $result) . "\n
"; +} + +class RenderContext { + public $names; + public $currentFile; +} + +class Definition { + public $name, $isLexical, $isOneOf, $rules; + public function __construct($name, $isLexical, $isOneOf, $rules) { + $this->name = $name; + $this->isLexical = $isLexical; + $this->isOneOf = $isOneOf; + $this->rules = $rules; + } + public function render($ctx) { + $sep = $this->isLexical ? '::' : ':'; + $oneOf = $this->isOneOf ? ' one of' : ''; + $result = "name\">$this->name$sep$oneOf"; + foreach ($this->rules as $rule) { + $result .= "\n " . $rule->render($ctx); + } + return $result; + } +} +class Rule { + public $parts; + public function __construct($parts) { + $this->parts = $parts; + } + public function render($ctx) { + $parts = []; + foreach ($this->parts as $part) { + $parts[] = $part->render($ctx); + } + return implode(' ', $parts); + } +} +class Reference { + public $name; + public function __construct($name) { + $this->name = $name; + } + public function render($ctx) { + if (!isset($ctx->names[$this->name])) { + throw new \Exception("Reference to unknown name $this->name"); + } + $fileName = $ctx->names[$this->name]; + $anchor = "#grammar-$this->name"; + if ($fileName != $ctx->currentFile) { + $anchor = $fileName . $anchor; + } + return "$this->name"; + } +} +class Plain { + public $string; + public function __construct($string) { + $this->string = $string; + } + public function render($ctx) { + return htmlspecialchars($this->string); + } +} +class Opt { + public $inner; + public function __construct($inner) { + $this->inner = $inner; + } + public function render($ctx) { + return $this->inner->render($ctx) . 'opt'; + } +} From ae3a7639a05fae1cd1690ef28213bfebcb7d3af0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 26 Nov 2016 14:54:36 +0100 Subject: [PATCH 062/146] Fix grammar markup Instead of use id attribute on tag of the definition. --- spec/04-basic-concepts.md | 10 +- spec/05-types.md | 8 +- spec/07-variables.md | 12 +- spec/09-lexical-structure.md | 134 ++++----- spec/10-expressions.md | 186 ++++++------ spec/11-statements.md | 86 +++--- spec/13-functions.md | 22 +- spec/14-classes.md | 44 +-- spec/15-interfaces.md | 8 +- spec/16-traits.md | 22 +- spec/18-namespaces.md | 20 +- spec/19-grammar.md | 540 +++++++++++++++++------------------ tools/grammar_util.php | 2 +- 13 files changed, 547 insertions(+), 547 deletions(-) diff --git a/spec/04-basic-concepts.md b/spec/04-basic-concepts.md index a3fe9491..ceca1916 100644 --- a/spec/04-basic-concepts.md +++ b/spec/04-basic-concepts.md @@ -23,21 +23,21 @@ text: -->
-script:
+script:
    script-section
    script   script-section
 
-script-section:
+script-section:
    textopt   start-tag   statement-listopt   end-tagopt   textopt
 
-start-tag:
+start-tag:
    <?php
    <?=
 
-end-tag:
+end-tag:
    ?>
 
-text:
+text:
    arbitrary text not containing any of   start-tag   sequences
 
diff --git a/spec/05-types.md b/spec/05-types.md index 0074793c..4bd7772a 100644 --- a/spec/05-types.md +++ b/spec/05-types.md @@ -139,20 +139,20 @@ str-number:: -->
-str-numeric::
+str-numeric::
    str-whitespaceopt   signopt   str-number
 
-str-whitespace::
+str-whitespace::
    str-whitespaceopt   str-whitespace-char
 
-str-whitespace-char::
+str-whitespace-char::
    new-line
    Space character (U+0020)
    Horizontal-tab character (U+0009)
    Vertical-tab character (U+000B)
    Form-feed character (U+000C)
 
-str-number::
+str-number::
    digit-sequence
    floating-literal
 
diff --git a/spec/07-variables.md b/spec/07-variables.md index 9a09e039..58fdf9ee 100644 --- a/spec/07-variables.md +++ b/spec/07-variables.md @@ -282,17 +282,17 @@ function-static-initializer: -->
-function-static-declaration:
+function-static-declaration:
    static   static-variable-name-list   ;
 
-static-variable-name-list:
+static-variable-name-list:
    static-variable-declaration
    static-variable-name-list   ,   static-variable-declaration
 
-static-variable-declaration:
+static-variable-declaration:
    variable-name   function-static-initializeropt
 
-function-static-initializer:
+function-static-initializer:
    =   constant-expression
 
@@ -370,10 +370,10 @@ variable-name-list: -->
-global-declaration:
+global-declaration:
    global   variable-name-list   ;
 
-variable-name-list:
+variable-name-list:
    simple-variable
    variable-name-list   ,   simple-variable
 
diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index ded9eb93..ae8d4a22 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -50,7 +50,7 @@ single-line-comment-example:: -->
-single-line-comment-example::
+single-line-comment-example::
    //   input-charactersopt
    #   input-charactersopt
 
@@ -71,7 +71,7 @@ hexadecimal-digit-example:: one of -->
-hexadecimal-digit-example:: one of
+hexadecimal-digit-example:: one of
    0   1   2   3   4   5   6   7   8   9
    a   b   c   d   e   f
    A   B   C   D   E   F
@@ -98,11 +98,11 @@ input-element::
 -->
 
 
-input-file::
+input-file::
    input-element
    input-file   input-element
 
-input-element::
+input-element::
    comment
    white-space
    token
@@ -154,27 +154,27 @@ delimited-comment::
 -->
 
 
-comment::
+comment::
    single-line-comment
    delimited-comment
 
-single-line-comment::
+single-line-comment::
    //   input-charactersopt
    #   input-charactersopt
 
-input-characters::
+input-characters::
    input-character
    input-characters   input-character
 
-input-character::
+input-character::
    Any source character except   new-line
 
-new-line::
+new-line::
    Carriage-return character (U+000D)
    Line-feed character (U+000A)
    Carriage-return character (U+000D) followed by line-feed character (U+000A)
 
-delimited-comment::
+delimited-comment::
    /*   No characters or any source character sequence except */   */
 
@@ -217,11 +217,11 @@ white-space-character:: -->
-white-space::
+white-space::
    white-space-character
    white-space   white-space-character
 
-white-space-character::
+white-space-character::
    new-line
    Space character (U+0020)
    Horizontal-tab character (U+0009)
@@ -252,7 +252,7 @@ token::
 -->
 
 
-token::
+token::
    variable-name
    name
    keyword
@@ -301,32 +301,32 @@ nondigit:: one of
 -->
 
 
-variable-name::
+variable-name::
    $   name
 
-namespace-name::
+namespace-name::
    name
    namespace-name   \   name
 
-namespace-name-as-a-prefix::
+namespace-name-as-a-prefix::
    \
    \opt   namespace-name   \
    namespace   \
    namespace   \   namespace-name   \
 
-qualified-name::
+qualified-name::
    namespace-name-as-a-prefixopt   name
 
-name::
+name::
    name-nondigit
    name   name-nondigit
    name   digit
 
-name-nondigit::
+name-nondigit::
    nondigit
    one of the characters U+0080–U+00ff
 
-nondigit:: one of
+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
@@ -402,7 +402,7 @@ keyword:: one of
 -->
 
 
-keyword:: one of
+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
@@ -477,49 +477,49 @@ binary-digit:: one of
 -->
 
 
-integer-literal::
+integer-literal::
    decimal-literal
    octal-literal
    hexadecimal-literal
    binary-literal
 
-decimal-literal::
+decimal-literal::
    nonzero-digit
    decimal-literal   digit
 
-octal-literal::
+octal-literal::
    0
    octal-literal   octal-digit
 
-hexadecimal-literal::
+hexadecimal-literal::
    hexadecimal-prefix   hexadecimal-digit
    hexadecimal-literal   hexadecimal-digit
 
-hexadecimal-prefix:: one of
+hexadecimal-prefix:: one of
    0x   0X
 
-binary-literal::
+binary-literal::
    binary-prefix   binary-digit
    binary-literal   binary-digit
 
-binary-prefix:: one of
+binary-prefix:: one of
    0b   0B
 
-digit:: one of
+digit:: one of
    0   1   2   3   4   5   6   7   8   9
 
-nonzero-digit:: one of
+nonzero-digit:: one of
    1   2   3   4   5   6   7   8   9
 
-octal-digit:: one of
+octal-digit:: one of
    0   1   2   3   4   5   6   7
 
-hexadecimal-digit:: one of
+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
+binary-digit:: one of
    0   1
 
@@ -592,22 +592,22 @@ digit-sequence:: -->
-floating-literal::
+floating-literal::
    fractional-literal   exponent-partopt
    digit-sequence   exponent-part
 
-fractional-literal::
+fractional-literal::
    digit-sequenceopt   .   digit-sequence
    digit-sequence   .
 
-exponent-part::
+exponent-part::
    e   signopt   digit-sequence
    E   signopt   digit-sequence
 
-sign:: one of
+sign:: one of
    +   -
 
-digit-sequence::
+digit-sequence::
    digit
    digit-sequence   digit
 
@@ -645,7 +645,7 @@ string-literal:: -->
-string-literal::
+string-literal::
    single-quoted-string-literal
    double-quoted-string-literal
    heredoc-string-literal
@@ -683,21 +683,21 @@ b-prefix:: one of
 -->
 
 
-single-quoted-string-literal::
+single-quoted-string-literal::
    b-prefixopt   '   sq-char-sequenceopt   '
 
-sq-char-sequence::
+sq-char-sequence::
    sq-char
    sq-char-sequence   sq-char
 
-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
+sq-escape-sequence:: one of
    \'   \\
 
-b-prefix:: one of
+b-prefix:: one of
    b   B
 
@@ -766,40 +766,40 @@ codepoint-digits:: -->
-double-quoted-string-literal::
+double-quoted-string-literal::
    b-prefixopt   "   dq-char-sequenceopt   "
 
-dq-char-sequence::
+dq-char-sequence::
    dq-char
    dq-char-sequence   dq-char
 
-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-escape-sequence::
    dq-simple-escape-sequence
    dq-octal-escape-sequence
    dq-hexadecimal-escape-sequence
    dq-unicode-escape-sequence
 
-dq-simple-escape-sequence:: one of
+dq-simple-escape-sequence:: one of
    \"   \\   \$   \e   \f   \n   \r   \t   \v
 
-dq-octal-escape-sequence::
+dq-octal-escape-sequence::
    \   octal-digit
    \   octal-digit   octal-digit
    \   octal-digit   octal-digit   octal-digit
 
-dq-hexadecimal-escape-sequence::
+dq-hexadecimal-escape-sequence::
    \x   hexadecimal-digit   hexadecimal-digitopt
    \X   hexadecimal-digit   hexadecimal-digitopt
 
-dq-unicode-escape-sequence::
+dq-unicode-escape-sequence::
    \u{   codepoint-digits   }
 
-codepoint-digits::
+codepoint-digits::
    hexadecimal-digit
    hexadecimal-digit   codepoint-digits
 
@@ -882,20 +882,20 @@ property-in-string:: -->
-string-variable::
+string-variable::
    variable-name   offset-or-propertyopt
    ${   expression   }
 
-offset-or-property::
+offset-or-property::
    offset-in-string
    property-in-string
 
-offset-in-string::
+offset-in-string::
    [   name   ]
    [   variable-name   ]
    [   integer-literal   ]
 
-property-in-string::
+property-in-string::
    ->   name
 
@@ -985,35 +985,35 @@ hd-simple-escape-sequence:: one of -->
-heredoc-string-literal::
+heredoc-string-literal::
    b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
 
-hd-start-identifier::
+hd-start-identifier::
    name
    "   name   "
 
-hd-end-identifier::
+hd-end-identifier::
    name
 
-hd-body::
+hd-body::
    hd-char-sequenceopt   new-line
 
-hd-char-sequence::
+hd-char-sequence::
    hd-char
    hd-char-sequence   hd-char
 
-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-escape-sequence::
    hd-simple-escape-sequence
    dq-octal-escape-sequence
    dq-hexadecimal-escape-sequence
    dq-unicode-escape-sequence
 
-hd-simple-escape-sequence:: one of
+hd-simple-escape-sequence:: one of
    \\   \$   \e   \f   \n   \r   \t   \v
 
@@ -1065,7 +1065,7 @@ nowdoc-string-literal:: -->
-nowdoc-string-literal::
+nowdoc-string-literal::
    b-prefixopt   <<<   '   name   '   new-line   hd-bodyopt   name   ;opt   new-line
 
@@ -1113,7 +1113,7 @@ operator-or-punctuator:: one of -->
-operator-or-punctuator:: one of
+operator-or-punctuator:: one of
    [   ]   (   )   {   }   .   ->   ++   --   **   *   +   -   ~   !
    $   /   %   <<   >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
    &   &&   ||   ?   :   ;   =   **=   *=   /=   %=   +=   -=   .=   <<=
diff --git a/spec/10-expressions.md b/spec/10-expressions.md
index f421ba65..3fc913ae 100644
--- a/spec/10-expressions.md
+++ b/spec/10-expressions.md
@@ -102,7 +102,7 @@ primary-expression:
 -->
 
 
-primary-expression:
+primary-expression:
    variable
    class-constant-access-expression
    constant-access-expression
@@ -130,7 +130,7 @@ simple-variable:
 -->
 
 
-simple-variable:
+simple-variable:
    variable-name
    $   simple-variable
    $   {   expression   }
@@ -195,13 +195,13 @@ callable-expression:
 -->
 
 
-dereferencable-expression:
+dereferencable-expression:
    variable
    (   expression   )
    array-creation-expression
    string-literal
 
-callable-expression:
+callable-expression:
    callable-variable
    (   expression   )
    array-creation-expression
@@ -238,14 +238,14 @@ variable:
 -->
 
 
-callable-variable:
+callable-variable:
    simple-variable
    subscript-expression
    member-call-expression
    scoped-call-expression
    function-call-expression
 
-variable:
+variable:
    callable-variable
    scoped-property-access-expression
    member-access-expression
@@ -265,7 +265,7 @@ constant-access-expression:
 -->
 
 
-constant-access-expression:
+constant-access-expression:
    qualified-name
 
@@ -286,7 +286,7 @@ literal: -->
-literal:
+literal:
    integer-literal
    floating-literal
    string-literal
@@ -321,16 +321,16 @@ intrinsic-operator:
 -->
 
 
-intrinsic:
+intrinsic:
    intrinsic-construct
    intrinsic-operator
 
-intrinsic-construct:
+intrinsic-construct:
    echo-intrinsic
    list-intrinsic
    unset-intrinsic
 
-intrinsic-operator:
+intrinsic-operator:
    empty-intrinsic
    eval-intrinsic
    exit-intrinsic
@@ -363,10 +363,10 @@ expression-list:
 -->
 
 
-echo-intrinsic:
+echo-intrinsic:
    echo   expression-list
 
-expression-list:
+expression-list:
    expression
    expression-list   ,   expression
 
@@ -409,7 +409,7 @@ empty-intrinsic: -->
-empty-intrinsic:
+empty-intrinsic:
    empty   (   expression   )
 
@@ -449,7 +449,7 @@ eval-intrinsic: -->
-eval-intrinsic:
+eval-intrinsic:
    eval   (   expression   )
 
@@ -495,7 +495,7 @@ exit-intrinsic: -->
-exit-intrinsic:
+exit-intrinsic:
    exit
    exit   (   expressionopt   )
    die
@@ -548,10 +548,10 @@ variable-list:
 -->
 
 
-isset-intrinsic:
+isset-intrinsic:
    isset   (   variable-list   )
 
-variable-list:
+variable-list:
    variable
    variable-list   ,   variable
 
@@ -607,23 +607,23 @@ list-or-variable: -->
-list-intrinsic:
+list-intrinsic:
    list   (   list-expression-list   )
 
-list-expression-list:
+list-expression-list:
    unkeyed-list-expression-list
    keyed-list-expression-list   ,opt
 
-unkeyed-list-expression-list:
+unkeyed-list-expression-list:
    list-or-variable
    ,
    unkeyed-list-expression-list   ,   list-or-variableopt
 
-keyed-list-expression-list:
+keyed-list-expression-list:
    expression   =>   list-or-variable
    keyed-list-expression-list   ,   expression   =>   list-or-variable
 
-list-or-variable:
+list-or-variable:
    list-intrinsic
    expression
 
@@ -722,7 +722,7 @@ print-intrinsic: -->
-print-intrinsic:
+print-intrinsic:
    print   expression
 
@@ -764,7 +764,7 @@ unset-intrinsic: -->
-unset-intrinsic:
+unset-intrinsic:
    unset   (   variable-list   )
 
@@ -823,13 +823,13 @@ use-variable-name-list: -->
-anonymous-function-creation-expression:
+anonymous-function-creation-expression:
    static?   function   &opt   (   parameter-declaration-listopt   )   return-typeopt   anonymous-function-use-clauseopt   compound-statement
 
-anonymous-function-use-clause:
+anonymous-function-use-clause:
    use   (   use-variable-name-list   )
 
-use-variable-name-list:
+use-variable-name-list:
    &opt   variable-name
    use-variable-name-list   ,   &opt   variable-name
 
@@ -910,7 +910,7 @@ postfix-expression: -->
-postfix-expression:
+postfix-expression:
    primary-expression
    clone-expression
    object-creation-expression
@@ -933,7 +933,7 @@ clone-expression:
 -->
 
 
-clone-expression:
+clone-expression:
    clone   expression
 
@@ -995,13 +995,13 @@ class-type-designator: -->
-object-creation-expression:
+object-creation-expression:
    new   class-type-designator   (   argument-expression-listopt   )
    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:
+class-type-designator:
    qualified-name
    expression
 
@@ -1098,25 +1098,25 @@ element-value: -->
-array-creation-expression:
+array-creation-expression:
    array   (   array-initializeropt   )
    [   array-initializeropt   ]
 
-array-initializer:
+array-initializer:
    array-initializer-list   ,opt
 
-array-initializer-list:
+array-initializer-list:
    array-element-initializer
    array-element-initializer   ,   array-initializer-list
 
-array-element-initializer:
+array-element-initializer:
    &opt   element-value
    element-key   =>   &opt   element-value
 
-element-key:
+element-key:
    expression
 
-element-value:
+element-value:
    expression
 
@@ -1194,7 +1194,7 @@ subscript-expression: -->
-subscript-expression:
+subscript-expression:
    dereferencable-expression   [   expressionopt   ]
    dereferencable-expression   {   expression   }   <b>[Deprecated form]</b>
 
@@ -1370,19 +1370,19 @@ variadic-unpacking: -->
-function-call-expression:
+function-call-expression:
    qualified-name   (   argument-expression-listopt   )
    callable-expression   (   argument-expression-listopt   )
 
-argument-expression-list:
+argument-expression-list:
    argument-expression
    argument-expression-list   ,   argument-expression
 
-argument-expression:
+argument-expression:
    variadic-unpacking
    assignment-expression
 
-variadic-unpacking:
+variadic-unpacking:
    ...   assignment-expression
 
@@ -1498,10 +1498,10 @@ member-name: -->
-member-access-expression:
+member-access-expression:
    dereferencable-expression   ->   member-name
 
-member-name:
+member-name:
    name
    simple-variable
    {   expression   }
@@ -1576,7 +1576,7 @@ member-call-expression:
 -->
 
 
-member-call-expression:
+member-call-expression:
    dereferencable-expression   ->   member-name   (   argument-expression-listopt   )
 
@@ -1619,10 +1619,10 @@ postfix-decrement-expression: -->
-postfix-increment-expression:
+postfix-increment-expression:
    variable   ++
 
-postfix-decrement-expression:
+postfix-decrement-expression:
    variable   --
 
@@ -1670,21 +1670,21 @@ relative-scope: -->
-scoped-property-access-expression:
+scoped-property-access-expression:
    scope-resolution-qualifier   ::   simple-variable
 
-scoped-call-expression:
+scoped-call-expression:
    scope-resolution-qualifier   ::   member-name   (   argument-expression-listopt   )
 
-class-constant-access-expression:
+class-constant-access-expression:
    scope-resolution-qualifier   ::   name
 
-scope-resolution-qualifier:
+scope-resolution-qualifier:
    relative-scope
    qualified-name
    dereferencable-expression
 
-relative-scope:
+relative-scope:
    self
    parent
    static
@@ -1794,7 +1794,7 @@ exponentiation-expression:
 -->
 
 
-exponentiation-expression:
+exponentiation-expression:
    expression   **   expression
 
@@ -1837,7 +1837,7 @@ unary-expression: -->
-unary-expression:
+unary-expression:
    postfix-expression
    prefix-increment-expression
    prefix-decrement-expression
@@ -1864,10 +1864,10 @@ prefix-decrement-expression:
 -->
 
 
-prefix-increment-expression:
+prefix-increment-expression:
    ++   variable
 
-prefix-decrement-expression:
+prefix-decrement-expression:
    --   variable
 
@@ -1978,10 +1978,10 @@ unary-operator: one of -->
-unary-op-expression:
+unary-op-expression:
    unary-operator   cast-expression
 
-unary-operator: one of
+unary-operator: one of
    +   -   !   ~
 
@@ -2070,7 +2070,7 @@ error-control-expression: -->
-error-control-expression:
+error-control-expression:
    @   expression
 
@@ -2127,7 +2127,7 @@ shell-command-expression: -->
-shell-command-expression:
+shell-command-expression:
    `   dq-char-sequenceopt   `
 
@@ -2170,11 +2170,11 @@ cast-type: one of -->
-cast-expression:
+cast-expression:
    unary-expression
    (   cast-type   )   expression
 
-cast-type: one of
+cast-type: one of
    array   binary   bool   boolean   double   int   integer   float   object
    real   string   unset
 
@@ -2234,14 +2234,14 @@ instanceof-type-designator: -->
-instanceof-expression:
+instanceof-expression:
    unary-expression
    instanceof-subject   instanceof   instanceof-type-designator
 
-instanceof-subject:
+instanceof-subject:
    expression
 
-instanceof-type-designator:
+instanceof-type-designator:
    qualified-name
    expression
 
@@ -2305,7 +2305,7 @@ multiplicative-expression: -->
-multiplicative-expression:
+multiplicative-expression:
    instanceof-expression
    multiplicative-expression   *   instanceof-expression
    multiplicative-expression   /   instanceof-expression
@@ -2380,7 +2380,7 @@ additive-expression:
 -->
 
 
-additive-expression:
+additive-expression:
    multiplicative-expression
    additive-expression   +   multiplicative-expression
    additive-expression   -   multiplicative-expression
@@ -2457,7 +2457,7 @@ shift-expression:
 -->
 
 
-shift-expression:
+shift-expression:
    additive-expression
    shift-expression   <<   additive-expression
    shift-expression   >>   additive-expression
@@ -2523,7 +2523,7 @@ relational-expression:
 -->
 
 
-relational-expression:
+relational-expression:
    shift-expression
    relational-expression   <   shift-expression
    relational-expression   >   shift-expression
@@ -2659,7 +2659,7 @@ equality-expression:
 -->
 
 
-equality-expression:
+equality-expression:
    relational-expression
    equality-expression   ==   relational-expression
    equality-expression   !=   relational-expression
@@ -2719,7 +2719,7 @@ bitwise-AND-expression:
 -->
 
 
-bitwise-AND-expression:
+bitwise-AND-expression:
    equality-expression
    bitwise-AND-expression   &   equality-expression
 
@@ -2766,7 +2766,7 @@ bitwise-exc-OR-expression: -->
-bitwise-exc-OR-expression:
+bitwise-exc-OR-expression:
    bitwise-AND-expression
    bitwise-exc-OR-expression   ^   bitwise-AND-expression
 
@@ -2815,7 +2815,7 @@ bitwise-inc-OR-expression: -->
-bitwise-inc-OR-expression:
+bitwise-inc-OR-expression:
    bitwise-exc-OR-expression
    bitwise-inc-OR-expression   |   bitwise-exc-OR-expression
 
@@ -2862,7 +2862,7 @@ logical-AND-expression-1: -->
-logical-AND-expression-1:
+logical-AND-expression-1:
    bitwise-inc-OR-expression
    logical-AND-expression-1   &&   bitwise-inc-OR-expression
 
@@ -2893,7 +2893,7 @@ logical-inc-OR-expression-1: -->
-logical-inc-OR-expression-1:
+logical-inc-OR-expression-1:
    logical-AND-expression-1
    logical-inc-OR-expression-1   ||   logical-AND-expression-1
 
@@ -2921,7 +2921,7 @@ conditional-expression: -->
-conditional-expression:
+conditional-expression:
    logical-inc-OR-expression-1
    logical-inc-OR-expression-1   ?   expressionopt   :   conditional-expression
 
@@ -2967,7 +2967,7 @@ coalesce-expression: -->
-coalesce-expression:
+coalesce-expression:
    logical-inc-OR-expression-1   ??   expression
 
@@ -3021,7 +3021,7 @@ assignment-expression: -->
-assignment-expression:
+assignment-expression:
    conditional-expression
    coalesce-expression
    simple-assignment-expression
@@ -3049,7 +3049,7 @@ simple-assignment-expression:
 -->
 
 
-simple-assignment-expression:
+simple-assignment-expression:
    variable   =   assignment-expression
    list-intrinsic   =   assignment-expression
 
@@ -3118,7 +3118,7 @@ byref-assignment-expression: -->
-byref-assignment-expression:
+byref-assignment-expression:
    variable   =   &   assignment-expression
 
@@ -3163,10 +3163,10 @@ compound-assignment-operator: one of -->
-compound-assignment-expression:
+compound-assignment-expression:
    variable   compound-assignment-operator   assignment-expression
 
-compound-assignment-operator: one of
+compound-assignment-operator: one of
    **=   *=   /=   %=   +=   -=   .=   <<=   >>=   &=   ^=   |=
 
@@ -3202,7 +3202,7 @@ logical-AND-expression-2: -->
-logical-AND-expression-2:
+logical-AND-expression-2:
    assignment-expression
    logical-AND-expression-2   and   assignment-expression
 
@@ -3223,7 +3223,7 @@ logical-exc-OR-expression: -->
-logical-exc-OR-expression:
+logical-exc-OR-expression:
    logical-AND-expression-2
    logical-exc-OR-expression   xor   logical-AND-expression-2
 
@@ -3257,7 +3257,7 @@ logical-inc-OR-expression-2: -->
-logical-inc-OR-expression-2:
+logical-inc-OR-expression-2:
    logical-exc-OR-expression
    logical-inc-OR-expression-2   or   logical-exc-OR-expression
 
@@ -3279,7 +3279,7 @@ yield-expression: -->
-yield-expression:
+yield-expression:
    logical-inc-OR-expression-2
    yield   array-element-initializer
    yield from   expression
@@ -3411,7 +3411,7 @@ expression:
 -->
 
 
-expression:
+expression:
    yield-expression
    include-expression
    include-once-expression
@@ -3582,7 +3582,7 @@ include-expression:
 -->
 
 
-include-expression:
+include-expression:
    include   expression
 
@@ -3634,7 +3634,7 @@ include-once-expression: -->
-include-once-expression:
+include-once-expression:
    include_once   expression
 
@@ -3682,7 +3682,7 @@ require-expression: -->
-require-expression:
+require-expression:
    require   expression
 
@@ -3702,7 +3702,7 @@ require-once-expression: -->
-require-once-expression:
+require-once-expression:
    require_once   expression
 
@@ -3729,7 +3729,7 @@ constant-expression: -->
-constant-expression:
+constant-expression:
    expression
 
diff --git a/spec/11-statements.md b/spec/11-statements.md index 0df7aa73..7f409e40 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -26,7 +26,7 @@ statement: -->
-statement:
+statement:
    compound-statement
    named-label-statement
    expression-statement
@@ -60,10 +60,10 @@ statement-list:
 -->
 
 
-compound-statement:
+compound-statement:
    {   statement-listopt   }
 
-statement-list:
+statement-list:
    statement
    statement-list   statement
 
@@ -102,7 +102,7 @@ named-label-statement: -->
-named-label-statement:
+named-label-statement:
    name   ;   statement
 
@@ -128,7 +128,7 @@ expression-statement: -->
-expression-statement:
+expression-statement:
    expressionopt   ;
 
@@ -183,7 +183,7 @@ selection-statement: -->
-selection-statement:
+selection-statement:
    if-statement
    switch-statement
 
@@ -224,28 +224,28 @@ else-clause-2: -->
-if-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-clauses-1:
    elseif-clause-1
    elseif-clauses-1   elseif-clause-1
 
-elseif-clause-1:
+elseif-clause-1:
    elseif   (   expression   )   statement
 
-else-clause-1:
+else-clause-1:
    else   statement
 
-elseif-clauses-2:
+elseif-clauses-2:
    elseif-clause-2
    elseif-clauses-2   elseif-clause-2
 
-elseif-clause-2:
+elseif-clause-2:
    elseif   (   expression   )   :   statement-list
 
-else-clause-2:
+else-clause-2:
    else   :   statement-list
 
@@ -331,21 +331,21 @@ case-default-label-terminator: -->
-switch-statement:
+switch-statement:
    switch   (   expression   )   {   case-statementsopt   }
    switch   (   expression   )   :   case-statementsopt   endswitch;
 
-case-statements:
+case-statements:
    case-statement   case-statementsopt
    default-statement   case-statementsopt
 
-case-statement:
+case-statement:
    case   expression   case-default-label-terminator   statement-listopt
 
-default-statement:
+default-statement:
    default   case-default-label-terminator   statement-listopt
 
-case-default-label-terminator:
+case-default-label-terminator:
    :
    ;
 
@@ -447,7 +447,7 @@ iteration-statement: -->
-iteration-statement:
+iteration-statement:
    while-statement
    do-statement
    for-statement
@@ -465,7 +465,7 @@ while-statement:
 -->
 
 
-while-statement:
+while-statement:
    while   (   expression   )   statement
    while   (   expression   )   :   statement-list   endwhile   ;
 
@@ -512,7 +512,7 @@ do-statement: -->
-do-statement:
+do-statement:
    do   statement   while   (   expression   )   ;
 
@@ -570,20 +570,20 @@ for-expression-group: -->
-for-statement:
+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-initializer:
    for-expression-group
 
-for-control:
+for-control:
    for-expression-group
 
-for-end-of-loop:
+for-end-of-loop:
    for-expression-group
 
-for-expression-group:
+for-expression-group:
    expression
    for-expression-group   ,   expression
 
@@ -672,17 +672,17 @@ foreach-value: -->
-foreach-statement:
+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:
+foreach-collection-name:
    expression
 
-foreach-key:
+foreach-key:
    expression   =>
 
-foreach-value:
+foreach-value:
    &opt   expression
    list-intrinsic
 
@@ -759,7 +759,7 @@ jump-statement: -->
-jump-statement:
+jump-statement:
    goto-statement
    continue-statement
    break-statement
@@ -777,7 +777,7 @@ goto-statement:
 -->
 
 
-goto-statement:
+goto-statement:
    goto   name   ;
 
@@ -833,10 +833,10 @@ breakout-level: -->
-continue-statement:
+continue-statement:
    continue   breakout-levelopt   ;
 
-breakout-level:
+breakout-level:
    integer-literal
 
@@ -886,7 +886,7 @@ break-statement: -->
-break-statement:
+break-statement:
    break   breakout-levelopt   ;
 
@@ -952,7 +952,7 @@ return-statement: -->
-return-statement:
+return-statement:
    return   expressionopt   ;
 
@@ -1065,7 +1065,7 @@ throw-statement: -->
-throw-statement:
+throw-statement:
    throw   expression   ;
 
@@ -1118,19 +1118,19 @@ finally-clause: -->
-try-statement:
+try-statement:
    try   compound-statement   catch-clauses
    try   compound-statement   finally-clause
    try   compound-statement   catch-clauses   finally-clause
 
-catch-clauses:
+catch-clauses:
    catch-clause
    catch-clauses   catch-clause
 
-catch-clause:
+catch-clause:
    catch   (   qualified-name   variable-name   )   compound-statement
 
-finally-clause:
+finally-clause:
    finally   compound-statement
 
@@ -1225,12 +1225,12 @@ declare-directive: -->
-declare-statement:
+declare-statement:
    declare   (   declare-directive   )   statement
    declare   (   declare-directive   )   :   statement-list   enddeclare   ;
    declare   (   declare-directive   )   ;
 
-declare-directive:
+declare-directive:
    ticks   =   literal
    encoding   =   literal
    strict_types   =   literal
diff --git a/spec/13-functions.md b/spec/13-functions.md
index f7ee26a9..4311b041 100644
--- a/spec/13-functions.md
+++ b/spec/13-functions.md
@@ -93,47 +93,47 @@ default-argument-specifier:
 -->
 
 
-function-definition:
+function-definition:
    function-definition-header   compound-statement
 
-function-definition-header:
+function-definition-header:
    function   &opt   name   (   parameter-declaration-listopt   )   return-typeopt
 
-parameter-declaration-list:
+parameter-declaration-list:
    simple-parameter-declaration-list
    variadic-declaration-list
 
-simple-parameter-declaration-list:
+simple-parameter-declaration-list:
    parameter-declaration
    parameter-declaration-list   ,   parameter-declaration
 
-variadic-declaration-list:
+variadic-declaration-list:
    simple-parameter-declaration-list   ,   variadic-parameter
    variadic-parameter
 
-parameter-declaration:
+parameter-declaration:
    type-declarationopt   &opt   variable-name   default-argument-specifieropt
 
-variadic-parameter:
+variadic-parameter:
    type-declarationopt   &opt   ...   variable-name
 
-return-type:
+return-type:
    :   type-declaration
    :   void
 
-type-declaration:
+type-declaration:
    array
    callable
    scalar-type
    qualified-name
 
-scalar-type:
+scalar-type:
    bool
    float
    int
    string
 
-default-argument-specifier:
+default-argument-specifier:
    =   constant-expression
 
diff --git a/spec/14-classes.md b/spec/14-classes.md index 29b6e605..9e20d344 100644 --- a/spec/14-classes.md +++ b/spec/14-classes.md @@ -75,17 +75,17 @@ class-interface-clause: -->
-class-declaration:
+class-declaration:
    class-modifieropt   class   name   class-base-clauseopt   class-interface-clauseopt   {   class-member-declarationsopt   }
 
-class-modifier:
+class-modifier:
    abstract
    final
 
-class-base-clause:
+class-base-clause:
    extends   qualified-name
 
-class-interface-clause:
+class-interface-clause:
    implements   qualified-name
    class-interface-clause   ,   qualified-name
 
@@ -224,11 +224,11 @@ class-member-declaration: -->
-class-member-declarations:
+class-member-declarations:
    class-member-declaration
    class-member-declarations   class-member-declaration
 
-class-member-declaration:
+class-member-declaration:
    class-const-declaration
    property-declaration
    method-declaration
@@ -419,17 +419,17 @@ const-element:
 -->
 
 
-const-declaration:
+const-declaration:
    const   const-elements   ;
 
-class-const-declaration:
+class-const-declaration:
    visibility-modifieropt   const   const-elements   ;
 
-const-elements:
+const-elements:
    const-element
    const-elements   const-element
 
-const-element:
+const-element:
    name   =   constant-expression
 
@@ -502,30 +502,30 @@ property-initializer: -->
-property-declaration:
+property-declaration:
    property-modifier   property-elements   ;
 
-property-modifier:
+property-modifier:
    var
    visibility-modifier   static-modifieropt
    static-modifier   visibility-modifieropt
 
-visibility-modifier:
+visibility-modifier:
    public
    protected
    private
 
-static-modifier:
+static-modifier:
    static
 
-property-elements:
+property-elements:
    property-element
    property-elements   property-element
 
-property-element:
+property-element:
    variable-name   property-initializeropt   ;
 
-property-initializer:
+property-initializer:
    =   constant-expression
 
@@ -576,15 +576,15 @@ method-modifier: -->
-method-declaration:
+method-declaration:
    method-modifiersopt   function-definition
    method-modifiers   function-definition-header   ;
 
-method-modifiers:
+method-modifiers:
    method-modifier
    method-modifiers   method-modifier
 
-method-modifier:
+method-modifier:
    visibility-modifier
    static-modifier
    class-modifier
@@ -632,7 +632,7 @@ constructor-declaration:
 -->
 
 
-constructor-declaration:
+constructor-declaration:
    method-modifiers   function   &opt   __construct   (   parameter-declaration-listopt   )   compound-statement
 
@@ -718,7 +718,7 @@ destructor-declaration: -->
-destructor-declaration:
+destructor-declaration:
    method-modifiers   function   &opt   __destruct   (   )   compound-statement
 
diff --git a/spec/15-interfaces.md b/spec/15-interfaces.md index b4a35532..a81ef76e 100644 --- a/spec/15-interfaces.md +++ b/spec/15-interfaces.md @@ -28,10 +28,10 @@ interface-base-clause: -->
-interface-declaration:
+interface-declaration:
    interface   name   interface-base-clauseopt   {   interface-member-declarationsopt   }
 
-interface-base-clause:
+interface-base-clause:
    extends   qualified-name
    interface-base-clause   ,   qualified-name
 
@@ -97,11 +97,11 @@ interface-member-declaration: -->
-interface-member-declarations:
+interface-member-declarations:
    interface-member-declaration
    interface-member-declarations   interface-member-declaration
 
-interface-member-declaration:
+interface-member-declaration:
    class-const-declaration
    method-declaration
 
diff --git a/spec/16-traits.md b/spec/16-traits.md index 84f96755..5138a51e 100644 --- a/spec/16-traits.md +++ b/spec/16-traits.md @@ -59,14 +59,14 @@ trait-member-declaration: -->
-trait-declaration:
+trait-declaration:
    trait   name   {   trait-member-declarationsopt   }
 
-trait-member-declarations:
+trait-member-declarations:
    trait-member-declaration
    trait-member-declarations   trait-member-declaration
 
-trait-member-declaration:
+trait-member-declaration:
    property-declaration
    method-declaration
    constructor-declaration
@@ -147,33 +147,33 @@ trait-alias-as-clause:
 -->
 
 
-trait-use-clauses:
+trait-use-clauses:
    trait-use-clause
    trait-use-clauses   trait-use-clause
 
-trait-use-clause:
+trait-use-clause:
    use   trait-name-list   trait-use-specification
 
-trait-name-list:
+trait-name-list:
    qualified-name
    trait-name-list   ,   qualified-name
 
-trait-use-specification:
+trait-use-specification:
    ;
    {   trait-select-and-alias-clausesopt   }
 
-trait-select-and-alias-clauses:
+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-and-alias-clause:
    trait-select-insteadof-clause   ;
    trait-alias-as-clause   ;
 
-trait-select-insteadof-clause:
+trait-select-insteadof-clause:
    name   insteadof   name
 
-trait-alias-as-clause:
+trait-alias-as-clause:
    name   as   visibility-modifieropt   name
    name   as   visibility-modifier   nameopt
 
diff --git a/spec/18-namespaces.md b/spec/18-namespaces.md index d3334cb1..420dbe40 100644 --- a/spec/18-namespaces.md +++ b/spec/18-namespaces.md @@ -43,7 +43,7 @@ namespace-definition: -->
-namespace-definition:
+namespace-definition:
    namespace   name   ;
    namespace   nameopt   compound-statement
 
@@ -155,37 +155,37 @@ namespace-use-group-clause-2: -->
-namespace-use-declaration:
+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-clauses:
    namespace-use-clause
    namespace-use-clauses   ,   namespace-use-clause
 
-namespace-use-clause:
+namespace-use-clause:
    qualified-name   namespace-aliasing-clauseopt
 
-namespace-aliasing-clause:
+namespace-aliasing-clause:
    as   name
 
-namespace-function-or-const:
+namespace-function-or-const:
    function
    const
 
-namespace-use-group-clauses-1:
+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-use-group-clause-1:
    namespace-name   namespace-aliasing-clauseopt
 
-namespace-use-group-clauses-2:
+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-use-group-clause-2:
    namespace-function-or-constopt   namespace-name   namespace-aliasing-clauseopt
 
diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 9482c24d..53ec956b 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -7,48 +7,48 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# ##Lexical Grammar
-input-file::
+input-file::
    input-element
    input-file   input-element
 
-input-element::
+input-element::
    comment
    white-space
    token
 
-comment::
+comment::
    single-line-comment
    delimited-comment
 
-single-line-comment::
+single-line-comment::
    //   input-charactersopt
    #   input-charactersopt
 
-input-characters::
+input-characters::
    input-character
    input-characters   input-character
 
-input-character::
+input-character::
    Any source character except   new-line
 
-new-line::
+new-line::
    Carriage-return character (U+000D)
    Line-feed character (U+000A)
    Carriage-return character (U+000D) followed by line-feed character (U+000A)
 
-delimited-comment::
+delimited-comment::
    /*   No characters or any source character sequence except */   */
 
-white-space::
+white-space::
    white-space-character
    white-space   white-space-character
 
-white-space-character::
+white-space-character::
    new-line
    Space character (U+0020)
    Horizontal-tab character (U+0009)
 
-token::
+token::
    variable-name
    name
    keyword
@@ -57,39 +57,39 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
    string-literal
    operator-or-punctuator
 
-variable-name::
+variable-name::
    $   name
 
-namespace-name::
+namespace-name::
    name
    namespace-name   \   name
 
-namespace-name-as-a-prefix::
+namespace-name-as-a-prefix::
    \
    \opt   namespace-name   \
    namespace   \
    namespace   \   namespace-name   \
 
-qualified-name::
+qualified-name::
    namespace-name-as-a-prefixopt   name
 
-name::
+name::
    name-nondigit
    name   name-nondigit
    name   digit
 
-name-nondigit::
+name-nondigit::
    nondigit
    one of the characters U+0080–U+00ff
 
-nondigit:: one of
+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
+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
@@ -99,181 +99,181 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
    protected   public   require   require_once   return   static   switch
    throw   trait   try   unset   use   var   while   xor   yield   yield from
 
-integer-literal::
+integer-literal::
    decimal-literal
    octal-literal
    hexadecimal-literal
    binary-literal
 
-decimal-literal::
+decimal-literal::
    nonzero-digit
    decimal-literal   digit
 
-octal-literal::
+octal-literal::
    0
    octal-literal   octal-digit
 
-hexadecimal-literal::
+hexadecimal-literal::
    hexadecimal-prefix   hexadecimal-digit
    hexadecimal-literal   hexadecimal-digit
 
-hexadecimal-prefix:: one of
+hexadecimal-prefix:: one of
    0x   0X
 
-binary-literal::
+binary-literal::
    binary-prefix   binary-digit
    binary-literal   binary-digit
 
-binary-prefix:: one of
+binary-prefix:: one of
    0b   0B
 
-digit:: one of
+digit:: one of
    0   1   2   3   4   5   6   7   8   9
 
-nonzero-digit:: one of
+nonzero-digit:: one of
    1   2   3   4   5   6   7   8   9
 
-octal-digit:: one of
+octal-digit:: one of
    0   1   2   3   4   5   6   7
 
-hexadecimal-digit:: one of
+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
+binary-digit:: one of
    0   1
 
-floating-literal::
+floating-literal::
    fractional-literal   exponent-partopt
    digit-sequence   exponent-part
 
-fractional-literal::
+fractional-literal::
    digit-sequenceopt   .   digit-sequence
    digit-sequence   .
 
-exponent-part::
+exponent-part::
    e   signopt   digit-sequence
    E   signopt   digit-sequence
 
-sign:: one of
+sign:: one of
    +   -
 
-digit-sequence::
+digit-sequence::
    digit
    digit-sequence   digit
 
-string-literal::
+string-literal::
    single-quoted-string-literal
    double-quoted-string-literal
    heredoc-string-literal
    nowdoc-string-literal
 
-single-quoted-string-literal::
+single-quoted-string-literal::
    b-prefixopt   '   sq-char-sequenceopt   '
 
-sq-char-sequence::
+sq-char-sequence::
    sq-char
    sq-char-sequence   sq-char
 
-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
+sq-escape-sequence:: one of
    \'   \\
 
-b-prefix:: one of
+b-prefix:: one of
    b   B
 
-double-quoted-string-literal::
+double-quoted-string-literal::
    b-prefixopt   "   dq-char-sequenceopt   "
 
-dq-char-sequence::
+dq-char-sequence::
    dq-char
    dq-char-sequence   dq-char
 
-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-escape-sequence::
    dq-simple-escape-sequence
    dq-octal-escape-sequence
    dq-hexadecimal-escape-sequence
    dq-unicode-escape-sequence
 
-dq-simple-escape-sequence:: one of
+dq-simple-escape-sequence:: one of
    \"   \\   \$   \e   \f   \n   \r   \t   \v
 
-dq-octal-escape-sequence::
+dq-octal-escape-sequence::
    \   octal-digit
    \   octal-digit   octal-digit
    \   octal-digit   octal-digit   octal-digit
 
-dq-hexadecimal-escape-sequence::
+dq-hexadecimal-escape-sequence::
    \x   hexadecimal-digit   hexadecimal-digitopt
    \X   hexadecimal-digit   hexadecimal-digitopt
 
-dq-unicode-escape-sequence::
+dq-unicode-escape-sequence::
    \u{   codepoint-digits   }
 
-codepoint-digits::
+codepoint-digits::
    hexadecimal-digit
    hexadecimal-digit   codepoint-digits
 
-string-variable::
+string-variable::
    variable-name   offset-or-propertyopt
    ${   expression   }
 
-offset-or-property::
+offset-or-property::
    offset-in-string
    property-in-string
 
-offset-in-string::
+offset-in-string::
    [   name   ]
    [   variable-name   ]
    [   integer-literal   ]
 
-property-in-string::
+property-in-string::
    ->   name
 
-heredoc-string-literal::
+heredoc-string-literal::
    b-prefixopt   <<<   hd-start-identifier   new-line   hd-bodyopt   hd-end-identifier   ;opt   new-line
 
-hd-start-identifier::
+hd-start-identifier::
    name
    "   name   "
 
-hd-end-identifier::
+hd-end-identifier::
    name
 
-hd-body::
+hd-body::
    hd-char-sequenceopt   new-line
 
-hd-char-sequence::
+hd-char-sequence::
    hd-char
    hd-char-sequence   hd-char
 
-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-escape-sequence::
    hd-simple-escape-sequence
    dq-octal-escape-sequence
    dq-hexadecimal-escape-sequence
    dq-unicode-escape-sequence
 
-hd-simple-escape-sequence:: one of
+hd-simple-escape-sequence:: one of
    \\   \$   \e   \f   \n   \r   \t   \v
 
-nowdoc-string-literal::
+nowdoc-string-literal::
    b-prefixopt   <<<   '   name   '   new-line   hd-bodyopt   name   ;opt   new-line
 
-operator-or-punctuator:: one of
+operator-or-punctuator:: one of
    [   ]   (   )   {   }   .   ->   ++   --   **   *   +   -   ~   !
    $   /   %   <<   >>   <   >   <=   >=   ==   ===   !=   !==   ^   |
    &   &&   ||   ?   :   ;   =   **=   *=   /=   %=   +=   -=   .=   <<=
@@ -285,44 +285,44 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 ###Basic Concepts
 
 
-script:
+script:
    script-section
    script   script-section
 
-script-section:
+script-section:
    textopt   start-tag   statement-listopt   end-tagopt   textopt
 
-start-tag:
+start-tag:
    <?php
    <?=
 
-end-tag:
+end-tag:
    ?>
 
-text:
+text:
    arbitrary text not containing any of   start-tag   sequences
 
###Variables
-function-static-declaration:
+function-static-declaration:
    static   static-variable-name-list   ;
 
-static-variable-name-list:
+static-variable-name-list:
    static-variable-declaration
    static-variable-name-list   ,   static-variable-declaration
 
-static-variable-declaration:
+static-variable-declaration:
    variable-name   function-static-initializeropt
 
-function-static-initializer:
+function-static-initializer:
    =   constant-expression
 
-global-declaration:
+global-declaration:
    global   variable-name-list   ;
 
-variable-name-list:
+variable-name-list:
    simple-variable
    variable-name-list   ,   simple-variable
 
@@ -330,7 +330,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# ###Expressions
-primary-expression:
+primary-expression:
    variable
    class-constant-access-expression
    constant-access-expression
@@ -340,122 +340,122 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
    anonymous-function-creation-expression
    (   expression   )
 
-simple-variable:
+simple-variable:
    variable-name
    $   simple-variable
    $   {   expression   }
 
-dereferencable-expression:
+dereferencable-expression:
    variable
    (   expression   )
    array-creation-expression
    string-literal
 
-callable-expression:
+callable-expression:
    callable-variable
    (   expression   )
    array-creation-expression
    string-literal
 
-callable-variable:
+callable-variable:
    simple-variable
    subscript-expression
    member-call-expression
    scoped-call-expression
    function-call-expression
 
-variable:
+variable:
    callable-variable
    scoped-property-access-expression
    member-access-expression
 
-constant-access-expression:
+constant-access-expression:
    qualified-name
 
-literal:
+literal:
    integer-literal
    floating-literal
    string-literal
 
-intrinsic:
+intrinsic:
    intrinsic-construct
    intrinsic-operator
 
-intrinsic-construct:
+intrinsic-construct:
    echo-intrinsic
    list-intrinsic
    unset-intrinsic
 
-intrinsic-operator:
+intrinsic-operator:
    empty-intrinsic
    eval-intrinsic
    exit-intrinsic
    isset-intrinsic
    print-intrinsic
 
-echo-intrinsic:
+echo-intrinsic:
    echo   expression-list
 
-expression-list:
+expression-list:
    expression
    expression-list   ,   expression
 
-empty-intrinsic:
+empty-intrinsic:
    empty   (   expression   )
 
-eval-intrinsic:
+eval-intrinsic:
    eval   (   expression   )
 
-exit-intrinsic:
+exit-intrinsic:
    exit
    exit   (   expressionopt   )
    die
    die   (   expressionopt   )
 
-isset-intrinsic:
+isset-intrinsic:
    isset   (   variable-list   )
 
-variable-list:
+variable-list:
    variable
    variable-list   ,   variable
 
-list-intrinsic:
+list-intrinsic:
    list   (   list-expression-list   )
 
-list-expression-list:
+list-expression-list:
    unkeyed-list-expression-list
    keyed-list-expression-list   ,opt
 
-unkeyed-list-expression-list:
+unkeyed-list-expression-list:
    list-or-variable
    ,
    unkeyed-list-expression-list   ,   list-or-variableopt
 
-keyed-list-expression-list:
+keyed-list-expression-list:
    expression   =>   list-or-variable
    keyed-list-expression-list   ,   expression   =>   list-or-variable
 
-list-or-variable:
+list-or-variable:
    list-intrinsic
    expression
 
-print-intrinsic:
+print-intrinsic:
    print   expression
 
-unset-intrinsic:
+unset-intrinsic:
    unset   (   variable-list   )
 
-anonymous-function-creation-expression:
+anonymous-function-creation-expression:
    static?   function   &opt   (   parameter-declaration-listopt   )   return-typeopt   anonymous-function-use-clauseopt   compound-statement
 
-anonymous-function-use-clause:
+anonymous-function-use-clause:
    use   (   use-variable-name-list   )
 
-use-variable-name-list:
+use-variable-name-list:
    &opt   variable-name
    use-variable-name-list   ,   &opt   variable-name
 
-postfix-expression:
+postfix-expression:
    primary-expression
    clone-expression
    object-creation-expression
@@ -463,99 +463,99 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
    postfix-decrement-expression
    exponentiation-expression
 
-clone-expression:
+clone-expression:
    clone   expression
 
-object-creation-expression:
+object-creation-expression:
    new   class-type-designator   (   argument-expression-listopt   )
    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:
+class-type-designator:
    qualified-name
    expression
 
-array-creation-expression:
+array-creation-expression:
    array   (   array-initializeropt   )
    [   array-initializeropt   ]
 
-array-initializer:
+array-initializer:
    array-initializer-list   ,opt
 
-array-initializer-list:
+array-initializer-list:
    array-element-initializer
    array-element-initializer   ,   array-initializer-list
 
-array-element-initializer:
+array-element-initializer:
    &opt   element-value
    element-key   =>   &opt   element-value
 
-element-key:
+element-key:
    expression
 
-element-value:
+element-value:
    expression
 
-subscript-expression:
+subscript-expression:
    dereferencable-expression   [   expressionopt   ]
    dereferencable-expression   {   expression   }   <b>[Deprecated form]</b>
 
-function-call-expression:
+function-call-expression:
    qualified-name   (   argument-expression-listopt   )
    callable-expression   (   argument-expression-listopt   )
 
-argument-expression-list:
+argument-expression-list:
    argument-expression
    argument-expression-list   ,   argument-expression
 
-argument-expression:
+argument-expression:
    variadic-unpacking
    assignment-expression
 
-variadic-unpacking:
+variadic-unpacking:
    ...   assignment-expression
 
-member-access-expression:
+member-access-expression:
    dereferencable-expression   ->   member-name
 
-member-name:
+member-name:
    name
    simple-variable
    {   expression   }
 
-member-call-expression:
+member-call-expression:
    dereferencable-expression   ->   member-name   (   argument-expression-listopt   )
 
-postfix-increment-expression:
+postfix-increment-expression:
    variable   ++
 
-postfix-decrement-expression:
+postfix-decrement-expression:
    variable   --
 
-scoped-property-access-expression:
+scoped-property-access-expression:
    scope-resolution-qualifier   ::   simple-variable
 
-scoped-call-expression:
+scoped-call-expression:
    scope-resolution-qualifier   ::   member-name   (   argument-expression-listopt   )
 
-class-constant-access-expression:
+class-constant-access-expression:
    scope-resolution-qualifier   ::   name
 
-scope-resolution-qualifier:
+scope-resolution-qualifier:
    relative-scope
    qualified-name
    dereferencable-expression
 
-relative-scope:
+relative-scope:
    self
    parent
    static
 
-exponentiation-expression:
+exponentiation-expression:
    expression   **   expression
 
-unary-expression:
+unary-expression:
    postfix-expression
    prefix-increment-expression
    prefix-decrement-expression
@@ -564,61 +564,61 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
    shell-command-expression
    cast-expression
 
-prefix-increment-expression:
+prefix-increment-expression:
    ++   variable
 
-prefix-decrement-expression:
+prefix-decrement-expression:
    --   variable
 
-unary-op-expression:
+unary-op-expression:
    unary-operator   cast-expression
 
-unary-operator: one of
+unary-operator: one of
    +   -   !   ~
 
-error-control-expression:
+error-control-expression:
    @   expression
 
-shell-command-expression:
+shell-command-expression:
    `   dq-char-sequenceopt   `
 
-cast-expression:
+cast-expression:
    unary-expression
    (   cast-type   )   expression
 
-cast-type: one of
+cast-type: one of
    array   binary   bool   boolean   double   int   integer   float   object
    real   string   unset
 
-instanceof-expression:
+instanceof-expression:
    unary-expression
    instanceof-subject   instanceof   instanceof-type-designator
 
-instanceof-subject:
+instanceof-subject:
    expression
 
-instanceof-type-designator:
+instanceof-type-designator:
    qualified-name
    expression
 
-multiplicative-expression:
+multiplicative-expression:
    instanceof-expression
    multiplicative-expression   *   instanceof-expression
    multiplicative-expression   /   instanceof-expression
    multiplicative-expression   %   instanceof-expression
 
-additive-expression:
+additive-expression:
    multiplicative-expression
    additive-expression   +   multiplicative-expression
    additive-expression   -   multiplicative-expression
    additive-expression   .   multiplicative-expression
 
-shift-expression:
+shift-expression:
    additive-expression
    shift-expression   <<   additive-expression
    shift-expression   >>   additive-expression
 
-relational-expression:
+relational-expression:
    shift-expression
    relational-expression   <   shift-expression
    relational-expression   >   shift-expression
@@ -626,7 +626,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
    relational-expression   >=   shift-expression
    relational-expression   <=>   shift-expression
 
-equality-expression:
+equality-expression:
    relational-expression
    equality-expression   ==   relational-expression
    equality-expression   !=   relational-expression
@@ -634,97 +634,97 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
    equality-expression   ===   relational-expression
    equality-expression   !==   relational-expression
 
-bitwise-AND-expression:
+bitwise-AND-expression:
    equality-expression
    bitwise-AND-expression   &   equality-expression
 
-bitwise-exc-OR-expression:
+bitwise-exc-OR-expression:
    bitwise-AND-expression
    bitwise-exc-OR-expression   ^   bitwise-AND-expression
 
-bitwise-inc-OR-expression:
+bitwise-inc-OR-expression:
    bitwise-exc-OR-expression
    bitwise-inc-OR-expression   |   bitwise-exc-OR-expression
 
-logical-AND-expression-1:
+logical-AND-expression-1:
    bitwise-inc-OR-expression
    logical-AND-expression-1   &&   bitwise-inc-OR-expression
 
-logical-inc-OR-expression-1:
+logical-inc-OR-expression-1:
    logical-AND-expression-1
    logical-inc-OR-expression-1   ||   logical-AND-expression-1
 
-conditional-expression:
+conditional-expression:
    logical-inc-OR-expression-1
    logical-inc-OR-expression-1   ?   expressionopt   :   conditional-expression
 
-coalesce-expression:
+coalesce-expression:
    logical-inc-OR-expression-1   ??   expression
 
-assignment-expression:
+assignment-expression:
    conditional-expression
    coalesce-expression
    simple-assignment-expression
    byref-assignment-expression
    compound-assignment-expression
 
-simple-assignment-expression:
+simple-assignment-expression:
    variable   =   assignment-expression
    list-intrinsic   =   assignment-expression
 
-byref-assignment-expression:
+byref-assignment-expression:
    variable   =   &   assignment-expression
 
-compound-assignment-expression:
+compound-assignment-expression:
    variable   compound-assignment-operator   assignment-expression
 
-compound-assignment-operator: one of
+compound-assignment-operator: one of
    **=   *=   /=   %=   +=   -=   .=   <<=   >>=   &=   ^=   |=
 
-logical-AND-expression-2:
+logical-AND-expression-2:
    assignment-expression
    logical-AND-expression-2   and   assignment-expression
 
-logical-exc-OR-expression:
+logical-exc-OR-expression:
    logical-AND-expression-2
    logical-exc-OR-expression   xor   logical-AND-expression-2
 
-logical-inc-OR-expression-2:
+logical-inc-OR-expression-2:
    logical-exc-OR-expression
    logical-inc-OR-expression-2   or   logical-exc-OR-expression
 
-yield-expression:
+yield-expression:
    logical-inc-OR-expression-2
    yield   array-element-initializer
    yield from   expression
 
-expression:
+expression:
    yield-expression
    include-expression
    include-once-expression
    require-expression
    require-once-expression
 
-include-expression:
+include-expression:
    include   expression
 
-include-once-expression:
+include-once-expression:
    include_once   expression
 
-require-expression:
+require-expression:
    require   expression
 
-require-once-expression:
+require-once-expression:
    require_once   expression
 
-constant-expression:
+constant-expression:
    expression
 
###Statements
-statement:
+statement:
    compound-statement
    named-label-statement
    expression-statement
@@ -743,155 +743,155 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
    global-declaration
    function-static-declaration
 
-compound-statement:
+compound-statement:
    {   statement-listopt   }
 
-statement-list:
+statement-list:
    statement
    statement-list   statement
 
-named-label-statement:
+named-label-statement:
    name   ;   statement
 
-expression-statement:
+expression-statement:
    expressionopt   ;
 
-selection-statement:
+selection-statement:
    if-statement
    switch-statement
 
-if-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-clauses-1:
    elseif-clause-1
    elseif-clauses-1   elseif-clause-1
 
-elseif-clause-1:
+elseif-clause-1:
    elseif   (   expression   )   statement
 
-else-clause-1:
+else-clause-1:
    else   statement
 
-elseif-clauses-2:
+elseif-clauses-2:
    elseif-clause-2
    elseif-clauses-2   elseif-clause-2
 
-elseif-clause-2:
+elseif-clause-2:
    elseif   (   expression   )   :   statement-list
 
-else-clause-2:
+else-clause-2:
    else   :   statement-list
 
-switch-statement:
+switch-statement:
    switch   (   expression   )   {   case-statementsopt   }
    switch   (   expression   )   :   case-statementsopt   endswitch;
 
-case-statements:
+case-statements:
    case-statement   case-statementsopt
    default-statement   case-statementsopt
 
-case-statement:
+case-statement:
    case   expression   case-default-label-terminator   statement-listopt
 
-default-statement:
+default-statement:
    default   case-default-label-terminator   statement-listopt
 
-case-default-label-terminator:
+case-default-label-terminator:
    :
    ;
 
-iteration-statement:
+iteration-statement:
    while-statement
    do-statement
    for-statement
    foreach-statement
 
-while-statement:
+while-statement:
    while   (   expression   )   statement
    while   (   expression   )   :   statement-list   endwhile   ;
 
-do-statement:
+do-statement:
    do   statement   while   (   expression   )   ;
 
-for-statement:
+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-initializer:
    for-expression-group
 
-for-control:
+for-control:
    for-expression-group
 
-for-end-of-loop:
+for-end-of-loop:
    for-expression-group
 
-for-expression-group:
+for-expression-group:
    expression
    for-expression-group   ,   expression
 
-foreach-statement:
+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:
+foreach-collection-name:
    expression
 
-foreach-key:
+foreach-key:
    expression   =>
 
-foreach-value:
+foreach-value:
    &opt   expression
    list-intrinsic
 
-jump-statement:
+jump-statement:
    goto-statement
    continue-statement
    break-statement
    return-statement
    throw-statement
 
-goto-statement:
+goto-statement:
    goto   name   ;
 
-continue-statement:
+continue-statement:
    continue   breakout-levelopt   ;
 
-breakout-level:
+breakout-level:
    integer-literal
 
-break-statement:
+break-statement:
    break   breakout-levelopt   ;
 
-return-statement:
+return-statement:
    return   expressionopt   ;
 
-throw-statement:
+throw-statement:
    throw   expression   ;
 
-try-statement:
+try-statement:
    try   compound-statement   catch-clauses
    try   compound-statement   finally-clause
    try   compound-statement   catch-clauses   finally-clause
 
-catch-clauses:
+catch-clauses:
    catch-clause
    catch-clauses   catch-clause
 
-catch-clause:
+catch-clause:
    catch   (   qualified-name   variable-name   )   compound-statement
 
-finally-clause:
+finally-clause:
    finally   compound-statement
 
-declare-statement:
+declare-statement:
    declare   (   declare-directive   )   statement
    declare   (   declare-directive   )   :   statement-list   enddeclare   ;
    declare   (   declare-directive   )   ;
 
-declare-directive:
+declare-directive:
    ticks   =   literal
    encoding   =   literal
    strict_types   =   literal
@@ -900,72 +900,72 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 ###Functions
 
 
-function-definition:
+function-definition:
    function-definition-header   compound-statement
 
-function-definition-header:
+function-definition-header:
    function   &opt   name   (   parameter-declaration-listopt   )   return-typeopt
 
-parameter-declaration-list:
+parameter-declaration-list:
    simple-parameter-declaration-list
    variadic-declaration-list
 
-simple-parameter-declaration-list:
+simple-parameter-declaration-list:
    parameter-declaration
    parameter-declaration-list   ,   parameter-declaration
 
-variadic-declaration-list:
+variadic-declaration-list:
    simple-parameter-declaration-list   ,   variadic-parameter
    variadic-parameter
 
-parameter-declaration:
+parameter-declaration:
    type-declarationopt   &opt   variable-name   default-argument-specifieropt
 
-variadic-parameter:
+variadic-parameter:
    type-declarationopt   &opt   ...   variable-name
 
-return-type:
+return-type:
    :   type-declaration
    :   void
 
-type-declaration:
+type-declaration:
    array
    callable
    scalar-type
    qualified-name
 
-scalar-type:
+scalar-type:
    bool
    float
    int
    string
 
-default-argument-specifier:
+default-argument-specifier:
    =   constant-expression
 
###Classes
-class-declaration:
+class-declaration:
    class-modifieropt   class   name   class-base-clauseopt   class-interface-clauseopt   {   class-member-declarationsopt   }
 
-class-modifier:
+class-modifier:
    abstract
    final
 
-class-base-clause:
+class-base-clause:
    extends   qualified-name
 
-class-interface-clause:
+class-interface-clause:
    implements   qualified-name
    class-interface-clause   ,   qualified-name
 
-class-member-declarations:
+class-member-declarations:
    class-member-declaration
    class-member-declarations   class-member-declaration
 
-class-member-declaration:
+class-member-declaration:
    class-const-declaration
    property-declaration
    method-declaration
@@ -973,80 +973,80 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
    destructor-declaration
    trait-use-clause
 
-const-declaration:
+const-declaration:
    const   const-elements   ;
 
-class-const-declaration:
+class-const-declaration:
    visibility-modifieropt   const   const-elements   ;
 
-const-elements:
+const-elements:
    const-element
    const-elements   const-element
 
-const-element:
+const-element:
    name   =   constant-expression
 
-property-declaration:
+property-declaration:
    property-modifier   property-elements   ;
 
-property-modifier:
+property-modifier:
    var
    visibility-modifier   static-modifieropt
    static-modifier   visibility-modifieropt
 
-visibility-modifier:
+visibility-modifier:
    public
    protected
    private
 
-static-modifier:
+static-modifier:
    static
 
-property-elements:
+property-elements:
    property-element
    property-elements   property-element
 
-property-element:
+property-element:
    variable-name   property-initializeropt   ;
 
-property-initializer:
+property-initializer:
    =   constant-expression
 
-method-declaration:
+method-declaration:
    method-modifiersopt   function-definition
    method-modifiers   function-definition-header   ;
 
-method-modifiers:
+method-modifiers:
    method-modifier
    method-modifiers   method-modifier
 
-method-modifier:
+method-modifier:
    visibility-modifier
    static-modifier
    class-modifier
 
-constructor-declaration:
+constructor-declaration:
    method-modifiers   function   &opt   __construct   (   parameter-declaration-listopt   )   compound-statement
 
-destructor-declaration:
+destructor-declaration:
    method-modifiers   function   &opt   __destruct   (   )   compound-statement
 
###Interfaces
-interface-declaration:
+interface-declaration:
    interface   name   interface-base-clauseopt   {   interface-member-declarationsopt   }
 
-interface-base-clause:
+interface-base-clause:
    extends   qualified-name
    interface-base-clause   ,   qualified-name
 
-interface-member-declarations:
+interface-member-declarations:
    interface-member-declaration
    interface-member-declarations   interface-member-declaration
 
-interface-member-declaration:
+interface-member-declaration:
    class-const-declaration
    method-declaration
 
@@ -1054,47 +1054,47 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# ###Traits
-trait-declaration:
+trait-declaration:
    trait   name   {   trait-member-declarationsopt   }
 
-trait-member-declarations:
+trait-member-declarations:
    trait-member-declaration
    trait-member-declarations   trait-member-declaration
 
-trait-member-declaration:
+trait-member-declaration:
    property-declaration
    method-declaration
    constructor-declaration
    destructor-declaration
    trait-use-clauses
 
-trait-use-clauses:
+trait-use-clauses:
    trait-use-clause
    trait-use-clauses   trait-use-clause
 
-trait-use-clause:
+trait-use-clause:
    use   trait-name-list   trait-use-specification
 
-trait-name-list:
+trait-name-list:
    qualified-name
    trait-name-list   ,   qualified-name
 
-trait-use-specification:
+trait-use-specification:
    ;
    {   trait-select-and-alias-clausesopt   }
 
-trait-select-and-alias-clauses:
+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-and-alias-clause:
    trait-select-insteadof-clause   ;
    trait-alias-as-clause   ;
 
-trait-select-insteadof-clause:
+trait-select-insteadof-clause:
    name   insteadof   name
 
-trait-alias-as-clause:
+trait-alias-as-clause:
    name   as   visibility-modifieropt   name
    name   as   visibility-modifier   nameopt
 
@@ -1102,40 +1102,40 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# ###Namespaces
-namespace-definition:
+namespace-definition:
    namespace   name   ;
    namespace   nameopt   compound-statement
 
-namespace-use-declaration:
+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-clauses:
    namespace-use-clause
    namespace-use-clauses   ,   namespace-use-clause
 
-namespace-use-clause:
+namespace-use-clause:
    qualified-name   namespace-aliasing-clauseopt
 
-namespace-aliasing-clause:
+namespace-aliasing-clause:
    as   name
 
-namespace-function-or-const:
+namespace-function-or-const:
    function
    const
 
-namespace-use-group-clauses-1:
+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-use-group-clause-1:
    namespace-name   namespace-aliasing-clauseopt
 
-namespace-use-group-clauses-2:
+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-use-group-clause-2:
    namespace-function-or-constopt   namespace-name   namespace-aliasing-clauseopt
 
diff --git a/tools/grammar_util.php b/tools/grammar_util.php index 14cf44e5..c25d1657 100644 --- a/tools/grammar_util.php +++ b/tools/grammar_util.php @@ -83,7 +83,7 @@ public function __construct($name, $isLexical, $isOneOf, $rules) { public function render($ctx) { $sep = $this->isLexical ? '::' : ':'; $oneOf = $this->isOneOf ? ' one of' : ''; - $result = "name\">$this->name$sep$oneOf"; + $result = "name\">$this->name$sep$oneOf"; foreach ($this->rules as $rule) { $result .= "\n " . $rule->render($ctx); } From 248ec2865a64827570a6894c732f5e6b481e0d95 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 2 Dec 2016 09:13:57 +0100 Subject: [PATCH 063/146] Add the `iterable` pseudo-type. See https://wiki.php.net/rfc/iterable. --- spec/09-lexical-structure.md | 2 +- spec/13-functions.md | 12 ++++++++---- spec/19-grammar.md | 1 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index ae8d4a22..7d11b777 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -355,7 +355,7 @@ Unless stated otherwise ([functions](13-functions.md#function-definitions), Names beginning with two underscores (__) are reserved by the PHP language and should not be defined by the user code. -The following names cannot be used as the names of classes, interfaces, or traits: `bool`, `FALSE`, `float`, `int`, `NULL`, `string`, `TRUE`, and `void`. +The following names cannot be used as the names of classes, interfaces, or traits: `bool`, `FALSE`, `float`, `int`, `NULL`, `string`, `TRUE`, `iterable`, and `void`. The following names are reserved for future use and should not be used as the names of classes, interfaces, or traits: `mixed`, `numeric`, `object`, and `resource`. diff --git a/spec/13-functions.md b/spec/13-functions.md index 4311b041..1d3ff818 100644 --- a/spec/13-functions.md +++ b/spec/13-functions.md @@ -79,6 +79,7 @@ return-type: type-declaration: 'array' 'callable' + 'iterable' scalar-type qualified-name @@ -124,6 +125,7 @@ default-argument-specifier: type-declaration: array callable + iterable scalar-type qualified-name @@ -193,10 +195,12 @@ By default, a parameter will accept an argument of any type. However, by specifying a *type-declaration*, the types of argument accepted can be restricted. By specifying `array`, only an argument of the `array` type is accepted. By specifying `callable`, only an argument designating a -function (see below) is accepted. By specifying *qualified-name*, only an instance -of a class having that type, or being derived from that type, are -accepted, or only an instance of a class that implements that interface -type directly or indirectly is accepted. The check is the same as for [`instanceof` operator](10-expressions.md#instanceof-operator). +function (see below) is accepted. By specifying `iterable`, only an argument that +is of type `array` or an object implementing the `Traversable` interface is accepted. +By specifying *qualified-name*, only an instance of a class having that type, +or being derived from that type, are accepted, or only an instance of a class that +implements that interface type directly or indirectly is accepted. The check is the +same as for [`instanceof` operator](10-expressions.md#instanceof-operator). `callable` pseudo-type accepts the following: * A string value containing the name of a function defined at the moment of the call. diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 53ec956b..19750707 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -931,6 +931,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# type-declaration: array callable + iterable scalar-type qualified-name From 44e1b9afa049975e898667b3819555041e383406 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 2 Dec 2016 17:32:45 +0100 Subject: [PATCH 064/146] Fix typo in anon func grammar --- spec/10-expressions.md | 4 ++-- spec/19-grammar.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 3fc913ae..755f243b 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -812,7 +812,7 @@ unset($x->m); // if m is a dynamic property, $x->__unset("m") is called [VStore int 123]<---------------------------------------+ ``` -###Argument Passing +### Argument Passing Argument passing is defined in terms of [simple assignment](#assignment) or [byRef assignment](#byref-assignment-for-scalar-types-with-local-variables), depending on how the parameter is declared. That is, passing an argument to a function having a corresponding parameter is like assigning that argument to that parameter. The @@ -1213,7 +1213,7 @@ function call situations involving missing arguments or undefined variable arguments are discussed in section describing [the function call operator](10-expressions.md#function-call-operator). -###Value Returning +### Value Returning Returning a value from a function is defined in terms of [simple assignment](#assignment) or [byRef assignment](#byref-assignment-for-scalar-types-with-local-variables), depending on how the function is declared. That is, returning a value from a function to its caller is like assigning that value to the user of the caller's return @@ -1248,7 +1248,7 @@ Passing function's return to another function is considered the same as assignin the value to the corresponding function's parameter, with byRef parameters treated as byRef assignments. -###Cloning objects +### Cloning objects When an object instance is allocated, operator [`new`](10-expressions.md#the-new-operator) returns a handle that points to that object. As described [above](#value-assignment-of-objects-to-a-local-variable), value assignment of a handle to an object does not copy the object HStore itself. Instead, it creates a copy of the handle. @@ -1294,7 +1294,7 @@ copy*. If a *deep copy* of an object is desired, the programmer must achieve this manually by using the [method `__clone`](14-classes.md#method-__clone) which is called after the initial shallow copy has been performed. -##Scope +## Scope The same name can designate different things at different places in a program. For each different thing that a name designates, that name is @@ -1346,7 +1346,7 @@ When a [trait](16-traits.md#general) is used by a class or an interface, the [tr members](16-traits.md#trait-declarations) take on the class scope of a member of that class or interface. -##Storage Duration +## Storage Duration The lifetime of a variable is the time during program execution that storage for that variable is guaranteed to exist. This lifetime is diff --git a/spec/05-types.md b/spec/05-types.md index fbf0c360..676480ee 100644 --- a/spec/05-types.md +++ b/spec/05-types.md @@ -1,6 +1,6 @@ -#Types +# Types -##General +## General The meaning of a value is determined by its *type*. PHP's types are categorized as *scalar types* and *composite types*. The scalar types @@ -26,9 +26,9 @@ The same variable can contain values of different types at different times. Useful library functions for interrogating and using type information include [`gettype`](http://www.php.net/gettype), [`is_type`](http://www.php.net/is_type), [`settype`](http://www.php.net/settype), and [`var_dump`](http://www.php.net/var_dump). -##Scalar Types +## Scalar Types -###General +### General The integer and floating-point types are collectively known as *arithmetic types*. The library function [`is_numeric`](http://www.php.net/is_numeric) indicates if @@ -43,7 +43,7 @@ convertible to scalar types (this is currently available only to internal classe Such object types together with scalar types are called *scalar-compatible types*. Note that the same object type may be scalar-compatible for one operation but not for another. -###The Boolean Type +### The Boolean Type The Boolean type is `bool`, for which the name `boolean` is a synonym. This type is capable of storing two distinct values, which correspond to the @@ -53,7 +53,7 @@ The internal representation of this type and its values is unspecified. The library function [`is_bool`](http://www.php.net/is_bool) indicates if a given value has type `bool`. -###The Integer Type +### The Integer Type There is one integer type, `int`, for which the name `integer` is a synonym. This type is binary, signed, and uses twos-complement representation for @@ -77,7 +77,7 @@ characteristics about type `int`. The library function [`is_int`](http://www.php.net/is_int) indicates if a given value has type `int`. -###The Floating-Point Type +### The Floating-Point Type There is one floating-point type, `float`, for which the names `double` and `real` are synonyms. The `float` type must support at least the range and @@ -90,7 +90,7 @@ indicates if a given floating-point value is infinite. The library function [`is_nan`](http://www.php.net/is_nan) indicates if a given floating-point value is a `NaN`. -###The String Type +### The String Type A string is a set of contiguous bytes that represents a sequence of zero or more characters. @@ -166,16 +166,16 @@ assignment, which involves the simple assignment [operator =](10-expressions.md# The library function [`is_string`](http://www.php.net/is_string) indicates if a given value has type string. -###The Null Type +### The Null Type The null type has only one possible value, [`NULL`](06-constants.md#core-predefined-constants). The representation of this type and its value is unspecified. The library function [`is_null`](http://www.php.net/is_null) indicates if a given value is `NULL`. -##Composite Types +## Composite Types -###The Array Type +### The Array Type An array is a data structure that contains a collection of zero or more elements whose values are accessed through keys that are of type `int` or @@ -184,7 +184,7 @@ elements whose values are accessed through keys that are of type `int` or The library function [`is_array`](http://www.php.net/is_array) indicates if a given value is an array. -###Objects +### Objects An *object* is an instance of a [class](14-classes.md#classes). Each distinct [*class-declaration*](14-classes.md#class-declarations) defines a new class type, and each class @@ -194,7 +194,7 @@ The library function [`is_object`](http://www.php.net/is_object) indicates if a object, and the library function [`get_class`](http://php.net/manual/function.get-class.php) indicates the name of an object's class. -###Resources +### Resources A [*resource*](http://php.net/manual/language.types.resource.php) is a descriptor to some sort of external entity. Examples include diff --git a/spec/06-constants.md b/spec/06-constants.md index ca8b84cf..76e2c1db 100644 --- a/spec/06-constants.md +++ b/spec/06-constants.md @@ -1,6 +1,6 @@ -#Constants +# Constants -##General +## General A *constant* is a [named](09-lexical-structure.md#names) value. Once defined, the value of the constant can not be changed. @@ -34,7 +34,7 @@ define('COEFFICIENT_1', 2.345, TRUE); // define a case-insensitive d-constant define('FAILURE', FALSE, FALSE); // define a case-sensitive d-constant ``` -##Context-Dependent Constants +## Context-Dependent Constants The following constants—sometimes referred to as *magic constants*—are automatically available to all scripts; their values are not fixed and they are case-insensitive: @@ -53,7 +53,7 @@ automatically available to all scripts; their values are not fixed and they are Constant names beginning with __ are reserved for future use by the Engine. -##Core Predefined Constants +## Core Predefined Constants The following constants are automatically available to all scripts; they are case-sensitive with the exception of `NULL`, `TRUE` and `FALSE`: @@ -134,7 +134,7 @@ Constant Name | Description The members of the `E_*` family have values that are powers of 2, so they can be combined meaningfully using bitwise operators. -##User-Defined Constants +## User-Defined Constants A constant may be defined inside or outside of functions, inside a [class](14-classes.md#constants), or inside an [interface](15-interfaces.md#constants). diff --git a/spec/07-variables.md b/spec/07-variables.md index 990f0bcc..1e810998 100644 --- a/spec/07-variables.md +++ b/spec/07-variables.md @@ -1,6 +1,6 @@ -#Variables +# Variables -##General +## General A *variable* is a named area of data storage that contains a PHP value. A variable is represented by a [VSlot](04-basic-concepts.md#general). A variable is created by [assigning a value](04-basic-concepts.md#assignment) to it. A variable is destroyed by *unsetting* it, either by an explicit call to the intrinsic [`unset`](10-expressions.md#unset), or by the Engine. The intrinsic [`isset`](10-expressions.md#isset) tests if a given variable exists and is not set to `NULL`. @@ -28,9 +28,9 @@ The following kinds of variable may exist in a script: - [Static class property](#static-properties). - [Class and interface constant](#class-and-interface-constants). -##Kinds of Variables +## Kinds of Variables -###Constants +### Constants **Syntax** @@ -89,7 +89,7 @@ echo Exception::MESSAGE; // undefined class constant. Throws an exception ``` -###Local Variables +### Local Variables **Syntax** @@ -213,7 +213,7 @@ $l = $k; // a VSlot for $l was created and the value of $k (which is NULL) ``` -###Array Elements +### Array Elements **Syntax** @@ -262,7 +262,7 @@ $b = &colors[100]; // a VSlot for $b is created which points to the array // NULL is assigned to it. A notice is *not* emitted. ``` -###Function Statics +### Function Statics **Syntax** @@ -356,7 +356,7 @@ f(); echo "\$fs = $fs\n"; // $fs = 3 ``` -###Global Variables +### Global Variables **Syntax** @@ -445,26 +445,26 @@ function f() Be also aware that declaring a variable global can hide a local variable and/or a function static with the same name. See [static variables section](#hidingNotice) for an example. -###Instance Properties +### Instance Properties These are described in [class instance properties section](14-classes.md#properties). They have class [scope](04-basic-concepts.md#scope) of the defining class and allocated [storage duration](04-basic-concepts.md#storage-duration). Access to the instance properties is governed by [visibility rules](14-classes.md#general). -###Static Properties +### Static Properties These are described in [class static properties section](14-classes.md#properties). They have class [scope](04-basic-concepts.md#scope) of the defining class and static [storage duration](04-basic-concepts.md#storage-duration). Access to the static properties is governed by [visibility rules](14-classes.md#general). -###Class and Interface Constants +### Class and Interface Constants These are described in [class constants section](14-classes.md#constants) and [interface constants section](15-interfaces.md#constants). They have class [scope](04-basic-concepts.md#scope) of the defining class or interface and static [storage duration](04-basic-concepts.md#storage-duration). -##Predefined Variables +## Predefined Variables The following global variables are available to all scripts: diff --git a/spec/08-conversions.md b/spec/08-conversions.md index 51ba0a4c..4870b928 100644 --- a/spec/08-conversions.md +++ b/spec/08-conversions.md @@ -1,6 +1,6 @@ -#Conversions +# Conversions -##General +## General Explicit type conversion is performed using the [cast operator](10-expressions.md#cast-operator). If an operation or language construct expects operand of one type and a value of another type is given, @@ -12,7 +12,7 @@ result are the same as the type and value of the expression. Conversions to `resource` and `null` types can not be performed. -##Converting to Boolean Type +## Converting to Boolean Type The [result type] (http://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting) is [`bool`](05-types.md#the-boolean-type). @@ -34,7 +34,7 @@ If the source is a resource, the result value is `TRUE`. The library function [`boolval`](http://www.php.net/boolval) allows values to be converted to `bool`. -##Converting to Integer Type +## Converting to Integer Type The [result type](http://www.php.net/manual/en/language.types.integer.php#language.types.integer.casting) is [`int`](05-types.md#the-integer-type). @@ -84,7 +84,7 @@ If the source is a resource, the result is the resource's unique ID. The library function [`intval`](http://php.net/manual/function.intval.php) allows values to be converted to `int`. -##Converting to Floating-Point Type +## Converting to Floating-Point Type The [result type](http://www.php.net/manual/en/language.types.float.php#language.types.float.casting) is [`float`](05-types.md#the-floating-point-type). @@ -110,7 +110,7 @@ For sources of all other types, the conversion result is obtained by first The library function [`floatval`](http://www.php.net/floatval) allows values to be converted to float. -##Converting to String Type +## Converting to String Type The [result type](http://www.php.net/manual/en/language.types.string.php#language.types.string.casting) is [`string`](05-types.md#the-string-type). @@ -136,7 +136,7 @@ implementation-defined string. The library function [`strval`](http://www.php.net/strval) allows values to be converted to string. -##Converting to Array Type +## Converting to Array Type The [result type](http://www.php.net/manual/en/language.types.array.php#language.types.array.casting) is [`array`](05-types.md#the-array-type). @@ -167,7 +167,7 @@ where *name* is that of the property. The value for each key is that from the corresponding property, or `NULL` if the property was not initialized. -##Converting to Object Type +## Converting to Object Type The [result type](http://www.php.net/manual/en/language.types.object.php#language.types.object.casting) is [`object`](05-types.md#objects). diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index f06cbe7f..262b3041 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -1,6 +1,6 @@ -#Lexical Structure +# Lexical Structure -##Scripts +## Scripts A [script](04-basic-concepts.md#program-structure) is an ordered sequence of characters. Typically, a script has a one-to-one correspondence with a file in a file system, but @@ -22,7 +22,7 @@ encoding form (as defined by the Unicode standard), and transform them into a sequence of characters. Implementations can choose to accept and transform additional character encoding schemes. -##Grammars +## Grammars This specification shows the syntax of the PHP programming language using two grammars. The *lexical grammar* defines how source @@ -77,9 +77,9 @@ hexadecimal-digit-example:: one of A B C D E F
-##Lexical analysis +## Lexical analysis -###General +### General The production *input-file* is the root of the lexical structure for a script. Each script must conform to this production. @@ -121,7 +121,7 @@ Lexical processing always results in the creation of the longest possible lexical element. (For example, `$a+++++$b` must be parsed as `$a++ ++ +$b`, which syntactically is invalid). -###Comments +### Comments Two forms of comments are supported: *delimited comments* and *single-line comments*. @@ -198,7 +198,7 @@ space](#white-space) can occur. (For example; During tokenizing, an implementation can treat a delimited comment as though it was white space. -###White Space +### White Space White space consists of an arbitrary combination of one or more new-line, space and horizontal tab characters. @@ -232,9 +232,9 @@ white-space-character:: The space and horizontal tab characters are considered *horizontal white-space characters*. -###Tokens +### Tokens -####General +#### General There are several kinds of source *tokens*: @@ -262,7 +262,7 @@ token:: operator-or-punctuator
-####Names +#### Names **Syntax** @@ -382,7 +382,7 @@ interface ICollection { /*...*/ } An implementation is discouraged from placing arbitrary restrictions on name lengths. -####Keywords +#### Keywords A *keyword* is a name-like sequence of characters that is reserved, and cannot be used as a name. @@ -421,11 +421,11 @@ Note carefully that `yield from` is a single token that contains whitespace. How Also, all [*magic constants*](06-constants.md#context-dependent-constants) are also treated as keywords. -####Literals +#### Literals The source code representation of a value is called a *literal*. -#####Integer Literals +##### Integer Literals **Syntax** @@ -566,7 +566,7 @@ On an implementation using 32-bit int representation 0x80000000 -> 2147483648 (too big for int, so is a float) ``` -#####Floating-Point Literals +##### Floating-Point Literals **Syntax** @@ -632,7 +632,7 @@ A floating point literal is always a constant expression. $values = array(1.23, 3e12, 543.678E-23); ``` -#####String Literals +##### String Literals **Syntax** @@ -659,7 +659,7 @@ some fashion. The delimiters are not part of the literal's content. The type of a string literal is `string`. -######Single-Quoted String Literals +###### Single-Quoted String Literals **Syntax** @@ -722,7 +722,7 @@ A single-quoted string literal is always a constant expression. 'Can embed a single quote (\') and a backslash (\\) like this' ``` -######Double-Quoted String Literals +###### Double-Quoted String Literals **Syntax** @@ -947,7 +947,7 @@ $myC = new C(); echo "\$myC->p1 = >$myC->p1<\n"; // → $myC->p1 = >2< ``` -######Heredoc String Literals +###### Heredoc String Literals **Syntax** @@ -1055,7 +1055,7 @@ echo ">$s<"; // Some more text< ``` -######Nowdoc String Literals +###### Nowdoc String Literals **Syntax** @@ -1100,7 +1100,7 @@ echo ">$s<\n\n"; // Some more text< ``` -####Operators and Punctuators +#### Operators and Punctuators **Syntax** diff --git a/spec/10-expressions.md b/spec/10-expressions.md index f886082c..6c802724 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -1,6 +1,6 @@ -#Expressions +# Expressions -##General +## General An *expression* involves one or more terms and zero or more operators. @@ -83,9 +83,9 @@ of `return $a++;` and `return ++$a;`, it is obvious what value must be returned in each case, but if `$a` is a variable local to the enclosing function, `$a` need not actually be incremented. -##Primary Expressions +## Primary Expressions -###General +### General **Syntax** @@ -118,7 +118,7 @@ primary-expression: The type and value of parenthesized expression are identical to those of the un-parenthesized expression. -###Simple Variable +### Simple Variable **Syntax** @@ -176,7 +176,7 @@ function f1 () { return 2.5; } ${1 + f1()} = 1000; // equivalent to ${3.5} = 1000 ``` -###Dereferencable expression +### Dereferencable expression **Syntax** @@ -219,7 +219,7 @@ A *dereferencable-expression* can be used as the left hand side of dereferencing as `[]`, `->` and `::`. A *callable-expression* can be used as the left hand side of the [function call operator](#function-call-operator). -###Variables +### Variables **Syntax** @@ -257,7 +257,7 @@ A *variable* is an expression that can *in principle* be used as an lvalue. Howe individual possible expressions may further restrict whether they can behave as lvalues. An expression that is not a *variable* can never act as an lvalue. -###Constant Access Expression +### Constant Access Expression -#Specification for PHP +# Specification for PHP Facebook has dedicated all copyright to this specification to the public domain worldwide under the CC0 Public Domain Dedication located at . This specification From befef5a037689d587b159933c21f334c39151170 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 5 May 2017 18:25:25 +0200 Subject: [PATCH 075/146] Account for deprecation notice in (unset) test --- tests/expressions/unary_operators/cast.phpt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/expressions/unary_operators/cast.phpt b/tests/expressions/unary_operators/cast.phpt index d87341e5..399ea3a4 100644 --- a/tests/expressions/unary_operators/cast.phpt +++ b/tests/expressions/unary_operators/cast.phpt @@ -146,6 +146,7 @@ var_dump($binStr); $binStr = b"AaBb123$%^"; var_dump($binStr); --EXPECTF-- +Deprecated: The (unset) cast is deprecated in %s on line %d bool(false) bool(false) int(0) From 993ab3eb81f3529ae0ad5b534a2396405306fe00 Mon Sep 17 00:00:00 2001 From: ekinhbayar Date: Sat, 6 May 2017 18:32:56 +0300 Subject: [PATCH 076/146] Fix markdown and grammar tool --- spec/00-specification-for-php.md | 2 +- tools/grammar.php | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/00-specification-for-php.md b/spec/00-specification-for-php.md index a40f29d2..d2d2f4c9 100644 --- a/spec/00-specification-for-php.md +++ b/spec/00-specification-for-php.md @@ -1,7 +1,7 @@ -#Specification for PHP +# Specification for PHP Facebook has dedicated all copyright to this specification to the public domain worldwide under the CC0 Public Domain Dedication located at . This specification diff --git a/tools/grammar.php b/tools/grammar.php index 289aea49..a7494503 100644 --- a/tools/grammar.php +++ b/tools/grammar.php @@ -48,22 +48,22 @@ function($matches) use($names, $fileName) { $grammarFile = $dir . '19-grammar.md'; $output = <<<'END' -#Grammar +# Grammar -##General +## General The grammar notation is described in [Grammars section](09-lexical-structure.md#grammars). -##Lexical Grammar +## Lexical Grammar END; $lexical = file_get_contents($dir . '09-lexical-structure.md'); -$lexical = strstr($lexical, '##Lexical analysis'); +$lexical = strstr($lexical, '## Lexical analysis'); $output .= extract_grammar($lexical, $names); -$output .= "\n\n##Syntactic Grammar"; +$output .= "\n\n## Syntactic Grammar"; $skipFiles = ['05-types.md', '09-lexical-structure.md', '19-grammar.md']; foreach (spec_files($skipFiles) as $fileName => $path) { @@ -74,7 +74,7 @@ function($matches) use($names, $fileName) { } $heading = extract_heading($code); - $output .= "\n\n###$heading\n\n" . $grammar; + $output .= "\n\n### $heading\n\n" . $grammar; } $output .= "\n"; From 11b13919b0f7d8b4f7b4ba40d48d497f480b6a64 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 05:31:30 +0200 Subject: [PATCH 077/146] Add missing comma in const-elements production Fixes #205. --- spec/14-classes.md | 4 ++-- spec/19-grammar.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/14-classes.md b/spec/14-classes.md index 3ad353ff..384181ed 100644 --- a/spec/14-classes.md +++ b/spec/14-classes.md @@ -412,7 +412,7 @@ class-const-declaration: const-elements: const-element - const-elements const-element + const-elements ',' const-element const-element: name '=' constant-expression @@ -427,7 +427,7 @@ const-element: const-elements: const-element - const-elements const-element + const-elements , const-element const-element: name = constant-expression diff --git a/spec/19-grammar.md b/spec/19-grammar.md index d4df4ca3..a16a8c97 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -982,7 +982,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# const-elements: const-element - const-elements const-element + const-elements , const-element const-element: name = constant-expression From 32fe82511d7ea4c6d73ae6279edd3e24fada5aff Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 05:36:34 +0200 Subject: [PATCH 078/146] Use variable in list-or-variable --- spec/10-expressions.md | 6 +++--- spec/19-grammar.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 6c802724..880d6a26 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -603,7 +603,7 @@ keyed-list-expression-list: list-or-variable: list-intrinsic - expression + variable -->
@@ -625,7 +625,7 @@ list-or-variable:
 
 list-or-variable:
    list-intrinsic
-   expression
+   variable
 
**Constraints** @@ -635,7 +635,7 @@ list-or-variable: operand must be an expression that designates an array or object implementing the `ArrayAccess` interface (called the *source array*). -Each *expression* in *list-or-variable* must designate a variable (called +Each *variable* in *list-or-variable* must designate a writable variable (called the *target variable*). At least one of the elements of the *list-expression-list* must be non-empty. diff --git a/spec/19-grammar.md b/spec/19-grammar.md index a16a8c97..b5a59219 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -437,7 +437,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# list-or-variable: list-intrinsic - expression + variable print-intrinsic: print expression From 3c6875b738786cea3ac87e90d7f781e13d66aa8f Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 05:38:28 +0200 Subject: [PATCH 079/146] Use variable in instanceof-type-designator --- spec/10-expressions.md | 9 +++++---- spec/19-grammar.md | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 880d6a26..9bf100fa 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -2230,7 +2230,7 @@ instanceof-subject: instanceof-type-designator: qualified-name - expression + variable -->
@@ -2243,13 +2243,14 @@ instanceof-type-designator:
 
 instanceof-type-designator:
    qualified-name
-   expression
+   variable
 
**Constraints** -The *expression* in *instanceof-type-designator* and *instanceof-subject* must not be any form of -literal. +The *expression* in *instanceof-subject* must not be any form of literal. + +The *variable* in *instanceof-type-designator* must not contain calls. **Semantics** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index b5a59219..d3e82ba0 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -599,7 +599,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# instanceof-type-designator: qualified-name - expression + variable multiplicative-expression: instanceof-expression From 8082f0911ad18da427d2920599d06a1a0632edbc Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 05:46:21 +0200 Subject: [PATCH 080/146] Fix precedence of coalesce operator Fix #201. --- spec/00-specification-for-php.md | 2 +- spec/10-expressions.md | 107 ++++++++++++++++--------------- spec/19-grammar.md | 10 +-- 3 files changed, 60 insertions(+), 59 deletions(-) diff --git a/spec/00-specification-for-php.md b/spec/00-specification-for-php.md index d2d2f4c9..fb7fe9b8 100644 --- a/spec/00-specification-for-php.md +++ b/spec/00-specification-for-php.md @@ -144,8 +144,8 @@ is distributed without any warranty. - [Bitwise Inclusive OR Operator](10-expressions.md#bitwise-inclusive-or-operator) - [Logical AND Operator (form 1)](10-expressions.md#logical-and-operator-form-1) - [Logical Inclusive OR Operator (form 1)](10-expressions.md#logical-inclusive-or-operator-form-1) - - [Conditional Operator](10-expressions.md#conditional-operator) - [Coalesce Operator](10-expressions.md#coalesce-operator) + - [Conditional Operator](10-expressions.md#conditional-operator) - [Assignment Operators](10-expressions.md#assignment-operators) - [General](10-expressions.md#general-5) - [Simple Assignment](10-expressions.md#simple-assignment) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 9bf100fa..e99a4a37 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -2911,65 +2911,20 @@ This operator associates left-to-right. if ($month < 1 || $month > 12) ... ``` -## Conditional Operator - -**Syntax** - - - -
-conditional-expression:
-   logical-inc-OR-expression-1
-   logical-inc-OR-expression-1   ?   expressionopt   :   conditional-expression
-
- -**Semantics** -Given the expression `e1 ? e2 : e3`, `e1` is evaluated first and [converted to `bool`](08-conversions.md#converting-to-boolean-type) if it has another type. -If the result is `TRUE`, then and only then is `e2` evaluated, and the result and its type become the result and type of -the whole expression. Otherwise, then and only then is `e3` evaluated, and -the result and its type become the result and type of the whole -expression. There is a sequence point after the evaluation of `e1`. If `e2` -is omitted, the result and type of the whole expression is the value and -type of `e1` (before the conversion to `bool`). - -This operator associates left-to-right. - -**Examples** - -```PHP -for ($i = -5; $i <= 5; ++$i) - echo "$i is ".(($i & 1 == TRUE) ? "odd\n" : "even\n"); -// ----------------------------------------- -$a = 10 ? : "Hello"; // result is int with value 10 -$a = 0 ? : "Hello"; // result is string with value "Hello" -$i = PHP_INT_MAX; -$a = $i++ ? : "red"; // result is int with value 2147483647 (on a 32-bit - // system) even though $i is now the float 2147483648.0 -// ----------------------------------------- -$i++ ? f($i) : f(++$i); // the sequence point makes this well-defined -// ----------------------------------------- -function factorial($int) -{ - return ($int > 1) ? $int * factorial($int - 1) : $int; -} -``` - ## Coalesce Operator **Syntax**
 coalesce-expression:
-   logical-inc-OR-expression-1   ??   expression
+   logical-inc-OR-expression-1
+   logical-inc-OR-expression-1   ??   coalesce-expression
 
**Semantics** @@ -2979,8 +2934,8 @@ Given the expression `e1 ?? e2`, if `e1` is set and not `NULL` (i.e. TRUE for evaluated, and the result becomes the result of the whole expression. There is a sequence point after the evaluation of `e1`. -Note that the semantics of `??` is similar to `isset` so that uninitialized variables will not produce -warnings when used in `e1`. +Note that the semantics of `??` is similar to `isset` so that uninitialized variables will +not produce warnings when used in `e1`. This operator associates right-to-left. @@ -3006,6 +2961,54 @@ function foo() { var_dump(true ?? foo()); // outputs bool(true), "executed!" does not appear as it short-circuits ``` +## Conditional Operator + +**Syntax** + + + +
+conditional-expression:
+   coalesce-expression
+   conditional-expression   ?   expressionopt   :   coalesce-expression
+
+ +**Semantics** +Given the expression `e1 ? e2 : e3`, `e1` is evaluated first and [converted to `bool`](08-conversions.md#converting-to-boolean-type) if it has another type. +If the result is `TRUE`, then and only then is `e2` evaluated, and the result and its type become the result and type of +the whole expression. Otherwise, then and only then is `e3` evaluated, and +the result and its type become the result and type of the whole +expression. There is a sequence point after the evaluation of `e1`. If `e2` +is omitted, the result and type of the whole expression is the value and +type of `e1` (before the conversion to `bool`). + +This operator associates left-to-right. + +**Examples** + +```PHP +for ($i = -5; $i <= 5; ++$i) + echo "$i is ".(($i & 1 == TRUE) ? "odd\n" : "even\n"); +// ----------------------------------------- +$a = 10 ? : "Hello"; // result is int with value 10 +$a = 0 ? : "Hello"; // result is string with value "Hello" +$i = PHP_INT_MAX; +$a = $i++ ? : "red"; // result is int with value 2147483647 (on a 32-bit + // system) even though $i is now the float 2147483648.0 +// ----------------------------------------- +$i++ ? f($i) : f(++$i); // the sequence point makes this well-defined +// ----------------------------------------- +function factorial($int) +{ + return ($int > 1) ? $int * factorial($int - 1) : $int; +} +``` + + ## Assignment Operators ### General @@ -3015,7 +3018,6 @@ var_dump(true ?? foo()); // outputs bool(true), "executed!" does not appear as i
 byref-assignment-expression:
-   variable   =   &   assignment-expression
+   variable   =   &   variable
 
**Constraints** -*assignment-expression* must be an lvalue or a call to a function that -returns a value byRef. +The right-hand-side *variable* must be an lvalue or a call to a function +that returns a value byRef. **Semantics** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 6f17c924..0cc0a9a7 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -673,7 +673,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# list-intrinsic = assignment-expression byref-assignment-expression: - variable = & assignment-expression + variable = & variable compound-assignment-expression: variable compound-assignment-operator assignment-expression From 9cf8b200e55968b9e542c6cb70563d35ec347bf8 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Tue, 19 Sep 2017 08:20:39 +0200 Subject: [PATCH 082/146] Fix definition list rendering on GitHub in Terms and Definitions --- spec/03-terms-and-definitions.md | 84 ++++++++++++++++---------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/spec/03-terms-and-definitions.md b/spec/03-terms-and-definitions.md index 0624f02c..fe4d15a6 100644 --- a/spec/03-terms-and-definitions.md +++ b/spec/03-terms-and-definitions.md @@ -3,63 +3,63 @@ For the purposes of this document, the following terms and definitions apply:
-
argument
-
a value passed to a function, that is intended to map to a - corresponding parameter.
+
argument
+
a value passed to a function, that is intended to map to a + corresponding parameter.
-
behavior
-
external appearance or action.
+
behavior
+
external appearance or action.
-
behavior, implementation-defined
-
behavior specific to an implementation, where that implementation - must document that behavior.
+
behavior, implementation-defined
+
behavior specific to an implementation, where that implementation + must document that behavior.
-
behavior, undefined
-
behavior which is not guaranteed to produce any specific result. - Usually follows an erroneous program construct or data.
+
behavior, undefined
+
behavior which is not guaranteed to produce any specific result. + Usually follows an erroneous program construct or data.
-
behavior, unspecified
-
behavior for which this specification provides no requirements.
+
behavior, unspecified
+
behavior for which this specification provides no requirements.
-
constraint
-
restriction, either syntactic or semantic, on how language elements - can be used.
+
constraint
+
restriction, either syntactic or semantic, on how language elements + can be used.
-
error, fatal
-
a condition in which the engine cannot continue executing the script - and must terminate.
+
error, fatal
+
a condition in which the engine cannot continue executing the script + and must terminate.
-
error, fatal, catchable
-
a fatal error that can be caught by a user-defined handler.
+
error, fatal, catchable
+
a fatal error that can be caught by a user-defined handler.
-
error, non-fatal
-
an error that is not a fatal error and allows for the engine to - continue execution.
+
error, non-fatal
+
an error that is not a fatal error and allows for the engine to + continue execution.
-
lvalue
-
an expression that designates a location that can store a value.
+
lvalue
+
an expression that designates a location that can store a value.
-
lvalue, modifiable
-
an lvalue whose value can be changed.
+
lvalue, modifiable
+
an lvalue whose value can be changed.
-
lvalue, non-modifiable
-
an lvalue whose value cannot be changed.
+
lvalue, non-modifiable
+
an lvalue whose value cannot be changed.
-
notice
-
an informational message informing user of the code that may not work as intended.
+
notice
+
an informational message informing user of the code that may not work as intended.
-
parameter
-
a variable declared in the parameter list of a function that is - intended to map to a corresponding argument in a call to that - function.
+
parameter
+
a variable declared in the parameter list of a function that is + intended to map to a corresponding argument in a call to that + function.
-
PHP Run-Time Engine
-
the software that executes a PHP program. Referred to as the - Engine throughout this specification.
+
PHP Run-Time Engine
+
the software that executes a PHP program. Referred to as the + Engine throughout this specification.
-
value
-
a primitive unit of data operated by the Engine having a type - and potentially other content depending on the type.
+
value
+
a primitive unit of data operated by the Engine having a type + and potentially other content depending on the type.
Other terms are defined throughout this specification, as needed, with From 287030c352f0019a2f9dee2077ad146d0d3e3e8c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 08:34:50 +0200 Subject: [PATCH 083/146] Add nullable types Fixed #196. --- spec/13-functions.md | 10 +++++++++- spec/19-grammar.md | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/spec/13-functions.md b/spec/13-functions.md index 3e253de3..6d46b018 100644 --- a/spec/13-functions.md +++ b/spec/13-functions.md @@ -77,6 +77,9 @@ return-type: ':' 'void' type-declaration: + '?'? base-type-declaration + +base-type-declaration: 'array' 'callable' 'iterable' @@ -123,6 +126,9 @@ default-argument-specifier: : void type-declaration: + ?opt base-type-declaration + +base-type-declaration: array callable iterable @@ -218,7 +224,9 @@ Parameters typed with *scalar-type* are accepted if they pass the type check for as [described below](#type-check-modes). Once the checks have been passed, the parameter types are always of the scalar type specified (or `NULL` if `NULL` is allowed). -If a parameter has a type declaration, `NULL` is not accepted unless it has a default value that evaluates to `NULL`. +If a parameter has a type declaration, `NULL` is not accepted unless the +type is nullable. A type is nullable if it is prefixed with `?` or if the +parameter has a default value that evaluates to `NULL`. The default value for a typed parameter must be of the type specified, or `NULL`, and conversion is not be performed for defaults, regardless of the mode. diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 0cc0a9a7..16c007e7 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -929,6 +929,9 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# : void type-declaration: + ?opt base-type-declaration + +base-type-declaration: array callable iterable From 687ecf0dbc2397b79a9b5a39be05105b9f42ac8a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 08:47:48 +0200 Subject: [PATCH 084/146] Introduce new-variable for new/instanceof Fixes #202. --- spec/10-expressions.md | 55 ++++++++++++++++++++++++------------------ spec/19-grammar.md | 17 ++++++++----- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index c29629f9..6fd5db67 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -991,7 +991,16 @@ object-creation-expression: class-type-designator: qualified-name - expression + new-variable + +new-variable: + simple-variable + new-variable '[' expression? ']' + new-variable '{' expression '}' + new-variable '->' member-name + qualified-name '::' simple-variable + relative-scope '::' simple-variable + new-variable '::' simple-variable -->
@@ -1003,15 +1012,23 @@ class-type-designator:
 
 class-type-designator:
    qualified-name
-   expression
+   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
 
**Constraints** *qualified-name* must name a class. -*expression* must be a value of type `string` (but not be a string -literal) that contains the name of a class, or an object. +*new-variable* must be a value of type `string` that contains the name of a class, or an object. *class-type-designator* must not designate an [abstract class](14-classes.md#general). @@ -1022,9 +1039,11 @@ as many as the number of non-optional parameters defined for the class's [constr The `new` *class-type-designator* forms create an object of the class type specified by *class-type-designator*. The `new class` forms create an object of an *anonymous class type*, a type that has an unspecified name. In all other respects, however, an anonymous class has the same capabilities as a named class type. -If the *class-type-designator* is an expression resulting in a string value, +If the *class-type-designator* is a *new-variable* resulting in a string value, that string is used as the class name. If the expression results in an object, -the class of the object is used as the class for the new object. +the class of the object is used as the class for the new object. The *new-variable* +has the same semantics as a *variable*, but the grammar is restricted to exclude +calls. The *qualified-name* is resolved according to the rules described in [scope resolution operator](#scope-resolution-operator), including @@ -2223,47 +2242,37 @@ A *cast-type* of `unset` always results in a value of `NULL`. (This use of
 instanceof-expression:
    unary-expression
-   instanceof-subject   instanceof   instanceof-type-designator
+   instanceof-subject   instanceof   class-type-designator
 
 instanceof-subject:
    expression
-
-instanceof-type-designator:
-   qualified-name
-   variable
 
**Constraints** The *expression* in *instanceof-subject* must not be any form of literal. -The *variable* in *instanceof-type-designator* must not contain calls. - **Semantics** Operator `instanceof` returns `TRUE` if the value designated by *expression* in *instanceof-subject* is an object having the type specified -by *instanceof-type-designator*, is an object whose type is derived from that type, -or is an object whose type implements the interface specified by *instanceof-type-designator*. +by *class-type-designator*, is an object whose type is derived from that type, +or is an object whose type implements the interface specified by *class-type-designator*. Otherwise, it returns `FALSE`. -The type can be specified by *instanceof-type-designator* in one of the three forms: +The type can be specified by *class-type-designator* in one of the three forms: 1. *qualified-name* specifies the type name directly. - 2. When the *expression* form is used, *expression* may have a string value that contains a class or interface name. - 3. Alternatively, *expression* can designate an object, in which case the type of the object is used as the specified type. + 2. When the *new-variable* form is used, *new-variable* may have a string value that contains a class or interface name. + 3. Alternatively, *new-variable* can designate an object, in which case the type of the object is used as the specified type. Note that an interface can not be specified with this form. Note that `instanceof` will not invoke autoloader if the name of the type given does not diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 16c007e7..7d4738ac 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -474,7 +474,16 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# class-type-designator: qualified-name - expression + 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 ) @@ -592,15 +601,11 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# instanceof-expression: unary-expression - instanceof-subject instanceof instanceof-type-designator + instanceof-subject instanceof class-type-designator instanceof-subject: expression -instanceof-type-designator: - qualified-name - variable - multiplicative-expression: instanceof-expression multiplicative-expression * instanceof-expression From e3eb18b757b24b0b1f97dc9bb9a24cf12697eb99 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 08:51:25 +0200 Subject: [PATCH 085/146] Don't require statement after label Fixes #190. --- spec/11-statements.md | 11 ++++------- spec/19-grammar.md | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/spec/11-statements.md b/spec/11-statements.md index 4a5a0fcd..427c74b8 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -98,25 +98,22 @@ while (condition)
 named-label-statement:
-   name   ;   statement
+   name   :
 
**Constraints** -A named label can be used as the target of a [`goto` statement](#the-goto-statement). - Named labels must be unique within a function. **Semantics** -Any statement may be preceded by a token sequence that declares a name -as a label name. The presence of a label does not alter the flow of -execution. +A named label can be used as the target of a [`goto` statement](#the-goto-statement). +The presence of a label does not by itself alter the flow of execution. ## Expression Statements diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 7d4738ac..32661cbb 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -756,7 +756,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# statement-list statement named-label-statement: - name ; statement + name : expression-statement: expressionopt ; From 7d6ae475928a67c706aeaec8c131bed9567aafed Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 09:21:02 +0200 Subject: [PATCH 086/146] Remove cast-expression/unary-expression recursion --- spec/10-expressions.md | 6 ++---- spec/19-grammar.md | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 6fd5db67..cfae2030 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -1990,7 +1990,7 @@ $a = "^^Z^^"; ++$a; // $a is now "^^Z^^"
@@ -2001,7 +2001,7 @@ unary-operator: one of
    unary-operator   unary-expression
 
 unary-operator: one of
-   +   -   !   ~
+   +   -   ~
 
**Constraints** @@ -2013,10 +2013,6 @@ an object supporting `~`. **Semantics** -For a unary `!` operator the type of the result is `bool`. -The value of the operand is [converted to type `bool`](08-conversions.md#converting-to-boolean-type) -and if it is `TRUE` then the of the operator result is `FALSE`, and the result is `TRUE` otherwise. - *Arithmetic Operands* For a unary `+` operator used with an arithmetic operand, the type and @@ -2073,8 +2069,6 @@ and for `+` and `-` the object is [converted to `int`](08-conversions.md#convert ```PHP $v = +10; if ($v1 > -5) // ... -$t = TRUE; -if (!$t) // ... $v = ~0b1010101; $s = "\x86\x97"; $s = ~$s; // $s is "yh" ``` @@ -2300,24 +2294,50 @@ $e2 = new E1; var_dump($e2 instanceof $e1); // TRUE ``` +## Logical NOT Operator + + + +
+logical-NOT-expression:
+   instanceof-expression
+   !   instanceof-expression
+
+ +**Semantics** + +The value of the operand is [converted to type `bool`](08-conversions.md#converting-to-boolean-type) +and if it is `TRUE` then the result of the operator is `FALSE`. The result is `TRUE` otherwise. + +**Examples** + +```PHP +$t = TRUE; +if (!$t) // ... +``` + ## Multiplicative Operators **Syntax**
 multiplicative-expression:
-   instanceof-expression
-   multiplicative-expression   *   instanceof-expression
-   multiplicative-expression   /   instanceof-expression
-   multiplicative-expression   %   instanceof-expression
+   logical-NOT-expression
+   multiplicative-expression   *   logical-NOT-expression
+   multiplicative-expression   /   logical-NOT-expression
+   multiplicative-expression   %   logical-NOT-expression
 
**Constraints** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 08f7ac38..06fcb025 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -583,7 +583,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# unary-operator unary-expression unary-operator: one of - + - ! ~ + + - ~ error-control-expression: @ expression @@ -605,11 +605,15 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# instanceof-subject: expression -multiplicative-expression: +logical-NOT-expression: instanceof-expression - multiplicative-expression * instanceof-expression - multiplicative-expression / instanceof-expression - multiplicative-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 From b7f82175abd71600c3a825e642d57ddef6b5b826 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 09:35:19 +0200 Subject: [PATCH 088/146] Fix cast/suppression precedence --- spec/10-expressions.md | 10 +++++----- spec/19-grammar.md | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index f854436f..df755639 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -2079,18 +2079,18 @@ $s = "\x86\x97"; $s = ~$s; // $s is "yh"
 error-control-expression:
-   @   expression
+   @   unary-expression
 
**Semantics** Operator `@` suppresses the reporting of any error messages generated by the evaluation of -*expression*. +*unary-expression*. If a custom error-handler has been established using the library function [`set_error_handler`](http://php.net/manual/function.set-error-handler.php), that handler is @@ -2174,7 +2174,7 @@ $result = `$d {$f}`; // result is the output of command dir *.*
 exponentiation-expression:
-   expression   **   expression
+   postfix-expression   **   exponentiation-expression
 
**Semantics** @@ -1830,7 +1830,9 @@ to type `int` or `float`, as appropriate. If both operands have non-negative integer values and the result can be represented as an `int`, the result has type `int`; otherwise, the result has type `float`. If either or both operands were leading-numeric or non-numeric strings, a non-fatal error must be produced -for each. **Examples** +for each. + +**Examples** ```PHP 2**3; // int with value 8 @@ -1846,7 +1848,7 @@ for each. **Examples**
 postfix-expression:
    primary-expression
-   clone-expression
    object-creation-expression
    postfix-increment-expression
    postfix-decrement-expression
-   exponentiation-expression
 
**Semantics** These operators associate left-to-right. -### The `clone` Operator - -**Syntax** - - - -
-clone-expression:
-   clone   expression
-
- -**Constraints** - -*expression* must designate an object. - -**Semantics** - -The `clone` operator creates a new object that is a shallow copy of the object designated by *expression*. -Then, if the class type of *expression* has a method called [`__clone`](14-classes.md#method-__clone), it is called to perform a deep copy. -The result is the new object. - -**Examples** - -Consider a class `Employee`, from which is derived a class `Manager`. Let us -assume that both classes contain properties that are objects. `clone` is -used to make a copy of a `Manager` object, and behind the scenes, the -`Manager` object uses clone to copy the properties for the base class, -`Employee`. - -```PHP -class Employee -{ - //... - public function __clone() - { - // make a deep copy of Employee object - } -} -class Manager extends Employee -{ - //... - public function __clone() - { - $v = parent::__clone(); - // make a deep copy of Manager object - - } -} -$obj1 = new Manager("Smith", 23); -$obj2 = clone $obj1; // creates a new Manager that is a deep copy -``` - ### The `new` Operator **Syntax** @@ -1803,18 +1744,80 @@ class Point } ``` +## The `clone` Operator + +**Syntax** + + + +
+clone-expression:
+   postfix-expression
+   clone   postfix-expression
+
+ +**Constraints** + +*postfix-expression* must designate an object. + +**Semantics** + +The `clone` operator creates a new object that is a shallow copy of the object designated +by *postfix-expression*. +Then, if the class type of *postfix-expression* has a method called +[`__clone`](14-classes.md#method-__clone), it is called to perform a deep copy. +The result is the new object. + +**Examples** + +Consider a class `Employee`, from which is derived a class `Manager`. Let us +assume that both classes contain properties that are objects. `clone` is +used to make a copy of a `Manager` object, and behind the scenes, the +`Manager` object uses clone to copy the properties for the base class, +`Employee`. + +```PHP +class Employee +{ + //... + public function __clone() + { + // make a deep copy of Employee object + } +} +class Manager extends Employee +{ + //... + public function __clone() + { + $v = parent::__clone(); + // make a deep copy of Manager object + + } +} +$obj1 = new Manager("Smith", 23); +$obj2 = clone $obj1; // creates a new Manager that is a deep copy +``` + + ## Exponentiation Operator **Syntax**
 exponentiation-expression:
-   postfix-expression   **   exponentiation-expression
+   clone-expression
+   clone-expression   **   exponentiation-expression
 
**Semantics** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 4fcba005..584e39e7 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -457,14 +457,9 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# postfix-expression: primary-expression - clone-expression object-creation-expression postfix-increment-expression postfix-decrement-expression - exponentiation-expression - -clone-expression: - clone expression object-creation-expression: new class-type-designator ( argument-expression-listopt ) @@ -561,8 +556,13 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# parent static +clone-expression: + postfix-expression + clone postfix-expression + exponentiation-expression: - postfix-expression ** exponentiation-expression + clone-expression + clone-expression ** exponentiation-expression unary-expression: exponentiation-expression From def41da2f80e8e66c136334ea6b7fc86db89e1f0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 10:01:20 +0200 Subject: [PATCH 091/146] Merge postfix-expression into postfix-expression The distinction is not meaningful, these are also primary expressions. --- spec/00-specification-for-php.md | 8 +++--- spec/10-expressions.md | 46 +++++++++----------------------- spec/19-grammar.md | 13 ++++----- 3 files changed, 21 insertions(+), 46 deletions(-) diff --git a/spec/00-specification-for-php.md b/spec/00-specification-for-php.md index 64df6952..5646214f 100644 --- a/spec/00-specification-for-php.md +++ b/spec/00-specification-for-php.md @@ -114,8 +114,6 @@ is distributed without any warranty. - [print](10-expressions.md#print) - [unset](10-expressions.md#unset) - [Anonymous Function Creation](10-expressions.md#anonymous-function-creation) - - [Postfix Operators](10-expressions.md#postfix-operators) - - [General](10-expressions.md#general-3) - [The `new` Operator](10-expressions.md#the-new-operator) - [Array Creation Operator](10-expressions.md#array-creation-operator) - [Subscript Operator](10-expressions.md#subscript-operator) @@ -127,7 +125,7 @@ is distributed without any warranty. - [The `clone` Operator](10-expressions.md#the-clone-operator) - [Exponentiation Operator](10-expressions.md#exponentiation-operator) - [Unary Operators](10-expressions.md#unary-operators) - - [General](10-expressions.md#general-4) + - [General](10-expressions.md#general-3) - [Prefix Increment and Decrement Operators](10-expressions.md#prefix-increment-and-decrement-operators) - [Unary Arithmetic Operators](10-expressions.md#unary-arithmetic-operators) - [Error Control Operator](10-expressions.md#error-control-operator) @@ -148,7 +146,7 @@ is distributed without any warranty. - [Coalesce Operator](10-expressions.md#coalesce-operator) - [Conditional Operator](10-expressions.md#conditional-operator) - [Assignment Operators](10-expressions.md#assignment-operators) - - [General](10-expressions.md#general-5) + - [General](10-expressions.md#general-4) - [Simple Assignment](10-expressions.md#simple-assignment) - [byRef Assignment](10-expressions.md#byref-assignment) - [Compound Assignment](10-expressions.md#compound-assignment) @@ -157,7 +155,7 @@ is distributed without any warranty. - [Logical Inclusive OR Operator (form 2)](10-expressions.md#logical-inclusive-or-operator-form-2) - [`yield` Operator](10-expressions.md#yield-operator) - [Script Inclusion Operators](10-expressions.md#script-inclusion-operators) - - [General](10-expressions.md#general-6) + - [General](10-expressions.md#general-5) - [The `include` Operator](10-expressions.md#the-include-operator) - [The `include_once` Operator](10-expressions.md#the-include_once-operator) - [The `require` Operator](10-expressions.md#the-require-operator) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 7431eaf4..5f22dc72 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -98,6 +98,9 @@ primary-expression: array-creation-expression intrinsic anonymous-function-creation-expression + object-creation-expression + postfix-increment-expression + postfix-decrement-expression '(' expression ')' --> @@ -110,6 +113,9 @@ primary-expression: array-creation-expression intrinsic anonymous-function-creation-expression + object-creation-expression + postfix-increment-expression + postfix-decrement-expression ( expression )
@@ -893,32 +899,6 @@ class C } ``` -## Postfix Operators - -### General - -**Syntax** - - - -
-postfix-expression:
-   primary-expression
-   object-creation-expression
-   postfix-increment-expression
-   postfix-decrement-expression
-
- -**Semantics** - -These operators associate left-to-right. - ### The `new` Operator **Syntax** @@ -1750,25 +1730,25 @@ class Point
 clone-expression:
-   postfix-expression
-   clone   postfix-expression
+   primary-expression
+   clone   primary-expression
 
**Constraints** -*postfix-expression* must designate an object. +*primary-expression* must designate an object. **Semantics** The `clone` operator creates a new object that is a shallow copy of the object designated -by *postfix-expression*. -Then, if the class type of *postfix-expression* has a method called +by *primary-expression*. +Then, if the class type of *primary-expression* has a method called [`__clone`](14-classes.md#method-__clone), it is called to perform a deep copy. The result is the new object. diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 584e39e7..ceb9677b 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -338,6 +338,9 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# array-creation-expression intrinsic anonymous-function-creation-expression + object-creation-expression + postfix-increment-expression + postfix-decrement-expression ( expression ) simple-variable: @@ -455,12 +458,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# &opt variable-name use-variable-name-list , &opt variable-name -postfix-expression: - primary-expression - object-creation-expression - postfix-increment-expression - postfix-decrement-expression - object-creation-expression: new class-type-designator ( argument-expression-listopt ) new class-type-designator @@ -557,8 +554,8 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# static clone-expression: - postfix-expression - clone postfix-expression + primary-expression + clone primary-expression exponentiation-expression: clone-expression From 1aed868c28bcbbb0f1d011169163aab1e66413c9 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 10:05:45 +0200 Subject: [PATCH 092/146] Move pre-inc/dec and shell-exec into primary expression Otherwise the precedence would be wrong... --- spec/00-specification-for-php.md | 4 +- spec/10-expressions.md | 322 ++++++++++++++++--------------- spec/19-grammar.md | 24 +-- 3 files changed, 176 insertions(+), 174 deletions(-) diff --git a/spec/00-specification-for-php.md b/spec/00-specification-for-php.md index 5646214f..7e16198d 100644 --- a/spec/00-specification-for-php.md +++ b/spec/00-specification-for-php.md @@ -121,15 +121,15 @@ is distributed without any warranty. - [Member Access Operator](10-expressions.md#member-access-operator) - [Member Call Operator](10-expressions.md#member-call-operator) - [Postfix Increment and Decrement Operators](10-expressions.md#postfix-increment-and-decrement-operators) + - [Prefix Increment and Decrement Operators](10-expressions.md#prefix-increment-and-decrement-operators) + - [Shell Command Operator](10-expressions.md#shell-command-operator) - [Scope-Resolution Operator](10-expressions.md#scope-resolution-operator) - [The `clone` Operator](10-expressions.md#the-clone-operator) - [Exponentiation Operator](10-expressions.md#exponentiation-operator) - [Unary Operators](10-expressions.md#unary-operators) - [General](10-expressions.md#general-3) - - [Prefix Increment and Decrement Operators](10-expressions.md#prefix-increment-and-decrement-operators) - [Unary Arithmetic Operators](10-expressions.md#unary-arithmetic-operators) - [Error Control Operator](10-expressions.md#error-control-operator) - - [Shell Command Operator](10-expressions.md#shell-command-operator) - [Cast Operator](10-expressions.md#cast-operator) - [`instanceof` Operator](10-expressions.md#instanceof-operator) - [Logical NOT Operator](10-expressions.md#logical-not-operator) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 5f22dc72..ed50d757 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -101,6 +101,9 @@ primary-expression: object-creation-expression postfix-increment-expression postfix-decrement-expression + prefix-increment-expression + prefix-decrement-expression + shell-command-expression '(' expression ')' --> @@ -116,6 +119,9 @@ primary-expression: object-creation-expression postfix-increment-expression postfix-decrement-expression + prefix-increment-expression + prefix-decrement-expression + shell-command-expression ( expression )
@@ -1494,9 +1500,10 @@ class Point public function __toString() { return '(' . $this->x . ',' . $this->y . ')'; - } // get private properties $x and $y - public function __set($name, $value) { ... } - public function __get($name) { ... } + } + // get private properties $x and $y + public function __set($name, $value) { ... } + public function __get($name) { ... } } $p1 = new Point; $p1->move(3, 9); // calls public instance method move by name @@ -1584,6 +1591,158 @@ $i = 10; $j = $i-- + 100; // old value of $i (10) is added to 100 $a = array(100, 200); $v = $a[1]++; // old value of $ia[1] (200) is assigned ``` +### Prefix Increment and Decrement Operators + +**Syntax** + + + +
+prefix-increment-expression:
+   ++   variable
+
+prefix-decrement-expression:
+   --   variable
+
+ +**Constraints** + +The operand of the prefix `++` or `--` operator must be a modifiable lvalue +that has scalar-compatible type. + +**Semantics** + +*Arithmetic Operands* + +For a prefix `++` operator used with an arithmetic operand, the [side +effect](#general) of the operator is to increment the value of the operand by 1. +The result is the value of the operand after it +has been incremented. If an `int` operand's value is the largest +representable for that type, the operand is incremented as if it were `float`. + +For a prefix `--` operator used with an arithmetic operand, the side +effect of the operator is to decrement the value of the operand by 1. +The result is the value of the operand after it has been +decremented. If an `int` operand's value is the smallest representable for +that type, the operand is decremented as if it were `float`. + +For a prefix `++` or `--` operator used with an operand having the value +`INF`, `-INF`, or `NAN`, there is no side effect, and the result is the +operand's value. + +*Boolean Operands* + +For a prefix `++` or `--` operator used with a Boolean-valued operand, there +is no side effect, and the result is the operand's value. + +*NULL-valued Operands* + +For a prefix -- operator used with a `NULL`-valued operand, there is no +side effect, and the result is the operand's value. For a prefix `++` +operator used with a `NULL`-valued operand, the side effect is that the +operand's type is changed to int, the operand's value is set to zero, +and that value is incremented by 1. The result is the value of the +operand after it has been incremented. + +*String Operands* + +For a prefix `--` operator used with an operand whose value is an empty +string, the side effect is that the operand's type is changed to `int`, +the operand's value is set to zero, and that value is decremented by 1. +The result is the value of the operand after it has been incremented. + +For a prefix `++` operator used with an operand whose value is an empty +string, the side effect is that the operand's value is changed to the +string "1". The type of the operand is unchanged. The result is the new +value of the operand. + +For a prefix `--` or `++` operator used with a numeric string, the numeric +string is treated as the corresponding `int` or `float` value. + +For a prefix `--` operator used with a non-numeric string-valued operand, +there is no side effect, and the result is the operand's value. + +For a non-numeric string-valued operand that contains only alphanumeric +characters, for a prefix `++` operator, the operand is considered to be a +representation of a base-36 number (i.e., with digits 0–9 followed by A–Z or a–z) in +which letter case is ignored for value purposes. The right-most digit is +incremented by 1. For the digits 0–8, that means going to 1–9. For the +letters "A"–"Y" (or "a"–"y"), that means going to "B"–"Z" (or "b"–"z"). +For the digit 9, the digit becomes 0, and the carry is added to the next +left-most digit, and so on. For the digit "Z" (or "z"), the resulting +string has an extra digit "A" (or "a") appended. For example, when +incrementing, "a" -> "b", "Z" -> "AA", "AA" -> "AB", "F29" -> "F30", "FZ9" -> "GA0", and "ZZ9" -> "AAA0". A digit position containing a number wraps +modulo-10, while a digit position containing a letter wraps modulo-26. + +For a non-numeric string-valued operand that contains any +non-alphanumeric characters, for a prefix `++` operator, all characters up +to and including the right-most non-alphanumeric character is passed +through to the resulting string, unchanged. Characters to the right of +that right-most non-alphanumeric character are treated like a +non-numeric string-valued operand that contains only alphanumeric +characters, except that the resulting string will not be extended. +Instead, a digit position containing a number wraps modulo-10, while a +digit position containing a letter wraps modulo-26. + +*Object Operands* + +If the operand has an object type supporting the operation, +then the object semantics defines the result. Otherwise, the operation has +no effect and the result is the operand. + +**Examples** + +```PHP +$i = 10; $j = --$i + 100; // new value of $i (9) is added to 100 +$a = array(100, 200); $v = ++$a[1]; // new value of $a[1] (201) is assigned +$a = "^^Z"; ++$a; // $a is now "^^A" +$a = "^^Z^^"; ++$a; // $a is now "^^Z^^" +``` + +### Shell Command Operator + +**Syntax** + + + +
+shell-command-expression:
+   `   dq-char-sequenceopt   `
+
+ +where \` is the GRAVE ACCENT character U+0060, commonly referred to as a +*backtick*. + +**Semantics** + +This operator passes *dq-char-sequence* to the command shell for +execution, as though it was being passed to the library function +[`shell_exec`](http://www.php.net/shell_exec). If the output from execution of that command is +written to [`STDOUT`](06-constants.md#core-predefined-constants), that output is the result of this operator +as a string. If the output is redirected away from `STDOUT`, or +*dq-char-sequence* is empty or contains only white space, the result of +the operator is `NULL`. + +If [`shell_exec`](http://php.net/manual/function.shell-exec.php) is disabled, this operator is disabled. + +**Examples** + +```PHP +$result = `ls`; // result is the output of command ls +$result = `ls >dirlist.txt`; // result is NULL +$d = "dir"; $f = "*.*"; +$result = `$d {$f}`; // result is the output of command dir *.* +``` + ### Scope-Resolution Operator **Syntax** @@ -1832,22 +1991,16 @@ for each.
 unary-expression:
    exponentiation-expression
-   prefix-increment-expression
-   prefix-decrement-expression
    unary-op-expression
    error-control-expression
-   shell-command-expression
    cast-expression
 
@@ -1855,119 +2008,6 @@ unary-expression: These operators associate right-to-left. -### Prefix Increment and Decrement Operators - -**Syntax** - - - -
-prefix-increment-expression:
-   ++   variable
-
-prefix-decrement-expression:
-   --   variable
-
- -**Constraints** - -The operand of the prefix `++` or `--` operator must be a modifiable lvalue -that has scalar-compatible type. - -**Semantics** - -*Arithmetic Operands* - -For a prefix `++` operator used with an arithmetic operand, the [side -effect](#general) of the operator is to increment the value of the operand by 1. -The result is the value of the operand after it -has been incremented. If an `int` operand's value is the largest -representable for that type, the operand is incremented as if it were `float`. - -For a prefix `--` operator used with an arithmetic operand, the side -effect of the operator is to decrement the value of the operand by 1. -The result is the value of the operand after it has been -decremented. If an `int` operand's value is the smallest representable for -that type, the operand is decremented as if it were `float`. - -For a prefix `++` or `--` operator used with an operand having the value -`INF`, `-INF`, or `NAN`, there is no side effect, and the result is the -operand's value. - -*Boolean Operands* - -For a prefix `++` or `--` operator used with a Boolean-valued operand, there -is no side effect, and the result is the operand's value. - -*NULL-valued Operands* - -For a prefix -- operator used with a `NULL`-valued operand, there is no -side effect, and the result is the operand's value. For a prefix `++` -operator used with a `NULL`-valued operand, the side effect is that the -operand's type is changed to int, the operand's value is set to zero, -and that value is incremented by 1. The result is the value of the -operand after it has been incremented. - -*String Operands* - -For a prefix `--` operator used with an operand whose value is an empty -string, the side effect is that the operand's type is changed to `int`, -the operand's value is set to zero, and that value is decremented by 1. -The result is the value of the operand after it has been incremented. - -For a prefix `++` operator used with an operand whose value is an empty -string, the side effect is that the operand's value is changed to the -string "1". The type of the operand is unchanged. The result is the new -value of the operand. - -For a prefix `--` or `++` operator used with a numeric string, the numeric -string is treated as the corresponding `int` or `float` value. - -For a prefix `--` operator used with a non-numeric string-valued operand, -there is no side effect, and the result is the operand's value. - -For a non-numeric string-valued operand that contains only alphanumeric -characters, for a prefix `++` operator, the operand is considered to be a -representation of a base-36 number (i.e., with digits 0–9 followed by A–Z or a–z) in -which letter case is ignored for value purposes. The right-most digit is -incremented by 1. For the digits 0–8, that means going to 1–9. For the -letters "A"–"Y" (or "a"–"y"), that means going to "B"–"Z" (or "b"–"z"). -For the digit 9, the digit becomes 0, and the carry is added to the next -left-most digit, and so on. For the digit "Z" (or "z"), the resulting -string has an extra digit "A" (or "a") appended. For example, when -incrementing, "a" -> "b", "Z" -> "AA", "AA" -> "AB", "F29" -> "F30", "FZ9" -> "GA0", and "ZZ9" -> "AAA0". A digit position containing a number wraps -modulo-10, while a digit position containing a letter wraps modulo-26. - -For a non-numeric string-valued operand that contains any -non-alphanumeric characters, for a prefix `++` operator, all characters up -to and including the right-most non-alphanumeric character is passed -through to the resulting string, unchanged. Characters to the right of -that right-most non-alphanumeric character are treated like a -non-numeric string-valued operand that contains only alphanumeric -characters, except that the resulting string will not be extended. -Instead, a digit position containing a number wraps modulo-10, while a -digit position containing a letter wraps modulo-26. - -*Object Operands* - -If the operand has an object type supporting the operation, -then the object semantics defines the result. Otherwise, the operation has -no effect and the result is the operand. - -**Examples** - -```PHP -$i = 10; $j = --$i + 100; // new value of $i (9) is added to 100 -$a = array(100, 200); $v = ++$a[1]; // new value of $a[1] (201) is assigned -$a = "^^Z"; ++$a; // $a is now "^^A" -$a = "^^Z^^"; ++$a; // $a is now "^^Z^^" -``` ### Unary Arithmetic Operators @@ -2115,44 +2155,6 @@ if ($curER === 0) error_reporting($origER); $x = $tmp; ``` -### Shell Command Operator - -**Syntax** - - - -
-shell-command-expression:
-   `   dq-char-sequenceopt   `
-
- -where \` is the GRAVE ACCENT character U+0060, commonly referred to as a -*backtick*. - -**Semantics** - -This operator passes *dq-char-sequence* to the command shell for -execution, as though it was being passed to the library function -[`shell_exec`](http://www.php.net/shell_exec). If the output from execution of that command is -written to [`STDOUT`](06-constants.md#core-predefined-constants), that output is the result of this operator -as a string. If the output is redirected away from `STDOUT`, or -*dq-char-sequence* is empty or contains only white space, the result of -the operator is `NULL`. - -If [`shell_exec`](http://php.net/manual/function.shell-exec.php) is disabled, this operator is disabled. - -**Examples** - -```PHP -$result = `ls`; // result is the output of command ls -$result = `ls >dirlist.txt`; // result is NULL -$d = "dir"; $f = "*.*"; -$result = `$d {$f}`; // result is the output of command dir *.* -``` - ### Cast Operator **Syntax** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index ceb9677b..2162fbfc 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -341,6 +341,9 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# object-creation-expression postfix-increment-expression postfix-decrement-expression + prefix-increment-expression + prefix-decrement-expression + shell-command-expression ( expression ) simple-variable: @@ -534,6 +537,15 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# 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 @@ -563,19 +575,10 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# unary-expression: exponentiation-expression - prefix-increment-expression - prefix-decrement-expression unary-op-expression error-control-expression - shell-command-expression cast-expression -prefix-increment-expression: - ++ variable - -prefix-decrement-expression: - -- variable - unary-op-expression: unary-operator unary-expression @@ -585,9 +588,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# error-control-expression: @ unary-expression -shell-command-expression: - ` dq-char-sequenceopt ` - cast-expression: ( cast-type ) unary-expression From c17f3a1eb766d1b09c4fd0d9a032312b1f8ee250 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 10:11:58 +0200 Subject: [PATCH 093/146] Fix precedence in instanceof-subject --- spec/10-expressions.md | 8 ++++---- spec/19-grammar.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index ed50d757..9cc864eb 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -2224,7 +2224,7 @@ instanceof-expression: instanceof-subject 'instanceof' class-type-designator instanceof-subject: - expression + unary-expression -->
@@ -2233,17 +2233,17 @@ instanceof-subject:
    instanceof-subject   instanceof   class-type-designator
 
 instanceof-subject:
-   expression
+   unary-expression
 
**Constraints** -The *expression* in *instanceof-subject* must not be any form of literal. +The *unary-expression* in *instanceof-subject* must not be any form of literal. **Semantics** Operator `instanceof` returns `TRUE` if the value designated by -*expression* in *instanceof-subject* is an object having the type specified +*unary-expression* in *instanceof-subject* is an object having the type specified by *class-type-designator*, is an object whose type is derived from that type, or is an object whose type implements the interface specified by *class-type-designator*. Otherwise, it returns `FALSE`. diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 2162fbfc..4dfd3547 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -600,7 +600,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# instanceof-subject instanceof class-type-designator instanceof-subject: - expression + unary-expression logical-NOT-expression: instanceof-expression From 140cc0b4ff9b79da138e0ae547556d600cf49b13 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 10:22:41 +0200 Subject: [PATCH 094/146] yield has higher precedence than AND --- spec/00-specification-for-php.md | 2 +- spec/10-expressions.md | 160 +++++++++++++++---------------- spec/19-grammar.md | 16 ++-- 3 files changed, 89 insertions(+), 89 deletions(-) diff --git a/spec/00-specification-for-php.md b/spec/00-specification-for-php.md index 7e16198d..e8fa9b2d 100644 --- a/spec/00-specification-for-php.md +++ b/spec/00-specification-for-php.md @@ -150,10 +150,10 @@ is distributed without any warranty. - [Simple Assignment](10-expressions.md#simple-assignment) - [byRef Assignment](10-expressions.md#byref-assignment) - [Compound Assignment](10-expressions.md#compound-assignment) + - [`yield` Operator](10-expressions.md#yield-operator) - [Logical AND Operator (form 2)](10-expressions.md#logical-and-operator-form-2) - [Logical Exclusive OR Operator](10-expressions.md#logical-exclusive-or-operator) - [Logical Inclusive OR Operator (form 2)](10-expressions.md#logical-inclusive-or-operator-form-2) - - [`yield` Operator](10-expressions.md#yield-operator) - [Script Inclusion Operators](10-expressions.md#script-inclusion-operators) - [General](10-expressions.md#general-5) - [The `include` Operator](10-expressions.md#the-include-operator) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 9cc864eb..6176ba6b 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -3207,96 +3207,20 @@ $i = 1; $a[$i++] += 50; // $a[1] = 250, $i → 2 ``` -## Logical AND Operator (form 2) - -**Syntax** - - - -
-logical-AND-expression-2:
-   assignment-expression
-   logical-AND-expression-2   and   assignment-expression
-
- -**Semantics** - -Except for the difference in precedence, operator and has exactly the -same semantics as [operator `&&`](#logical-and-operator-form-1). - -## Logical Exclusive OR Operator - -**Syntax** - - - -
-logical-exc-OR-expression:
-   logical-AND-expression-2
-   logical-exc-OR-expression   xor   logical-AND-expression-2
-
- -**Semantics** - -If either operand does not have type `bool`, its value is first converted -to that type. - -Given the expression `e1 xor e2`, `e1` is evaluated first, then `e2`. If -either `e1` or `e2` [converted to `bool`](08-conversions.md#converting-to-boolean-type) as `TRUE`, but not both, the result has type `bool`, value -`TRUE`. Otherwise, the result has type `bool`, value `FALSE`. There is a -sequence point after the evaluation of `e1`. - -This operator associates left-to-right. - -**Examples** - -```PHP -f($i++) xor g($i) // the sequence point makes this well-defined -``` - -## Logical Inclusive OR Operator (form 2) - -**Syntax** - - - -
-logical-inc-OR-expression-2:
-   logical-exc-OR-expression
-   logical-inc-OR-expression-2   or   logical-exc-OR-expression
-
- -**Semantics** - -Except for the difference in precedence, operator and has exactly the -same semantics as [operator `||`](#logical-inclusive-or-operator-form-1). - ## `yield` Operator **Syntax**
 yield-expression:
-   logical-inc-OR-expression-2
+   assignment-expression
    yield   array-element-initializer
    yield from   expression
 
@@ -3411,6 +3335,82 @@ foreach ($g as $yielded) { } ``` +## Logical AND Operator (form 2) + +**Syntax** + + + +
+logical-AND-expression-2:
+   yield-expression
+   logical-AND-expression-2   and   yield-expression
+
+ +**Semantics** + +Except for the difference in precedence, operator and has exactly the +same semantics as [operator `&&`](#logical-and-operator-form-1). + +## Logical Exclusive OR Operator + +**Syntax** + + + +
+logical-exc-OR-expression:
+   logical-AND-expression-2
+   logical-exc-OR-expression   xor   logical-AND-expression-2
+
+ +**Semantics** + +If either operand does not have type `bool`, its value is first converted +to that type. + +Given the expression `e1 xor e2`, `e1` is evaluated first, then `e2`. If +either `e1` or `e2` [converted to `bool`](08-conversions.md#converting-to-boolean-type) as `TRUE`, but not both, the result has type `bool`, value +`TRUE`. Otherwise, the result has type `bool`, value `FALSE`. There is a +sequence point after the evaluation of `e1`. + +This operator associates left-to-right. + +**Examples** + +```PHP +f($i++) xor g($i) // the sequence point makes this well-defined +``` + +## Logical Inclusive OR Operator (form 2) + +**Syntax** + + + +
+logical-inc-OR-expression-2:
+   logical-exc-OR-expression
+   logical-inc-OR-expression-2   or   logical-exc-OR-expression
+
+ +**Semantics** + +Except for the difference in precedence, operator and has exactly the +same semantics as [operator `||`](#logical-inclusive-or-operator-form-1). + ## Script Inclusion Operators ### General @@ -3419,7 +3419,7 @@ foreach ($g as $yielded) {
@@ -1326,10 +1326,10 @@ variadic-unpacking:
 
 argument-expression:
    variadic-unpacking
-   assignment-expression
+   expression
 
 variadic-unpacking:
-   ...   assignment-expression
+   ...   expression
 
**Constraints** @@ -1358,7 +1358,7 @@ call*. The expression designates the *called function*, and *argument-expression-list* specifies the arguments to be passed to that function. An argument can be any value. In a function call, *callable-expression* is evaluated first, followed by each -*assignment-expression* in the order left-to-right. There is +*expression* in the order left-to-right. There is a [sequence point](#general) after each argument is evaluated and right before the function is called. For details of the result of a function call see [`return` statement](11-statements.md#the-return-statement). The value of a function call is a modifiable lvalue only if the function returns a modifiable value byRef. diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 3aeb971f..249f65dc 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -515,10 +515,10 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# argument-expression: variadic-unpacking - assignment-expression + expression variadic-unpacking: - ... assignment-expression + ... expression member-access-expression: dereferencable-expression -> member-name From 57e9922e041babddc29de6fde7a45f6f7bf20573 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 11:29:33 +0200 Subject: [PATCH 096/146] Move list() out of intrinsic section This is not a general-purpose expression, it is only valid in specific syntactic contexts. --- spec/00-specification-for-php.md | 2 +- spec/10-expressions.md | 266 +++++++++++++++---------------- spec/19-grammar.md | 41 +++-- 3 files changed, 153 insertions(+), 156 deletions(-) diff --git a/spec/00-specification-for-php.md b/spec/00-specification-for-php.md index e8fa9b2d..891cc9e0 100644 --- a/spec/00-specification-for-php.md +++ b/spec/00-specification-for-php.md @@ -110,7 +110,6 @@ is distributed without any warranty. - [eval](10-expressions.md#eval) - [exit/die](10-expressions.md#exitdie) - [isset](10-expressions.md#isset) - - [list](10-expressions.md#list) - [print](10-expressions.md#print) - [unset](10-expressions.md#unset) - [Anonymous Function Creation](10-expressions.md#anonymous-function-creation) @@ -148,6 +147,7 @@ is distributed without any warranty. - [Assignment Operators](10-expressions.md#assignment-operators) - [General](10-expressions.md#general-4) - [Simple Assignment](10-expressions.md#simple-assignment) + - [list intrinsic](10-expressions.md#list-intrinsic) - [byRef Assignment](10-expressions.md#byref-assignment) - [Compound Assignment](10-expressions.md#compound-assignment) - [`yield` Operator](10-expressions.md#yield-operator) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 39c909e5..8f11177f 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -321,7 +321,6 @@ intrinsic: intrinsic-construct: echo-intrinsic - list-intrinsic unset-intrinsic intrinsic-operator: @@ -339,7 +338,6 @@ intrinsic-operator: intrinsic-construct: echo-intrinsic - list-intrinsic unset-intrinsic intrinsic-operator: @@ -592,138 +590,6 @@ $v1 = TRUE; $v2 = 12.3; $v3 = NULL; isset($v1, $v2, $v3); // results in FALSE ``` -#### list - -**Syntax** - - - -
-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
-   variable
-
- -**Constraints** - -*list-intrinsic* must be used as the left-hand operand in a -[*simple-assignment-expression*](#simple-assignment) of which the right-hand -operand must be an expression that designates an array or object implementing -the `ArrayAccess` interface (called the *source array*). - -Each *variable* in *list-or-variable* must designate a writable variable (called -the *target variable*). - -At least one of the elements of the *list-expression-list* must be non-empty. - -**Semantics** - -This intrinsic assigns one or more elements of the source array to the -target variables. On success, it returns a copy of the source array. If the -source array is not an array or object implementing `ArrayAccess` no -assignments are performed and the return value is `NULL`. - -For *unkeyed-list-expression-list*, all elements in the source array having -keys of type `string` are ignored. -The element having an `int` key of 0 is assigned to the first target -variable, the element having an `int` key of 1 is assigned to the second -target variable, and so on, until all target variables have been -assigned. Any other array elements are ignored. If there are -fewer source array elements having int keys than there are target -variables, the unassigned target variables are set to `NULL` and -a non-fatal error is produced. - -For *keyed-list-expression-list*, each key-variable pair is handled in turn, -with the key and variable being separated by the `=>` symbol. -The element having the first key, with the key having been converted using the -same rules as the [subscript operator](10-expressions.md#subscript-operator), -is assigned to the frst target variable. This process is repeated for the -second `=>` pair, if any, and so on. Any other array elements are ignored. -If there is no array element with a given key, the unassigned target variable -is set to `NULL` and a non-fatal error is produced. - -The assignments must occur in this order. - -Any target variable may be a list, in which case, the corresponding -element is expected to be an array. - -If the source array elements and the target variables overlap in any -way, the behavior is unspecified. - -**Examples** - -```PHP -list($min, $max, $avg) = array(0, 100, 67); - // $min is 0, $max is 100, $avg is 67 -list($min, $max, $avg) = array(2 => 67, 1 => 100, 0 => 0); - // same as example above -list($min, , $avg) = array(0, 100, 67); - // $min is 0, $avg is 67 -list($min, $max, $avg) = array(0, 2 => 100, 4 => 67); - // $min is 0, $max is NULL, $avg is 100 -list($min, list($max, $avg)) = [0, [1 => 67, 99, 0 => 100], 33]; - // $min is 0, $max is 100, $avg is 67 - -list($arr[1], $arr[0]) = [0, 1]; - // $arr is [1 => 0, 0 => 1], in this order -list($arr2[], $arr2[]) = [0, 1]; - // $arr2 is [0, 1] - -list("one" => $one, "two" => $two) = ["one" => 1, "two" => 2]; - // $one is 1, $two is 2 -list( - "one" => $one, - "two" => $two, -) = [ - "one" => 1, - "two" => 2, -]; - // $one is 1, $two is 2 -list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = [ - ["x" => 1, "y" => 2], - ["x" => 3, "y" => 4] -]; - // $x1 is 1, $y1 is 2, $x2 is 3, $y2 is 4 -list(0 => list($x1, $x2), 1 => list($x2, $y2)) = [[1, 2], [3, 4]]; - // $x1 is 1, $y1 is 2, $x2 is 3, $y2 is 4 -``` - #### print **Syntax** @@ -3124,6 +2990,138 @@ class C { ... } $a = new C; // make $a point to the allocated object ``` +#### list intrinsic + +**Syntax** + + + +
+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
+   variable
+
+ +**Constraints** + +*list-intrinsic* must be used as the left-hand operand in a +[*simple-assignment-expression*](#simple-assignment) of which the right-hand +operand must be an expression that designates an array or object implementing +the `ArrayAccess` interface (called the *source array*). + +Each *variable* in *list-or-variable* must designate a writable variable (called +the *target variable*). + +At least one of the elements of the *list-expression-list* must be non-empty. + +**Semantics** + +This intrinsic assigns one or more elements of the source array to the +target variables. On success, it returns a copy of the source array. If the +source array is not an array or object implementing `ArrayAccess` no +assignments are performed and the return value is `NULL`. + +For *unkeyed-list-expression-list*, all elements in the source array having +keys of type `string` are ignored. +The element having an `int` key of 0 is assigned to the first target +variable, the element having an `int` key of 1 is assigned to the second +target variable, and so on, until all target variables have been +assigned. Any other array elements are ignored. If there are +fewer source array elements having int keys than there are target +variables, the unassigned target variables are set to `NULL` and +a non-fatal error is produced. + +For *keyed-list-expression-list*, each key-variable pair is handled in turn, +with the key and variable being separated by the `=>` symbol. +The element having the first key, with the key having been converted using the +same rules as the [subscript operator](10-expressions.md#subscript-operator), +is assigned to the frst target variable. This process is repeated for the +second `=>` pair, if any, and so on. Any other array elements are ignored. +If there is no array element with a given key, the unassigned target variable +is set to `NULL` and a non-fatal error is produced. + +The assignments must occur in this order. + +Any target variable may be a list, in which case, the corresponding +element is expected to be an array. + +If the source array elements and the target variables overlap in any +way, the behavior is unspecified. + +**Examples** + +```PHP +list($min, $max, $avg) = array(0, 100, 67); + // $min is 0, $max is 100, $avg is 67 +list($min, $max, $avg) = array(2 => 67, 1 => 100, 0 => 0); + // same as example above +list($min, , $avg) = array(0, 100, 67); + // $min is 0, $avg is 67 +list($min, $max, $avg) = array(0, 2 => 100, 4 => 67); + // $min is 0, $max is NULL, $avg is 100 +list($min, list($max, $avg)) = [0, [1 => 67, 99, 0 => 100], 33]; + // $min is 0, $max is 100, $avg is 67 + +list($arr[1], $arr[0]) = [0, 1]; + // $arr is [1 => 0, 0 => 1], in this order +list($arr2[], $arr2[]) = [0, 1]; + // $arr2 is [0, 1] + +list("one" => $one, "two" => $two) = ["one" => 1, "two" => 2]; + // $one is 1, $two is 2 +list( + "one" => $one, + "two" => $two, +) = [ + "one" => 1, + "two" => 2, +]; + // $one is 1, $two is 2 +list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = [ + ["x" => 1, "y" => 2], + ["x" => 3, "y" => 4] +]; + // $x1 is 1, $y1 is 2, $x2 is 3, $y2 is 4 +list(0 => list($x1, $x2), 1 => list($x2, $y2)) = [[1, 2], [3, 4]]; + // $x1 is 1, $y1 is 2, $x2 is 3, $y2 is 4 +``` + ### byRef Assignment **Syntax** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 249f65dc..1d74076e 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -389,7 +389,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# intrinsic-construct: echo-intrinsic - list-intrinsic unset-intrinsic intrinsic-operator: @@ -425,26 +424,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# variable variable-list , variable -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 - variable - print-intrinsic: print expression @@ -677,6 +656,26 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# 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 + variable + byref-assignment-expression: variable = & variable From cbb78dacad82dfc11e12399ab076d023f8efea69 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 11:35:44 +0200 Subject: [PATCH 097/146] Move echo and unset from intrinsics to statements --- spec/00-specification-for-php.md | 4 +- spec/10-expressions.md | 123 ------------------------------- spec/11-statements.md | 107 +++++++++++++++++++++++++++ spec/19-grammar.md | 30 +++----- 4 files changed, 121 insertions(+), 143 deletions(-) diff --git a/spec/00-specification-for-php.md b/spec/00-specification-for-php.md index 891cc9e0..92b26120 100644 --- a/spec/00-specification-for-php.md +++ b/spec/00-specification-for-php.md @@ -105,13 +105,11 @@ is distributed without any warranty. - [Literals](10-expressions.md#literals) - [Intrinsics](10-expressions.md#intrinsics) - [General](10-expressions.md#general-2) - - [echo](10-expressions.md#echo) - [empty](10-expressions.md#empty) - [eval](10-expressions.md#eval) - [exit/die](10-expressions.md#exitdie) - [isset](10-expressions.md#isset) - [print](10-expressions.md#print) - - [unset](10-expressions.md#unset) - [Anonymous Function Creation](10-expressions.md#anonymous-function-creation) - [The `new` Operator](10-expressions.md#the-new-operator) - [Array Creation Operator](10-expressions.md#array-creation-operator) @@ -185,6 +183,8 @@ is distributed without any warranty. - [The `throw` Statement](11-statements.md#the-throw-statement) - [The `try` Statement](11-statements.md#the-try-statement) - [The `declare` Statement](11-statements.md#the-declare-statement) + - [The `echo` statement](11-statements.md#the-echo-statement) + - [The `unset` statement](11-statements.md#the-unset-statement) - [Arrays](12-arrays.md#arrays) - [General](12-arrays.md#general) - [Array Creation and Initialization](12-arrays.md#array-creation-and-initialization) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 8f11177f..8cf1ae8e 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -316,14 +316,6 @@ A literal evaluates to its value, as specified in the lexical specification for **Syntax** - -
-echo-intrinsic:
-   echo   expression-list
-
-expression-list:
-   expression
-   expression-list   ,   expression
-
- -**Constraints** - -*expression* value must be [convertable to a string](08-conversions.md#converting-to-string-type). -In particular, it should not be an array and if it is an object, it must implement -a [`__toString` method](14-classes.md#method-__tostring). - -**Semantics** - -After converting each of its *expression*s' values to strings, if -necessary, `echo` concatenates them in order given, and writes the -resulting string to [`STDOUT`](06-constants.md#core-predefined-constants). Unlike [`print`](#print), it does -not produce a result. - -See also: [double quoted strings](09-lexical-structure.md#double-quoted-string-literals) and -[heredoc documents](09-lexical-structure.md#heredoc-string-literals), [conversion to string](08-conversions.md#converting-to-string-type). - -**Examples** - -```PHP -$v1 = TRUE; -$v2 = 123; -echo '>>' . $v1 . '|' . $v2 . "<<\n"; // outputs ">>1|123<<" -echo '>>' , $v1 , '|' , $v2 , "<<\n"; // outputs ">>1|123<<" -echo ('>>' . $v1 . '|' . $v2 . "<<\n"); // outputs ">>1|123<<" -$v3 = "qqq{$v2}zzz"; -echo "$v3\n"; -``` - #### empty **Syntax** @@ -632,58 +561,6 @@ print "$v3\n"; // outputs "qqq123zzz" $a > $b ? print "..." : print "..."; ``` -#### unset - -**Syntax** - - - -
-unset-intrinsic:
-   unset   (   variable-list   )
-
- -**Semantics** - -This intrinsic [unsets](07-variables.md#general) the variables designated by each -*variable* in *variable-list*. No value is returned. An -attempt to unset a non-existent variable (such as a non-existent element -in an array) is ignored. - -When called from inside a function, this intrinsic behaves, as follows: - -- For a variable declared `global` in that function, `unset` removes the - alias to that variable from the scope of the current call to that - function. The global variable remains set. - (To unset the global variable, use unset on the corresponding - [`$GLOBALS`](07-variables.md#predefined-variables) array entry. -- For a variable passed byRef to that function, `unset` removes the - alias to that variable from the scope of the current call to that - function. Once the function returns, the passed-in argument variable - is still set. -- For a variable declared static in that function, `unset` removes the - alias to that variable from the scope of the current call to that - function. In subsequent calls to that function, the static variable - is still set and retains its value from call to call. - -Any visible instance property may be unset, in which case, the property -is removed from that instance. - -If this intrinsic is used with an expression that designates a [dynamic -property](14-classes.md#dynamic-members), then if the class of that property has an [`__unset` -method](14-classes.md#method-__unset), that method is called. - -**Examples** - -```PHP -unset($v); -unset($v1, $v2, $v3); -unset($x->m); // if m is a dynamic property, $x->__unset("m") is called -``` - ### Anonymous Function Creation **Syntax** diff --git a/spec/11-statements.md b/spec/11-statements.md index 427c74b8..2ecec513 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -14,6 +14,8 @@ statement: jump-statement try-statement declare-statement + echo-statement + unset-statement const-declaration function-definition class-declaration @@ -35,6 +37,8 @@ statement: jump-statement try-statement declare-statement + echo-statement + unset-statement const-declaration function-definition class-declaration @@ -1286,3 +1290,106 @@ declare(ticks = 1) { ... } declare(encoding = 'ISO-8859-1'); // Latin-1 Western European declare(encoding = 'ISO-8859-5'); // Latin/Cyrillic ``` + +## The `echo` statement + +**Syntax** + + + +
+echo-statement:
+   echo   expression-list   ;
+
+expression-list:
+   expression
+   expression-list   ,   expression
+
+ +**Constraints** + +The *expression* value must be +[convertable to a string](08-conversions.md#converting-to-string-type). +In particular, it should not be an array and if it is an object, it must implement +a [`__toString` method](14-classes.md#method-__tostring). + +**Semantics** + +After converting each of its *expression*s' values to strings, if +necessary, `echo` concatenates them in order given, and writes the +resulting string to [`STDOUT`](06-constants.md#core-predefined-constants). Unlike [`print`](10-expressions.md#print), it does +not produce a result. + +See also: [double quoted strings](09-lexical-structure.md#double-quoted-string-literals) and +[heredoc documents](09-lexical-structure.md#heredoc-string-literals), [conversion to string](08-conversions.md#converting-to-string-type). + +**Examples** + +```PHP +$v1 = TRUE; +$v2 = 123; +echo '>>' . $v1 . '|' . $v2 . "<<\n"; // outputs ">>1|123<<" +echo '>>' , $v1 , '|' , $v2 , "<<\n"; // outputs ">>1|123<<" +echo ('>>' . $v1 . '|' . $v2 . "<<\n"); // outputs ">>1|123<<" +$v3 = "qqq{$v2}zzz"; +echo "$v3\n"; +``` + +## The `unset` statement + +**Syntax** + + + +
+unset-statement:
+   unset   (   variable-list   )   ;
+
+ +**Semantics** + +This statement [unsets](07-variables.md#general) the variables designated by each +*variable* in *variable-list*. No value is returned. An +attempt to unset a non-existent variable (such as a non-existent element +in an array) is ignored. + +When called from inside a function, this statement behaves, as follows: + +- For a variable declared `global` in that function, `unset` removes the + alias to that variable from the scope of the current call to that + function. The global variable remains set. + (To unset the global variable, use unset on the corresponding + [`$GLOBALS`](07-variables.md#predefined-variables) array entry. +- For a variable passed byRef to that function, `unset` removes the + alias to that variable from the scope of the current call to that + function. Once the function returns, the passed-in argument variable + is still set. +- For a variable declared static in that function, `unset` removes the + alias to that variable from the scope of the current call to that + function. In subsequent calls to that function, the static variable + is still set and retains its value from call to call. + +Any visible instance property may be unset, in which case, the property +is removed from that instance. + +If this statement is used with an expression that designates a [dynamic +property](14-classes.md#dynamic-members), then if the class of that property has an [`__unset` +method](14-classes.md#method-__unset), that method is called. + +**Examples** + +```PHP +unset($v); +unset($v1, $v2, $v3); +unset($x->m); // if m is a dynamic property, $x->__unset("m") is called +``` diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 1d74076e..821487b4 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -384,27 +384,12 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# string-literal intrinsic: - intrinsic-construct - intrinsic-operator - -intrinsic-construct: - echo-intrinsic - unset-intrinsic - -intrinsic-operator: empty-intrinsic eval-intrinsic exit-intrinsic isset-intrinsic print-intrinsic -echo-intrinsic: - echo expression-list - -expression-list: - expression - expression-list , expression - empty-intrinsic: empty ( expression ) @@ -427,9 +412,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# print-intrinsic: print expression -unset-intrinsic: - unset ( variable-list ) - anonymous-function-creation-expression: staticopt function &opt ( parameter-declaration-listopt ) anonymous-function-use-clauseopt return-typeopt compound-statement @@ -737,6 +719,8 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# jump-statement try-statement declare-statement + echo-statement + unset-statement const-declaration function-definition class-declaration @@ -899,6 +883,16 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# ticks = literal encoding = literal strict_types = literal + +echo-statement: + echo expression-list ; + +expression-list: + expression + expression-list , expression + +unset-statement: + unset ( variable-list ) ;
### Functions From 1baff2105284c1e964de18fc7d40d7b1dc6900a0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 19 Sep 2017 11:44:28 +0200 Subject: [PATCH 098/146] Fix some references These got left behind after shuffling things around too much. --- spec/04-basic-concepts.md | 16 +++++++++------- spec/07-variables.md | 8 ++++---- spec/10-expressions.md | 6 +++--- spec/11-statements.md | 3 ++- spec/12-arrays.md | 2 +- spec/14-classes.md | 6 +++--- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/spec/04-basic-concepts.md b/spec/04-basic-concepts.md index 9887815d..bdb84eb0 100644 --- a/spec/04-basic-concepts.md +++ b/spec/04-basic-concepts.md @@ -43,7 +43,8 @@ text: All of the sections in a script are treated as though they belonged to one continuous section, except that any intervening text is treated as -though it were a string literal given to the [intrinsic `echo`](10-expressions.md#echo). +though it were a string literal given to the +[`echo` statement](11-statements.md#the-echo-statement). A script can import another script via a [script inclusion operator](10-expressions.md#script-inclusion-operators). @@ -51,8 +52,8 @@ A script can import another script via a [script inclusion operator](10-expressi The top level of a script is simply referred to as the *top level*. -If ` Date: Mon, 25 Sep 2017 21:37:18 +0200 Subject: [PATCH 099/146] Fix grammar for breakout-level The optional breakout-level constant for `break` and `continue` statements can also be enclosed in parentheses. --- spec/11-statements.md | 2 ++ spec/19-grammar.md | 1 + 2 files changed, 3 insertions(+) diff --git a/spec/11-statements.md b/spec/11-statements.md index f3aa7780..99f60d08 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -831,6 +831,7 @@ continue-statement: breakout-level: integer-literal + '(' breakout-level ')' -->
@@ -839,6 +840,7 @@ breakout-level:
 
 breakout-level:
    integer-literal
+   (   breakout-level   )
 
**Constraints** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 821487b4..66573bfa 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -849,6 +849,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# breakout-level: integer-literal + ( breakout-level ) break-statement: break breakout-levelopt ; From 7741beb3af80779a223bc61ef0d4d7a31bf12f50 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 26 Sep 2017 10:53:52 +0200 Subject: [PATCH 100/146] Add sample git pre-commit hook --- tools/pre-commit | 4 ++++ 1 file changed, 4 insertions(+) create mode 100755 tools/pre-commit diff --git a/tools/pre-commit b/tools/pre-commit new file mode 100755 index 00000000..3fb22d32 --- /dev/null +++ b/tools/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +php tools/grammar.php && \ +php tools/toc.php && \ +php tools/check_refs.php From b0e2ca93602b649d936295a0fceaec5381b64101 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 26 Sep 2017 10:59:40 +0200 Subject: [PATCH 101/146] Mention generated files + pre-commit hook in CONTRIBUTING --- CONTRIBUTING.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0b60901b..681fd4b8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,24 @@ ## Contributing to the Specification for PHP We'd love your help in improving, correcting, adding to the specification. -Please [file an issue](https://bugs.php.net/) or [submit a pull request](https://wiki.php.net/vcs/gitworkflow) -at the [spec git repo](https://github.com/php/php-langspec). +Please [file an issue](https://github.com/php/php-langspec/issues) +or [submit a pull request](https://github.com/php/php-langspec/pulls). + +## Generated content + +The grammar listings and table of contents of the specification are automatically +generated. If you want to change the grammar, you need to modify the respective +`
 member-call-expression:
    dereferencable-expression   ->   member-name   (   argument-expression-listopt   )
+   dereferencable-expression   ->   member-name   (   argument-expression-list   ,   )
 
**Constraints** @@ -1496,6 +1504,7 @@ scoped-property-access-expression: scoped-call-expression: scope-resolution-qualifier '::' member-name '(' argument-expression-list? ')' + scope-resolution-qualifier '::' member-name '(' argument-expression-list ',' ')' class-constant-access-expression: scope-resolution-qualifier '::' name @@ -1517,6 +1526,7 @@ relative-scope: 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 diff --git a/spec/11-statements.md b/spec/11-statements.md index 6534929f..39bd0ce1 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -1361,12 +1361,12 @@ echo "$v3\n";
 unset-statement:
-   unset   (   variable-list   )   ;
+   unset   (   variable-list   ,opt   )   ;
 
**Semantics** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index e6473426..c9cd8282 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -403,7 +403,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# die ( expressionopt ) isset-intrinsic: - isset ( variable-list ) + isset ( variable-list ,opt ) variable-list: variable @@ -424,6 +424,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# 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 } @@ -468,7 +469,9 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# 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 @@ -491,6 +494,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# member-call-expression: dereferencable-expression -> member-name ( argument-expression-listopt ) + dereferencable-expression -> member-name ( argument-expression-list , ) postfix-increment-expression: variable ++ @@ -512,6 +516,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# 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 @@ -897,7 +902,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# expression-list , expression unset-statement: - unset ( variable-list ) ; + unset ( variable-list ,opt ) ;
### Functions diff --git a/tests/classes/dynamic_methods.phpt b/tests/classes/dynamic_methods.phpt index 0fb4b6ae..002497ec 100644 --- a/tests/classes/dynamic_methods.phpt +++ b/tests/classes/dynamic_methods.phpt @@ -50,7 +50,7 @@ $obj = new Widget; $v = $obj->iDoit(); $obj->__call('iDoit', []); -$v = $obj->iMethod(10, TRUE, "abc"); +$v = $obj->iMethod(10, TRUE, "abc",); var_dump($v); $obj->__call('iMethod', array(10, TRUE, "abc")); $obj->__call('123#$%', []); @@ -58,7 +58,7 @@ $obj->__call('123#$%', []); $v = Widget::sDoit(); Widget::__callStatic('sDoit', []); -$v = Widget::sMethod(NULL, 1.234); +$v = Widget::sMethod(NULL, 1.234,); var_dump($v); Widget::__callStatic('sMethod', array(NULL, 1.234)); Widget::__callStatic('[]{}', []); diff --git a/tests/classes/property_initializer.phpt b/tests/classes/property_initializer.phpt index 368de322..8837354a 100644 --- a/tests/classes/property_initializer.phpt +++ b/tests/classes/property_initializer.phpt @@ -35,7 +35,7 @@ echo $p . "\n"; $p = new Point(); echo $p . "\n"; -$p = new Point(100); +$p = new Point(100,); echo $p . "\n"; $p = new Point(1000, 2000); diff --git a/tests/expressions/primary_expressions/intrinsics_isset.phpt b/tests/expressions/primary_expressions/intrinsics_isset.phpt index 86293ee4..2dfd4907 100644 --- a/tests/expressions/primary_expressions/intrinsics_isset.phpt +++ b/tests/expressions/primary_expressions/intrinsics_isset.phpt @@ -15,6 +15,10 @@ echo "--------- TRUE -------------\n"; $v = TRUE; var_dump(isset($v)); +echo "--------- TRUE -------------\n"; + +$v = TRUE; +var_dump(isset($v,)); echo "--------- NULL -------------\n"; @@ -52,6 +56,8 @@ var_dump(isset($x2->m)); --EXPECTF-- --------- TRUE ------------- bool(true) +--------- TRUE ------------- +bool(true) --------- NULL ------------- bool(false) --------- TRUE, 12.3, NULL ------------- diff --git a/tests/expressions/primary_expressions/intrinsics_unset.phpt b/tests/expressions/primary_expressions/intrinsics_unset.phpt index 3e775806..7ec56a45 100644 --- a/tests/expressions/primary_expressions/intrinsics_unset.phpt +++ b/tests/expressions/primary_expressions/intrinsics_unset.phpt @@ -18,6 +18,13 @@ var_dump(isset($v)); unset($v); var_dump(isset($v)); +echo "--------- TRUE -------------\n"; + +$v = TRUE; +var_dump(isset($v)); +unset($v,); +var_dump(isset($v)); + echo "--------- NULL -------------\n"; $v = NULL; @@ -164,6 +171,9 @@ print_r($a); --------- TRUE ------------- bool(true) bool(false) +--------- TRUE ------------- +bool(true) +bool(false) --------- NULL ------------- bool(false) bool(false) diff --git a/tests/functions/basics.phpt b/tests/functions/basics.phpt index 5cebce85..f8e1bec4 100644 --- a/tests/functions/basics.phpt +++ b/tests/functions/basics.phpt @@ -39,7 +39,7 @@ $f(); // call f1 indirectly via $f // f1() = 123; // a function return is not an lvalue f1(); -f1(10); +f1(10,); f1(TRUE, "green"); f1(23.45, NULL, array(1,2,3)); From 313688242e8cefdd99349f592a81a67a157c0fb6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 22 Dec 2018 13:29:45 +0100 Subject: [PATCH 119/146] Adjust constant warning message for PHP 7.3 The spec already correctly mentions that resources are allowed. The warning was clarified in PHP 7.3. --- tests/constants/constants.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/constants/constants.phpt b/tests/constants/constants.phpt index b1fe1c45..5e6b66f9 100644 --- a/tests/constants/constants.phpt +++ b/tests/constants/constants.phpt @@ -214,7 +214,7 @@ define COLORS succeeded Notice: Array to string conversion in %s/constants/constants.php on line 16 ; value is >Array< -Warning: Constants may only evaluate to scalar values or arrays in %s/constants/constants.php on line 13 +Warning: Constants may only evaluate to scalar values, arrays or resources in %s/constants/constants.php on line 13 define MY_OBJECT failed; not defined Warning: fopen(Testfile.txt): failed to open stream: No such file or directory in %s/constants/constants.php on line 90 From 2c380e4cc0a62485fd0a77af86a5b847949ab742 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 22 Dec 2018 13:39:27 +0100 Subject: [PATCH 120/146] Use PHP 7.3 on Travis Apparently the master/nightly builds haven't updated since September... --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 89a4b980..594e5103 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: php php: - - master + - 7.3 script: - - REPORT_EXIT_STATUS=1 TEST_PHP_EXECUTABLE=~/.phpenv/versions/$(phpenv version-name)/bin/php php ~/.phpenv/versions/$(phpenv version-name)/lib/php/build/run-tests.php -c ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini -q -x --show-diff + - REPORT_EXIT_STATUS=1 php ~/.phpenv/versions/$(phpenv version-name)/lib/php/build/run-tests.php -P -c ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini -q -x --show-diff From 1058a5042032e0ad00aed869ce80b839f3927d2c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 14 Mar 2019 13:33:24 +0100 Subject: [PATCH 121/146] Fix precedence of by-ref assignment Because it has variables on both sides, this is a primary expression. --- spec/10-expressions.md | 4 ++-- spec/19-grammar.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 060f1f32..15231792 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -103,6 +103,7 @@ primary-expression: postfix-decrement-expression prefix-increment-expression prefix-decrement-expression + byref-assignment-expression shell-command-expression '(' expression ')' --> @@ -121,6 +122,7 @@ primary-expression: postfix-decrement-expression prefix-increment-expression prefix-decrement-expression + byref-assignment-expression shell-command-expression ( expression )
@@ -2786,7 +2788,6 @@ function factorial($int) assignment-expression: conditional-expression simple-assignment-expression - byref-assignment-expression compound-assignment-expression --> @@ -2794,7 +2795,6 @@ assignment-expression: assignment-expression: conditional-expression simple-assignment-expression - byref-assignment-expression compound-assignment-expression
diff --git a/spec/19-grammar.md b/spec/19-grammar.md index c9cd8282..8e2e69f4 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -343,6 +343,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# postfix-decrement-expression prefix-increment-expression prefix-decrement-expression + byref-assignment-expression shell-command-expression ( expression ) @@ -636,7 +637,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# assignment-expression: conditional-expression simple-assignment-expression - byref-assignment-expression compound-assignment-expression simple-assignment-expression: From b0dadd509b0fa94667f96ef32af4481ff2a23e1e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 15 Mar 2019 09:47:54 +0100 Subject: [PATCH 122/146] Fix yield / yield from precedence --- spec/10-expressions.md | 45 +++++++++++++++++++++--------------------- spec/19-grammar.md | 10 +++++++--- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 15231792..3ae61b3b 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -3097,17 +3097,25 @@ $a[$i++] += 50; // $a[1] = 250, $i → 2 **Syntax**
+yield-from-expression:
+   yield from   assignment-expression
+
 yield-expression:
-   assignment-expression
-   yield   array-element-initializer
-   yield from   expression
+   yield-from-expression
+   yield
+   yield   yield-expression
+   yield   yield-from-expression   =>   yield-expression
 
**Semantics** @@ -3127,22 +3135,13 @@ The `yield` operator produces the result `NULL` unless the method [`Generator->send`](14-classes.md#class-generator) was called to provide a result value. This operator has the side effect of generating the next value in the collection. -Before being used, an *element-key* must have, or be converted to, type -`int` or `string`. Keys with `float` or `bool` values, or numeric strings, are -[converted to `int`](08-conversions.md#converting-to-integer-type). Values of all other key types are [converted to -`string`](08-conversions.md#converting-to-string-type). - -If *element-key* is omitted from an *array-element-initializer*, an +If the key is omitted from an a *yield-expression*, an element key of type `int` is associated with the corresponding -*element-value*. The key associated is one more than the previously +value. The key associated is one more than the previously assigned int key for this collection. However, if this is the first -element in this collection with an `int` key, key zero is used. If -*element-key* is provided, it is associated with the corresponding -*element-value*. The resulting key/value pair is made available by -`yield`. +element in this collection with an `int` key, zero is used. -If *array-element-initializer* is omitted, default int-key assignment is -used and each value is `NULL`. +If the value is also omitted, `NULL` will be used instead. If the generator function definition declares that it returns byRef, each value in a key/value pair is yielded byRef. @@ -3151,15 +3150,15 @@ The following applies only to the `yield from` form: A generator function (referred to as a *delegating generator*) can delegate to another generator function (referred to as a *subgenerator*), a Traversable object, or an array, each of which is designated by *expression*. -Each value yielded by *expression* is passed directly to the delegating generator's caller. +Each value yielded by *assignment-expression* is passed directly to the delegating generator's caller. -Each value sent to the delegating generator's `send` method is passed to the subgenerator's `send` method. If *expression* is not a generator function, any sent values are ignored. +Each value sent to the delegating generator's `send` method is passed to the subgenerator's `send` method. If *assignment-expression* is not a generator function, any sent values are ignored. -Exceptions thrown by *expression* are propagated up to the delegating generator. +Exceptions thrown by *assignment-expression* are propagated up to the delegating generator. Upon traversable completion, `NULL` is returned to the delegating generator if the traversable is not a generator. If the traversable is a generator, its return value is sent to the delegating generator as the value of the `yield from` *expression*. -An exception of type `Error` is thrown if *expression* evaluates to a generator that previously terminated with an uncaught exception, or it evaluates to something that is neither Traversable nor an array. +An exception of type `Error` is thrown if *assignment-expression* evaluates to a generator that previously terminated with an uncaught exception, or it evaluates to something that is neither Traversable nor an array. **Examples** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 8e2e69f4..8d51d22b 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -672,10 +672,14 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# compound-assignment-operator: one of **= *= /= %= += -= .= <<= >>= &= ^= |= +yield-from-expression: + yield from assignment-expression + yield-expression: - assignment-expression - yield array-element-initializer - yield from expression + yield-from-expression + yield + yield yield-expression + yield yield-from-expression => yield-expression logical-AND-expression-2: yield-expression From 63d72a6df5d2c7b1b7a8aedde1410c780cfd92af Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 15 Mar 2019 09:52:05 +0100 Subject: [PATCH 123/146] Fix print precedence --- spec/10-expressions.md | 88 +++++++++++++++++++++--------------------- spec/19-grammar.md | 8 ++-- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 3ae61b3b..988acaf9 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -322,7 +322,6 @@ intrinsic: eval-intrinsic exit-intrinsic isset-intrinsic - print-intrinsic -->
@@ -331,7 +330,6 @@ intrinsic:
    eval-intrinsic
    exit-intrinsic
    isset-intrinsic
-   print-intrinsic
 
**Semantics** @@ -521,48 +519,6 @@ $v1 = TRUE; $v2 = 12.3; $v3 = NULL; isset($v1, $v2, $v3); // results in FALSE ``` -#### print - -**Syntax** - - - -
-print-intrinsic:
-   print   expression
-
- -**Constraints** - -*expression* value must be [convertable to a string](08-conversions.md#converting-to-string-type). -In particular, it should not be an array and if it is an object, it must implement -a [`__toString` method](14-classes.md#method-__tostring). - -**Semantics** - -After converting its *expression*'s value to a string, if necessary, -`print` writes the resulting string to [`STDOUT`](06-constants.md#core-predefined-constants). -Unlike [`echo`](11-statements.md#the-echo-statement), `print` can be used in any context -allowing an expression. It always returns the value 1. - -See also: [double quoted strings](09-lexical-structure.md#double-quoted-string-literals) and -[heredoc documents](09-lexical-structure.md#heredoc-string-literals), [conversion to string](08-conversions.md#converting-to-string-type). - -**Examples** - -```PHP -$v1 = TRUE; -$v2 = 123; -print '>>' . $v1 . '|' . $v2 . "<<\n"; // outputs ">>1|123<<" -print ('>>' . $v1 . '|' . $v2 . "<<\n"); // outputs ">>1|123<<" -$v3 = "qqq{$v2}zzz"; -print "$v3\n"; // outputs "qqq123zzz" -$a > $b ? print "..." : print "..."; -``` - ### Anonymous Function Creation **Syntax** @@ -3219,6 +3175,50 @@ foreach ($g as $yielded) { } ``` +## Print expression + +**Syntax** + + + +
+print-expression:
+   yield-expression
+   print   print-expression
+
+ +**Constraints** + +*print-expression* value must be [convertable to a string](08-conversions.md#converting-to-string-type). +In particular, it should not be an array and if it is an object, it must implement +a [`__toString` method](14-classes.md#method-__tostring). + +**Semantics** + +After converting *print-expression*'s value into a string, if necessary, +`print` writes the resulting string to [`STDOUT`](06-constants.md#core-predefined-constants). +Unlike [`echo`](11-statements.md#the-echo-statement), `print` can be used in any context +allowing an expression. It always returns the value 1. + +See also: [double quoted strings](09-lexical-structure.md#double-quoted-string-literals) and +[heredoc documents](09-lexical-structure.md#heredoc-string-literals), [conversion to string](08-conversions.md#converting-to-string-type). + +**Examples** + +```PHP +$v1 = TRUE; +$v2 = 123; +print '>>' . $v1 . '|' . $v2 . "<<\n"; // outputs ">>1|123<<" +print ('>>' . $v1 . '|' . $v2 . "<<\n"); // outputs ">>1|123<<" +$v3 = "qqq{$v2}zzz"; +print "$v3\n"; // outputs "qqq123zzz" +$a > $b ? print "..." : print "..."; +``` + ## Logical AND Operator (form 2) **Syntax** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 8d51d22b..6b666332 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -389,7 +389,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# eval-intrinsic exit-intrinsic isset-intrinsic - print-intrinsic empty-intrinsic: empty ( expression ) @@ -410,9 +409,6 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# variable variable-list , variable -print-intrinsic: - print expression - anonymous-function-creation-expression: staticopt function &opt ( parameter-declaration-listopt ) anonymous-function-use-clauseopt return-typeopt compound-statement @@ -681,6 +677,10 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# yield yield-expression yield yield-from-expression => yield-expression +print-expression: + yield-expression + print print-expression + logical-AND-expression-2: yield-expression logical-AND-expression-2 and yield-expression From 15aa45273f4e5533ed252a612a5e6e7349a4d3ec Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 15 Mar 2019 09:54:22 +0100 Subject: [PATCH 124/146] Mark instanceof as left-associative May not have been originally intended this way, but it's how the language works right now, so specify it as such (#226). --- spec/10-expressions.md | 10 +++------- spec/19-grammar.md | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 988acaf9..8c8af696 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -1935,7 +1935,7 @@ instanceof-expression: instanceof-subject 'instanceof' class-type-designator instanceof-subject: - unary-expression + instanceof-expression -->
@@ -1944,17 +1944,13 @@ instanceof-subject:
    instanceof-subject   instanceof   class-type-designator
 
 instanceof-subject:
-   unary-expression
+   instanceof-expression
 
-**Constraints** - -The *unary-expression* in *instanceof-subject* must not be any form of literal. - **Semantics** Operator `instanceof` returns `TRUE` if the value designated by -*unary-expression* in *instanceof-subject* is an object having the type specified +*instanceof-subject* is an object having the type specified by *class-type-designator*, is an object whose type is derived from that type, or is an object whose type implements the interface specified by *class-type-designator*. Otherwise, it returns `FALSE`. diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 6b666332..0cc4f686 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -563,7 +563,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# instanceof-subject instanceof class-type-designator instanceof-subject: - unary-expression + instanceof-expression logical-NOT-expression: instanceof-expression From f35bd70531c012544e9061731415be8dcfe77f32 Mon Sep 17 00:00:00 2001 From: agares Date: Thu, 21 Feb 2019 19:29:59 +0100 Subject: [PATCH 125/146] Define encoding of PHP scripts 1. Remove references to unicode codepoints (as those were ambigouous without a defined encoding) and replace them with byte values 2. Define the encoding of PHP scripts as ASCII, where bytes greater than 0x7F are allowed --- spec/05-types.md | 16 +++---- spec/09-lexical-structure.md | 48 +++++++++---------- spec/10-expressions.md | 6 +-- spec/19-grammar.md | 15 +++--- .../unicode_escape.phpt | 2 +- 5 files changed, 45 insertions(+), 42 deletions(-) diff --git a/spec/05-types.md b/spec/05-types.md index 11cfb3b8..703da4f8 100644 --- a/spec/05-types.md +++ b/spec/05-types.md @@ -128,10 +128,10 @@ str-whitespace:: str-whitespace-char:: new-line - "Space character (U+0020)" - "Horizontal-tab character (U+0009)" - "Vertical-tab character (U+000B)" - "Form-feed character (U+000C)" + "Space character (0x20)" + "Horizontal-tab character (0x09)" + "Vertical-tab character (0x0B)" + "Form-feed character (0x0C)" str-number:: digit-sequence @@ -147,10 +147,10 @@ str-number:: str-whitespace-char:: new-line - Space character (U+0020) - Horizontal-tab character (U+0009) - Vertical-tab character (U+000B) - Form-feed character (U+000C) + Space character (0x20) + Horizontal-tab character (0x09) + Vertical-tab character (0x0B) + Form-feed character (0x0C) str-number:: digit-sequence diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index 262b3041..f4ec536e 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -145,9 +145,9 @@ input-character:: "Any source character except" new-line new-line:: - "Carriage-return character (U+000D)" - "Line-feed character (U+000A)" - "Carriage-return character (U+000D) followed by line-feed character (U+000A)" + "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 */" '*/' @@ -170,9 +170,9 @@ delimited-comment:: Any source character except new-line new-line:: - Carriage-return character (U+000D) - Line-feed character (U+000A) - Carriage-return character (U+000D) followed by line-feed character (U+000A) + 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 */ */ @@ -212,8 +212,8 @@ white-space:: white-space-character:: new-line - "Space character (U+0020)" - "Horizontal-tab character (U+0009)" + "Space character (0x20)" + "Horizontal-tab character (0x09)" -->
@@ -223,8 +223,8 @@ white-space-character::
 
 white-space-character::
    new-line
-   Space character (U+0020)
-   Horizontal-tab character (U+0009)
+   Space character (0x20)
+   Horizontal-tab character (0x09)
 
**Semantics** @@ -290,7 +290,7 @@ name:: name-nondigit:: nondigit - "one of the characters U+0080–U+00ff" + "one of the characters 0x80–0xff" nondigit:: one of '_' @@ -324,7 +324,7 @@ nondigit:: one of name-nondigit:: nondigit - one of the characters U+0080–U+00ff + one of the characters 0x80–0xff nondigit:: one of _ @@ -344,7 +344,7 @@ Names are used to identify the following: [constants](06-constants.md#general), and names in [heredoc](#heredoc-string-literals) and [nowdoc comments](#nowdoc-string-literals). A *name* begins with an underscore (_), *name-nondigit*, or extended -name character in the range U+0080–-U+00ff. Subsequent characters can +name character in the range 0x80–-0xff. Subsequent characters can also include *digits*. A *variable name* is a name with a leading dollar ($). @@ -704,7 +704,7 @@ b-prefix:: one of **Semantics** A single-quoted string literal is a string literal delimited by -single-quotes (`'`, U+0027). The literal can contain any source character except +single-quotes (`'`, 0x27). The literal can contain any source character except single-quote (`'`) and backslash (`\\`), which can only be represented by their corresponding escape sequence. @@ -807,7 +807,7 @@ codepoint-digits:: **Semantics** A double-quoted string literal is a string literal delimited by -double-quotes (`"`, U+0022). The literal can contain any source character except +double-quotes (`"`, 0x22). The literal can contain any source character except double-quote (`"`) and backslash (`\\`), which can only be represented by their corresponding escape sequence. Certain other (and sometimes non-printable) characters can also be expressed as escape sequences. @@ -821,15 +821,15 @@ in the table below: Escape sequence | Character name | Unicode character --------------- | --------------| ------ -\$ | Dollar sign | U+0024 -\" | Double quote | U+0022 -\\ | Backslash | U+005C -\e | Escape | U+001B -\f | Form feed | U+000C -\n | New line | U+000A -\r | Carriage Return | U+000D -\t | Horizontal Tab | U+0009 -\v | Vertical Tab | U+000B +\$ | Dollar sign | 0x24 +\" | Double quote | 0x22 +\\ | Backslash | 0x5C +\e | Escape | 0x1B +\f | Form feed | 0x0C +\n | New line | 0x0A +\r | Carriage Return | 0x0D +\t | Horizontal Tab | 0x09 +\v | Vertical Tab | 0x0B \ooo | 1–3-digit octal digit value ooo \xhh or \Xhh | 1–2-digit hexadecimal digit value hh \u{xxxxxx} | UTF-8 encoding of Unicode codepoint U+xxxxxx | U+xxxxxx diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 8c8af696..7184f310 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -1428,7 +1428,7 @@ shell-command-expression: ` dq-char-sequenceopt `
-where \` is the GRAVE ACCENT character U+0060, commonly referred to as a +where \` is the GRAVE ACCENT character 0x60, commonly referred to as a *backtick*. **Semantics** @@ -2804,9 +2804,9 @@ character from the right-hand operand is stored at the designated location; all other characters in the right-hand operand string are ignored. If the designated location is beyond the end of the destination string, that string is extended to the new length with -spaces (U+0020) added as padding beyond the old end and before the newly +spaces (0x20) added as padding beyond the old end and before the newly added character. If the right-hand operand is an empty string, the null -character \\0 (U+0000) is stored. +character \\0 (0x00) is stored. **Examples** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 0cc4f686..6bdb90c9 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -3,6 +3,9 @@ ## General The grammar notation is described in [Grammars section](09-lexical-structure.md#grammars). +PHP scripts are encoded as ASCII, but bytes 0x80 to 0xFF are allowed in some places, as defined in the grammar. +PHP scripts are parsed as a series of 8-bit bytes, rather than code points from Unicode or any other character repertoire. +Within this specification, bytes are represented by their ASCII interpretations where these are printable characters. ## Lexical Grammar @@ -32,9 +35,9 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# Any source character except new-line new-line:: - Carriage-return character (U+000D) - Line-feed character (U+000A) - Carriage-return character (U+000D) followed by line-feed character (U+000A) + 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 */ */ @@ -45,8 +48,8 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# white-space-character:: new-line - Space character (U+0020) - Horizontal-tab character (U+0009) + Space character (0x20) + Horizontal-tab character (0x09) token:: variable-name @@ -80,7 +83,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# name-nondigit:: nondigit - one of the characters U+0080–U+00ff + one of the characters 0x80–0xff nondigit:: one of _ diff --git a/tests/lexical_structure/unicode_string_escape_sequence/unicode_escape.phpt b/tests/lexical_structure/unicode_string_escape_sequence/unicode_escape.phpt index d729c630..cc19773f 100644 --- a/tests/lexical_structure/unicode_string_escape_sequence/unicode_escape.phpt +++ b/tests/lexical_structure/unicode_string_escape_sequence/unicode_escape.phpt @@ -3,7 +3,7 @@ PHP Spec test generated from ./lexical_structure/unicode_string_escape_sequence/ --FILE-- Date: Fri, 15 Mar 2019 10:30:07 +0100 Subject: [PATCH 126/146] Revert "Define encoding of PHP scripts" This reverts commit f35bd70531c012544e9061731415be8dcfe77f32. --- spec/05-types.md | 16 +++---- spec/09-lexical-structure.md | 48 +++++++++---------- spec/10-expressions.md | 6 +-- spec/19-grammar.md | 15 +++--- .../unicode_escape.phpt | 2 +- 5 files changed, 42 insertions(+), 45 deletions(-) diff --git a/spec/05-types.md b/spec/05-types.md index 703da4f8..11cfb3b8 100644 --- a/spec/05-types.md +++ b/spec/05-types.md @@ -128,10 +128,10 @@ str-whitespace:: str-whitespace-char:: new-line - "Space character (0x20)" - "Horizontal-tab character (0x09)" - "Vertical-tab character (0x0B)" - "Form-feed character (0x0C)" + "Space character (U+0020)" + "Horizontal-tab character (U+0009)" + "Vertical-tab character (U+000B)" + "Form-feed character (U+000C)" str-number:: digit-sequence @@ -147,10 +147,10 @@ str-number:: str-whitespace-char:: new-line - Space character (0x20) - Horizontal-tab character (0x09) - Vertical-tab character (0x0B) - Form-feed character (0x0C) + Space character (U+0020) + Horizontal-tab character (U+0009) + Vertical-tab character (U+000B) + Form-feed character (U+000C) str-number:: digit-sequence diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index f4ec536e..262b3041 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -145,9 +145,9 @@ 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)" + "Carriage-return character (U+000D)" + "Line-feed character (U+000A)" + "Carriage-return character (U+000D) followed by line-feed character (U+000A)" delimited-comment:: '/*' "No characters or any source character sequence except */" '*/' @@ -170,9 +170,9 @@ delimited-comment:: 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) + Carriage-return character (U+000D) + Line-feed character (U+000A) + Carriage-return character (U+000D) followed by line-feed character (U+000A) delimited-comment:: /* No characters or any source character sequence except */ */ @@ -212,8 +212,8 @@ white-space:: white-space-character:: new-line - "Space character (0x20)" - "Horizontal-tab character (0x09)" + "Space character (U+0020)" + "Horizontal-tab character (U+0009)" -->
@@ -223,8 +223,8 @@ white-space-character::
 
 white-space-character::
    new-line
-   Space character (0x20)
-   Horizontal-tab character (0x09)
+   Space character (U+0020)
+   Horizontal-tab character (U+0009)
 
**Semantics** @@ -290,7 +290,7 @@ name:: name-nondigit:: nondigit - "one of the characters 0x80–0xff" + "one of the characters U+0080–U+00ff" nondigit:: one of '_' @@ -324,7 +324,7 @@ nondigit:: one of name-nondigit:: nondigit - one of the characters 0x80–0xff + one of the characters U+0080–U+00ff nondigit:: one of _ @@ -344,7 +344,7 @@ Names are used to identify the following: [constants](06-constants.md#general), and names in [heredoc](#heredoc-string-literals) and [nowdoc comments](#nowdoc-string-literals). A *name* begins with an underscore (_), *name-nondigit*, or extended -name character in the range 0x80–-0xff. Subsequent characters can +name character in the range U+0080–-U+00ff. Subsequent characters can also include *digits*. A *variable name* is a name with a leading dollar ($). @@ -704,7 +704,7 @@ b-prefix:: one of **Semantics** A single-quoted string literal is a string literal delimited by -single-quotes (`'`, 0x27). The literal can contain any source character except +single-quotes (`'`, U+0027). The literal can contain any source character except single-quote (`'`) and backslash (`\\`), which can only be represented by their corresponding escape sequence. @@ -807,7 +807,7 @@ codepoint-digits:: **Semantics** A double-quoted string literal is a string literal delimited by -double-quotes (`"`, 0x22). The literal can contain any source character except +double-quotes (`"`, U+0022). The literal can contain any source character except double-quote (`"`) and backslash (`\\`), which can only be represented by their corresponding escape sequence. Certain other (and sometimes non-printable) characters can also be expressed as escape sequences. @@ -821,15 +821,15 @@ in the table below: Escape sequence | Character name | Unicode character --------------- | --------------| ------ -\$ | Dollar sign | 0x24 -\" | Double quote | 0x22 -\\ | Backslash | 0x5C -\e | Escape | 0x1B -\f | Form feed | 0x0C -\n | New line | 0x0A -\r | Carriage Return | 0x0D -\t | Horizontal Tab | 0x09 -\v | Vertical Tab | 0x0B +\$ | Dollar sign | U+0024 +\" | Double quote | U+0022 +\\ | Backslash | U+005C +\e | Escape | U+001B +\f | Form feed | U+000C +\n | New line | U+000A +\r | Carriage Return | U+000D +\t | Horizontal Tab | U+0009 +\v | Vertical Tab | U+000B \ooo | 1–3-digit octal digit value ooo \xhh or \Xhh | 1–2-digit hexadecimal digit value hh \u{xxxxxx} | UTF-8 encoding of Unicode codepoint U+xxxxxx | U+xxxxxx diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 7184f310..8c8af696 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -1428,7 +1428,7 @@ shell-command-expression: ` dq-char-sequenceopt `
-where \` is the GRAVE ACCENT character 0x60, commonly referred to as a +where \` is the GRAVE ACCENT character U+0060, commonly referred to as a *backtick*. **Semantics** @@ -2804,9 +2804,9 @@ character from the right-hand operand is stored at the designated location; all other characters in the right-hand operand string are ignored. If the designated location is beyond the end of the destination string, that string is extended to the new length with -spaces (0x20) added as padding beyond the old end and before the newly +spaces (U+0020) added as padding beyond the old end and before the newly added character. If the right-hand operand is an empty string, the null -character \\0 (0x00) is stored. +character \\0 (U+0000) is stored. **Examples** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 6bdb90c9..0cc4f686 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -3,9 +3,6 @@ ## General The grammar notation is described in [Grammars section](09-lexical-structure.md#grammars). -PHP scripts are encoded as ASCII, but bytes 0x80 to 0xFF are allowed in some places, as defined in the grammar. -PHP scripts are parsed as a series of 8-bit bytes, rather than code points from Unicode or any other character repertoire. -Within this specification, bytes are represented by their ASCII interpretations where these are printable characters. ## Lexical Grammar @@ -35,9 +32,9 @@ Within this specification, bytes are represented by their ASCII interpretations 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) + Carriage-return character (U+000D) + Line-feed character (U+000A) + Carriage-return character (U+000D) followed by line-feed character (U+000A) delimited-comment:: /* No characters or any source character sequence except */ */ @@ -48,8 +45,8 @@ Within this specification, bytes are represented by their ASCII interpretations white-space-character:: new-line - Space character (0x20) - Horizontal-tab character (0x09) + Space character (U+0020) + Horizontal-tab character (U+0009) token:: variable-name @@ -83,7 +80,7 @@ Within this specification, bytes are represented by their ASCII interpretations name-nondigit:: nondigit - one of the characters 0x80–0xff + one of the characters U+0080–U+00ff nondigit:: one of _ diff --git a/tests/lexical_structure/unicode_string_escape_sequence/unicode_escape.phpt b/tests/lexical_structure/unicode_string_escape_sequence/unicode_escape.phpt index cc19773f..d729c630 100644 --- a/tests/lexical_structure/unicode_string_escape_sequence/unicode_escape.phpt +++ b/tests/lexical_structure/unicode_string_escape_sequence/unicode_escape.phpt @@ -3,7 +3,7 @@ PHP Spec test generated from ./lexical_structure/unicode_string_escape_sequence/ --FILE-- Date: Fri, 30 Dec 2016 20:20:48 -0700 Subject: [PATCH 127/146] Update spec for by-ref list RFC --- spec/10-expressions.md | 20 +++++++++++++++++--- spec/19-grammar.md | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 8c8af696..0e8fc928 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -2852,7 +2852,7 @@ keyed-list-expression-list: list-or-variable: list-intrinsic - variable + '&'? variable -->
@@ -2874,7 +2874,7 @@ list-or-variable:
 
 list-or-variable:
    list-intrinsic
-   variable
+   &opt   variable
 
**Constraints** @@ -2892,7 +2892,8 @@ At least one of the elements of the *list-expression-list* must be non-empty. **Semantics** This intrinsic assigns one or more elements of the source array to the -target variables. On success, it returns a copy of the source array. If the +target variables. Target variables may be assigned by reference. +On success, it will return a copy of the source array. If the source array is not an array or object implementing `ArrayAccess` no assignments are performed and the return value is `NULL`. @@ -2942,6 +2943,12 @@ list($arr[1], $arr[0]) = [0, 1]; list($arr2[], $arr2[]) = [0, 1]; // $arr2 is [0, 1] +$a = [1, 2]; +list(&$one, $two) = $a; + // $a[0] is 1, $a[1] is 2 +$one++; + // $a[0] is 2, $a[1] is 2 + list("one" => $one, "two" => $two) = ["one" => 1, "two" => 2]; // $one is 1, $two is 2 list( @@ -2952,6 +2959,13 @@ list( "two" => 2, ]; // $one is 1, $two is 2 + +$a = ['one' => 1, 'two' => 2]; +list('one' => &$one, 'two' => $two) = $a; + // $a['one'] is 1, $a['two'] is 2 +$one++; + // $a['one'] is 2, $a['two'] is 2 + list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = [ ["x" => 1, "y" => 2], ["x" => 3, "y" => 4] diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 0cc4f686..3755b4bd 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -657,7 +657,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# list-or-variable: list-intrinsic - variable + &opt variable byref-assignment-expression: variable = & variable From fd81c6b8f6a4d512d88f216497f272a7bcf7953b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 8 Apr 2019 08:50:22 +0200 Subject: [PATCH 128/146] Fix print-expression/yield-expression mixup Fixes #236. --- spec/10-expressions.md | 4 ++-- spec/19-grammar.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 0e8fc928..6dd1240e 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -3235,13 +3235,13 @@ $a > $b ? print "..." : print "...";
 logical-AND-expression-2:
-   yield-expression
+   print-expression
    logical-AND-expression-2   and   yield-expression
 
diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 3755b4bd..7a9e548d 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -682,7 +682,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# print print-expression logical-AND-expression-2: - yield-expression + print-expression logical-AND-expression-2 and yield-expression logical-exc-OR-expression: From fe55bee01293a925120cfe330b62a94fc5140e35 Mon Sep 17 00:00:00 2001 From: agares Date: Sat, 23 Mar 2019 12:57:53 +0100 Subject: [PATCH 129/146] Define encoding of PHP scripts --- spec/05-types.md | 16 +++++----- spec/09-lexical-structure.md | 57 ++++++++++++++++++------------------ spec/10-expressions.md | 6 ++-- spec/19-grammar.md | 12 ++++---- 4 files changed, 45 insertions(+), 46 deletions(-) diff --git a/spec/05-types.md b/spec/05-types.md index 11cfb3b8..703da4f8 100644 --- a/spec/05-types.md +++ b/spec/05-types.md @@ -128,10 +128,10 @@ str-whitespace:: str-whitespace-char:: new-line - "Space character (U+0020)" - "Horizontal-tab character (U+0009)" - "Vertical-tab character (U+000B)" - "Form-feed character (U+000C)" + "Space character (0x20)" + "Horizontal-tab character (0x09)" + "Vertical-tab character (0x0B)" + "Form-feed character (0x0C)" str-number:: digit-sequence @@ -147,10 +147,10 @@ str-number:: str-whitespace-char:: new-line - Space character (U+0020) - Horizontal-tab character (U+0009) - Vertical-tab character (U+000B) - Form-feed character (U+000C) + Space character (0x20) + Horizontal-tab character (0x09) + Vertical-tab character (0x0B) + Form-feed character (0x0C) str-number:: digit-sequence diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index 262b3041..4a25908c 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -5,16 +5,15 @@ A [script](04-basic-concepts.md#program-structure) is an ordered sequence of characters. Typically, a script has a one-to-one correspondence with a file in a file system, but this correspondence is not required. +PHP scripts are parsed as a series of 8-bit bytes, rather than code points from Unicode or any other character repertoire. +Within this specification, bytes are represented by their ASCII interpretations where these are printable characters. Conceptually speaking, a script is translated using the following steps: -1. Transformation, which converts a script from a particular character - repertoire and encoding scheme into a sequence of 8-bit characters. - -2. Lexical analysis, which translates a stream of input characters into +1. Lexical analysis, which translates a stream of input characters into a stream of tokens. -3. Syntactic analysis, which translates the stream of tokens into +2. Syntactic analysis, which translates the stream of tokens into executable code. Conforming implementations must accept scripts encoded with the UTF-8 @@ -145,9 +144,9 @@ input-character:: "Any source character except" new-line new-line:: - "Carriage-return character (U+000D)" - "Line-feed character (U+000A)" - "Carriage-return character (U+000D) followed by line-feed character (U+000A)" + "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 */" '*/' @@ -170,9 +169,9 @@ delimited-comment:: Any source character except new-line new-line:: - Carriage-return character (U+000D) - Line-feed character (U+000A) - Carriage-return character (U+000D) followed by line-feed character (U+000A) + 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 */ */ @@ -212,8 +211,8 @@ white-space:: white-space-character:: new-line - "Space character (U+0020)" - "Horizontal-tab character (U+0009)" + "Space character (0x20)" + "Horizontal-tab character (0x09)" -->
@@ -223,8 +222,8 @@ white-space-character::
 
 white-space-character::
    new-line
-   Space character (U+0020)
-   Horizontal-tab character (U+0009)
+   Space character (0x20)
+   Horizontal-tab character (0x09)
 
**Semantics** @@ -290,7 +289,7 @@ name:: name-nondigit:: nondigit - "one of the characters U+0080–U+00ff" + "one of the characters 0x80–0xff" nondigit:: one of '_' @@ -324,7 +323,7 @@ nondigit:: one of name-nondigit:: nondigit - one of the characters U+0080–U+00ff + one of the characters 0x80–0xff nondigit:: one of _ @@ -344,7 +343,7 @@ Names are used to identify the following: [constants](06-constants.md#general), and names in [heredoc](#heredoc-string-literals) and [nowdoc comments](#nowdoc-string-literals). A *name* begins with an underscore (_), *name-nondigit*, or extended -name character in the range U+0080–-U+00ff. Subsequent characters can +name character in the range 0x80–-0xff. Subsequent characters can also include *digits*. A *variable name* is a name with a leading dollar ($). @@ -704,7 +703,7 @@ b-prefix:: one of **Semantics** A single-quoted string literal is a string literal delimited by -single-quotes (`'`, U+0027). The literal can contain any source character except +single-quotes (`'`, 0x27). The literal can contain any source character except single-quote (`'`) and backslash (`\\`), which can only be represented by their corresponding escape sequence. @@ -807,7 +806,7 @@ codepoint-digits:: **Semantics** A double-quoted string literal is a string literal delimited by -double-quotes (`"`, U+0022). The literal can contain any source character except +double-quotes (`"`, 0x22). The literal can contain any source character except double-quote (`"`) and backslash (`\\`), which can only be represented by their corresponding escape sequence. Certain other (and sometimes non-printable) characters can also be expressed as escape sequences. @@ -821,15 +820,15 @@ in the table below: Escape sequence | Character name | Unicode character --------------- | --------------| ------ -\$ | Dollar sign | U+0024 -\" | Double quote | U+0022 -\\ | Backslash | U+005C -\e | Escape | U+001B -\f | Form feed | U+000C -\n | New line | U+000A -\r | Carriage Return | U+000D -\t | Horizontal Tab | U+0009 -\v | Vertical Tab | U+000B +\$ | Dollar sign | 0x24 +\" | Double quote | 0x22 +\\ | Backslash | 0x5C +\e | Escape | 0x1B +\f | Form feed | 0x0C +\n | New line | 0x0A +\r | Carriage Return | 0x0D +\t | Horizontal Tab | 0x09 +\v | Vertical Tab | 0x0B \ooo | 1–3-digit octal digit value ooo \xhh or \Xhh | 1–2-digit hexadecimal digit value hh \u{xxxxxx} | UTF-8 encoding of Unicode codepoint U+xxxxxx | U+xxxxxx diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 6dd1240e..689fec71 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -1428,7 +1428,7 @@ shell-command-expression: ` dq-char-sequenceopt `
-where \` is the GRAVE ACCENT character U+0060, commonly referred to as a +where \` is the GRAVE ACCENT character 0x60, commonly referred to as a *backtick*. **Semantics** @@ -2804,9 +2804,9 @@ character from the right-hand operand is stored at the designated location; all other characters in the right-hand operand string are ignored. If the designated location is beyond the end of the destination string, that string is extended to the new length with -spaces (U+0020) added as padding beyond the old end and before the newly +spaces (0x20) added as padding beyond the old end and before the newly added character. If the right-hand operand is an empty string, the null -character \\0 (U+0000) is stored. +character \\0 (0x00) is stored. **Examples** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 7a9e548d..1ebc1927 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -32,9 +32,9 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# Any source character except new-line new-line:: - Carriage-return character (U+000D) - Line-feed character (U+000A) - Carriage-return character (U+000D) followed by line-feed character (U+000A) + 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 */ */ @@ -45,8 +45,8 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# white-space-character:: new-line - Space character (U+0020) - Horizontal-tab character (U+0009) + Space character (0x20) + Horizontal-tab character (0x09) token:: variable-name @@ -80,7 +80,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# name-nondigit:: nondigit - one of the characters U+0080–U+00ff + one of the characters 0x80–0xff nondigit:: one of _ From dc2e8d9593bd6b5826d10afcfbb86140733d4b13 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 8 Apr 2019 08:59:24 +0200 Subject: [PATCH 130/146] Fix constant uses in basic.phpt These are no longer legal in PHP 8. This is supposed to be testing dynamic function calls, for which we should be using the string and not rely on the bareword fallback. --- tests/functions/basics.phpt | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/tests/functions/basics.phpt b/tests/functions/basics.phpt index f8e1bec4..2a3bc2c8 100644 --- a/tests/functions/basics.phpt +++ b/tests/functions/basics.phpt @@ -30,11 +30,9 @@ function f1() } var_dump(f1()); // call f1, default return value is NULL -f1; // valid, but vacuous, as it has no side effect and its value is not used -var_dump(f1); // string with value "f1" -$f = f1; // assign this string to a variable +$f = "f1"; // assign the name of the function to a variable $f(); // call f1 indirectly via $f -//"f1"(); // call f1 via the string "f1" -- Can't be a string literal!!! +"f1"(); // call f1 via the string "f1" // f1() = 123; // a function return is not an lvalue @@ -74,20 +72,14 @@ f2(10, 20, 30); // pass 3 (> 2) function square($v) { return $v * $v; } echo "5 squared = ".square(5)."\n"; -var_dump($funct = square); +$funct = "square"; var_dump($funct(-2.3)); echo strlen("abcedfg")."\n"; --EXPECTF-- f1: # arguments passed is 0 NULL - -Warning: Use of undefined constant f1 - assumed 'f1' (this will throw an Error in a future version of PHP) in %s/functions/basics.php on line 30 - -Warning: Use of undefined constant f1 - assumed 'f1' (this will throw an Error in a future version of PHP) in %s/functions/basics.php on line 31 -string(2) "f1" - -Warning: Use of undefined constant f1 - assumed 'f1' (this will throw an Error in a future version of PHP) in %s/functions/basics.php on line 32 +f1: # arguments passed is 0 f1: # arguments passed is 0 f1: # arguments passed is 0 f1: # arguments passed is 1 @@ -106,8 +98,5 @@ Too few arguments to function f2(), 1 passed in %s on line %d and exactly 2 expe f2: $p1 = 10, $p2 = 20 f2: $p1 = 10, $p2 = 20 5 squared = 25 - -Warning: Use of undefined constant square - assumed 'square' (this will throw an Error in a future version of PHP) in %s/functions/basics.php on line 74 -string(6) "square" float(5.29) 7 From 5fc96c5dfd962ef25a362fc6108acae39cf9f1fd Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 8 Apr 2019 09:02:56 +0200 Subject: [PATCH 131/146] (unset) casts are no longer supported since PHP 8 --- spec/10-expressions.md | 7 ++++--- tests/expressions/unary_operators/cast.phpt | 15 +++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 689fec71..93c81122 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -1888,6 +1888,10 @@ cast-type: one of real string unset
+**Constaints** + +A *cast-type* of `unset` is no longer supported and results in a compile-time error. + **Semantics** With the exception of the *cast-type* unset and binary (see below), the @@ -1914,9 +1918,6 @@ A *cast-type* of `object` results in a [conversion to type `object`](08-conversi A *cast-type* of `string` results in a [conversion to type `string`](08-conversions.md#converting-to-string-type). -A *cast-type* of `unset` always results in a value of `NULL`. (This use of -`unset` should not be confused with the [`unset` statement](11-statements.md#the-unset-statement). - **Examples** ```PHP diff --git a/tests/expressions/unary_operators/cast.phpt b/tests/expressions/unary_operators/cast.phpt index 6e487533..9c714384 100644 --- a/tests/expressions/unary_operators/cast.phpt +++ b/tests/expressions/unary_operators/cast.phpt @@ -29,8 +29,10 @@ echo var_dump((binary)""); echo var_dump((binary)"abcdef"); echo var_dump($v); -echo var_dump((unset)$v); -echo var_dump($v); + +// The (unset) cast is no longer supported +//echo var_dump((unset)$v); +//echo var_dump($v); //*/ ///* @@ -146,7 +148,6 @@ var_dump($binStr); $binStr = b"AaBb123$%^"; var_dump($binStr); --EXPECTF-- -Deprecated: The (unset) cast is deprecated in %s on line %d bool(false) bool(false) int(0) @@ -167,8 +168,6 @@ string(1) "0" string(0) "" string(6) "abcdef" int(0) -NULL -int(0) int(10) bool(true) bool(true) @@ -456,7 +455,7 @@ array(2) { int(1) float(1) -Notice: Array to string conversion in %s/expressions/unary_operators/cast.php on line 50 +Notice: Array to string conversion in %s/expressions/unary_operators/cast.php on line %d string(5) "Array" array(2) { [5]=> @@ -485,7 +484,7 @@ array(4) { int(1) float(1) -Notice: Array to string conversion in %s/expressions/unary_operators/cast.php on line 50 +Notice: Array to string conversion in %s/expressions/unary_operators/cast.php on line %d string(5) "Array" array(4) { [0]=> @@ -555,7 +554,7 @@ object(E)#3 (3) { $key: >Epriv_prop<, len: 12, $val: >< $key: >*prot_prop<, len: 12, $val: >12.345< -Notice: Array to string conversion in %s/expressions/unary_operators/cast.php on line 115 +Notice: Array to string conversion in %s/expressions/unary_operators/cast.php on line %d $key: >publ_prop<, len: 9, $val: >Array< --------------- resource(1) of type (stream) From 64dd279d2829244050bb099f65a987c50324b8f5 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 8 Apr 2019 09:05:15 +0200 Subject: [PATCH 132/146] Fix more undefined constant uses --- tests/functions/order_of_evaluation.phpt | 12 +++--------- tests/variables/variable_names.phpt | 8 ++------ 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/tests/functions/order_of_evaluation.phpt b/tests/functions/order_of_evaluation.phpt index 220c2f47..356b10fd 100644 --- a/tests/functions/order_of_evaluation.phpt +++ b/tests/functions/order_of_evaluation.phpt @@ -34,9 +34,9 @@ function h($p1, $p2, $p3, $p4, $p5) // Create a table of function designators -$funcTable = array(f, g, h); // list of 3 functions -var_dump($funcTable); // array of 3 strings -var_dump($funcTable[0]); // a string +$funcTable = array("f", "g", "h"); // list of 3 functions +var_dump($funcTable); // array of 3 strings +var_dump($funcTable[0]); // a string // Call all 3 functions indirectly through table @@ -52,12 +52,6 @@ $funcTable[$i++]($i, ++$i, $i, $i = 12, --$i); // function designator side effec // g: $p1 = 2, $p2 = 3, $p3 = 3, $p4 = 12, $p5 = 11 --EXPECTF-- f: $p1 = 0, $p2 = 1, $p3 = 1, $p4 = 12, $p5 = 11 - -Warning: Use of undefined constant f - assumed 'f' (this will throw an Error in a future version of PHP) in %s/functions/order_of_evaluation.php on line 34 - -Warning: Use of undefined constant g - assumed 'g' (this will throw an Error in a future version of PHP) in %s/functions/order_of_evaluation.php on line 34 - -Warning: Use of undefined constant h - assumed 'h' (this will throw an Error in a future version of PHP) in %s/functions/order_of_evaluation.php on line 34 array(3) { [0]=> string(1) "f" diff --git a/tests/variables/variable_names.phpt b/tests/variables/variable_names.phpt index 26f467ff..d236317d 100644 --- a/tests/variables/variable_names.phpt +++ b/tests/variables/variable_names.phpt @@ -25,7 +25,7 @@ ${TRUE} = 104; ${FALSE} = 105; ${NULL} = 106; -${total} = 1000; // allowed after warning: Use of undefined constant total - assumed 'total' +//${total} = 1000; // disallowed; undefined constant total //${t o tal} = 1000; // disallowed; ill-formed expression //${+} = 1000; // disallowed; ill-formed expression ${10 + 4} = 1000; // allowed @@ -53,9 +53,7 @@ print_globals(); int(99) int(100) int(101) - -Warning: Use of undefined constant total - assumed 'total' (this will throw an Error in a future version of PHP) in %s/variables/variable_names.php on line 25 -array(12) { +array(11) { ["argc"]=> int(1) ["v"]=> @@ -70,8 +68,6 @@ array(12) { int(104) [""]=> int(106) - ["total"]=> - int(1000) [14]=> int(1000) ["abxy"]=> From 231e64995d5e6446101aa3da0d5ef62e2b5f204f Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 8 Apr 2019 09:10:24 +0200 Subject: [PATCH 133/146] Case-insensitive constants are no longer supported --- spec/06-constants.md | 4 ---- tests/constants/constants.phpt | 12 ++++++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/spec/06-constants.md b/spec/06-constants.md index 3b6b6110..06217185 100644 --- a/spec/06-constants.md +++ b/spec/06-constants.md @@ -12,10 +12,6 @@ Specifically: - The name of a c-constant must comply with the lexical grammar for a name while that for a d-constant can contain any source character. -- The name of a c-constant is case-sensitive while that for a - d-constant can be case-sensitive or case-insensitive based on the - value of the third argument passed to `define`. The definition of - case-insensitive constants is deprecated. - If `define` is able to define the given name, it returns `TRUE`; otherwise, it returns `FALSE`. diff --git a/tests/constants/constants.phpt b/tests/constants/constants.phpt index 5e6b66f9..23f3324b 100644 --- a/tests/constants/constants.phpt +++ b/tests/constants/constants.phpt @@ -11,9 +11,9 @@ PHP Spec test generated from ./constants/constants.php error_reporting(-1); -function trace($name, $value, $b = FALSE) +function trace($name, $value) { - $r = define($name, $value, $b); + $r = define($name, $value); echo "define $name " . ($r ? "succeeded" : "failed"); if (defined($name)) echo "; value is >" . constant($name) . "<\n"; @@ -26,7 +26,7 @@ function trace($name, $value, $b = FALSE) trace("STATUS1", TRUE); trace("MIN", 10); -trace("MAX", 20, TRUE); // HHVM Warning: Case insensitive constant names are not supported in HipHop +trace("MAX", 20); trace("MY_PI", 3.1415926); trace("MY_COLOR", "red"); trace("C1", NULL); @@ -184,8 +184,6 @@ echo "CON1: " . C3::CON1 . "\n"; // use :: notation, as a const is implicitly st --EXPECTF-- define STATUS1 succeeded; value is >1< define MIN succeeded; value is >10< - -Deprecated: define(): Declaration of case-insensitive constants is deprecated in %s on line %d define MAX succeeded; value is >20< define MY_PI succeeded; value is >3.1415926< define MY_COLOR succeeded; value is >red< @@ -208,7 +206,9 @@ define #%& succeeded; value is >200< Notice: Constant MY_COLOR already defined in %s/constants/constants.php on line 13 define MY_COLOR failed; value is >red< -define TRUE succeeded; value is >999< + +Notice: Constant TRUE already defined in %s/constants/constants.php on line 13 +define TRUE failed; value is >1< TRUE's value:1 define COLORS succeeded Notice: Array to string conversion in %s/constants/constants.php on line 16 From 2f0881e79809cb0e910b38208f60a46106a60cf3 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 8 Apr 2019 09:12:32 +0200 Subject: [PATCH 134/146] Avoid static call to non-static method --- tests/traits/traits.phpt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/traits/traits.phpt b/tests/traits/traits.phpt index 4aebc6d9..6887badb 100644 --- a/tests/traits/traits.phpt +++ b/tests/traits/traits.phpt @@ -238,9 +238,8 @@ trait T7 } } -T7::f(); // calls f like a static function with class name being the trait name +// T7::f(); // Static call to non-static method is not allowed -echo "-------\n"; T7::g(); /* @@ -336,10 +335,6 @@ $v = 1 Inside T6::f $v = 2 ===================== Using a Trait without a Class ========================= -%AInside T7 -Inside T7 -Inside T7::f -------- Inside T7 Inside T7 Inside T7::g From 51566692791bfab5250488f319831925ca0c1c3b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 8 Apr 2019 09:21:58 +0200 Subject: [PATCH 135/146] Adjust for PHP 8 negative array key change --- spec/10-expressions.md | 5 ++--- tests/expressions/postfix_operators/subscripting_2.phpt | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/spec/10-expressions.md b/spec/10-expressions.md index 93c81122..a3289600 100644 --- a/spec/10-expressions.md +++ b/spec/10-expressions.md @@ -888,9 +888,8 @@ and value of the result is the type and value of that element; otherwise, the result is `NULL`. If *expression* is omitted, a new element is inserted. Its key has type -`int` and is one more than the highest, previously assigned, non-negative -`int` key for this array. If this is the first element with a non-negative -`int` key, key `0` is used. +`int` and is one more than the highest, previously assigned `int` key for +this array. If this is the first element with an `int` key, key `0` is used. If the largest previously assigned `int` key is the largest integer value that can be represented, the new element is not added. The result is the added new element, or `NULL` if the element was not added. diff --git a/tests/expressions/postfix_operators/subscripting_2.phpt b/tests/expressions/postfix_operators/subscripting_2.phpt index c9c2b490..a269350d 100644 --- a/tests/expressions/postfix_operators/subscripting_2.phpt +++ b/tests/expressions/postfix_operators/subscripting_2.phpt @@ -11,7 +11,7 @@ var_dump($a); echo "------\n"; $a = array(-30 => 33, -10 => -11); -var_dump($a[] = 991); // creates $a[0] +var_dump($a[] = 991); // creates $a[-9] var_dump($a); echo "------\n"; @@ -170,7 +170,7 @@ array(3) { int(33) [-10]=> int(-11) - [0]=> + [-9]=> int(991) } ------ From ab19cb01fd935c7d40a7250b551156cf273b61d5 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 8 Apr 2019 09:24:02 +0200 Subject: [PATCH 136/146] Adjust serialization tests I believe this is due to the support for unserializing with changed visibility, which will assign to the private x/y properties now. --- tests/classes/sleep_and_wakeup.phpt | Bin 6095 -> 6061 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/classes/sleep_and_wakeup.phpt b/tests/classes/sleep_and_wakeup.phpt index 0974abc549a252d03add520473d074d2a15cc7ab..6c1d5dc4bd621cc1393db9086a1ce1454a688a51 100644 GIT binary patch delta 16 YcmX@FzgB;PyBMR%WDl`vlf=&h05qBg8~^|S delta 51 wcmZ3he_nrsyBMR{WDl`viV6zRN|j2nwsu?!3VxwJK0qp3sRBu0@?EhD0C@xskN^Mx From 694b0290a6ec0722820d2db848cc510104623e5d Mon Sep 17 00:00:00 2001 From: Rodion Efremov Date: Sat, 15 Jun 2019 15:16:14 +0300 Subject: [PATCH 137/146] Fixed the leftwards diagram arrows from < to <. Some arrow diagrams are rendered as `<--` instead of `<--`. --- spec/04-basic-concepts.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/spec/04-basic-concepts.md b/spec/04-basic-concepts.md index bdb84eb0..bfc81b60 100644 --- a/spec/04-basic-concepts.md +++ b/spec/04-basic-concepts.md @@ -516,12 +516,12 @@ We can remove all these handles using `$a = NULL` and `$b = NULL`: ``` [VSlot $a *]-->[VStore null] [HStore Point [VSlot $x *] [VSlot $y *] (dead)] | | -[VSlot $b *]-->[VStore null] [VStore int 2 (dead)]<--+ V +[VSlot $b *]-->[VStore null] [VStore int 2 (dead)]<--+ V [VStore int 1 (dead)] [HStore Point [VSlot $x *] [VSlot $y *] (dead)] | | - [VStore int 4 (dead)]<--+ V + [VStore int 4 (dead)]<--+ V [VStore int 6 (dead)] ``` @@ -750,7 +750,7 @@ assignment of other types. Recall the `Point` class from [the examples](#value-a V V [VStore int 10] [VStore Obj *] | - [HStore Point [VSlot $x *] [VSlot $y *]]<----+ + [HStore Point [VSlot $x *] [VSlot $y *]]<----+ | | V V [VStore int 1] [VStore int 3] @@ -782,7 +782,7 @@ the value assignment `$b = $a`: | | | +---------+ +---------+ | V V | -[VStore int 10] [VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *]]<---+ +[VStore int 10] [VStore object *]-->[HStore Point [VSlot $x *] [VSlot $y *]]<---+ | | V V [VStore int 1] [VStore int 3] @@ -830,7 +830,7 @@ implementation. Here is the first possible outcome: ``` [VSlot $a *]---->[VStore array *]---->[HStore Array [VSlot 0 *]] | -[VSlot $x *]-------------------------+ [VStore array *]<---+ +[VSlot $x *]-------------------------+ [VStore array *]<---+ | | [VSlot $b *]-->[VStore array *] | V | | [HStore Array [VSlot 0 *][VSlot 1 *]] @@ -852,7 +852,7 @@ Here is the second possible outcome: ``` [VSlot $a *]---->[VStore array *]---->[HStore Array [VSlot 0 *]] | -[VSlot $x *]-------------------------+ [VStore array *]<----+ +[VSlot $x *]-------------------------+ [VStore array *]<----+ | | [VSlot $b *]-->[VStore array *] | V | | [HStore Array [VSlot 0 *] [VSlot 1 *]] @@ -939,7 +939,7 @@ $b = $a; ``` [VSlot $a *]--->[VStore array *]--->[HStore Array [VSlot 0 *]] ^ | - | [VStore array *]<--+ + | [VStore array *]<--+ [VSlot $b *]--->[VStore Arr-D *]------+ | V [HStore Array [VSlot 0 *] [VSlot 1 *]] @@ -1036,7 +1036,7 @@ possible outcome: ``` [VSlot $a *]---->[VStore array *]---->[HStore Array [VSlot 0 *]] | -[VSlot $b *]-->[VStore array *] [VStore array *]<---+ +[VSlot $b *]-->[VStore array *] [VStore array *]<---+ | | V V [HStore Array [VSlot 0 *] [VSlot 1 *]] [HStore Array [VSlot 0 *] [VSlot 1 *]] @@ -1057,8 +1057,8 @@ Here is the third possible outcome: ``` [VSlot $a *]---->[VStore array *-]---->[HStore Array [VSlot 0 *]] - | -[VSlot $b *]-->[VStore array *] [VStore array *]<---+ + | +[VSlot $b *]-->[VStore array *] [VStore array *]<---+ | | V V [HStore Array [VSlot 0 *] [VSlot 1 *]] [HStore Array [VSlot 0 *] [VSlot 1 *]] @@ -1204,7 +1204,7 @@ Will result in: | | | V V | [VStore int 1] [VStore int 3] | -[VSlot $b *]---------------->[VStore int 123]<---------------------------------------+ +[VSlot $b *]---------------->[VStore int 123]<---------------------------------------+ ``` ### Argument Passing @@ -1267,7 +1267,7 @@ some type(s) or to an instance of some other type. V V [VStore int 10] [VStore object *] | - [HStore ...]<---------+ + [HStore ...]<---------+ ``` Let us consider the result of `$b = clone $a`: @@ -1279,7 +1279,7 @@ Let us consider the result of `$b = clone $a`: | [VStore int 10] [VStore object *] +-----------------------+ | V | - [HStore Widget [VSlot $p1 *] [VSlot $p2 *]] +--->[HStore ...]<-+ + [HStore Widget [VSlot $p1 *] [VSlot $p2 *]] +--->[HStore ...]<-+ | | | V V | [VStore int 10] [VStore object *]----------+ From 8a7e96736ac18cdd159b7af2e7d1e4c666c9c822 Mon Sep 17 00:00:00 2001 From: Rodion Efremov Date: Sat, 15 Jun 2019 15:11:13 +0300 Subject: [PATCH 138/146] Added missing $ to &colors. Line 257 reads "$b = &colors[100];", but should be "$b = &$colors[100];". --- spec/07-variables.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/07-variables.md b/spec/07-variables.md index cfb17ff1..b280fda8 100644 --- a/spec/07-variables.md +++ b/spec/07-variables.md @@ -254,7 +254,7 @@ echo $colors[100]; // element with offset 100 is still undefined and NULL // is used as substitution value instead. Another // notice is emitted. -$b = &colors[100]; // a VSlot for $b is created which points to the array +$b = &$colors[100]; // a VSlot for $b is created which points to the array // element with the offset 100. An array element with // offset 100 was undefined but implicitly defined // because the assignment is byRef. Thus a VSlot for From 6e288468b63910d0e5f9ec06fd35b2d0b2e52327 Mon Sep 17 00:00:00 2001 From: Tiffany Date: Thu, 6 May 2021 20:19:38 -0500 Subject: [PATCH 139/146] Fix encoding for < to < --- spec/04-basic-concepts.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/04-basic-concepts.md b/spec/04-basic-concepts.md index bfc81b60..6f99d468 100644 --- a/spec/04-basic-concepts.md +++ b/spec/04-basic-concepts.md @@ -1001,7 +1001,7 @@ outcomes: ``` [VSlot $a *]---->[VStore array *]---->[HStore Array [VSlot 0 *]] | -[VSlot $b *]-->[VStore array *] [VStore Arr *]<---+ +[VSlot $b *]-->[VStore array *] [VStore Arr *]<---+ | | +----------------------+ +----------+ V V @@ -1050,7 +1050,7 @@ possible outcome: | V | | [VStore string 'hi'] | V | - [VSlot $x *]--------------------->[VStore int 123]<--------+ + [VSlot $x *]--------------------->[VStore int 123]<--------+ ``` Here is the third possible outcome: @@ -1068,11 +1068,11 @@ Here is the third possible outcome: V | V [VStore Arr-D *]-->[HStore Array [VSlot 0 *] [VSlot 1 *]] | [VStore string 'hi'] | | | - [VStore int 123]<-------+ | | + [VStore int 123]<-------+ | | V | [VStore string 'hi'] | | - [VSlot $x *]--------------------->[VStore int 123]<---------+ + [VSlot $x *]--------------------->[VStore int 123]<---------+ ``` The second and third possible outcomes show what can possibly happen if From f9d4f7480aae28805c5be13a26ac8d193dea21b1 Mon Sep 17 00:00:00 2001 From: David Findley Date: Sat, 5 Feb 2022 13:57:00 -0600 Subject: [PATCH 140/146] Namespace definition grammar fix (#254) * Fix the `namespace-definition` production The `namespace-definition` production was changed to use `name` instead of `namespace-name` in c1ac5314798f6740f and a6520fb35b746a6e6c275. This appears to be a mistake, since `name` can not produce a `\`. The spec was originally using `namespace-name` for `namespace-definition`. This commit restores that grammar production. * Regenerate using `tools/pre-commit` It appears that the pre-commit scripts were not used to properly regenerate the spec recently. This caused some small styling changes (using html entities for some chars). It also caused a bigger change due to `print` being moved out of the intrinsics section in 63d72a6df5d2c7b1b7a8a. It's not completely clear if this was intentional or not, since `print` is a language intrinsic. --- spec/00-specification-for-php.md | 2 +- spec/09-lexical-structure.md | 8 ++++---- spec/11-statements.md | 2 +- spec/18-namespaces.md | 8 ++++---- spec/19-grammar.md | 12 ++++++------ 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/spec/00-specification-for-php.md b/spec/00-specification-for-php.md index a99db747..19e5b3d2 100644 --- a/spec/00-specification-for-php.md +++ b/spec/00-specification-for-php.md @@ -109,7 +109,6 @@ is distributed without any warranty. - [eval](10-expressions.md#eval) - [exit/die](10-expressions.md#exitdie) - [isset](10-expressions.md#isset) - - [print](10-expressions.md#print) - [Anonymous Function Creation](10-expressions.md#anonymous-function-creation) - [The `new` Operator](10-expressions.md#the-new-operator) - [Array Creation Operator](10-expressions.md#array-creation-operator) @@ -149,6 +148,7 @@ is distributed without any warranty. - [byRef Assignment](10-expressions.md#byref-assignment) - [Compound Assignment](10-expressions.md#compound-assignment) - [`yield` Operator](10-expressions.md#yield-operator) + - [Print expression](10-expressions.md#print-expression) - [Logical AND Operator (form 2)](10-expressions.md#logical-and-operator-form-2) - [Logical Exclusive OR Operator](10-expressions.md#logical-exclusive-or-operator) - [Logical Inclusive OR Operator (form 2)](10-expressions.md#logical-inclusive-or-operator-form-2) diff --git a/spec/09-lexical-structure.md b/spec/09-lexical-structure.md index 4a25908c..537c9936 100644 --- a/spec/09-lexical-structure.md +++ b/spec/09-lexical-structure.md @@ -683,7 +683,7 @@ b-prefix:: one of
 single-quoted-string-literal::
-   b-prefixopt   '   sq-char-sequenceopt   '
+   b-prefixopt   '   sq-char-sequenceopt   '
 
 sq-char-sequence::
    sq-char
@@ -691,10 +691,10 @@ b-prefix:: one of
 
 sq-char::
    sq-escape-sequence
-   \opt   any member of the source character set except single-quote (') or backslash (\)
+   \opt   any member of the source character set except single-quote (') or backslash (\)
 
 sq-escape-sequence:: one of
-   \'   \\
+   \'   \\
 
 b-prefix:: one of
    b   B
@@ -1065,7 +1065,7 @@ nowdoc-string-literal::
 
 
 nowdoc-string-literal::
-   b-prefixopt   <<<   '   name   '   new-line   hd-bodyopt   name   ;opt   new-line
+   b-prefixopt   <<<   '   name   '   new-line   hd-bodyopt   name   ;opt   new-line
 
**Constraints** diff --git a/spec/11-statements.md b/spec/11-statements.md index 39bd0ce1..d9eb5d1d 100644 --- a/spec/11-statements.md +++ b/spec/11-statements.md @@ -1337,7 +1337,7 @@ a [`__toString` method](14-classes.md#method-__tostring). After converting each of its *expression*s' values to strings, if necessary, `echo` concatenates them in order given, and writes the -resulting string to [`STDOUT`](06-constants.md#core-predefined-constants). Unlike [`print`](10-expressions.md#print), it does +resulting string to [`STDOUT`](06-constants.md#core-predefined-constants). Unlike [`print`](10-expressions.md#print-expression), it does not produce a result. See also: [double quoted strings](09-lexical-structure.md#double-quoted-string-literals) and diff --git a/spec/18-namespaces.md b/spec/18-namespaces.md index 76d473af..715dff62 100644 --- a/spec/18-namespaces.md +++ b/spec/18-namespaces.md @@ -38,14 +38,14 @@ prefixes are reserved for use by PHP.
 namespace-definition:
-   namespace   name   ;
-   namespace   nameopt   compound-statement
+   namespace   namespace-name   ;
+   namespace   namespace-nameopt   compound-statement
 
**Constraints** diff --git a/spec/19-grammar.md b/spec/19-grammar.md index 1ebc1927..e52237c2 100644 --- a/spec/19-grammar.md +++ b/spec/19-grammar.md @@ -170,7 +170,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# nowdoc-string-literal single-quoted-string-literal:: - b-prefixopt ' sq-char-sequenceopt ' + b-prefixopt ' sq-char-sequenceopt ' sq-char-sequence:: sq-char @@ -178,10 +178,10 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# sq-char:: sq-escape-sequence - \opt any member of the source character set except single-quote (') or backslash (\) + \opt any member of the source character set except single-quote (') or backslash (\) sq-escape-sequence:: one of - \' \\ + \' \\ b-prefix:: one of b B @@ -271,7 +271,7 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md# \\ \$ \e \f \n \r \t \v nowdoc-string-literal:: - b-prefixopt <<< ' name ' new-line hd-bodyopt name ;opt new-line + b-prefixopt <<< ' name ' new-line hd-bodyopt name ;opt new-line operator-or-punctuator:: one of [ ] ( ) { } . -> ++ -- ** * + - ~ ! @@ -1119,8 +1119,8 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
 namespace-definition:
-   namespace   name   ;
-   namespace   nameopt   compound-statement
+   namespace   namespace-name   ;
+   namespace   namespace-nameopt   compound-statement
 
 namespace-use-declaration:
    use   namespace-function-or-constopt   namespace-use-clauses   ;

From f268abd41944313b606b007caf177919f4ab4fe7 Mon Sep 17 00:00:00 2001
From: Carter Snook 
Date: Mon, 12 Dec 2022 06:35:09 -0600
Subject: [PATCH 141/146] fix(constants): remove duplicate E_USER_DEPRECATED
 def

Closes GH-256.
---
 spec/06-constants.md | 1 -
 1 file changed, 1 deletion(-)

diff --git a/spec/06-constants.md b/spec/06-constants.md
index 06217185..8b23a2af 100644
--- a/spec/06-constants.md
+++ b/spec/06-constants.md
@@ -73,7 +73,6 @@ Constant Name | Description
 `E_USER_NOTICE` | `int`; User-generated warning message. This is like an `E_NOTICE`, except that `E_USER_NOTICE` is generated in PHP code by using the library function [`trigger_error`](http://www.php.net/trigger_error).
 `E_USER_WARNING` |  `int`; User-generated warning message. This is like an `E_WARNING`, except that  `E_USER_WARNING` is generated in PHP code by using the library function [`trigger_error`](http://www.php.net/trigger_error).
 `E_WARNING` | `int`; Run-time warnings (non-fatal errors). Execution of the script is not halted.
-`E_USER_DEPRECATED` | `int`; User-generated warning message. This is like an `E_DEPRECATED`, except that `E_USER_DEPRECATED` is generated in PHP code by using the library function [`trigger_error`](http://www.php.net/trigger_error).
 `FALSE` |   `bool`; the case-insensitive Boolean value `FALSE`.
 `INF` | `float`; Infinity
 `M_1_PI` |  `float`; 1/pi

From ffa3fa58a1062aed7c85f04d10e340677364ce48 Mon Sep 17 00:00:00 2001
From: Peter Kokot 
Date: Fri, 3 Feb 2023 21:43:24 +0100
Subject: [PATCH 142/146] Mention GitHub upstream instead of obsolete
 git.php.net

---
 README.md | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 5c35b654..14f780c2 100644
--- a/README.md
+++ b/README.md
@@ -10,11 +10,7 @@ Bug reports can be filed at:
 
 > [https://github.com/php/php-langspec/issues](https://github.com/php/php-langspec/issues)
 
-The upstream url of this repo is:
-
-    git@git.php.net:/php-langspec.git
-
-It is also mirrored on GitHub:
+The upstream URL of this repo is:
 
 > [https://github.com/php/php-langspec](https://github.com/php/php-langspec)
 

From 4c19272d1f832faba8c7bc808bf4a2db4412a6c4 Mon Sep 17 00:00:00 2001
From: Superkooka 
Date: Fri, 24 Feb 2023 00:43:29 +0100
Subject: [PATCH 143/146] Fix markdown typo in spec/ (#249)

---
 spec/08-conversions.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spec/08-conversions.md b/spec/08-conversions.md
index e93183d3..069676d6 100644
--- a/spec/08-conversions.md
+++ b/spec/08-conversions.md
@@ -14,7 +14,7 @@ Conversions to `resource` and `null` types can not be performed.
 
 ## Converting to Boolean Type
 
-The [result type] (http://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting) is [`bool`](05-types.md#the-boolean-type).
+The [result type](http://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting) is [`bool`](05-types.md#the-boolean-type).
 
 If the source type is `int` or `float`, then if the source value tests equal
 to 0, the result value is `FALSE`; otherwise, the result value is `TRUE`.

From bf7423a820247f6584c329b5a75ca0e61b7e2940 Mon Sep 17 00:00:00 2001
From: Sergey Panteleev 
Date: Sat, 24 Feb 2024 18:48:02 +0300
Subject: [PATCH 144/146] Update ML instructions

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 14f780c2..5875ef0e 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ This repo contains the WIP PHP Language Specifications.
 
 To join the conversation, send a blank email to:
 
-> [standards-subscribe@lists.php.net](mailto:standards-subscribe@lists.php.net)
+> [standards+subscribe@lists.php.net](mailto:standards+subscribe@lists.php.net)
 
 Bug reports can be filed at:
 

From 287f3d0e12391be858d6623a4bec035d2647c621 Mon Sep 17 00:00:00 2001
From: Ben Ramsey 
Date: Sat, 24 Feb 2024 17:08:39 -0600
Subject: [PATCH 145/146] Indicate space is allowed between "endswitch" and ";"

---
 spec/11-statements.md | 4 ++--
 spec/19-grammar.md    | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/spec/11-statements.md b/spec/11-statements.md
index d9eb5d1d..61af9cc8 100644
--- a/spec/11-statements.md
+++ b/spec/11-statements.md
@@ -314,7 +314,7 @@ else  // this else does go with the outer if