Çoğu programlama dili neden blok yorumları yuvalamıyor?


18

Birkaç kişi biliyor, ama bildiğim kadarıyla popüler olanlardan değil. Yorumları yerleştirmeyle ilgili kötü bir şey var mı?

Üzerinde çalıştığım (küçük) dilde blok yorumları yerleştirmeyi planlıyorum, ancak bunun kötü bir fikir olup olmadığını bilmek istiyorum.


birkaç cevap yeniden: ohh, bu mantıklı =) Ben tamamen o zaman iç içe blok yorum yapıyorum; Ayrı bir lexing aşamam olmasına rağmen, açıklanan sınırlayıcı SK-mantığı değil.

@Vuntic: Normal ifadelerden daha karmaşık şeyler kullanan ayrı bir lexing aşamanız varsa, performans sorunlarınız olabilir. RE'ler DFA'ları uygulayarak hızlı ve kullanımı kolaydır.
David Thornley

Yuvalamaya izin vermemek için daha önce daha fazla hata yakalar

4
@David: ... hiç de değil. Aslında çok hızlı.
amara

Yuvalanmış yorumlara izin vermek istiyorsanız, başlangıç ​​yorumu etiketlerinin bir jetonla işaretlenmesine izin vermenizi ve bir başlangıç ​​yorumu etiketi bu şekilde işaretlenirse, son yorum etiketinin aynı şekilde işaretlenmesi gerektiğini öneririm. Bu, dengesiz başlangıç ​​/ bitiş etiketlerinin hızlı bir şekilde tanımlanmasına olanak tanır ve dengesiz dengesiz etiketlerin neden olduğu hata olasılığını önler.
supercat

Yanıtlar:


6

Kimsenin henüz bahsetmediği bir şey, bu yüzden şunu söyleyeceğim: Yorum yerleştirme arzusu genellikle programcının Yanlış Yaptığını gösterir.

İlk olarak, programcı tarafından "iç içe geçme" veya "iç içe geçmeme" durumunun görülebileceği tek zamanın, programcının yapısal olarak şöyle bir şey yazdığı zaman olduğunu kabul edelim:

do_something();
/* comment /* nested comment */ more comment */
do_something_else();

Şimdi, böyle bir şey pratikte ne zaman ortaya çıkıyor? Kesinlikle programcı, tam olarak yukarıdaki pasaj gibi görünen iç içe yorumlar yazmayacak! Hayır, pratikte yorumları iç içe yerleştirdiğimizde (veya iç içe geçirebilmemizi dilediğimizde) bunun gibi bir şey yazmak istediğimiz için:

do_something();  /* do a thing */
/* [ajo] 2017-12-03 this turned out to be unnecessary
do_something_else(); /* do another thing */
*/

Ve bu KÖTÜ. Bu (dil tasarımcıları olarak) teşvik etmek istediğimiz bir model değil! Doğru Yukarıdaki pasajı yazmak için yoludur:

do_something();  /* do a thing */

Bu "yanlış" kod, yanlış başlangıç ​​veya her neyse, kod tabanına ait değil. En iyi ihtimalle, kaynak kontrol geçmişine aittir. İdeal olarak, başlamak için asla yanlış kod yazmazsınız, değil mi? Ve yanlış kod orada bir amaca hizmet ediyorsa, bakıcıları bir nedenden ötürü eski durumuna getirmemeleri konusunda uyararak, bu muhtemelen iyi yazılmış ve kasıtlı bir kod yorumu için bir iştir . Sadece X yapan bazı eski kodları bırakarak "X yapma" ifadesini ifade etmeye çalışmak, insanların X yapmasını engellemenin en okunaklı veya etkili yolu değildir.

Tüm bunlar daha önce duymuş olabileceğiniz basit bir kuralla sınırlıdır: Kodu yorumlamayın. (Bu ifadeyi aradığınızda , anlaşmada çok sayıda fikir ortaya çıkacaktır .)

