Yorumlar genellikle nasıl ayrıştırılır?


31

Yorumlar genellikle programlama dillerinde ve işaretlemede nasıl ele alınır? Bazı özel biçimlendirme dili için bir ayrıştırıcı yazıyorum ve en az sürpriz ilkesini takip etmek istiyorum , bu yüzden genel sözleşmeyi belirlemeye çalışıyorum.

Örneğin, bir belirteç içine gömülü bir yorum belirteçle etkileşime girmeli mi, gelmemeli mi? Genellikle şöyle bir şeydir:

Sys/* comment */tem.out.println()

geçerli?

Ayrıca, dil yeni satırlara duyarlıysa ve yorum yeni satırı kapsıyorsa, yeni satır düşünülmeli mi yoksa edilmemeli mi?

stuff stuff /* this is comment
this is still comment */more stuff 

gibi muamele görmek

stuff stuff more stuff

veya

stuff stuff
more stuff

?

Birkaç özel dilin ne yaptığını biliyorum, ne de fikirler arıyorum, ancak bakıp bakamayacağımı arıyorum: genel olarak belirteçler ve yeni çizgilerle ilgili bir işaretleme ile beklenen bir fikir birliği var mı?


Özel bağlamım, wiki benzeri bir işaretlemedir.


Yeni satır, yorumun içinde var mı? Neden yorumdaki herhangi bir karakterden farklı bir şekilde ele alındı?

1
@Snowman bu perspektifi var, ancak öte yandan 'x' belirteci özel çizgiye sahipse, hatta çizgideki ilk belirteç ise ve hatta hem kaynağa hem de kişiye arayan kişide çizginin ilk belirteci olarak görünüyorsa satır satır satır okuma ayrıştırıcı. Bir ikilem gibi görünüyor bu yüzden soruyu sordum.
Kızak

4
Bunu bir süre önce tam olarak tayin etmem gerekiyordu ve gcc'nin belgelerini mükemmel bir kaynak olarak buldum . Düşünmediğiniz bazı garip köşe davaları var.
Karl Bielefeldt

Yanıtlar:


40

Genellikle yorumlar, belirtme işleminin bir parçası olarak, ancak ayrıştırmadan önce taranır (ve atılır). Bir yorum, çevresindeki boşluk olmadığında bile belirteç ayırıcı gibi çalışır.

Sizin de belirttiğiniz gibi, C spesifikasyonu açıkça yorumların tek bir boşlukla değiştirildiğini belirtir. Gerçekte, sadece bir teknik özelliktir, çünkü gerçek dünyadaki bir çözümleyici aslında hiçbir şeyin yerine geçmeyecek, ancak bir yorumu beyaz boşluk karakterlerini taradığı ve attığı gibi tarayacak ve atacaktır. Ancak, bir yorumun belirteçleri bir alandaki gibi ayırdığı basit bir şekilde açıklar.

Yorumların içeriği göz ardı edilir, bu nedenle çok satırlı yorumların içindeki satır boşluklarının etkisi yoktur. Satır sonlarına (Python ve Visual Basic) duyarlı olan diller genellikle çok satırlı yorumlara sahip değildir, ancak JavaScript bir istisnadır. Örneğin:

return /*
       */ 17

Eşittir

return 17

değil

return
17

Tek satırlı yorumlar satır sonunu korur;

return // single line comment
    17

eşittir

return
17

değil

return 17

Yorumlar tarandığından ancak ayrıştırılmadığından iç içe geçme eğilimindedirler. Yani

 /*  /* nested comment */ */

yorum bir ilk tarafından açıldığından ve ilk /*tarafından kapatıldığından sözdizimi hatası*/


