]> granicus.if.org Git - php/commitdiff
Improve output of tokens in Parse Errors
authorRowan Tommins <git@rwec.co.uk>
Thu, 11 Jun 2020 19:56:22 +0000 (20:56 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 13 Jul 2020 09:07:40 +0000 (11:07 +0200)
Currently, unexpected tokens in the parser are shown as the text
found, plus the internal token name, including the notorious
"unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)".

This commit replaces that with a more user-friendly format, with
two main types of token:

* Tokens which always represent the same text are shown like
  'unexpected token "::"' and 'expected "::"'
* Tokens which have variable text are given a user-friendly
  name, and show like 'unexpected identifier "foo"', and
  'expected identifer'.

A few tokens have special cases:

* unexpected token """ -> unexpected double-quote mark
* unexpected quoted string "'foo'" -> unexpected single-quoted
  string "foo"
* unexpected quoted string ""foo"" -> unexpected double-quoted
  string "foo"
* unexpected illegal character "_" -> unexpected character 0xNN
  (where _ is almost certainly a control character, and NN is the
   hexadecimal value of the byte)

The \ token has a special case in the implementation just to stop
bison making a mess of escaping it and it coming out as \\

53 files changed:
Zend/tests/attributes/019_variable_attribute_name.phpt
Zend/tests/bug43343.phpt
Zend/tests/bug70430.phpt
Zend/tests/bug75252.phpt
Zend/tests/bug77993.phpt
Zend/tests/bug78454_1.phpt
Zend/tests/bug78454_2.phpt
Zend/tests/ctor_promotion_additional_modifiers.phpt
Zend/tests/flexible-heredoc-error7.phpt
Zend/tests/flexible-nowdoc-error7.phpt
Zend/tests/flexible-nowdoc-error8.phpt
Zend/tests/function_arguments/call_with_leading_comma_error.phpt
Zend/tests/function_arguments/call_with_multi_inner_comma_error.phpt
Zend/tests/function_arguments/call_with_multi_trailing_comma_error.phpt
Zend/tests/function_arguments/call_with_only_comma_error.phpt
Zend/tests/grammar/regression_004.phpt
Zend/tests/grammar/regression_005.phpt
Zend/tests/grammar/regression_012.phpt
Zend/tests/list_011.phpt
Zend/tests/ns_088.phpt
Zend/tests/ns_094.phpt
Zend/tests/ns_096.phpt
Zend/tests/ns_trailing_comma_error_01.phpt
Zend/tests/ns_trailing_comma_error_02.phpt
Zend/tests/ns_trailing_comma_error_03.phpt
Zend/tests/ns_trailing_comma_error_04.phpt
Zend/tests/ns_trailing_comma_error_05.phpt
Zend/tests/ns_trailing_comma_error_06.phpt
Zend/tests/ns_trailing_comma_error_07.phpt
Zend/tests/ns_trailing_comma_error_08.phpt
Zend/tests/numeric_literal_separator_002.phpt
Zend/tests/numeric_literal_separator_003.phpt
Zend/tests/numeric_literal_separator_004.phpt
Zend/tests/numeric_literal_separator_005.phpt
Zend/tests/numeric_literal_separator_006.phpt
Zend/tests/numeric_literal_separator_007.phpt
Zend/tests/numeric_literal_separator_008.phpt
Zend/tests/numeric_literal_separator_009.phpt
Zend/tests/require_parse_exception.phpt
Zend/tests/traits/bug55524.phpt
Zend/tests/traits/bugs/interfaces.phpt
Zend/tests/type_declarations/mixed/casting/mixed_cast_error.phpt
Zend/tests/type_declarations/static_type_param.phpt
Zend/tests/type_declarations/static_type_property.phpt
Zend/tests/type_declarations/typed_properties_025.phpt
Zend/tests/varSyntax/globalNonSimpleVariableError.phpt
Zend/zend_language_parser.y
ext/reflection/tests/bug74454.phpt
ext/spl/tests/bug74372.phpt
ext/tokenizer/tests/token_get_all_TOKEN_PARSE_000.phpt
ext/tokenizer/tests/token_get_all_heredoc_nowdoc.phpt
tests/lang/bug21820.phpt
tests/lang/bug71897.phpt

index 64fb69a4e0318f5c1ab5589201ad133c21e172fc..2710abbed9f9439c6e53e3c05f2981d2914f4c04 100644 (file)
@@ -8,4 +8,4 @@ class A {}
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected '$x' (T_VARIABLE), expecting identifier (T_STRING) or static (T_STATIC) or namespace (T_NAMESPACE) or \\ (T_NS_SEPARATOR) in %s on line %d
+Parse error: syntax error, unexpected variable "$x", expecting identifier or "static" or "namespace" or "\" in %s on line %d
index 79b3e5a24ad3883c6b5576c5dddbe4e5571bc99b..db72fe98ecfa7459aaeb9212d3fb99a929559810 100644 (file)
@@ -8,4 +8,4 @@ $foo = 'bar';
 var_dump(new namespace::$foo);
 ?>
 --EXPECTF--
-Parse error: %s error%sexpecting%sT_NS_SEPARATOR%sin %sbug43343.php on line 5
+Parse error: %s error%sexpecting%s"\"%sin %sbug43343.php on line 5
index 59983653e91fa473f8faffcdc0fc50e13280fc73..1577a00587fb9b94aa1265871a58fc9b4b1d2f1f 100644 (file)
@@ -7,4 +7,4 @@ $"*** Testing function() :  ***\n";
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected '"*** Testing function() :  ***' (T_CONSTANT_ENCAPSED_STRING), expecting variable (T_VARIABLE) or '{' or '$' in %s on line %d
+Parse error: syntax error, unexpected double-quoted string "*** Testing function() :  ***\n", expecting variable or "{" or "$" in %s on line %d
index 16679e4d6e4f0008eb5898f53f9770719759db51..b4e0a1b5bdc31a1464a897a35ebc392b9122dfa4 100644 (file)
@@ -24,5 +24,5 @@ try {
 
 ?>
 --EXPECT--
-string(41) "syntax error, unexpected 'FOO' (T_STRING)"
-string(41) "syntax error, unexpected 'FOO' (T_STRING)"
+string(41) "syntax error, unexpected identifier "FOO""
+string(41) "syntax error, unexpected identifier "FOO""
index c19841811b207c473b833d1586725fd0c621ce03..46eed0f4dc104a7f21e388cffe6bdc13fd0ddd5d 100644 (file)
@@ -4,4 +4,4 @@ Bug #77993 (Wrong parse error for invalid hex literal on Windows)
 <?php
 0xg10;
 --EXPECTF--
-Parse error: syntax error, unexpected 'xg10' (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected identifier "xg10" in %s on line %d
index 184d358372e1725c0880f0c5ee914316b7360a78..fb4d329578ceb8417b620ad6c18b92221eac168a 100644 (file)
@@ -4,4 +4,4 @@ Invalid consecutive numeric separators after hex literal
 <?php
 0x0__F;
 --EXPECTF--
-Parse error: syntax error, unexpected '__F' (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected identifier "__F" in %s on line %d
index b67b8396ac0903aa6cb41f43a9e88c9c808ea4d0..f57eda491d0da746bc85885e314eaf621ae20ea7 100644 (file)
@@ -4,4 +4,4 @@ Invalid consecutive numeric separators after binary literal
 <?php
 0b0__1
 --EXPECTF--
-Parse error: syntax error, unexpected '__1' (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected identifier "__1" in %s on line %d
index fb3b092d66f501146aa6e497b7bdef9db86c1647..1d2e7f3cd5462bd56323fa9fdc331554845a25ea 100644 (file)
@@ -9,4 +9,4 @@ class Test {
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected 'static' (T_STATIC), expecting variable (T_VARIABLE) in %s on line %d
+Parse error: syntax error, unexpected token "static", expecting variable in %s on line %d
index ae9d1da0cd85b45055c0db73fef89a069b17f41b..d31b430b5670c6606c45fb6d4825c8c914507b7a 100644 (file)
@@ -8,4 +8,4 @@ Note: the closing ?> has been deliberately elided.
 echo <<<END
 
 --EXPECTF--
-Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABLE) or heredoc end (T_END_HEREDOC) or ${ (T_DOLLAR_OPEN_CURLY_BRACES) or {$ (T_CURLY_OPEN) in %s on line %d
+Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" in %s on line %d
index 27d5dbb46ec243a47185ba13649d7e2def828689..b31b3e5d3b3b6f212f7813ebfbeaf9acfce22f67 100644 (file)
@@ -8,4 +8,4 @@ Note: the closing ?> has been deliberately elided.
 echo <<<'END'
 
 --EXPECTF--
-Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABLE) or heredoc end (T_END_HEREDOC) or ${ (T_DOLLAR_OPEN_CURLY_BRACES) or {$ (T_CURLY_OPEN) in %s on line %d
+Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" in %s on line %d
index ba6a2b85d87ff37519288c96befb922e46758b5c..5c5643206b91c93c37c3c8a3374de72abc1c2340 100644 (file)
@@ -8,4 +8,4 @@ eval('<<<\'end\'
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABLE) or heredoc end (T_END_HEREDOC) or ${ (T_DOLLAR_OPEN_CURLY_BRACES) or {$ (T_CURLY_OPEN) in %s on line %d
+Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" in %s on line %d
index 1f587dd8f55b692d2c044887a0a2190e0eb6e633..4067723a6f926d45828aa40d921cf3e107cf9874 100644 (file)
@@ -5,4 +5,4 @@ Leading commas in function calls is not allowed
 foo(,$foo);
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected ',' in %s on line %d
+Parse error: syntax error, unexpected token "," in %s on line %d
index d8250536dab9a62e2f4c82c52eaf2d8952aa6fc1..916ed7d4e5cd49a7a1fe028acf653234334190af 100644 (file)
@@ -5,4 +5,4 @@ Multiple inner commas in function calls is not allowed
 foo($foo,,$bar);
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected ',', expecting ')' in %s on line %d
+Parse error: syntax error, unexpected token ",", expecting ")" in %s on line %d
index a38a01644b6dcd05d13047a6188b1f0afdd32bf8..7e80b032a801f46c9bfc9d5a52fe5ee7dc351692 100644 (file)
@@ -5,4 +5,4 @@ Multiple trailing commas in function calls is not allowed
 foo($foo,,);
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected ',', expecting ')' in %s on line %d
+Parse error: syntax error, unexpected token ",", expecting ")" in %s on line %d
index 8a0ce6810d666d022f4fe2081fcfe60e854d94b7..467a5be5c0d159d108f7a816529968be5939150a 100644 (file)
@@ -5,4 +5,4 @@ Single comma in function calls is not allowed
 foo(,);
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected ',' in %s on line %d
+Parse error: syntax error, unexpected token "," in %s on line %d
index f032fc882dabbd0b8ec61c8c28798a0565ba8de0..b820cee1e85b2714e73197dcaef36a84f26f740a 100644 (file)
@@ -11,4 +11,4 @@ class Obj
 
 function echo(){} // not valid
 --EXPECTF--
-Parse error: syntax error, unexpected 'echo' (T_ECHO), expecting %s in %s on line 9
+Parse error: syntax error, unexpected token "echo", expecting "(" in %s on line %d
index ad83ee717d9cbfd409d4e3cf8bbd10ad1a58d94c..2735829f2c8caa0b76dcb548ea21718b337620ce 100644 (file)
@@ -10,4 +10,4 @@ class Obj
 
 const return = 'nope';
 --EXPECTF--
-Parse error: syntax error, unexpected 'return' (T_RETURN), expecting identifier (T_STRING) in %s on line 8
+Parse error: syntax error, unexpected token "return", expecting identifier in %s on line %d
index 817f337a5c80d90246430682da6a8885970e3cc8..4e3e175b41ae697abba19254becea256dff73129 100644 (file)
@@ -9,4 +9,4 @@ class A {
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected 'FOREACH' (T_FOREACH), expecting ']' in %s on line %d
+Parse error: syntax error, unexpected token "foreach", expecting "]" in %s on line %d
index 316498c4116860df7ef6d80070e15d1c36afc4b8..a5cfe69f0cc2e137f68d24bc2bfebd38cbac1665 100644 (file)
@@ -7,4 +7,4 @@ var_dump(list(1, 2, 3));
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected ')', expecting '=' in %s on line %d
+Parse error: syntax error, unexpected token ")", expecting "=" in %s on line %d
index 18210da6df817375cca58f054872733b7f8dbce4..01ea1175c079fb785a8fa6ac8f27e7ca07142cfd 100644 (file)
@@ -14,4 +14,4 @@ namespace Fiz\Biz\Buz {
 }
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected '{', expecting '}' in %sns_088.php on line 5
+Parse error: syntax error, unexpected token "{", expecting "}" in %s on line %d
index 06947bb6dd14cea40851eac3f8b581706aeebb8e..67cf4b6e2a73303148f335ac4d220db2c0b74895 100644 (file)
@@ -11,4 +11,4 @@ use const Foo\Bar\{
     function C
 };
 --EXPECTF--
-Parse error: syntax error, unexpected 'const' (T_CONST), expecting '}' in %s on line 7
+Parse error: syntax error, unexpected token "const", expecting "}" in %s on line %d
index 48f0c75387a9decf558a7afceceff3ee396acafe..f72e37f7d3b1f3dc69f25f709e59b6b9ee1e81bf 100644 (file)
@@ -7,4 +7,4 @@ use Foo\Bar\{\Baz};
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected '\' (T_NS_SEPARATOR), expecting identifier (T_STRING) or function (T_FUNCTION) or const (T_CONST) in %s on line 3
+Parse error: syntax error, unexpected token "\", expecting identifier or "function" or "const" in %s on line %d
index 1b226036cfe7e68fe7cb11c68e72b006f214c2e8..7b9c5177bf1dcbbc88050b97b0761ddb1759eaea 100644 (file)
@@ -5,4 +5,4 @@ Group use declarations mustn't be empty
 use Baz\{};
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected '}', expecting identifier (T_STRING) or function (T_FUNCTION) or const (T_CONST) in %s on line %d
+Parse error: syntax error, unexpected token "}", expecting identifier or "function" or "const" in %s on line %d
index c2123a85f5a4e13f91227b8e15a5e7f39fc0a915..91b70d3bd640f2547fb2a6959aeee6b206a0f615 100644 (file)
@@ -5,4 +5,4 @@ Group use declarations mustn't contain just a comma
 use Baz\{,};
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected ',', expecting identifier (T_STRING) or function (T_FUNCTION) or const (T_CONST) in %s on line %d
+Parse error: syntax error, unexpected token ",", expecting identifier or "function" or "const" in %s on line %d
index a07720becc7c170e0821406734976d337a366347..3455f55533bab10042b46dbdac6a100e55841394 100644 (file)
@@ -5,4 +5,4 @@ Group use declarations mustn't allow more than one comma
 use Baz\{Foo,,};
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected ',', expecting '}' in %s on line %d
+Parse error: syntax error, unexpected token ",", expecting "}" in %s on line %d
index 09d7ebf34924de518de120c83b4d51ac4abcc114..2712c5aa115c4e7eab568640d5fdaf0b9ea2e6fd 100644 (file)
@@ -5,4 +5,4 @@ Group use declarations mustn't begin with a comma
 use Baz\{,Foo};
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected ',', expecting identifier (T_STRING) or function (T_FUNCTION) or const (T_CONST) in %s on line %d
+Parse error: syntax error, unexpected token ",", expecting identifier or "function" or "const" in %s on line %d
index d748747a03fc3f4dbea4020c3ca90a76a0d453db..93cb93964ba3da6bd3419407587c7c67825b0ad2 100644 (file)
@@ -5,4 +5,4 @@ Group use declarations mustn't contain two commas mid-list
 use Baz\{Foo,,Bar};
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected ',', expecting '}' in %s on line %d
+Parse error: syntax error, unexpected token ",", expecting "}" in %s on line %d
index 8d8b759a5a9be36f36494eaaf08f16cf6c01acf0..2547a6f0275bfb7870af112b678033c920b5625b 100644 (file)
@@ -5,4 +5,4 @@ Unmixed group use declarations mustn't allow more than one comma
 use const Baz\{Foo,,};
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected ',', expecting '}' in %s on line %d
+Parse error: syntax error, unexpected token ",", expecting "}" in %s on line %d
index e925a60de8c2ecc21e4c3ded49625200a27bfd09..742d809bbc9cab13885a5d4bf18794730840c3e5 100644 (file)
@@ -5,4 +5,4 @@ Unmixed group use declarations mustn't begin with a comma
 use function Baz\{,Foo};
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected ',', expecting identifier (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected token ",", expecting identifier in %s on line %d
index b3804aeb764010928c4586838e325fc0e3254947..287f35d2eb963e705a024589933a12c0134c94bb 100644 (file)
@@ -5,4 +5,4 @@ Unmixed group use declarations mustn't contain two commas mid-list
 use const Baz\{Foo,,Bar};
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected ',', expecting '}' in %s on line %d
+Parse error: syntax error, unexpected token ",", expecting "}" in %s on line %d
index 984438fc0709ecdca39b137bba7b9f56eeb4b06c..5eacdf056f7ced40e72e6b8f0a8a6bfe97ef4750 100644 (file)
@@ -4,4 +4,4 @@ Invalid use: trailing underscore
 <?php
 100_;
 --EXPECTF--
-Parse error: syntax error, unexpected '_' (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected identifier "_" in %s on line %d
index e0cd716223bce065bbc3fb95a42b248c81083a30..d4b6b81bc4a6b975d872eb96f75074bf271ffce4 100644 (file)
@@ -4,4 +4,4 @@ Invalid use: adjacent underscores
 <?php
 10__0;
 --EXPECTF--
-Parse error: syntax error, unexpected '__0' (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected identifier "__0" in %s on line %d
index 6db8f8eb86356eca236792454733383ca90a959b..53c9fea9715ef96eadfa84ac0bcacd7db6824227 100644 (file)
@@ -4,4 +4,4 @@ Invalid use: underscore left of period
 <?php
 100_.0;
 --EXPECTF--
-Parse error: syntax error, unexpected '_' (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected identifier "_" in %s on line %d
index 4b454e2d1788ca097706e12a6504dd3b55cc0d80..0c86ecfa5e23241a5385dbd536075adbd00672bc 100644 (file)
@@ -4,4 +4,4 @@ Invalid use: underscore right of period
 <?php
 100._0;
 --EXPECTF--
-Parse error: syntax error, unexpected '_0' (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected identifier "_0" in %s on line %d
index 14bd290992e0f3786c2c9694a41320b3ada86fb9..3ef391f63be5f89a09fef2924ac3fd1bb82fa2a1 100644 (file)
@@ -4,4 +4,4 @@ Invalid use: underscore next to 0x
 <?php
 0x_0123;
 --EXPECTF--
-Parse error: syntax error, unexpected 'x_0123' (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected identifier "x_0123" in %s on line %d
index e74c7ed03316e0873fb6112fafaa2e614c30e4d6..b2a04a82a18379ade5d343629404b3317e6a32d8 100644 (file)
@@ -4,4 +4,4 @@ Invalid use: underscore next to 0b
 <?php
 0b_0101;
 --EXPECTF--
-Parse error: syntax error, unexpected 'b_0101' (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected identifier "b_0101" in %s on line %d
index 66f1d0ff6acbd9c4621f34899e0bdcb961d2a66f..8c789b4e804f4fc70311e55a091a2aade6fb9d10 100644 (file)
@@ -4,4 +4,4 @@ Invalid use: underscore left of e
 <?php
 1_e2;
 --EXPECTF--
-Parse error: syntax error, unexpected '_e2' (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected identifier "_e2" in %s on line %d
index c690f66b1058fb0a7f121ac1846060ece4288e1f..74a20b7827518b4fa98d8529571dac50b699f8c5 100644 (file)
@@ -4,4 +4,4 @@ Invalid use: underscore right of e
 <?php
 1e_2;
 --EXPECTF--
-Parse error: syntax error, unexpected 'e_2' (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected identifier "e_2" in %s on line %d
index d035e296245a57cf4941e05f91fc1f871ae582a0..d64efe178671c904adcac9cd73a56ae382e92966 100644 (file)
@@ -45,7 +45,7 @@ var_dump("\u{ffffff}");');
 Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0
 Unclosed '{' on line 2
 Unclosed '{' on line 3
-syntax error, unexpected end of file, expecting '(' on line 2
+syntax error, unexpected end of file, expecting "(" on line 2
 Invalid numeric literal on line 2
 Invalid UTF-8 codepoint escape sequence on line 2
 Invalid UTF-8 codepoint escape sequence: Codepoint too large on line 2
index 9fe36d7a80d0c155148a4e519743c070f591d00c..d37737aaca5b519a11332f27b6689cb49e4baadf 100644 (file)
@@ -12,4 +12,4 @@ trait Foo extends Base {
 echo 'DONE';
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected 'extends' (T_EXTENDS), expecting '{' in %s on line %d
+Parse error: syntax error, unexpected token "extends", expecting "{" in %s on line %d
index e68e54f3de40c9c34afa5c7f9d23ca66edf7b093..39146f97a4af38dd78900a9b75cbc40bcb452d05 100644 (file)
@@ -16,4 +16,4 @@ trait THello implements MyInterface {
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected 'implements' (T_IMPLEMENTS), expecting '{' in %s on line %d
+Parse error: syntax error, unexpected token "implements", expecting "{" in %s on line %d
index 416bddddc275a2906c1d6e811d455c3c12174467..5deef1923417defa78e7e186462bc5a9d1cc30f5 100644 (file)
@@ -7,4 +7,4 @@ $foo = (mixed) 12;
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected '12' (T_LNUMBER) in %s on line %d
+Parse error: syntax error, unexpected integer "12" in %s on line %d
index 4c0d6b1dfc9a9ef6ec0a8d62e0b1861bdceab012..22bcda4ae73430d16965acc8211d0922ee507da5 100644 (file)
@@ -12,4 +12,4 @@ class Test {
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected 'static' (T_STATIC), expecting variable (T_VARIABLE) in %s on line %d
+Parse error: syntax error, unexpected token "static", expecting variable in %s on line %d
index aba303d5fa22520181f036198e217fa748e08b37..62bb99706782bc1809d0201faa1a0d52418ac4fa 100644 (file)
@@ -10,4 +10,4 @@ class Test {
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected 'static' (T_STATIC) in %s on line %d
+Parse error: syntax error, unexpected token "static" in %s on line %d
index d38d5ddb9414b3890340ac251890fc8803db65c1..5ff9d35d7b7cc4c96003550bd73d5d1152f0a2e5 100644 (file)
@@ -8,4 +8,4 @@ class Foo {
 }
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected 'int' (T_STRING), expecting variable (T_VARIABLE) in %s on line 4
+Parse error: syntax error, unexpected identifier "int", expecting variable in %s on line %d
index 6847c6f2ea7ab6481d04202274a9fe848b78c29a..6162cbc993ff8d98c86ff9563ef43ecfd4f9cee3 100644 (file)
@@ -7,4 +7,4 @@ global $$foo->bar;
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR), expecting ';' or ',' in %s on line %d
+Parse error: syntax error, unexpected token "->", expecting ";" or "," in %s on line %d
index aa3164b735d0a148c78c14f0fde7add8df48c686..40938256f2a5ef7b457a75e2e0578d4d7504d1dc 100644 (file)
@@ -86,146 +86,146 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
 %precedence T_ELSEIF
 %precedence T_ELSE
 
-%token <ast> T_LNUMBER   "integer number (T_LNUMBER)"
-%token <ast> T_DNUMBER   "floating-point number (T_DNUMBER)"
-%token <ast> T_STRING    "identifier (T_STRING)"
-%token <ast> T_VARIABLE  "variable (T_VARIABLE)"
+%token <ast> T_LNUMBER   "integer"
+%token <ast> T_DNUMBER   "floating-point number"
+%token <ast> T_STRING    "identifier"
+%token <ast> T_VARIABLE  "variable"
 %token <ast> T_INLINE_HTML
-%token <ast> T_ENCAPSED_AND_WHITESPACE  "quoted-string and whitespace (T_ENCAPSED_AND_WHITESPACE)"
-%token <ast> T_CONSTANT_ENCAPSED_STRING "quoted-string (T_CONSTANT_ENCAPSED_STRING)"
-%token <ast> T_STRING_VARNAME "variable name (T_STRING_VARNAME)"
-%token <ast> T_NUM_STRING "number (T_NUM_STRING)"
-
-%token <ident> T_INCLUDE       "include (T_INCLUDE)"
-%token <ident> T_INCLUDE_ONCE  "include_once (T_INCLUDE_ONCE)"
-%token <ident> T_EVAL          "eval (T_EVAL)"
-%token <ident> T_REQUIRE       "require (T_REQUIRE)"
-%token <ident> T_REQUIRE_ONCE  "require_once (T_REQUIRE_ONCE)"
-%token <ident> T_LOGICAL_OR    "or (T_LOGICAL_OR)"
-%token <ident> T_LOGICAL_XOR   "xor (T_LOGICAL_XOR)"
-%token <ident> T_LOGICAL_AND   "and (T_LOGICAL_AND)"
-%token <ident> T_PRINT         "print (T_PRINT)"
-%token <ident> T_YIELD         "yield (T_YIELD)"
-%token <ident> T_YIELD_FROM    "yield from (T_YIELD_FROM)"
-%token <ident> T_INSTANCEOF    "instanceof (T_INSTANCEOF)"
-%token <ident> T_NEW           "new (T_NEW)"
-%token <ident> T_CLONE         "clone (T_CLONE)"
-%token <ident> T_EXIT          "exit (T_EXIT)"
-%token <ident> T_IF            "if (T_IF)"
-%token <ident> T_ELSEIF        "elseif (T_ELSEIF)"
-%token <ident> T_ELSE          "else (T_ELSE)"
-%token <ident> T_ENDIF         "endif (T_ENDIF)"
-%token <ident> T_ECHO          "echo (T_ECHO)"
-%token <ident> T_DO            "do (T_DO)"
-%token <ident> T_WHILE         "while (T_WHILE)"
-%token <ident> T_ENDWHILE      "endwhile (T_ENDWHILE)"
-%token <ident> T_FOR           "for (T_FOR)"
-%token <ident> T_ENDFOR        "endfor (T_ENDFOR)"
-%token <ident> T_FOREACH       "foreach (T_FOREACH)"
-%token <ident> T_ENDFOREACH    "endforeach (T_ENDFOREACH)"
-%token <ident> T_DECLARE       "declare (T_DECLARE)"
-%token <ident> T_ENDDECLARE    "enddeclare (T_ENDDECLARE)"
-%token <ident> T_AS            "as (T_AS)"
-%token <ident> T_SWITCH        "switch (T_SWITCH)"
-%token <ident> T_ENDSWITCH     "endswitch (T_ENDSWITCH)"
-%token <ident> T_CASE          "case (T_CASE)"
-%token <ident> T_DEFAULT       "default (T_DEFAULT)"
-%token <ident> T_MATCH         "match (T_MATCH)"
-%token <ident> T_BREAK         "break (T_BREAK)"
-%token <ident> T_CONTINUE      "continue (T_CONTINUE)"
-%token <ident> T_GOTO          "goto (T_GOTO)"
-%token <ident> T_FUNCTION      "function (T_FUNCTION)"
-%token <ident> T_FN            "fn (T_FN)"
-%token <ident> T_CONST         "const (T_CONST)"
-%token <ident> T_RETURN        "return (T_RETURN)"
-%token <ident> T_TRY           "try (T_TRY)"
-%token <ident> T_CATCH         "catch (T_CATCH)"
-%token <ident> T_FINALLY       "finally (T_FINALLY)"
-%token <ident> T_THROW         "throw (T_THROW)"
-%token <ident> T_USE           "use (T_USE)"
-%token <ident> T_INSTEADOF     "insteadof (T_INSTEADOF)"
-%token <ident> T_GLOBAL        "global (T_GLOBAL)"
-%token <ident> T_STATIC        "static (T_STATIC)"
-%token <ident> T_ABSTRACT      "abstract (T_ABSTRACT)"
-%token <ident> T_FINAL         "final (T_FINAL)"
-%token <ident> T_PRIVATE       "private (T_PRIVATE)"
-%token <ident> T_PROTECTED     "protected (T_PROTECTED)"
-%token <ident> T_PUBLIC        "public (T_PUBLIC)"
-%token <ident> T_VAR           "var (T_VAR)"
-%token <ident> T_UNSET         "unset (T_UNSET)"
-%token <ident> T_ISSET         "isset (T_ISSET)"
-%token <ident> T_EMPTY         "empty (T_EMPTY)"
-%token <ident> T_HALT_COMPILER "__halt_compiler (T_HALT_COMPILER)"
-%token <ident> T_CLASS         "class (T_CLASS)"
-%token <ident> T_TRAIT         "trait (T_TRAIT)"
-%token <ident> T_INTERFACE     "interface (T_INTERFACE)"
-%token <ident> T_EXTENDS       "extends (T_EXTENDS)"
-%token <ident> T_IMPLEMENTS    "implements (T_IMPLEMENTS)"
-%token <ident> T_NAMESPACE     "namespace (T_NAMESPACE)"
-%token <ident> T_LIST            "list (T_LIST)"
-%token <ident> T_ARRAY           "array (T_ARRAY)"
-%token <ident> T_CALLABLE        "callable (T_CALLABLE)"
-%token <ident> T_LINE            "__LINE__ (T_LINE)"
-%token <ident> T_FILE            "__FILE__ (T_FILE)"
-%token <ident> T_DIR             "__DIR__ (T_DIR)"
-%token <ident> T_CLASS_C         "__CLASS__ (T_CLASS_C)"
-%token <ident> T_TRAIT_C         "__TRAIT__ (T_TRAIT_C)"
-%token <ident> T_METHOD_C        "__METHOD__ (T_METHOD_C)"
-%token <ident> T_FUNC_C          "__FUNCTION__ (T_FUNC_C)"
-%token <ident> T_NS_C            "__NAMESPACE__ (T_NS_C)"
+%token <ast> T_ENCAPSED_AND_WHITESPACE  "string content"
+%token <ast> T_CONSTANT_ENCAPSED_STRING "quoted string"
+%token <ast> T_STRING_VARNAME "variable name"
+%token <ast> T_NUM_STRING "number"
+
+%token <ident> T_INCLUDE       "'include'"
+%token <ident> T_INCLUDE_ONCE  "'include_once'"
+%token <ident> T_EVAL          "'eval'"
+%token <ident> T_REQUIRE       "'require'"
+%token <ident> T_REQUIRE_ONCE  "'require_once'"
+%token <ident> T_LOGICAL_OR    "'or'"
+%token <ident> T_LOGICAL_XOR   "'xor'"
+%token <ident> T_LOGICAL_AND   "'and'"
+%token <ident> T_PRINT         "'print'"
+%token <ident> T_YIELD         "'yield'"
+%token <ident> T_YIELD_FROM    "'yield from'"
+%token <ident> T_INSTANCEOF    "'instanceof'"
+%token <ident> T_NEW           "'new'"
+%token <ident> T_CLONE         "'clone'"
+%token <ident> T_EXIT          "'exit'"
+%token <ident> T_IF            "'if'"
+%token <ident> T_ELSEIF        "'elseif'"
+%token <ident> T_ELSE          "'else'"
+%token <ident> T_ENDIF         "'endif'"
+%token <ident> T_ECHO          "'echo'"
+%token <ident> T_DO            "'do'"
+%token <ident> T_WHILE         "'while'"
+%token <ident> T_ENDWHILE      "'endwhile'"
+%token <ident> T_FOR           "'for'"
+%token <ident> T_ENDFOR        "'endfor'"
+%token <ident> T_FOREACH       "'foreach'"
+%token <ident> T_ENDFOREACH    "'endforeach'"
+%token <ident> T_DECLARE       "'declare'"
+%token <ident> T_ENDDECLARE    "'enddeclare'"
+%token <ident> T_AS            "'as'"
+%token <ident> T_SWITCH        "'switch'"
+%token <ident> T_ENDSWITCH     "'endswitch'"
+%token <ident> T_CASE          "'case'"
+%token <ident> T_DEFAULT       "'default'"
+%token <ident> T_MATCH         "'match'"
+%token <ident> T_BREAK         "'break'"
+%token <ident> T_CONTINUE      "'continue'"
+%token <ident> T_GOTO          "'goto'"
+%token <ident> T_FUNCTION      "'function'"
+%token <ident> T_FN            "'fn'"
+%token <ident> T_CONST         "'const'"
+%token <ident> T_RETURN        "'return'"
+%token <ident> T_TRY           "'try'"
+%token <ident> T_CATCH         "'catch'"
+%token <ident> T_FINALLY       "'finally'"
+%token <ident> T_THROW         "'throw'"
+%token <ident> T_USE           "'use'"
+%token <ident> T_INSTEADOF     "'insteadof'"
+%token <ident> T_GLOBAL        "'global'"
+%token <ident> T_STATIC        "'static'"
+%token <ident> T_ABSTRACT      "'abstract'"
+%token <ident> T_FINAL         "'final'"
+%token <ident> T_PRIVATE       "'private'"
+%token <ident> T_PROTECTED     "'protected'"
+%token <ident> T_PUBLIC        "'public'"
+%token <ident> T_VAR           "'var'"
+%token <ident> T_UNSET         "'unset'"
+%token <ident> T_ISSET         "'isset'"
+%token <ident> T_EMPTY         "'empty'"
+%token <ident> T_HALT_COMPILER "'__halt_compiler'"
+%token <ident> T_CLASS         "'class'"
+%token <ident> T_TRAIT         "'trait'"
+%token <ident> T_INTERFACE     "'interface'"
+%token <ident> T_EXTENDS       "'extends'"
+%token <ident> T_IMPLEMENTS    "'implements'"
+%token <ident> T_NAMESPACE     "'namespace'"
+%token <ident> T_LIST            "'list'"
+%token <ident> T_ARRAY           "'array'"
+%token <ident> T_CALLABLE        "'callable'"
+%token <ident> T_LINE            "'__LINE__'"
+%token <ident> T_FILE            "'__FILE__'"
+%token <ident> T_DIR             "'__DIR__'"
+%token <ident> T_CLASS_C         "'__CLASS__'"
+%token <ident> T_TRAIT_C         "'__TRAIT__'"
+%token <ident> T_METHOD_C        "'__METHOD__'"
+%token <ident> T_FUNC_C          "'__FUNCTION__'"
+%token <ident> T_NS_C            "'__NAMESPACE__'"
 
 %token END 0 "end of file"
-%token T_PLUS_EQUAL   "+= (T_PLUS_EQUAL)"
-%token T_MINUS_EQUAL  "-= (T_MINUS_EQUAL)"
-%token T_MUL_EQUAL    "*= (T_MUL_EQUAL)"
-%token T_DIV_EQUAL    "/= (T_DIV_EQUAL)"
-%token T_CONCAT_EQUAL ".= (T_CONCAT_EQUAL)"
-%token T_MOD_EQUAL    "%= (T_MOD_EQUAL)"
-%token T_AND_EQUAL    "&= (T_AND_EQUAL)"
-%token T_OR_EQUAL     "|= (T_OR_EQUAL)"
-%token T_XOR_EQUAL    "^= (T_XOR_EQUAL)"
-%token T_SL_EQUAL     "<<= (T_SL_EQUAL)"
-%token T_SR_EQUAL     ">>= (T_SR_EQUAL)"
-%token T_COALESCE_EQUAL "??= (T_COALESCE_EQUAL)"
-%token T_BOOLEAN_OR   "|| (T_BOOLEAN_OR)"
-%token T_BOOLEAN_AND  "&& (T_BOOLEAN_AND)"
-%token T_IS_EQUAL     "== (T_IS_EQUAL)"
-%token T_IS_NOT_EQUAL "!= (T_IS_NOT_EQUAL)"
-%token T_IS_IDENTICAL "=== (T_IS_IDENTICAL)"
-%token T_IS_NOT_IDENTICAL "!== (T_IS_NOT_IDENTICAL)"
-%token T_IS_SMALLER_OR_EQUAL "<= (T_IS_SMALLER_OR_EQUAL)"
-%token T_IS_GREATER_OR_EQUAL ">= (T_IS_GREATER_OR_EQUAL)"
-%token T_SPACESHIP "<=> (T_SPACESHIP)"
-%token T_SL "<< (T_SL)"
-%token T_SR ">> (T_SR)"
-%token T_INC "++ (T_INC)"
-%token T_DEC "-- (T_DEC)"
-%token T_INT_CAST    "(int) (T_INT_CAST)"
-%token T_DOUBLE_CAST "(double) (T_DOUBLE_CAST)"
-%token T_STRING_CAST "(string) (T_STRING_CAST)"
-%token T_ARRAY_CAST  "(array) (T_ARRAY_CAST)"
-%token T_OBJECT_CAST "(object) (T_OBJECT_CAST)"
-%token T_BOOL_CAST   "(bool) (T_BOOL_CAST)"
-%token T_UNSET_CAST  "(unset) (T_UNSET_CAST)"
-%token T_OBJECT_OPERATOR "-> (T_OBJECT_OPERATOR)"
-%token T_DOUBLE_ARROW    "=> (T_DOUBLE_ARROW)"
-%token T_COMMENT         "comment (T_COMMENT)"
-%token T_DOC_COMMENT     "doc comment (T_DOC_COMMENT)"
-%token T_OPEN_TAG        "open tag (T_OPEN_TAG)"
-%token T_OPEN_TAG_WITH_ECHO "open tag with echo (T_OPEN_TAG_WITH_ECHO)"
-%token T_CLOSE_TAG       "close tag (T_CLOSE_TAG)"
-%token T_WHITESPACE      "whitespace (T_WHITESPACE)"
-%token T_START_HEREDOC   "heredoc start (T_START_HEREDOC)"
-%token T_END_HEREDOC     "heredoc end (T_END_HEREDOC)"
-%token T_DOLLAR_OPEN_CURLY_BRACES "${ (T_DOLLAR_OPEN_CURLY_BRACES)"
-%token T_CURLY_OPEN      "{$ (T_CURLY_OPEN)"
-%token T_PAAMAYIM_NEKUDOTAYIM ":: (T_PAAMAYIM_NEKUDOTAYIM)"
-%token T_NS_SEPARATOR    "\\ (T_NS_SEPARATOR)"
-%token T_ELLIPSIS        "... (T_ELLIPSIS)"
-%token T_COALESCE        "?? (T_COALESCE)"
-%token T_POW             "** (T_POW)"
-%token T_POW_EQUAL       "**= (T_POW_EQUAL)"
-%token T_BAD_CHARACTER   "invalid character (T_BAD_CHARACTER)"
+%token T_PLUS_EQUAL   "'+='"
+%token T_MINUS_EQUAL  "'-='"
+%token T_MUL_EQUAL    "'*='"
+%token T_DIV_EQUAL    "'/='"
+%token T_CONCAT_EQUAL "'.='"
+%token T_MOD_EQUAL    "'%='"
+%token T_AND_EQUAL    "'&='"
+%token T_OR_EQUAL     "'|='"
+%token T_XOR_EQUAL    "'^='"
+%token T_SL_EQUAL     "'<<='"
+%token T_SR_EQUAL     "'>>='"
+%token T_COALESCE_EQUAL "'??='"
+%token T_BOOLEAN_OR   "'||'"
+%token T_BOOLEAN_AND  "'&&'"
+%token T_IS_EQUAL     "'=='"
+%token T_IS_NOT_EQUAL "'!='"
+%token T_IS_IDENTICAL "'==='"
+%token T_IS_NOT_IDENTICAL "'!=='"
+%token T_IS_SMALLER_OR_EQUAL "'<='"
+%token T_IS_GREATER_OR_EQUAL "'>='"
+%token T_SPACESHIP "'<=>'"
+%token T_SL "'<<'"
+%token T_SR "'>>'"
+%token T_INC "'++'"
+%token T_DEC "'--'"
+%token T_INT_CAST    "'(int)'"
+%token T_DOUBLE_CAST "'(double)'"
+%token T_STRING_CAST "'(string)'"
+%token T_ARRAY_CAST  "'(array)'"
+%token T_OBJECT_CAST "'(object)'"
+%token T_BOOL_CAST   "'(bool)'"
+%token T_UNSET_CAST  "'(unset)'"
+%token T_OBJECT_OPERATOR "'->'"
+%token T_DOUBLE_ARROW    "'=>'"
+%token T_COMMENT         "comment"
+%token T_DOC_COMMENT     "doc comment"
+%token T_OPEN_TAG        "open tag"
+%token T_OPEN_TAG_WITH_ECHO "'<?='"
+%token T_CLOSE_TAG       "'?>'"
+%token T_WHITESPACE      "whitespace"
+%token T_START_HEREDOC   "heredoc start"
+%token T_END_HEREDOC     "heredoc end"
+%token T_DOLLAR_OPEN_CURLY_BRACES "'${'"
+%token T_CURLY_OPEN      "'{$'"
+%token T_PAAMAYIM_NEKUDOTAYIM "'::'"
+%token T_NS_SEPARATOR    "'\\'"
+%token T_ELLIPSIS        "'...'"
+%token T_COALESCE        "'??'"
+%token T_POW             "'**'"
+%token T_POW_EQUAL       "'**='"
+%token T_BAD_CHARACTER   "invalid character"
 
 /* Token used to force a parse error from the lexer */
 %token T_ERROR
@@ -1438,15 +1438,16 @@ isset_variable:
 
 %%
 
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
-   quotes and backslashes, so that it's suitable for yyerror.  The
-   heuristic is that double-quoting is unnecessary unless the string
-   contains an apostrophe, a comma, or backslash (other than
-   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
-   null, do not copy; instead, return the length of what the result
-   would have been.  */
+/* Over-ride Bison formatting routine to give better token descriptions.
+   Copy to YYRES the contents of YYSTR for use in yyerror.
+   YYSTR is taken from yytname, from the %token declaration.
+   If YYRES is null, do not copy; instead, return the length of what
+   the result would have been.  */
 static YYSIZE_T zend_yytnamerr(char *yyres, const char *yystr)
 {
+       const char *toktype = yystr;
+       size_t toktype_len = strlen(toktype);
+
        /* CG(parse_error) states:
         * 0 => yyres = NULL, yystr is the unexpected token
         * 1 => yyres = NULL, yystr is one of the expected tokens
@@ -1460,63 +1461,141 @@ static YYSIZE_T zend_yytnamerr(char *yyres, const char *yystr)
        if (CG(parse_error) % 2 == 0) {
                /* The unexpected token */
                char buffer[120];
-               const unsigned char *end, *str, *tok1 = NULL, *tok2 = NULL;
-               unsigned int len = 0, toklen = 0, yystr_len;
+               const unsigned char *tokcontent, *tokcontent_end;
+               size_t tokcontent_len;
 
                CG(parse_error)++;
 
                if (LANG_SCNG(yy_text)[0] == 0 &&
                        LANG_SCNG(yy_leng) == 1 &&
-                       strcmp(yystr, "\"end of file\"") == 0) {
+                       strcmp(toktype, "\"end of file\"") == 0) {
                        if (yyres) {
                                yystpcpy(yyres, "end of file");
                        }
                        return sizeof("end of file")-1;
                }
 
-               str = LANG_SCNG(yy_text);
-               end = memchr(str, '\n', LANG_SCNG(yy_leng));
-               yystr_len = (unsigned int)strlen(yystr);
+               /* Prevent the backslash getting doubled in the output (eugh) */
+               if (strcmp(toktype, "\"'\\\\'\"") == 0) {
+                       if (yyres) {
+                               yystpcpy(yyres, "token \"\\\"");
+                       }
+                       return sizeof("token \"\\\"")-1;
+               }
 
-               if ((tok1 = memchr(yystr, '(', yystr_len)) != NULL
-                       && (tok2 = zend_memrchr(yystr, ')', yystr_len)) != NULL) {
-                       toklen = (tok2 - tok1) + 1;
-               } else {
-                       tok1 = tok2 = NULL;
-                       toklen = 0;
+               /* Avoid unreadable """ */
+               /* "'" would theoretically be just as bad, but is never currently parsed as a separate token */
+               if (strcmp(toktype, "'\"'") == 0) {
+                       if (yyres) {
+                               yystpcpy(yyres, "double-quote mark");
+                       }
+                       return sizeof("double-quote mark")-1;
                }
 
-               if (end == NULL) {
-                       len = LANG_SCNG(yy_leng) > 30 ? 30 : LANG_SCNG(yy_leng);
-               } else {
-                       len = (end - str) > 30 ? 30 : (end - str);
+               /* Strip off the outer quote marks */
+               if (toktype_len >= 2 && *toktype == '"') {
+                       toktype++;
+                       toktype_len -= 2;
                }
-               if (yyres) {
-                       if (toklen) {
-                               snprintf(buffer, sizeof(buffer), "'%.*s' %.*s", len, str, toklen, tok1);
-                       } else {
-                               snprintf(buffer, sizeof(buffer), "'%.*s'", len, str);
+
+               /* If the token always has one form, the %token line should have a single-quoted name */
+               /* The parser rules also include single-character un-named tokens which will be single-quoted here */
+               /* We re-format this with double quotes here to ensure everything's consistent */
+               if (toktype_len > 0 && *toktype == '\'') {
+                       if (yyres) {
+                               snprintf(buffer, sizeof(buffer), "token \"%.*s\"", (int)toktype_len-2, toktype+1);
+                               yystpcpy(yyres, buffer);
+                       }
+                       return toktype_len + sizeof("token ")-1;
+               }
+
+               /* Fetch the content of the last seen token from global lexer state */
+               tokcontent = LANG_SCNG(yy_text);
+               tokcontent_len = LANG_SCNG(yy_leng);
+
+               /* For T_BAD_CHARACTER, the content probably won't be a printable char */
+               /* Also, "unexpected invalid character" sounds a bit redundant */
+               if (tokcontent_len == 1 && strcmp(yystr, "\"invalid character\"") == 0) {
+                       if (yyres) {
+                               snprintf(buffer, sizeof(buffer), "character 0x%02hhX", *tokcontent);
+                               yystpcpy(yyres, buffer);
+                       }
+                       return sizeof("character 0x00")-1;
+               }
+
+               /* Truncate at line end to avoid messing up log formats */
+               tokcontent_end = memchr(tokcontent, '\n', tokcontent_len);
+               if (tokcontent_end != NULL) {
+                       tokcontent_len = (tokcontent_end - tokcontent);
+               }
+
+               /* Try to be helpful about what kind of string was found, before stripping the quotes */
+               if (tokcontent_len > 0 && strcmp(yystr, "\"quoted string\"") == 0) {
+                       if (*tokcontent == '"') {
+                               toktype = "double-quoted string";
+                               toktype_len = sizeof("double-quoted string")-1;
                        }
+                       else if (*tokcontent == '\'') {
+                               toktype = "single-quoted string";
+                               toktype_len = sizeof("single-quoted string")-1;
+                       }
+               }
+
+               /* For quoted strings, strip off another layer of quotes to avoid putting quotes inside quotes */
+               if (tokcontent_len > 0 && (*tokcontent == '\'' || *tokcontent=='"'))  {
+                       tokcontent++;
+                       tokcontent_len--;
+               }
+               if (tokcontent_len > 0 && (tokcontent[tokcontent_len-1] == '\'' || tokcontent[tokcontent_len-1] == '"'))  {
+                       tokcontent_len--;
+               }
+
+               /* Truncate to 30 characters and add a ... */
+               if (tokcontent_len > 30 + sizeof("...")-1) {
+                       if (yyres) {
+                               snprintf(buffer, sizeof(buffer), "%.*s \"%.*s...\"", (int)toktype_len, toktype, 30, tokcontent);
+                               yystpcpy(yyres, buffer);
+                       }
+                       return toktype_len + 30 + sizeof(" \"...\"")-1;
+               }
+
+               if (yyres) {
+                       snprintf(buffer, sizeof(buffer), "%.*s \"%.*s\"", (int)toktype_len, toktype, (int)tokcontent_len, tokcontent);
                        yystpcpy(yyres, buffer);
                }
-               return len + (toklen ? toklen + 1 : 0) + 2;
+               return toktype_len + tokcontent_len + sizeof(" \"\"")-1;
        }
 
        /* One of the expected tokens */
-       if (!yyres) {
-               return strlen(yystr) - (*yystr == '"' ? 2 : 0);
+
+       /* Prevent the backslash getting doubled in the output (eugh) */
+       if (strcmp(toktype, "\"'\\\\'\"") == 0) {
+               if (yyres) {
+                       yystpcpy(yyres, "\"\\\"");
+               }
+               return sizeof("\"\\\"")-1;
        }
 
-       if (*yystr == '"') {
+       /* Strip off the outer quote marks */
+       if (toktype_len >= 2 && *toktype == '"') {
+               toktype++;
+               toktype_len -= 2;
+       }
+
+       if (yyres) {
                YYSIZE_T yyn = 0;
-               const char *yyp = yystr;
 
-               for (; *++yyp != '"'; ++yyn) {
-                       yyres[yyn] = *yyp;
+               for (; yyn < toktype_len; ++yyn) {
+                       /* Replace single quotes with double for consistency */
+                       if (toktype[yyn] == '\'') {
+                               yyres[yyn] = '"';
+                       }
+                       else {
+                               yyres[yyn] = toktype[yyn];
+                       }
                }
-               yyres[yyn] = '\0';
-               return yyn;
+               yyres[toktype_len] = '\0';
        }
-       yystpcpy(yyres, yystr);
-       return strlen(yystr);
+
+       return toktype_len;
 }
index e311ab3beb31df97a17df4f2bfe06ef5b1416c4b..2a61ff7cc0b2811f330ba797a69089ec449b730c 100644 (file)
@@ -14,4 +14,4 @@ function load_file() {
 }
 ?>
 --EXPECT--
-ParseError: syntax error, unexpected 'if' (T_IF), expecting function (T_FUNCTION) or const (T_CONST)
+ParseError: syntax error, unexpected token "if", expecting "function" or "const"
index 161238af0eefcd1475926d05c2fd5c74e7973c2d..c2506009a584606272aed52802241c500d1024e0 100644 (file)
@@ -14,4 +14,4 @@ new Foo;
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected 'ha' (T_STRING) in %s on line %d
+Parse error: syntax error, unexpected identifier "ha" in %s on line %d
index b9da91502a687f6b550ff2e36621e2ce1766a511..2d418a423c004625d3ad5f7f8b2411cec84d56d9 100644 (file)
@@ -15,5 +15,5 @@ echo "Done";
 
 ?>
 --EXPECT--
-syntax error, unexpected 'code' (T_STRING)
+syntax error, unexpected identifier "code"
 Done
index 5f21c384d79c2a671c1a1183071fafc70594dcd1..d073fa59411e612ca4133e61f44b6e776f7afb47 100644 (file)
@@ -326,11 +326,11 @@ Line 2: T_END_HEREDOC ('  INNER_END')
 
 Test case 5
 
-Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABLE) or heredoc end (T_END_HEREDOC) or ${ (T_DOLLAR_OPEN_CURLY_BRACES) or {$ (T_CURLY_OPEN) on line 2
+Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" on line 2
 
 Test case 6
 
-Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABLE) or heredoc end (T_END_HEREDOC) or ${ (T_DOLLAR_OPEN_CURLY_BRACES) or {$ (T_CURLY_OPEN) on line 2
+Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" on line 2
 
 Test case 7
 
@@ -409,8 +409,8 @@ Line 3: T_END_HEREDOC ('   INNER_END')
 
 Test case 17
 
-Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABLE) or heredoc end (T_END_HEREDOC) or ${ (T_DOLLAR_OPEN_CURLY_BRACES) or {$ (T_CURLY_OPEN) on line 4
+Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" on line 4
 
 Test case 18
 
-Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABLE) or heredoc end (T_END_HEREDOC) or ${ (T_DOLLAR_OPEN_CURLY_BRACES) or {$ (T_CURLY_OPEN) on line 4
+Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" on line 4
index cbf466eea7fc2e2d7ebff3bd079430e1d93744e8..ec213db00d1c736d1b235827646bed58e73aa52f 100644 (file)
@@ -10,4 +10,4 @@ echo "$arr['foo']";
 
 ?>
 --EXPECTF--
-Parse error: %s error, %s(T_STRING)%s(T_VARIABLE)%s(T_NUM_STRING)%sin %sbug21820.php on line %d
+Parse error: %s error, %sidentifier%svariable%snumber%sin %sbug21820.php on line %d
index b2c41a359f53894c8a2b188ade4eb16ea902c930..9cbf17a64c5ee60f8b796a39711f93dad49016bb 100644 (file)
@@ -10,4 +10,4 @@ eval("
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected '%s' (T_BAD_CHARACTER) in %s on line %d
+Parse error: syntax error, unexpected character 0x7F in %s on line %d