Sormadan önce: evet, C, C # ve C ++ gibi diller programcıya büyük kod bloklarını "yorumlamak" için zaten başka bir araç verir #if 0. Ancak bu, kendi başına büyük ve kullanışlı bir araç olan C ön işlemcisinin özel bir uygulamasıdır. Bir dil ile koşullu derleme desteklemek için Aslında son derece zor ve özel Casey olacağını #ifve henüz değil desteklemek #if 0.


Bu nedenle, iç içe yorumların yalnızca programcı kodu yorumladığında alakalı olduğunu belirledik; ve kod yazmanın kötü bir şey olduğunu (birçok deneyimli programcının konsensüsüyle) tespit ettik.

Syllogism'i tamamlamak için, dil tasarımcılarının İyi Şeyler tanıtmak ve Kötü Şeyleri caydırmakla ilgisi olduğunu kabul etmeliyiz (diğer her şeyin eşit olduğunu varsayarak).

İç içe yorumların durumda, her şeyin olduğu eşit - güvenle yok sayabilirsiniz iddiası yuvalanmış ayrıştırma olduğunu cevapları düşük yüksek oyu /*nasılsa ayrıştırıcı için "zor" olurdu. (Yuvalanmış yuvalar , dünyadaki hemen hemen her ayrıştırıcının zaten ele alması gereken /*yuvalanmış olanlardan daha zor değildir (.)

Öyleyse, diğer her şey eşit olduğunda, bir dil tasarımcısı yorum yapmayı (yani kodu yorumlamak) kolaylaştırmalı mı yoksa zor mu? Kodu yorumlamanın bir Kötü Şey olduğunu hatırlayın.

QED


Dipnot. Yuvalanmış yorumlara izin vermezseniz,

hello /* foo*/bar.txt */ world

yanıltıcı bir "yorum" dur - buna eşdeğerdir

hello bar.txt */ world

(bu muhtemelen bir sözdizimi hatasıdır). Eğer Ama eğer bunu iç içe yorumlar, sonra izin

hello /* foo/*.txt */ world

yanıltıcı bir "yorum" dur - buna eşdeğerdir

hello

ancak yorumu dosyanın sonuna kadar açık bırakır (yine neredeyse kesinlikle bir sözdizimi hatasıdır). Bu nedenle, hiçbir şekilde kasti olmayan sözdizimi hatalarına daha az eğilimlidir. Tek fark, yorumlanmış kodun kasıtlı karşıtlığını işleme biçimidir.


1
Sadece gerçeğe dayalı farklı görüşüm var - her şeyi görmedim (ve siz de görmediniz). Bu yüzden "Kod hakkında yorum yapma" gibi altın kurallar güzel gözükse de, hayatın kendi yolları vardır. Bu özel durumda, bazı yeni özellikleri test ettiğimde ve kademeli olarak bazı kodları tanıtmak zorunda kaldığımda, anahtar olarak çok sık yapıyorum, bu yüzden kodu yorumluyorum, sonra daha az, daha az, daha az ve sonunda çalışma parçam var ve ben tüm yorumları kaldırabilir (kod üzerinden). Mükemmel dilim elbette iç içe yorumları destekleyecek :-).
greenoldman

@greenoldman: Çoğu dilde yorumlanabilir yorum yoktur, ancak "yorum bırak" özelliğinden daha az kullanılan "kod bloğunu kaldır" için bazı gerçek özelliklere sahip olurlar. C en #if DEADstandart ve en iyi tasarlanmış örnektir. Birçok dilde, ölü kodu eşdeğerine sarabilirsiniz if (DEAD). Ve birçok IDE'de, ölü kodu kaldırabilir ve isterseniz geri almak için Ctrl + Z ve / veya sürüm kontrolüne güvenebilirsiniz. Bir yorum bırakmak, docstring, metni bir grup ölü kod olan her şey , okunabilirlik için hala en kötü seçenektir.
Quuxplusone

11

