1
0
mirror of https://github.com/danog/PHP-Parser.git synced 2024-11-30 04:19:30 +01:00

Fix parsing of special int syntaxes

Also add the means to test code parsing.
This commit is contained in:
nikic 2011-11-26 16:09:39 +01:00
parent adfa67cdcf
commit 933bebb9b8
6 changed files with 143 additions and 10 deletions

View File

@ -132,12 +132,6 @@ function resolveMacros($code) {
return 'substr(' . $args[0] . ', 1)';
}
if ('parseLNumber' == $name) {
assertArgs(1, $args, $name);
return '(int) ' . $args[0];
}
if ('parseDNumber' == $name) {
assertArgs(1, $args, $name);

View File

@ -654,7 +654,7 @@ ctor_arguments:
;
common_scalar:
T_LNUMBER { $$ = Scalar_LNumber[parseLNumber($1)]; }
T_LNUMBER { $$ = Scalar_LNumber[Scalar_LNumber::parse($1)]; }
| T_DNUMBER { $$ = Scalar_DNumber[parseDNumber($1)]; }
| T_CONSTANT_ENCAPSED_STRING { $$ = Scalar_String::create($1, $line, $docComment); }
| T_LINE { $$ = Scalar_LineConst[]; }
@ -828,7 +828,7 @@ encaps_var:
encaps_var_offset:
T_STRING { $$ = Scalar_String[$1]; }
| T_NUM_STRING { $$ = Scalar_LNumber[parseLNumber($1)]; }
| T_NUM_STRING { $$ = Scalar_String[$1]; }
| T_VARIABLE { $$ = Expr_Variable[parseVar($1)]; }
;

View File

@ -20,4 +20,37 @@ class PHPParser_Node_Scalar_LNumber extends PHPParser_Node_Scalar
$line, $docComment
);
}
/**
* Parses an LNUMBER token (dec, hex, oct and bin notations) like PHP would.
*
* @param string $str A string number
*
* @return int The parsed number
*/
public static function parse($str) {
// handle plain 0 specially
if ('0' === $str) {
return 0;
}
// if first char is 0 (and number isn't 0) it's a special syntax
if ('0' === $str[0]) {
// hex
if ('x' === $str[1] || 'X' === $str[1]) {
return hexdec($str);
}
// bin
if ('b' === $str[1] || 'B' === $str[1]) {
return bindec($str);
}
// oct (intval instead of octdec to get proper cutting behavior with malformed numbers)
return intval($str, 8);
}
// dec
return (int) $str;
}
}

View File

@ -2164,7 +2164,7 @@ class PHPParser_Parser
}
protected function yyn284($line, $docComment) {
$this->yyval = new PHPParser_Node_Scalar_LNumber((int) $this->yyastk[$this->yysp-(1-1)], $line, $docComment);
$this->yyval = new PHPParser_Node_Scalar_LNumber(PHPParser_Node_Scalar_LNumber::parse($this->yyastk[$this->yysp-(1-1)]), $line, $docComment);
}
protected function yyn285($line, $docComment) {
@ -2520,7 +2520,7 @@ class PHPParser_Parser
}
protected function yyn373($line, $docComment) {
$this->yyval = new PHPParser_Node_Scalar_LNumber((int) $this->yyastk[$this->yysp-(1-1)], $line, $docComment);
$this->yyval = new PHPParser_Node_Scalar_String($this->yyastk[$this->yysp-(1-1)], $line, $docComment);
}
protected function yyn374($line, $docComment) {

View File

@ -0,0 +1,37 @@
<?php
class PHPParser_Tests_codeTest extends PHPUnit_Framework_TestCase
{
/**
* @dataProvider provideTestCode
*/
public function testCode($name, $code, $xml) {
$parser = new PHPParser_Parser;
$serializer = new PHPParser_Serializer_XML;
$stmts = $parser->parse(new PHPParser_Lexer($code));
$this->assertEquals($xml, trim($serializer->serialize($stmts)), $name);
}
public function provideTestCode() {
$tests = array();
$it = new RecursiveDirectoryIterator(dirname(__FILE__) . '/../../code');
$it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::LEAVES_ONLY);
$it = new RegexIterator($it, '~\.test$~');
foreach ($it as $file) {
$fileContents = file_get_contents($file);
// normalize EOL to Unix
$fileContents = str_replace(array("\r\n", "\r"), "\n", $fileContents);
// evaluate @@{expr}@@ expressions
$fileContents = preg_replace('/@@\{(.*?)\}@@/e', '$1', $fileContents);
$tests[] = array_map('trim', explode('-----', $fileContents));
}
return $tests;
}
}

69
test/code/scalar/int.test Normal file
View File

@ -0,0 +1,69 @@
Different integer syntaxes
-----
<?php
0;
1;
@@{ PHP_INT_MAX }@@;
@@{ PHP_INT_MAX + 1 }@@;
0xFFF;
0xfff;
0XfFf;
0777;
0787;
0b111000111000;
-----
<?xml version="1.0" encoding="UTF-8"?>
<AST xmlns:node="http://nikic.github.com/PHPParser/XML/node" xmlns:subNode="http://nikic.github.com/PHPParser/XML/subNode" xmlns:scalar="http://nikic.github.com/PHPParser/XML/scalar">
<scalar:array>
<node:Scalar_LNumber line="2">
<subNode:value>
<scalar:int>0</scalar:int>
</subNode:value>
</node:Scalar_LNumber>
<node:Scalar_LNumber line="3">
<subNode:value>
<scalar:int>1</scalar:int>
</subNode:value>
</node:Scalar_LNumber>
<node:Scalar_LNumber line="4">
<subNode:value>
<scalar:int>2147483647</scalar:int>
</subNode:value>
</node:Scalar_LNumber>
<node:Scalar_DNumber line="5">
<subNode:value>
<scalar:float>2147483648</scalar:float>
</subNode:value>
</node:Scalar_DNumber>
<node:Scalar_LNumber line="6">
<subNode:value>
<scalar:int>4095</scalar:int>
</subNode:value>
</node:Scalar_LNumber>
<node:Scalar_LNumber line="7">
<subNode:value>
<scalar:int>4095</scalar:int>
</subNode:value>
</node:Scalar_LNumber>
<node:Scalar_LNumber line="8">
<subNode:value>
<scalar:int>4095</scalar:int>
</subNode:value>
</node:Scalar_LNumber>
<node:Scalar_LNumber line="9">
<subNode:value>
<scalar:int>511</scalar:int>
</subNode:value>
</node:Scalar_LNumber>
<node:Scalar_LNumber line="10">
<subNode:value>
<scalar:int>7</scalar:int>
</subNode:value>
</node:Scalar_LNumber>
<node:Scalar_LNumber line="11">
<subNode:value>
<scalar:int>3640</scalar:int>
</subNode:value>
</node:Scalar_LNumber>
</scalar:array>
</AST>