diff --git a/lib/Node/Expr.php b/lib/Node/Expr.php index 747192b..387b4c9 100644 --- a/lib/Node/Expr.php +++ b/lib/Node/Expr.php @@ -1,5 +1,5 @@ p($node->var) . ' = ' . $this->p($node->expr); } + public function pExpr_AssignRef(Node_Expr_AssignRef $node) { + return $this->p($node->var) . ' =& ' . $this->p($node->refVar); + } + public function pExpr_AssignPlus(Node_Expr_AssignPlus $node) { return $this->p($node->var) . ' += ' . $this->p($node->expr); } @@ -116,6 +120,19 @@ class PrettyPrinter_Zend extends PrettyPrinterAbstract return $this->p($node->var) . ' >>= ' . $this->p($node->expr); } + public function pExpr_List(Node_Expr_List $node) { + $pAssignList = array(); + foreach ($node->assignList as $element) { + if (null === $element) { + $pAssignList[] = ''; + } else { + $pAssignList[] = $this->p($element); + } + } + + return 'list(' . implode(', ', $pAssignList) . ') = ' . $this->p($node->expr); + } + // Binary expressions public function pExpr_Plus(Node_Expr_Plus $node) { @@ -281,6 +298,12 @@ class PrettyPrinter_Zend extends PrettyPrinterAbstract . '(' . $this->pCommaSeparated($node->args) . ')'; } + public function pExpr_StaticCall(Node_Expr_StaticCall $node) { + return $this->p($node->class) . '::' + . ($node->func instanceof Node_Variable ? $this->p($node->func) : $node->func) + . '(' . $this->pCommaSeparated($node->args) . ')'; + } + public function pExpr_Empty(Node_Expr_Empty $node) { return 'empty(' . $this->p($node->var) . ')'; } @@ -328,10 +351,7 @@ class PrettyPrinter_Zend extends PrettyPrinterAbstract } public function pExpr_StaticPropertyFetch(Node_Expr_StaticPropertyFetch $node) { - // TODO - - return $this->p($node->class) . '::' - . ($node->name instanceof Node_Expr ? $this->p($node->name) : '$' . $node->name); + return $this->p($node->class) . '::$' . $this->pObjectProperty($node->name); } public function pExpr_LambdaFunc(Node_Expr_LambdaFunc $node) { @@ -355,15 +375,11 @@ class PrettyPrinter_Zend extends PrettyPrinterAbstract . ': ' . $this->p($node->else); } - // Statements - - public function pStmt_Break(Node_Stmt_Break $node) { - return 'break' . ($node->num !== null ? ' ' . $node->num : ''); + public function pExpr_Exit(Node_Expr_Exit $node) { + return 'die' . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : ''); } - public function pStmt_Continue(Node_Stmt_Continue $node) { - return 'continue' . ($node->num !== null ? ' ' . $node->num : ''); - } + // Declarations public function pStmt_Class(Node_Stmt_Class $node) { return $this->pModifiers($node->type) @@ -373,12 +389,13 @@ class PrettyPrinter_Zend extends PrettyPrinterAbstract . "\n" . '{' . "\n" . $this->pIndent($this->pStmts($node->stmts)) . '}'; } - public function pStmt_ClassConst(Node_Stmt_ClassConst $node) { - return 'const ' . $this->pCommaSeparated($node->consts); + public function pStmt_Property(Node_Stmt_Property $node) { + return $this->pModifiers($node->type) . $this->pCommaSeparated($node->props); } - public function pStmt_ClassConstConst(Node_Stmt_ClassConstConst $node) { - return $node->name . ' = ' . $this->p($node->value); + public function pStmt_PropertyProperty(Node_Stmt_PropertyProperty $node) { + return '$' . $node->name + . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); } public function pStmt_ClassMethod(Node_Stmt_ClassMethod $node) { @@ -388,15 +405,12 @@ class PrettyPrinter_Zend extends PrettyPrinterAbstract . "\n" . '{' . "\n" . $this->pIndent($this->pStmts($node->stmts)) . '}'; } - public function pStmt_Echo(Node_Stmt_Echo $node) { - return 'echo ' . $this->pCommaSeparated($node->exprs); + public function pStmt_ClassConst(Node_Stmt_ClassConst $node) { + return 'const ' . $this->pCommaSeparated($node->consts); } - public function pStmt_Foreach(Node_Stmt_Foreach $node) { - return 'foreach (' . $this->p($node->expr) . ' ' - . (null !== $node->keyVar ? $this->p($node) . ' as ' : '') - . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {' . "\n" - . $this->pIndent($this->pStmts($node->stmts)) . '}'; + public function pStmt_ClassConstConst(Node_Stmt_ClassConstConst $node) { + return $node->name . ' = ' . $this->p($node->value); } public function pStmt_Func(Node_Stmt_Func $node) { @@ -412,6 +426,16 @@ class PrettyPrinter_Zend extends PrettyPrinterAbstract . ($node->default ? ' = ' . $this->p($node->default) : ''); } + public function pStmt_Const(Node_Stmt_Const $node) { + return 'const ' . $this->pCommaSeparated($node->consts); + } + + public function pStmt_ConstConst(Node_Stmt_ConstConst $node) { + return $node->name . ' = ' . $this->p($node->value); + } + + // Control flow + public function pStmt_If(Node_Stmt_If $node) { return 'if (' . $this->p($node->cond) . ') {' . "\n" . $this->pIndent($this->pStmts($node->stmts)) . '}' @@ -420,7 +444,7 @@ class PrettyPrinter_Zend extends PrettyPrinterAbstract } public function pStmt_Elseif(Node_Stmt_Elseif $node) { - return ' elseif {' . "\n" + return ' elseif (' . $this->p($node->cond) . ') {' . "\n" . $this->pIndent($this->pStmts($node->stmts)) . '}'; } @@ -429,19 +453,62 @@ class PrettyPrinter_Zend extends PrettyPrinterAbstract . $this->pIndent($this->pStmts($node->stmts)) . '}'; } - public function pStmt_Property(Node_Stmt_Property $node) { - return $this->pModifiers($node->type) . $this->pCommaSeparated($node->props); + public function pStmt_For(Node_Stmt_For $node) { + return 'for (' + . $this->pCommaSeparated($node->init) . ';' + . $this->pCommaSeparated($node->cond) . ';' + . $this->pCommaSeparated($node->loop) + . ') {' . "\n" . $this->pIndent($this->pStmts($node->stmts)) . '}'; } - public function pStmt_PropertyProperty(Node_Stmt_PropertyProperty $node) { - return '$' . $node->name - . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); + public function pStmt_Foreach(Node_Stmt_Foreach $node) { + return 'foreach (' . $this->p($node->expr) . ' as ' + . (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '') + . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {' . "\n" + . $this->pIndent($this->pStmts($node->stmts)) . '}'; + } + + public function pStmt_While(Node_Stmt_While $node) { + return 'while (' . $this->p($node->cond) . ') {' + . "\n" . $this->pIndent($this->pStmts($node->stmts)) . '}'; + } + + public function pStmt_Switch(Node_Stmt_Switch $node) { + return 'switch (' . $this->p($node->cond) . ') {' + . "\n" . $this->pIndent($this->pImplode($node->caseList)) . '}'; + } + + public function pStmt_Case(Node_Stmt_Case $node) { + return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':' + . "\n" . $this->pIndent($this->pStmts($node->stmts)); + } + + public function pStmt_Break(Node_Stmt_Break $node) { + return 'break' . ($node->num !== null ? ' ' . $node->num : ''); + } + + public function pStmt_Continue(Node_Stmt_Continue $node) { + return 'continue' . ($node->num !== null ? ' ' . $node->num : ''); } public function pStmt_Return(Node_Stmt_Return $node) { return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : ''); } + public function pStmt_Throw(Node_Stmt_Throw $node) { + return 'throw' . (null !== $node->expr ? ' ' . $this->p($node->expr) : ''); + } + + // Other + + public function pStmt_Echo(Node_Stmt_Echo $node) { + return 'echo ' . $this->pCommaSeparated($node->exprs); + } + + public function pStmt_Noop(Node_Stmt_Noop $node) { + return ''; + } + public function pStmt_Static(Node_Stmt_Static $node) { return 'static ' . $this->pCommaSeparated($node->vars); } @@ -451,7 +518,7 @@ class PrettyPrinter_Zend extends PrettyPrinterAbstract . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); } - // helpers + // Helpers public function pObjectProperty($node) { if ($node instanceof Node_Expr) { diff --git a/lib/PrettyPrinterAbstract.php b/lib/PrettyPrinterAbstract.php index a59117e..a1cdf07 100644 --- a/lib/PrettyPrinterAbstract.php +++ b/lib/PrettyPrinterAbstract.php @@ -78,11 +78,14 @@ abstract class PrettyPrinterAbstract foreach ($nodes as $node) { $return .= $this->p($node); - if ($node instanceof Node_Stmt_Func - || $node instanceof Node_Stmt_Class - || $node instanceof Node_Stmt_ClassMethod - || $node instanceof Node_Stmt_Foreach - || $node instanceof Node_Stmt_If + if ( $node instanceof Node_Stmt_Func + || $node instanceof Node_Stmt_Class + || $node instanceof Node_Stmt_ClassMethod + || $node instanceof Node_Stmt_For + || $node instanceof Node_Stmt_Foreach + || $node instanceof Node_Stmt_If + || $node instanceof Node_Stmt_Switch + || $node instanceof Node_Stmt_While ) { $return .= "\n"; } else { diff --git a/test.php b/test.php index 6c0a796..1a01242 100644 --- a/test.php +++ b/test.php @@ -23,6 +23,7 @@ $stmts = $parser->yyparse(new Lexer( echo $msg; } ); + if (false !== $stmts) { foreach ($stmts as $stmt) { echo htmlspecialchars($stmt), "\n"; @@ -34,38 +35,9 @@ echo "\n\n"; $prettyPrinter = new PrettyPrinter_Zend; echo htmlspecialchars($prettyPrinter->pStmts( $parser->yyparse( - new Lexer(file_get_contents('./lib/Parser.php')), + new Lexer(file_get_contents('./grammar/analyzer.php')), function ($msg) { echo $msg; } ) -)); - -echo "\n\n"; - -// Correctness Demo -$GST = microtime(true); -foreach (new RecursiveIteratorIterator( - new RecursiveDirectoryIterator('.'), - RecursiveIteratorIterator::LEAVES_ONLY) - as $file) { - if ('.php' !== substr($file, -4)) { - continue; - } - - set_time_limit(5); - - $startTime = microtime(true); - $stmts = $parser->yyparse( - new Lexer(file_get_contents($file)), - function($msg) { - echo $msg, "\n"; - } - ); - $endTime = microtime(true); - - echo str_pad($file . ': ', 120, ' '), (false !== $stmts ? 'successful' : 'ERROR'), ' (', $endTime - $startTime, ')', "\n"; - - flush(); -} -echo microtime(true) - $GST; \ No newline at end of file +)); \ No newline at end of file diff --git a/test/testAgainstDirectory.php b/test/testAgainstDirectory.php new file mode 100644 index 0000000..d271fc0 --- /dev/null +++ b/test/testAgainstDirectory.php @@ -0,0 +1,120 @@ +yydebug = false; + +$prettyPrinter = new PrettyPrinter_Zend; + +echo ' + + + + + + + + + '; + +$GST = microtime(true); +foreach (new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($DIR), + RecursiveIteratorIterator::LEAVES_ONLY) + as $file) { + if ('.php' !== substr($file, -4)) { + continue; + } + + echo ' + + '; + + set_time_limit(5); + + $errMsg = ''; + $startTime = microtime(true); + + $stmts = $parser->yyparse( + new Lexer(file_get_contents($file)), + function($msg) use (&$errMsg) { + $errMsg = $msg; + } + ); + + $time = microtime(true) - $startTime; + + if (false !== $stmts) { + $code = 'pStmts($stmts); + + $ppStmts = $parser->yyparse( + new Lexer($code), + function($msg) use (&$errMsg) { + $errMsg = $msg; + } + ); + + if (false !== $ppStmts) { + if ($stmts == $ppStmts) { + echo ' + + + + + '; + } else { + echo ' + + + + + '; + } + } else { + echo ' + + + + + '; + } + } else { + echo ' + + + + + + '; + } + + flush(); +} + +echo ' +
FileParseTimePrettyPrintSame
' . $file . 'PASS' . $time . 'sPASSPASS
PASS' . $time . 'sPASSFAIL
PASS' . $time . 'sFAIL
FAIL' . $time . 's
' . $errMsg . '
'; + +echo 'Total time: ', microtime(true) - $GST; \ No newline at end of file