PHP 解析器 PHP-Parser 5.0.0 发布
PHP-Parser是
nikic
用PHP编写的PHP5.2
到PHP8.3
解析器,其目的是简化静态代码分析和操作。PHP Parser 是一个用于源代码解析的项目,值得一提的是它使用纯 PHP 编写,对于 PHP 程序员来说,能使用自己熟悉的语言来做静态分析等源码处理,无疑是一大便利。
5.0.0 发布列表
新增
-
添加了 PhpVersion
类,它在许多地方都被接受(例如ParserFactory,Parser,Lexer,PrettyPrinter
),并对目标PHP版本进行更精确的控制。 -
添加了 PHP8
解析器,尽管它与PHP 7解析器的区别仅在于连接优先级。 -
添加了 Parser::getTokens()
方法。 -
添加了一个 Modifiers
类,作为Stmt\Class_::MODIFIER_*
的替代。 -
添加了从 NodeVisitor::enterNode()
返回数组或REMOVE_NODE
的支持。 -
添加了许多额外的类型注释。 PhpStan
现在使用。 -
为 PHP-Fuzzer
添加了一个模糊目标,这就是发现很多漂亮的打印机错误的原因。 -
在 Param
上添加了isPromoted()
、isPublic()
、isProtected()
、isPrivate()
和isReadonly()
方法。 -
在trait builder中增加了对类常量的支持。 -
添加了 PrettyPrinter
接口。 -
添加了在切换静态修改器时对格式保留的支持。 -
php-parse
二进制文件现在接受-
作为文件名,在这种情况下,它将从stdin读取。 -
支持 NodeVisitor::REPLACE_WITH_NULL
。 -
在漂亮的打印机中增加了对CRLF换行符的支持,使用新的 newline
选项。 -
访问者现在可以直接传递给 NodeTraverser
构造函数。不再需要单独调用addVisitor()
。 -
在 NodeDumper
中添加了对打印附加属性(如kind
)的支持。 -
为 InterpolatedStringPart
和heredoc/nowdocString_
s添加了rawValue
属性,该属性提供原始的未解析值。它以前只适用于非插值的单引号/双引号字符串。 -
添加了 Stmt\Block
以表示{}
代码块。以前,这样的代码块被展平到父语句数组中。Stmt\Block
不会为通常与代码块一起使用的结构创建,例如if ($x) { $y; }
将如前所述表示,而if ($x) { { $x; } }
将具有额外的Stmt\Block
包装器。
修改
-
现在需要PHP 7.4来运行PHP-Parser。 -
在可能的情况下添加了属性类型。 -
标准漂亮打印机的屏幕已调整,以更紧密地匹配PSR-12。 -
内部token表示现在使用 PhpParser\Token
类,它与PHP 8 token表示(PhpToken
)兼容。 -
数组解构现在总是使用 Expr\List_
节点表示,即使它使用[]
语法。 -
重命名了许多节点类,并将不是真实的表达式/语句的内容移到了 Expr
/Stmt
层次结构之外。保留了旧名称的兼容性。 -
Pretty打印机不再无条件地将 yield
括在括号中,除非目标版本设置为早于PHP 7.0。 -
Pretty打印机现在默认为PHP 7.4作为目标版本。 -
打印 else if { }
而不是else { if { } }
。 -
访问者的 leaveNode()
方法现在以与enterNode()
相反的顺序调用。 -
将 NodeTraverser::REMOVE_NODE
等移至NodeVisitor::REMOVE_NODE
。旧的常量仍然可用,以便兼容。 -
Name
子节点parts
已被name
替换,它将名称存储为字符串,而不是由名称空间分隔符分隔的部分数组。getParts()
方法返回旧的表示。 -
不再接受Node构造函数中类型的字符串。相反,必须传递 Identifier
、Name
或ComplexType
。 -
Comment::getReformattedText()
现在将CRLF换行符规范化为LF换行符。 -
Lexer
不再接受选项。Lexer\Emulative
只接受PhpVersion
。startLexing()
、getTokens()
和handleHaltCompiler()
方法已被删除。相反,只有一个方法tokenize()
返回令牌。 -
属性处理已从词法分析器移到解析器,不再可配置。将始终添加comments、startLine、endLine、startTokenPos、endTokenPos、startFilePos和endFilePos属性。 -
如果目标版本是>= 7.3(灵活的heredoc/nowdoc),pretty打印机现在缩进heredoc/nowdoc字符串。 -
使用访问者分配评论。这解决了将注释分配给共享起始位置的所有节点的长期问题。现在只有最外层的节点将保存注释。 -
提高NodeDumper在大型转储中的性能。
移除
-
PHP 5解析器已被删除。PHP 7解析器已经过调整,可以更优雅地处理PHP 5代码。 -
删除了不推荐使用的 Error
构造函数,该构造函数采用行号而不是属性数组。 -
Comment::getLine()
、Comment::getTokenPos()
和Comment::getFilePos()
方法已被删除。使用Comment::getStartLine()
、Comment::getStartTokenPos()
和Comment::getStartFilePos()
代替。 -
删除 Stmt\Throw_
节点,使用Stmt\Expression
内的Expr\Throw_
代替。 -
删除 ParserFactory::create()
。
固定
-
漂亮的打印机现在使用一个更准确的处理一元运算符优先级,如果需要,只会把它们括在括号里。这允许修复许多其他与优先级相关的bug。 -
漂亮的打印机现在尊重 clone
,throw
和箭头函数的优先级。 -
修复了替代elseif/else语法的格式保留。 -
修复了将字符串打印为heredoc/nowdoc以适应灵活的文档字符串语义的安全性检查。 -
修复了文档字符串末尾的 \r
可能被错误地合并到CRLF序列中,后面是\n
的各种情况。 -
__halt_compiler
不再被识别为半保留关键字,符合PHP行为。 -
<?=
不再被识别为半保留关键字。 -
修复了对非常大的溢出 \u
转义序列的处理。 -
在格式保留打印机中不修剪前导空格。 -
根据目标PHP版本,在格式保留打印机中将DEL视为标签字符。 -
修正了在没有明确指定错误处理程序的情况下,在模拟lexer中报告错误的问题。 -
优雅地处理 Differ
中的非连续数组索引。
弃用
-
Node::getLine()
方法已被弃用。使用Node::getStartLine()
代替。
简单使用
对于以下一段 PHP 代码
<?php
echo 'Hi', '开源技术小栈';
编写解析文件
<?php
require __DIR__ . '/../vendor/autoload.php';
$code = <<<'CODE'
<?php
echo 'Hi', '开源技术小栈';
CODE;
$parser = (new \PhpParser\ParserFactory())->createForNewestSupportedVersion();
try {
$ast = $parser->parse($code);
} catch (\PhpParser\Error $error) {
echo "Parse error: {$error->getMessage()}\n";
return;
}
$dumper = new \PhpParser\NodeDumper;
echo $dumper->dump($ast) . "\n";
解析后生成的树结构如下
array(
0: Stmt_Echo(
exprs: array(
0: Scalar_String(
value: Hi
)
1: Scalar_String(
value: 开源技术小栈
)
)
)
)
THE END