Çünkü uygulamaların çoğu ayrı lexing ve ayrıştırma aşamaları kullanıyor ve lexing için düz eski düzenli ifadeler kullanıyorlar. Yorumlar beyaz alanlar olarak kabul edilir - yani yok sayılan jetonlar ve bu nedenle tamamen bir lexing geçişinde çözümlenmelidir. Bu yaklaşımın tek avantajı hızı ayrıştırmaktır. Çok sayıda dezavantaj, sözdizimi üzerinde ciddi sınırlamalar içerir (örneğin, sabit, içerikten bağımsız bir anahtar kelime kümesini koruma ihtiyacı).


3
Bugünlerde 'çoğu'ya katılmıyorum. Kesinlikle bu geleneksel bir yol, ancak C için EDG'nin önişlemci, lexing ve ayrıştırma işlemlerini birleştirdiğini ve hem GCC'nin hem de Microsoft'un da yaptığından şüpheleniyorum. Avantajı, gerektiğinde bunları ayrı ayrı uygulamanıza izin vermesidir.
Andrew Aylett

Clang da aynı şeyi yapıyor. Ama bu hala mevcut popüler dil derleyicilerinin sadece küçük bir kısmı.
SK-logic

@Neil Butterworth, mcs, javac, gcc'ye (evet, bir lexer'ı geri ekler, ancak yine de özel bir lexing geçişidir), clang (gcc ile aynı), dmd, fpc ve daha pek çok şey.
SK-logic

Hiç kimse önemsiz olmayan bir derleyici için sözcük ifadelerinde düzenli ifadeler kullanmaz.
Nuoji

@Nuoji - önemsiz olmayan için - tabii. Ancak esnek ve benzer araçlara güvenenler bunu yapar.
SK-logic

7

Yuvalanmış yorumları işleyebilen bir lexer yapmak mükemmel bir şekilde mümkündür. Boşluk yediğinde, gördüğünde /*bir derinlik sayacını artırabilir ve gördüğünde azaltabilir */ve derinlik sıfır olduğunda durabilir. Bununla birlikte, birçok ayrıştırıcı yaptım ve yorumların yuvalanması için asla iyi bir neden bulamadım.

Yorumlar yuvalanabilirse, bir dezavantajı uçlarını dengesiz hale getirmek kolaydır ve süslü bir editörünüz yoksa, orada olduğunu varsaydığınız kodu görünmez bir şekilde gizleyebilirsiniz.

Yuvalamayan yorumların tersi şuna benzer:

/*
some code
more code
blah blah blah
/**/

Burada, ilk satırı kaldırarak veya ekleyerek kodu 1 satırlık bir düzenleme olarak kolayca girip çıkarabilirsiniz. Tabii ki, bu kodun kendisi bir yorum içeriyorsa, C ++ tarzı yorumlara da izin vermezseniz , bu kırılır //. Ben de bunu yapmaya meyilliyim.


1
//yorumlar da C99 tarzıdır.
JAB

Alternatif olarak, bir dil bir-başlangıcı yorumdur belirtebilirsiniz /*$tokennerede, identifierherhangi bir alfasayısal simge olduğunu ve-of-comment sonudur token$*/. Belirteç için, her son yorum işaretinin eşleşen başlangıç ​​yorum bloğu için uygun jetonu içerdiğini doğrulamak için kod eklemesi nispeten basit olacaktır.
supercat

5

Kimse bundan bahsetmediği için, iç içe yorumları destekleyen birkaç dil listeleyeceğim: Rexx, Modula-2, Modula-3, Oberon. Buradaki zorluk ve hız sorunları ile ilgili tüm şikayetlere rağmen, bunların hiçbirinin büyük bir problemi yok gibi görünüyor.


4
Eklediğim ürün: Haskell, Frege
Ingo

Scala tarafından da destekleniyor.
Matt R

4

Blok yorumlarını iç içe yerleştirmenin iyi bir noktası, büyük kod bölümlerini kolayca yorumlayabilmenizdir (bir dize sabitinde blok yorumu bitiş dizisi yoksa neredeyse iyi).

Alternatif bir yöntem, onu destekleyen bir düzenleyiciniz varsa, bir satır satırını satır açıklaması başlatma sırasına yerleştirmektir.

