Ayrıştırıcı
Phasis, kendi JavaScript ayrıştırıcısını bağımsız bir PHP API olarak sunar. Kaynak metni türlenmiş bir AST'ye ayrıştırabilir, üzerinde dolaşabilir ve bir Engine oluşturmadan veya herhangi bir kod çalıştırmadan ESTree biçimli diziler ya da JSON olarak dışa aktarabilirsiniz.
parseSource
public static function parseSource(string $source, string $sourceType = 'script'): Program
Phasis\Parser\Parser üzerindeki tek çağrılı giriş noktası. $source'ı ayrıştırır ve kök Phasis\Ast\Program düğümünü döndürür.
use Phasis\Parser\Parser;
$program = Parser::parseSource('const x = [1, 2].map(n => n * 2);');
$module = Parser::parseSource('import { x } from "./x.js"; export default x;', 'module');
$sourceType, dilbilgisi hedefini seçer; adlandırma JS ayrıştırıcılarındaki aynı seçenekle aynıdır:
| Değer | Hedef |
|---|---|
script |
klasik Script. En üst düzeydeki import/export sözdizimi hatasıdır; await bir tanımlayıcıdır |
module |
ES Module. Örtük katı kip; import/export ve en üst düzeydeki await ayrıştırılır |
Diğer her değer \InvalidArgumentException fırlatır.
Daha ayrıntılı denetim için (doğrudan eval bağlamında katı kipi önceden etkinleştirmek, //# sourceURL pragma'sını okumak), ayrıştırıcıyı doğrudan oluşturun: new Parser($source) ile setModuleMode(), setStrictMode() ve parse().
Düğümler
Her AST sınıfı Phasis\Ast\Node sınıfını genişletir ve Phasis\Ast\{Declaration, Expression, Pattern, Statement} altında yer alır. Düğümler, salt okunur basit değer nesneleridir:
$node->type(), düğümün sınıf temel adı olan tür dizgesini döndürür ('BinaryExpression','ArrowFunction', ...).$node->location,Phasis\Lexer\SourceLocationolupline(1 tabanlı),column(0 tabanlı) veoffset(bayt ofseti) içerir. Yalnızca başlangıç konumları saklanır; düğümlerde bitiş ofseti yoktur.- Diğer tüm herkese açık alanlar düğümün alt öğeleri ve öznitelikleridir (
$binary->left,$binary->operator,$binary->right).
Tür adlarının çoğu ESTree ile eşleşir. Farklılıklar:
| Phasis türü | ESTree türü |
|---|---|
ArrowFunction |
ArrowFunctionExpression |
TaggedTemplate |
TaggedTemplateExpression |
ClassMethod |
MethodDefinition |
ClassProperty |
PropertyDefinition |
AssignmentProperty |
Property (ObjectPattern içinde) |
ExportDeclaration |
ExportNamedDeclaration / ExportDefaultDeclaration / ExportAllDeclaration |
ImportSpecifier |
ImportSpecifier / ImportDefaultSpecifier / ImportNamespaceSpecifier |
Bazı yapılar da farklıdır: sınıf gövdeleri, sınıf düğümünde düz bir öğe dizisidir (ClassBody sarmalayıcısı yoktur); içe/dışa aktarma adları, ifade etiketleri ve FunctionExpression adları iç içe Identifier düğümleri yerine dizgeler olarak saklanır; super ise super adlı bir Identifier olarak ayrıştırılır (Super düğüm sınıfı yoktur). Phasis\Ast\EstreeSerializer tüm bunları ESTree biçimine dönüştürür.
Sözdizimi hataları
Geçersiz girdi Phasis\Exceptions\SyntaxError fırlatır (genellikle alt sınıfı olan Phasis\Parser\ParseError). İstisna iletisi konumla biter; yapılandırılmış konum bilgisine istisna üzerinden erişilebilir:
use Phasis\Exceptions\SyntaxError;
use Phasis\Parser\Parser;
try {
Parser::parseSource("const a = 1;\nconst b = ;");
} catch (SyntaxError $e) {
echo $e->getMessage(); // Unexpected token (got ; ";") at line 2, column 10
echo $e->location->line; // 2
echo $e->location->column; // 10
echo $e->location->offset; // 23
}
Dolaşıcı
Phasis\Ast\Walker, estraverse tarzında, giriş/çıkış geri çağrılarıyla ağaçta derinlik öncelikli dolaşır:
public static function walk(Node $node, callable $enter, ?callable $leave = null): void
Her iki geri çağrı da (Node $node, ?Node $parent) alır. $enter içinden Walker::SKIP döndürmek, düğümün alt öğelerini atlar; düğümün kendi $leave geri çağrısı yine de çalışır.
use Phasis\Ast\Expression\Identifier;
use Phasis\Ast\Node;
use Phasis\Ast\Walker;
$names = [];
Walker::walk($program, function (Node $node) use (&$names) {
if ($node instanceof Identifier) {
$names[] = $node->name;
}
if ($node instanceof \Phasis\Ast\Expression\ArrowFunction) {
return Walker::SKIP;
}
});
Dolaşım salt okunurdur. Düğümler, salt okunur değer nesneleridir; bu nedenle değiştirme/değişiklik desteği yoktur.
Serileştirici
Phasis\Ast\Serializer, türlenmiş AST'yi Phasis tür adlarını ve alan düzenini kullanarak dizilere veya JSON biçimine dönüştürür; ayrıştırıcıya özgü önbellek alanları çıkarılır:
public static function toArray(Node $node): array
public static function toJson(Node $node, bool $pretty = false): string
Bu, bin/phasis --ast'ın yazdırdığı biçimdir.
EstreeSerializer
Phasis\Ast\EstreeSerializer, türlenmiş AST'yi bunun yerine ESTree biçimli dizilere dönüştürür: ESTree tür adları (yukarıdaki farklılık tablosuna göre), ESTree alan adları ve sıralaması, oluşturulmuş ClassBody / belirtici / kaynak-Literal düğümleri ve kaynaktan ayrıştırılan her düğüm için bir start bayt ofseti. Düğümler yalnızca başlangıç konumlarını sakladığından end ofsetleri yoktur; dizge Literal düğümleri de raw metni içermez.
public static function toArray(Node $node): array
public static function toJson(Node $node, bool $pretty = false): string
public static function summarize(Node $node): string
summarize(), her düğüm için tür ile name= / value= / op= / kind= özniteliklerini içeren, deterministik ve her satırda bir özet üretir; her derinlik düzeyinde iki boşluk girinti kullanır. Biçim, tests/Popular/acorn içindeki acorn fikstürünün ürettiği AST özetiyle bayt düzeyinde aynıdır; böylece aynı doğrulayıcı hem JS ayrıştırıcı yolunu hem de bu PHP dışa aktarımını değerlendirir:
use Phasis\Ast\EstreeSerializer;
use Phasis\Parser\Parser;
echo EstreeSerializer::summarize(Parser::parseSource('let x = a + 1;'));
// Program
// VariableDeclaration kind=let
// VariableDeclarator
// Identifier name=x
// BinaryExpression op=+
// Identifier name=a
// Literal value=1
CLI
bin/phasis --ast script.js bir dosyayı (script hedefiyle) ayrıştırır ve Serializer JSON dökümünü iki boşluk girintiyle yazdırır. Tüm bayrakların açıklaması için CLI bölümüne bakın.