(Bu istediğimden daha uzun; lütfen bana katlanın.)
Çoğu dil, "sözdizimi" adı verilen bir şeyden oluşur: dil, birkaç iyi tanımlanmış anahtar sözcükten oluşur ve bu dilde oluşturabileceğiniz tüm ifadeler bu sözdiziminden oluşturulur.
Örneğin, girdi olarak yalnızca tek basamaklı tam sayıları alan ve işlem sırasını tamamen yok sayan basit bir dört işlevli aritmetik "diliniz" olduğunu varsayalım (size bunun basit bir dil olduğunu söylemiştim). Bu dil sözdizimi ile tanımlanabilir:
$expression := $number | $expression $operator $expression
$number := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
$operator := + | - | * | /
Bu üç kuraldan, istediğiniz sayıda tek basamaklı giriş aritmetik ifadeleri oluşturabilirsiniz. Daha sonra, bu sözdizimi için bir ayrıştırıcı yazabilirsiniz herhangi bir geçerli bileşen tipe girdi (aşağı kırılır $expression
, $number
ya $operator
sonuçla) ve fırsatlar. Örneğin, ifade 3 + 4 * 5
aşağıdaki gibi bölünebilir:
$expression = 3 + 4 * 5
= $expression $operator (4 * 5)
= $number $operator $expression
= $number $operator $expression $operator $expression
= $number $operator $number $operator $number
Şimdi, orijinal ifade için tanımlı dilimizde tamamen ayrıştırılmış bir sözdizimimiz var. Bunu elde ettikten sonra, tüm kombinasyonlarının sonuçlarını bulmak için bir ayrıştırıcı yazabilir $number $operator $number
ve yalnızca bir tane kaldığımızda bir sonuç çıkarabiliriz $number
.
$expression
Orijinal ifademizin son ayrıştırılmış versiyonunda hiçbir yapı kalmadığına dikkat edin. Çünkü $expression
dilimizde her zaman başka şeylerin bir kombinasyonuna indirgenebilir.
PHP aşağı yukarı aynıdır: dil yapıları, $number
veya $operator
. Bunlar diğer dil yapılarının içine indirgenemez ; bunun yerine, dilin oluşturulduğu temel birimlerdir. Fonksiyonlar ve dil yapıları arasındaki temel fark şudur: ayrıştırıcı, doğrudan dil yapılarıyla ilgilenir. Fonksiyonları dil yapılarına dönüştürür.
Dil yapılarının parantez gerektirip gerektirmeyebileceğinin nedeni ve bazılarının dönüş değerlerine sahip olmasının, diğerlerinin ise tamamen PHP çözümleyici uygulamasının belirli teknik ayrıntılarına bağlı olmaması. Ayrıştırıcının nasıl çalıştığı konusunda o kadar bilgili değilim, bu yüzden bu soruları özel olarak ele alamam, ancak bir an için bununla başlayan bir dil hayal edin:
$expression := ($expression) | ...
Etkili bir şekilde, bu dil bulduğu ifadeleri almakta ve çevresindeki parantezlerden kurtulmakta özgürdür. PHP (ve burada saf tahmin kullanıyorum) dil yapıları için benzer bir şey kullanabilir: çözümlenmeden önce print("Hello")
kısaltılabilir print "Hello"
veya tam tersi olabilir (dil tanımları parantez ekleyebilir ve onlardan kurtulabilir).
Bu, echo
veya gibi dil yapılarını neden yeniden tanımlayamadığınızın köküdür print
: bunlar ayrıştırıcıya etkin bir şekilde kodlanırken, işlevler bir dizi dil yapısına eşlenir ve ayrıştırıcı, bu eşlemeyi derleme veya çalışma zamanında değiştirmenize izin verir. kendi dil yapılarınızı veya ifadelerinizi değiştirin.
Günün sonunda, yapılar ve ifadeler arasındaki iç fark şudur: dil yapıları çözümleyici tarafından anlaşılır ve ele alınır. Yerleşik işlevler, dil tarafından sağlanırken, ayrıştırmadan önce bir dizi dil yapısına eşlenir ve basitleştirilir.
Daha fazla bilgi:
- Backus-Naur formu , resmi dilleri tanımlamak için kullanılan sözdizimi (yacc bu formu kullanır)
Düzenleme: Diğer cevaplardan bazılarını okuyarak, insanlar iyi puanlar alıyor. Onların arasında:
- Yerleşik bir dil çağırmak bir işlevden daha hızlıdır. Bu, çok az da olsa doğrudur, çünkü PHP yorumlayıcısının bu işlevi ayrıştırmadan önce kendi dil yerleşik eşdeğerlerine eşlemesi gerekmez. Modern bir makinede ise fark oldukça önemsizdir.
- Yerleşik bir dil, hata denetimini atlar. Bu, her yerleşik için PHP'nin dahili uygulamasına bağlı olarak doğru olabilir veya olmayabilir. Çoğu zaman, işlevlerin daha gelişmiş hata denetimine ve yerleşiklerin sahip olmadığı diğer işlevlere sahip olacağı kesinlikle doğrudur.
- Dil yapıları, işlev geri çağırmaları olarak kullanılamaz. Bu doğrudur, çünkü bir yapı bir işlev değildir . Ayrı varlıklardır. Bir yerleşiği kodladığınızda, bağımsız değişkenler alan bir işlevi kodlamazsınız - yerleşiğin sözdizimi doğrudan ayrıştırıcı tarafından işlenir ve bir işlevden ziyade yerleşik olarak tanınır. (Birinci sınıf işlevlere sahip dilleri düşünürseniz, bunu anlamak daha kolay olabilir: etkili bir şekilde, işlevleri nesneler olarak geçirebilirsiniz. Bunu yerleşiklerle yapamazsınız.)