Çoğu programlama dilinin, bir sayı ile başlayan bir tanımlayıcı bildirmesine izin vermeyecek şekilde tasarlandığı görülmektedir. Sebebini bilmek sadece merak ettim. Web'i zaten aradım, ancak tatmin edici bir açıklama bulamadım.
Çoğu programlama dilinin, bir sayı ile başlayan bir tanımlayıcı bildirmesine izin vermeyecek şekilde tasarlandığı görülmektedir. Sebebini bilmek sadece merak ettim. Web'i zaten aradım, ancak tatmin edici bir açıklama bulamadım.
Yanıtlar:
C / C ++ 'da, bir harf tarafından takip edilen bir sayının sayısal bir sabit olduğu düşünülür ve ardından gelen dize, sabitin türünü nitelendirir. Örneğin (bunlar VC ++, ne kadar standart olduklarından emin değilsiniz):
Bu yüzden a) Daniel'in söylediği gibi lexer için daha kolay ancak b) 0y değişken olabileceğinden ancak 0u asla olamayacağı için açık bir ayrım yapar . Ayrıca "i64" gibi diğer niteleyiciler "l" veya "u" den çok daha sonra eklenmiş ve gerektiğinde daha fazla ekleme seçeneğini açık tutmak istemektedir.
Lexer'ı uygulayan insanların rahatlığı. (Hayır, cidden, bununla ilgili. Çeşitli dillerin başka nedenleri var, ama sonuçta buna bağlı.)
0flu
değişmez ve 0glu
yerel bir tanımlayıcı olsaydı çok garip olurdu .
int 0u = 5; unsigned int x = 0u;
Ancak bu kodun yorumunu tanımlamayı seçtiniz (muhtemelen x == 0 veya x == 5), insanların kafası karışacak belirsizlik yüzünden. Derleyiciyi bu şekilde uygulamak önemsiz olsa da, iyi bir tasarımcı muhtemelen yapmazdı.
Aşağıdaki 2 durumu göz önünde bulundurun:
Bir tanımlayıcının bir sayı ile başlayabileceğini varsayalım.
Dolayısıyla, aşağıdaki gibi bir ifade geçerli olur (bir tanımlayıcı 1 veya daha fazla karakter içerebildiğinden):
int 3;
Yukarıdaki değişkeni bir programda kullanmaya çalıştığımda, derleyici belirsizliğine neden olur:
int 3, a;
3 = 5;
a = 3;
İfadede a=3
3'ün rolü nedir (5 değerine sahip bir değişken mi yoksa 3 rakamı mı)?
Yukarıdaki örneğe zıt olarak, bir dilin gerçekte tanımlayıcı olarak kullanılmasına rağmen sayıları reddederken sayı ile başlayan tanımlayıcılara izin vermek olduğunu varsayalım. Bu, aşağıdaki sorunlara neden olabilir:
Bir değişkenin 1 veya daha fazla karakterden oluşabileceğini söyleyen değişkene ilişkin dil kuralları, aşağıdaki gibi karmaşık bir kural için yeniden tanımlanmalıdır: Bir değişken, bir veya daha fazla karaktere sahip olabilir ve bir sayı ile başlamazsa, benzersiz olması gerekir. Sayı ile başlarken tek karakter uzunluğunda olamaz (vb.)
Derleyici tüm sayılar (örneğin 333) ve geçerli alfabe sonekleri (örneğin 34L) değişken isimleri olarak kullanıldığında hata durumlarını kontrol etmek ve raporlamak zorunda kalacaktır. Python ve JS gibi gevşek olarak yazılan ve değişkenleri anında bildirmeden kullanabileceğiniz değişkenleri yazarken, örneğin tüm sayıları içeren özel durumları kontrol etmek bile imkansız if (33==5)
olabilir. Ancak derleyici bunu tanımlayamaz ve hatayı rapor edemez.
Bu kısıtlamanın yapılması, programcının numaraları tanımlayıcı adları olarak kullanmasını önleyecektir.
int char = float
olacağını hayal edebiliyor musun?
int
bir anahtar kelime değil bir tanımlayıcı olduğunu nasıl biliyor ? Şey, int
aynı sayısal sözlerin sahip olacağı gibi daha yüksek önceliğe sahip.
int 3,a; 3=5; a=3;
a = 3 ifadesinde, 3 tanımlayıcı mı yoksa bir sayı olarak mı yorumlanır? Bu belirsizliğe neden olur. Umarım açıktır.
Çoğu zaman bunun derleyici yazarlar için ayrıştırma verimliliğini ve ayrıştırma verimliliğini kolaylaştırmakla alakası yoktur, ancak daha net ve okunaklı ve açık kodları teşvik eden bir sözdizimi tasarlamakla daha fazla ilgisi yoktur.
Dil tasarımcıları, sadece 1 numara gibi nümerik harfleri sadece düz 1 olarak yazmanın iyi olacağını düşündüler .
Sayısal hazırlayıcıların bir şekilde örneğin tildas olarak yazıldığı bir dil sözdizimi tasarlamak oldukça mümkün olabilir, bu sayede bir numaralı sayısal hazırlayıcı ~ 1 ~ olarak kodlandı ve bir anahtar sözcük içermeyen ve tırnak içine alınmayan herhangi bir şey değişken bir ad olarak değerlendirildi .
Böylece aşağıdaki gibi kodları kodlayabilirsiniz:
1 = ~2~
two = 1 * ~2~
Ayrıca:
2 = ~3~
six = 2 + 2
Seçtiğiniz ve belirsiz ve takip etmek zor zor sözdizimi ne olursa olsun kaçınılmazdır.
C dili ve "kıvrımlı parantez" dillerinin çoğu, C'den gelen dilbilgisi programcılarının doğrudan Octal ve Onaltılık değişmezleri kodlamasını ve bunun önemini belirtmişse değişmezin türünü belirtmesini sağlamanın iyi bir fikir olduğunu düşünüyordu. Yani
010 // Octal 10 = 8;
0x10 // Hexadecimal 10 = 16;
5l // long integer with decimal value 5
2.0d // double float with value 2
Bu yüzden değişken isimlerine izin vermiş olsanız bile, en az bir harf içeren bir rakam ve harf kombinasyonunu izleyen bir rakamla başlasanız bile, programcıya belirli bir grubun değişken bir isim mi yoksa sayısal bir değişmez mi oluşturduğuna karar verme problemini sunarsınız.
2lll = 22 // OK
2ll = 2 // compiler error
Bu belirsizlik, program yazarken veya okurken hiç kimseye yardımcı olmaz.
Yakından ilgili bir gerçek dünya örneği için, tasarımcıları anahtar kelimeleri değişken adlar olarak kullanmanın iyi bir fikir olduğunu düşünen PL / 1 diline bakabilirsiniz ki:
IF THEN THEN THEN = ELSE; ELSE ELSE = THEN;
IF IF THEN ELSE = IF; ELSE THEN = ELSE;
DO WHILE (WHILE = DO); END = WHILE + DO; END;
Derleyen ve yürüten geçerli bir koddur.
Fortran'ın daha sonra dillerin nasıl tasarlandığı üzerinde çok büyük bir etkisi oldu. Daha önceleri (bu problemlerin bazıları giderildi) Fortran, bir tanımlayıcıya hangi ismi verebileceğinizi kısıtlayan neredeyse hiçbir kurala sahip değildi. Bu dilin hem derleyiciler hem de programcılar için ayrıştırılması son derece zor oldu. İşte klasik bir örnek:
if if .eq. then then = else else else = endif endif
K I K K I I K I I K
Burada "dil anahtar kelimeleri" K ve tanımlayıcıları (değişken isimleri) ile işaretledim. İmla konusunda hiçbir fark olmadığı göz önüne alındığında, bunun ne kadar kafa karıştırıcı olabileceğini muhtemelen anlayabileceğinizi düşünüyorum. Elbette, bu aşırı bir örnektir ve bilerek böyle bir kod yazan hiç kimsenin olasılığı düşüktür. Bazen insanlar yaptılar ve basit bir yazım hatası dil spec o hiç tasarlanmamış olsa bile, bu şekilde ayrıştırılması gerektiğini söyledi kod neden olabilecek durumlar bir çok - gerçi tanımlayıcı adları için "geri dönüşüm" dil anahtar kelimeleri. Tanınmış başka bir örnek için, bunu karşılaştırın:
do 10 i = 1,10
buna:
do 10 i = 1.10
İlki bir do döngüsüdür - 10 kez kod bloğunu tekrar eder. Ancak ikincisi, virgülün ondalık bir noktaya dönüşmesini sağladı, bu yüzden değeri 1.10
bir değişkene atadı do 10 i
.
Bu aynı zamanda bir Fortran ayrıştırıcı yazmanın göreceli olarak zor olduğu anlamına geliyordu - do
hattın başlangıcında satırın sonuna gelinceye kadar gerçekten anahtar bir kelime olduğundan emin olamazdınız ve do
döngü mevcuttu. Ayrıştırıcı, genellikle, gerçekte orada olanın "doğru" (ancak genellikle istenmeyen) cevabına gelmek için çizgiyi yeniden başlayarak yeniden parçalamaya hazır olmak zorundaydı.
Bundan birkaç yıl sonra, dil tasarımcıları (çoğu zaten) ters uç noktaya yöneldi - kullanıcılar hakkında çok fazla şikayet etmeden, dil hakkında neredeyse her şeyi mümkün olduğu kadar kısıtlamak .
Erken TEMEL, örneğin, temelde bile bir anahtar kelime kullanmayın söyledi kısmının bir tanımlayıcı - örneğin, fora=1
olarak çözümlenen for a = 1
(yani bir başlangıcı for
döngü, değil bir atama). Görünüşe göre bu çok uzun sürmeyecek kadar şikayet üretti. Rakamla bir tanımlayıcıyı başlatmayla ilgili kural, görünüşte çok fazla şikayet üretmedi, bu yüzden kullanılmaya devam ediyor (en azından çoğu dilde).
Muhtemelen bu sözleşme çok eski tarihsel dil tasarım kararlarından evrimleşmiştir, eski makinelerde, sözlüksel analiz de dahil olmak üzere tüm derleyicinin bir kaç kelimede çalışması gerekiyordu, mevcut mobil cihazlarda ilk seviye işlemci veri önbelleğinden bile daha az bellek vardı. bu yüzden izin verilen değişken isimleri çok sınırlıydı ve çok az sayıda op kodda sayısal sabitlerden ayırt edilmesi kolay olmalıydı.
Böylece, kongre programcı nesiller için kullanılan kuşak haline geldi.
Programlama dili için mantıklı bir kural değil, yalnızca birçok dil tasarımcısı tarafından kullanılan kuraldır.
Tanımlayıcılar için tüm karakterlere izin veren kökten farklı bir dil tasarlayabilirim. Tüm kod satırları için ilk 20 karakter ifade tipini tanımlayacaktır, ardından sonraki 20 karakter ifade için ilk sembolü tanımlayacak ve sonraki 20 karakter ifade için operand olacaktır. Bu dil bir yığın işlemcide yürütülecektir.
01234567890123456789 01234567890123456789 01234567890123456789
decl symbol 12345
assign value 12345 12345
decl symbol 99999
assign value 99999 12345
push 12345
push 99999
add
print top
Bu kod aşağıdaki gibi C dilinde çevrilebilir:
int i12345 = 12345;
int i99999 = 12345;
printf("%d", i12345+i9999);
Bu kadar. Bu anlamsız ve tanımlayıcıların sayısız kuralı da mantıklı temelde anlamsız.
"Lexer için kolaylık" ek olarak, aynı zamanda "okuyucu için kolaylık" dikkate alarak değer olduğunu düşünüyorum.
Kod okurken, hangi kelimelerin tanımlayıcı olduğunu ve hangilerinin rakam olduğunu hızlı ve tekrar tekrar tanımlamanız gerekir. Görsel desen eşleştirmemizde başlangıçta rakam aramak daha kolaydır; emin olmak için tüm karakterleri dikkatlice kontrol etmemiz gerekirse bir angarya olurdu.
Bu sorunun cevabı, normal ifadeyi tanımlayan otomatlarda veya daha kesin olarak sonlu otomatlardadır. Kural şudur: derleyiciler, ayrıştırdıkları her karakterde karar vermek için kesin algoritmalara veya kurallara ihtiyaç duyarlar. Eğer tanımlayıcılar bir sayıyla başlamaya izin verilseydi, derleyici düzeltilmiş olur ... gelenin niteliği hakkında ... bir sayı mı yoksa bir tanımlayıcı mı olur ... ve derleyiciler olarak önceki konumlara geri dönemez. .so .. derleyiciye yaklaşmakta olan belirtecin tam olarak bir tanımlayıcı veya bir sayı olduğunu açıkça belirtmek için ... bu kısıtlama var ... bu kodun ... derleyici sadece gelen belirteci ilk karakteri tarayarak bilir bir tanımlayıcı veya sayıdır.