Haskell blok yorumları iç içe geçirdi, ancak çoğu insan bunu fark etmiyor veya şikayet etmiyor gibi görünüyor. Sanırım bu, iç içe yorum beklemeyen insanların diğer dillerde sözcüksel bir hata olacağı için onlardan kaçınma eğiliminde olmalarıdır.


3

Yuvalanmış blok yorumları desteklemek ayrıştırıcıyı karmaşıklaştırır, bu da hem daha fazla çalışma hem de derleme süresini artırabilir. Bir dil için çok gerekli bir özellik değil, bu yüzden diğer iyileştirmeler ve optimizasyonlar için zaman ve çaba kullanmak daha iyidir.

Bence sadelik her zaman bir şey tasarlarken iyi bir şeydir. Bir özellik eklemenin, kaldırmaktan daha kolay olduğunu unutmayın. Yuvalanmış yorumlara izin verdiğinizde ve bunu kullanan programlar olduğunda, uyumluluğu bozmadan bunları çıkaramazsınız.


1
+1 için "özellik eklemek, kaldırmaktan daha kolay".
R .. GitHub BUZA YARDIMCI DURDUR

3
iç içe yorumlara izin vermediğinizde onlara da izin veremezsiniz, çünkü bu yorumları /*/**/
kıracaktır

2

Olası nedenlerden biri, iç içe yorumların ayrıştırıcı tarafından ele alınması gerektiğidir, çünkü sözlüklerde yaygın olarak kullanılan düzenli ifadelerin aroması özyinelemeyi desteklemez. Basit olanlar, lexer tarafından boşluk olarak ortadan kaldırılabilir, bu nedenle bu şekilde uygulanması daha kolaydır.


3
"Lezzet" değil. Normal ifadedeki "düzenli" kelimesi özünde özyinelemeyi dışlar.
R .. GitHub BUZA YARDIMCI DURDUR

3
@R: Matematikte elbette. Ancak programlamada, özyinelemeyi destekleyen regexes dediğimiz şeyler var.
amara

Soru şu: Bu bir sorun mu? Çoğu dil zaten yuvalama parantezleri ile uğraşmak zorunda. Bazılarını adlandırmak için: Lisp, C, Java, Python, Ruby, Perl.
Thomas Eding

İç içe parantezler iyidir, çünkü parantez içindeki şeyler dışarıdaki öğelerle aynıdır: normal simgeler. Yorumlarda jetonunuz yok, sadece metniniz var. Başlangıç ​​ve bitiş yorum belirteçlerini eşleştirebilmeniz gerekir, böylece 'int' bir açıklama mı yoksa bir yorumdaki sadece bir kelime mi olduğunu bilirsiniz. (Özellikle
lexer'daki

2
@ThePopMachine: Söylediğimden eminim, normalin kullandığınız anlamı değil, tanımlanmış bir resmi anlamı vardır ve "normal ifade" içindeki "normal" bu anlam için seçilmiştir. Özyinelemesiz olmak, tanımının bir sonucudur.
R .. GitHub BUZA YARDIMCI DURDUR

-1

Kim bilir? İç içe yorumların desteklenmesi daha fazla iş olduğundan - bir tür yığın bulundurmanız ve dil dilbilgisini karmaşıklaştırması nedeniyle tahmin ediyorum.


-1

Yuvalanmış yorumlar ayrıştırıcı için fazladan çalışma anlamına gelir. Genellikle bir yorumun başlangıcını gördüğünüzde, son yorum işaretine kadar her şeyi görmezden gelirsiniz. İç içe yorumları desteklemek için yorumlardaki metni de ayrıştırmanız gerekir. Bununla birlikte, en büyük sorun, bir programcının tüm iç içe yorumları doğru şekilde kapatmaya dikkat etmesi veya derleme hatalarına yol açmasıdır. Bir derleyiciyi doğru bir şekilde uygulamak, yapılabilecek bir şeydir, ancak bir programcı olarak iç içe yorumları izlemek oldukça hataya açık ve tahriş edicidir.


3
-1: doğru değil. Sane ayrıştırıcılar böyle çalışmaz.
amara
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.