3
Çoğu dilde satır içi yorumlar ( /* like this */), tek bir beyaz boşluğa ve EOL ile sonlandırılan yorumlar ( // like this) ise boş bir satıra eşit olarak kabul edilir .
9000

@JacquesB bu yüzden yorumları bütünüyle kaynağından değiştirilmiş olarak sıfır genişlikli bir alan olarak ele almayı düşünüyorum, bu sizin önerdiklerinize eşdeğer görünüyor.
Kızak

1
@artb sıradan bir alan gayet iyi çalışmalı ve ASCII kod sayfasında yer almalıdır.
John Dvorak

@JanDvorak bir alan görünüşünü etkileyecek ve anlayışı kaldırıyor ve "yorum gerçekten orada değil" anlamına daha yakın. Birincil görüntü oluşturma çıktısı HTML olacaktır, bu durumda benim durumumda ASCII tarayıcıların Unicode'u desteklediği kadar önemli değildir. Bununla birlikte, C standardının yorumların tek bir boşlukla değiştirilmesini zorunlu kıldığını düşünüyorum.
Kızak

1
Başta Raket olmak üzere bazı diller çok satırlı iç içe geçmiş yorumlar içermektedir: (define x #| this is #| a sub-comment |# the main comment |# 3) xverimler 3.
wchargin

9

Soruyu cevaplamak için:

Genel olarak bir işaretleme ile beklenenleri hakkında genel bir fikir birliği var mı?

Hiçbirinin bir jetonun içine gömülü bir yorumun yasal olmasını beklemeyeceğini söyleyebilirim.

Genel bir kural olarak, yorumlar boşluklarla aynı şekilde ele alınmalıdır. Fazladan bir boşluk için geçerli olabilecek herhangi bir yerin de gömülü bir yorum yapmasına izin verilmelidir. Tek istisna dizeler olacaktır:

trace("Hello /*world*/") // should print Hello /*world*/

Dizgelerin içindeki yorumları desteklemek oldukça garip olur ve onlardan kaçmayı sıkıcı hale getirir!


2
Dizeleri hiç düşünmedim, bu iyi bir durum. Benim şimdiki düşüncem yorumun başlangıcı ile bitişi arasında basit bir regex yapmak ve onu tek bir boşlukla değiştirmek oldu. Bu davanı tetiklerdi.
Kızak

3
Kaçan dizeler hakkında bu bit için +1. Bununla birlikte, örneğin, Hello /* world*/!yorum sınırlayıcıları bastırmak yerine genellikle yazdırmasını beklerdim . Ayrıca, Programcılara hoş geldiniz!
Saat

1
Teşekkürler 8 bitti! Ve kesinlikle demek istediğim buydu. Yeterince komik, ayrıca cevabımdaki ** kaçmaya ihtiyacım var ....
Connor Clark

2
@ArtB genel olarak, "ikame ile ayrıştırma", kenar kasaları ve diğer özelliklerle etkileşime girme konusunda çok zorlaşır ve en başından kaçınılması en iyisidir.
Ocaklar

7

Boşluğa duyarsız dillerde, yok sayılan karakterler (örneğin, boşluklar veya yorumun bir parçası olanlar) belirteçleri sınırlar.

Mesela Sys temiki tane belirteç var, bir tane ise System. Karşılaştırmak eğer bu faydası daha belirgin olabilir new Foo()ve newFoo()bunlardan biri bir örneğini inşa edecek Foodiğer aramalar sırasında newFoo.

Yorumlar, beyaz boşluklarla aynı rolü oynayabilir, örneğin new/**/Foo()aynı şekilde çalışır new Foo(). Elbette bu daha karmaşık olabilir, örneğin new /**/ /**/ Foo()ya da değil.

Teknik olarak, tanımlayıcılar içinde yorumlara izin vermek mümkün olmalıdır, ancak bunun özellikle pratik olduğundan şüpheliyim.

Şimdi, boşluklara duyarlı dillerden ne haber?

Python akla geliyor ve çok basit bir cevabı var: blok yorum yok. Bir yorum başlatırsınız #ve ayrıştırıcı tam olarak satırın geri kalanı yokmuş gibi çalışır, bunun yerine sadece yeni bir satırdı.

Bunun aksine yeşim , aynı girintiye döndüğünüzde bloğun bittiği yerde blok yorumlarına izin verir . Örnek:

body
  //-
    As much text as you want
    can go here.
  p this is no longer part of the comment

Bu yüzden, bu alemde, işlerin genellikle nasıl yapıldığını söyleyebileceğinizi söyleyemem . Ortak bir özellik olarak görünen, bir yorumun her zaman bir satır sonu ile sona ermesidir; bu, tüm yorumların tamamen yeni satırlarla aynı olduğu anlamına gelir.


Hmm, yeni satır asıl meseledir, çünkü yorumlar için HTML \ XML sözdizimini kullanıyoruz, böylece çok satırlı olacak.
Kızak

3
@ArtB HTML / XML sözdizimini kullanıyorsanız, davranışlarını kullanmak akıllıca olabilir.
Saat

1
@ 8bittree mantıklı, bunu düşünmeliydim. Soruyu bu şekilde daha faydalı olacağı için olduğu gibi bırakacağım.
Kızak

3

Geçmişte yorumları, sözcüksel analizin bir parçası olarak tek bir belirteç haline getirdim. Aynı dizeleri için de geçerli. Oradan, hayat kolaydır.

Yaptığım son ayrıştırıcının özel durumunda, üst düzey ayrıştırma yordamına bir kaçış kuralı iletilir. Kaçış kuralı, çekirdek dilbilgisi ile aynı çizgide bulunan yorum belirteçleri gibi belirteçleri işlemek için kullanılır. Genel olarak, bu belirteçler atıldı.

Bu şekilde yapmanın bir sonucu, bir tanımlayıcının ortasında bir yorumla gönderdiğiniz örnekte, tanımlayıcının tek bir tanımlayıcı olmamasıdır - bu, çalıştığım tüm dillerde (bellekten) beklenen davranış. .

Bir dizge içindeki bir yorumun durumu örtük olarak sözcüksel analiz tarafından ele alınmalıdır. Bir dizgenin işlenmesi ile ilgili kuralların yorumlara ilgisi yoktur ve bu nedenle yorum, dizenin içeriği olarak değerlendirilir. Aynısı bir yorumdaki bir dize (ya da değişmeyen) için de geçerlidir - dize açık bir şekilde tek bir belirteç olan bir yorumun bir parçasıdır; Bir yorumun işlenmesiyle ilgili kuralların dizelerle ilgisi yoktur.

Umarım bu mantıklı / yardımcı olur.


Öyleyse console.log(/*a comment containing "quotes" is possible*/ "and a string containing /*slash-star, star-slash*/ is possible"), bir yorumda alıntıların olduğu ve bir dizgede yorum sözdiziminin olduğu yerde kodunuz varsa , sözcü doğru bir şekilde belirtmeyi nasıl bilebilir? Lütfen bu davaların genel bir tanımını yaparak cevabınızı düzenleyebilir misiniz?
chharvey

1

Ayrıştırıcınızın hangi amacı olduğuna bağlı. Bir yorumdan derlemek üzere bir ayrıştırma ağacı oluşturmak için bir ayrıştırıcı yazarsanız, potansiyelleri ayıran işaretlerin yanında anlamsal bir değeri yoktur (örneğin, method / comment / (/ comment /)). Bu durumda, işlem görmüş boşluklar.

Ayrıştırıcınız bir kaynak dili başka bir kaynak dile çeviren bir aktarıcının parçasıysa veya ayrıştırıcınız bir derleme birimini bir kaynak dilde alan bir önişlemci ise, ayrıştırma, değiştirme ve değiştirilmiş sürümü aynı kaynak dile geri yazma, yorum yapma başka bir şey gibi çok önemli hale gelir.

Ayrıca yorumlarda meta bilgileriniz varsa ve özellikle JavaDoc gibi API-belgeleri oluştururken olduğu gibi yorumlara önem veriyorsanız, yorumlar aniden çok önemlidir.

Burada yorumlar sıklıkla belirteçlere eklenir. Bir yorum bulursanız, bir belirteç yorumuna eklersiniz. Bir belirteç, önce ve sonra birden çok belirteç içerebildiğinden, bu yorumların nasıl ele alınacağına bağlı olarak yine bir amaç vardır.

Yorum yapmayan belirteçlere yorum yazarken açıklama yapma düşüncesi, gramerdeki yorumları tamamen kaldırmaktır.

Ayrıştırma ağacına sahip olduğunuzda, bazı AST'ler, her bir belirteci kendi AST Öğesi ile temsil eden, ancak normal içindekiler ilişkisinin yanında başka bir AST Öğesine bağlı olan yorumları açmaya başlar. Açık kaynak IDE'de bulunan kaynak diller için tüm ayrıştırıcı / AST uygulamalarını kontrol etmek iyi bir fikirdir.

Çok iyi bir uygulama, Java dili için Eclipse derleyici altyapısıdır. Belirleme sırasında yorumları koruyorlar ve hatırladığım kadarıyla AST içindeki yorumları temsil ediyorlar. Ayrıca, bu ayrıştırıcı / AST uygulaması formatlamayı korur.

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.