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: 开源技术小栈
)
)
)
)
本文暂时没有评论,来添加一个吧(●'◡'●)