Hi,

I spent a while tonight tinkering with the parser to try to figure out
how to allow it to use T_IMPORT as well as T_STRING for method names,
and quickly came to the conclusion that this causes way more trouble
than it is worth.  However, in a moment of inspiration, I realized that
a minor change in the lexer would allow any reserved words for method
names.  The patch is attached.  This patch allows all kinds of odd
looking code that probably won't be used, but permanently guarantees
that code written for PHP now will never conflict with future reserved
words:

<?php
namespace testing;
class Test {
function array()
{
echo "array\n";
}
function class()
{
echo "class\n";
}
static function import()
{
echo "import\n";
}
function new()
{
echo "new\n";
}
$a = new Test;
$a->array();
$a->class();
$a->new();
Test::import();
testing::Test::import();
?>

The patch does not allow reserved names for class names, interface
names, functions, or for class constants.  This would be much harder to
implement in the lexer, and in my experience collisions with reserved
words most often happens with methods.

The patch only allows methods to use reserved words, not functions, and
causes a fatal error with this code:

<?php
function foreach($a)
{
}
?>

This prevents this wtf code, which would also produce a different (and
non-intuitive) fatal error:

<?php
foreach (foreach() as $foreach) {foreach();}
?>

The patch is against PHP 5.3, and PHP 6

Greg
? better_halt.patch.txt
? config.cli
? config.nice.nodebug
? err
? install-pear-nozlib.phar
? run-tests.oops.patch.txt
? smarter_lexer.patch.txt
? test-phar.sh
? test.phar
? testme.php
? zlib.patch
? Zend/tests/zend_function_name.phpt
? ext/gd/run-tests.php
? ext/gettext/run-tests.php
? ext/mysqli/run-tests.php
? ext/zip/run-tests.php
? ext/zlib/zlib_filter.c.2
? pear/scripts
? tests/lang/halt_compiler1.phpt
? tests/lang/halt_compiler2.phpt
? tests/lang/halt_compiler3.phpt
? tests/lang/halt_compiler4.phpt
Index: run-tests.php
===================================================================
RCS file: /repository/php-src/run-tests.php,v
retrieving revision 1.226.2.37.2.35
diff -u -r1.226.2.37.2.35 run-tests.php
--- run-tests.php       14 Sep 2007 15:28:03 -0000      1.226.2.37.2.35
+++ run-tests.php       3 Oct 2007 02:40:57 -0000
@@ -1328,12 +1328,15 @@
                $raw_lines = explode("\n", $post);
 
                $request = '';
+               $started = false;
                foreach ($raw_lines as $line) {
                        if (empty($env['CONTENT_TYPE']) && 
preg_match('/^Content-Type:(.*)/i', $line, $res)) {
                                $env['CONTENT_TYPE'] = trim(str_replace("\r", 
'', $res[1]));
                                continue;
                        }
-                       $request .= $line . "\n";
+                       if ($started) $request .= "\n";
+                       $started = true;
+                       $request .= $line;
                }
 
                $env['CONTENT_LENGTH'] = strlen($request);
Index: Zend/zend_language_scanner.l
===================================================================
RCS file: /repository/ZendEngine2/zend_language_scanner.l,v
retrieving revision 1.131.2.11.2.13.2.1
diff -u -r1.131.2.11.2.13.2.1 zend_language_scanner.l
--- Zend/zend_language_scanner.l        28 Sep 2007 19:52:50 -0000      
1.131.2.11.2.13.2.1
+++ Zend/zend_language_scanner.l        3 Oct 2007 02:41:02 -0000
@@ -978,6 +978,9 @@
 }
 
 <ST_IN_SCRIPTING>"function" {
+       if (CG(active_class_entry)) {
+               yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
+       }
        return T_FUNCTION;
 }
 
@@ -1118,6 +1121,14 @@
        return T_OBJECT_OPERATOR;
 }
 
+<ST_LOOKING_FOR_PROPERTY>{WHITESPACE} {
+       zendlval->value.str.val = yytext; /* no copying - intentional */
+       zendlval->value.str.len = yyleng;
+       zendlval->type = IS_STRING;
+       HANDLE_NEWLINES(yytext, yyleng);
+       return T_WHITESPACE;
+}
+
 <ST_LOOKING_FOR_PROPERTY>{LABEL} {
        yy_pop_state(TSRMLS_C);
        zend_copy_value(zendlval, yytext, yyleng);
@@ -1131,6 +1142,7 @@
 }
 
 <ST_IN_SCRIPTING>"::" {
+       yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
        return T_PAAMAYIM_NEKUDOTAYIM;
 }
 
Index: Zend/zend_language_scanner.l
===================================================================
RCS file: /repository/ZendEngine2/zend_language_scanner.l,v
retrieving revision 1.170
diff -u -r1.170 zend_language_scanner.l
--- Zend/zend_language_scanner.l        9 Sep 2007 22:49:31 -0000       1.170
+++ Zend/zend_language_scanner.l        3 Oct 2007 02:42:31 -0000
@@ -1483,6 +1483,9 @@
 }
 
 <ST_IN_SCRIPTING>"function" {
+       if (CG(active_class_entry)) {
+               yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
+       }
        return T_FUNCTION;
 }
 
@@ -1627,6 +1630,14 @@
        return T_OBJECT_OPERATOR;
 }
 
+<ST_LOOKING_FOR_PROPERTY>{WHITESPACE} {
+       Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
+       Z_STRLEN_P(zendlval) = yyleng;
+       Z_TYPE_P(zendlval) = IS_STRING;
+       HANDLE_NEWLINES(yytext, yyleng);
+       return T_WHITESPACE;
+}
+
 <ST_LOOKING_FOR_PROPERTY>{LABEL} {
        yy_pop_state(TSRMLS_C);
        if (!zend_copy_scanner_string(zendlval, yytext, yyleng, 
UG(unicode)?IS_UNICODE:IS_STRING, SCNG(output_conv) TSRMLS_CC)) {
@@ -1644,6 +1655,7 @@
 }
 
 <ST_IN_SCRIPTING>"::" {
+       yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
        return T_PAAMAYIM_NEKUDOTAYIM;
 }
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to