Cthulhu yolunu ayrıştırmaya karşı argümanlar nelerdir?


24

Şirket için oldukça önemli olabilecek bir araç için Etki Alanına Özel Bir Dilin uygulanması görevi verildi. Dil basit ama önemsiz değil, zaten iç içe döngülere, dizi birleştirmeye vb. İzin veriyor ve proje ilerledikçe diğer yapıların ekleneceğinden de kesin olarak emin.

Tecrübeyle, bir dilbilgisi / çözümleyici yazmanın, dilbilgisi önemsiz olmasa da elle zaman alıcı ve hataya açık bir süreç olduğunu biliyorum. Bu yüzden iki seçeneğim kalmıştı: bir ayrıştırma jeneratörü veya bir Parcec gibi bir birleştirme kütüphanesi. Birincisi de iyiydi ama ikincisini çeşitli nedenlerden dolayı seçtim ve çözümü işlevsel bir dilde uyguladım.

Sonuç gözlerim için oldukça muhteşem, kod çok özlü, zarif ve okunabilir / akıcı. Java / c # dışında başka bir programda programlanmadıysanız biraz garip gelebileceğini kabul ediyorum, ancak bu durumda java / c # ile yazılmış olmayan herhangi bir şey geçerli olacaktır.

Ancak bir noktada, tam anlamıyla bir iş arkadaşı tarafından saldırıya uğradım. Ekranıma kısa bir bakıştan sonra, kodun anlaşılmaz olduğunu ve ayrıştırmayı yeniden icat etmemem gerektiğini, herkes gibi bir yığın ve String.Split kullanacağımı açıkladı. Çok fazla gürültü yaptı ve onu kısmen ikna edemediğim için, kısmen şaşırttım ve açık bir açıklama yapmadığım için, kısmen fikri kabul edilemediği için (cezalandırılmadı). Ona dili açıklamayı bile teklif ettim, ama boşuna.

Tartışma yönetimin önünde yeniden yüzeye çıkacağından eminim, bu yüzden bazı sağlam argümanlar hazırlıyorum.

Bunlar String.Split tabanlı bir çözümden kaçınmak için aklıma gelen ilk birkaç neden:

  • Özel durumları ele almak için çok fazla ife ihtiyacınız var ve işler hızla kontrolden çıktı
  • çok sayıda kodlanmış dizi indeks bakımı acı verir
  • işlev çağrısı gibi şeyleri yöntem argümanı olarak ele almak son derece zor (ör. add ((add a, b), c)
  • sözdizimi hataları durumunda anlamlı hata mesajları sağlamak çok zor (gerçekleşmesi çok muhtemel)
  • Ben basitlik, açıklık ve gereksiz akıllı-kriptik şeylerden kaçınmak için her şeyim, ama aynı zamanda bir burger flipperının bile anlayabilmesi için kod tabanının her bölümünü aşağılamamasının bir hata olduğuna inanıyorum. Arayüzleri kullanmadığım, kaygıların ayrılmasını benimsemediğim, etrafa kopya-yapıştırma kodu koymama, vb. Duyduğum aynı argüman. Sonuçta bir yazılım projesi üzerinde çalışmak için en az teknik yeterlilik ve öğrenmeye istekli olmak gerekiyor. (Bu tartışmayı muhtemelen rahatsız edici geleceği için kullanmayacağım ve bir savaş başlatmak hiç kimseye yardımcı olmayacak)

Cthulhu yolunu ayrıştırmaya karşı en sevdiğiniz argümanlar nelerdir ? *

* tabii ki beni haklı olduğuna ikna edersen, ben de tamamen mutlu olacağım


9
Bana iş arkadaşınız DSL projesini yapmak için gönüllü oluyor gibi geliyor!
GrandmasterB

23
"Ayrıştırmayı yeniden icat etmemeliyim ama sadece bir yığın kullanıp String.Split herkesin yaptığı gibi" - kahretsin, bu adam cehaletin incitmemesine sevinmiş olmalı ...
Michael Borgwardt

4
İş arkadaşınıza, tüm Ejderha Kitabını okumadığı ve bir sınavı geçmediği sürece bu tartışmaya geri dönmemesi konusunda tavsiyede bulunun. Aksi halde ayrıştırma ile ilgili hiçbir şeyi tartışma hakkına sahip değildir.
SK-mantığı

4
üzgünüm, kim ayrıştırmayı yeniden icat ediyordu?
rwong

2
Sanırım bir dahaki sefere "kelimenin tam anlamıyla" kelimesini kullanan birini gördüğümde kafam kelimenin tam anlamıyla patlayacak.

Yanıtlar:


33

İki yaklaşım arasındaki kritik fark, tek doğru yol olarak kabul ettiği durumun zorunlu olduğudur ve sizin kararınızdır.

  • Yaklaşımınız açıkça kuralları belirtir, yani gramer kuralları (neredeyse) doğrudan kodunuzda kodlanır ve ayrıştırıcı kütüphanesi, ham durumu otomatik olarak ayrıştırılmış çıktıya dönüştürür, durum ve ele alınması zor olan diğer şeylerle ilgilenir. Kodunuz, sorun alanıyla çakışan tek bir soyutlama katmanına yazılır: ayrıştırma. Parsec'in doğruluğunu kabul etmek mantıklıdır; bu, burada hata için tek yer, dilbilgisi tanımınızın yanlış olduğu anlamına gelir. Fakat yine de, tamamen nitelikli kural nesneleriniz var ve bunlar kolayca yalıtılmış olarak test ediliyor. Ayrıca, olgun çözümleyici kütüphanelerinin önemli bir özelliğe sahip olduğu bildiriliyor: hata raporlama. Ayrıştırma yanlış gittiğinde iyi hata kurtarması önemsiz değildir. Kanıt olarak PHP'leri çağırdım parse error, unexpected T_PAAMAYIM_NEKUDOTAYIM: D

  • Yaklaşımı dizeleri manipüle eder, açıkça durumu korur ve ham girişi manuel olarak ayrıştırılmış girdilere yükseltir. Hata bildirme dahil her şeyi kendiniz yazmalısınız. Ve bir şeyler ters gittiğinde, tamamen kaybolacaksın.

İroni, sizin yaklaşımınızla yazılan bir ayrıştırıcının doğruluğunun nispeten kolay bir şekilde kanıtlanmasıdır. Bu durumda, neredeyse imkansız.

Bir yazılım tasarımı yapmanın iki yolu vardır: Bir yol, o kadar basit, açık bir şekilde hiçbir eksiklik olmayacak şekilde basitleştirmektir, diğer yol ise, belirgin bir eksikliğin olmadığı kadar karmaşık hale getirmektir. İlk yöntem çok daha zor.

ARAÇ Hoare

Kişisel yaklaşım olduğunu daha basit bir. Tek engellediği onun ufkunu biraz genişletmesi. Yaklaşımının sonucu, ufkunuz ne kadar geniş olursa olsun her zaman katlanacak.
Dürüst olmak gerekirse, bana öyle geliyor ki, adam blub sendromundan acı çeken, cahil bir aptal, sizi yanlış anladıysanız ve sizi anlayamıyorsa sizi bağırmak için kibirli.

Ancak sonuçta, soru şudur: bunu kim korumak zorunda olacak? Eğer sizseniz, o zaman sizin çağrınız, ne olursa olsun, ne söyleyeceğiniz önemli değil. Eğer o olacaksa, o zaman sadece iki olasılık var: Ayrıştırıcı kütüphanesini anlamasını sağlamak veya onun için zorunlu bir ayrıştırıcı yazmak için bir yol bulun. Ayrıştırıcı yapınızdan oluşturmanızı öneririm: D


İki yaklaşım arasındaki farkın mükemmel açıklaması.
smarmy53

6
Görünüşe göre Programcılar için TVTropes ile bağlantı kurdunuz. Güle güle öğleden sonra ...
Izkata

10

Ayrıştırma ifadesi dilbilgisi (Packrat ayrıştırıcı yaklaşımı gibi) veya ayrıştırıcı birleştirici ayrıştırmayı yeniden icat etmiyor. Bunlar fonksiyonel programlama dünyasında iyi bilinen tekniklerdir ve doğru ellerde alternatiflerden daha okunabilir olabilir. Birkaç yıl önce C # 'da oldukça basit bir dilbilgisi için ilk çare olarak kullandığım aracı olan inandırıcı bir PEG gösterisi gördüm.

Ayrıştırıcı birleştiricileri veya bir PEG kullanan zarif bir çözümünüz varsa, bu oldukça kolay bir satım olmalı: oldukça genişleyebilir, işlevsel programlama korkunuzu üstlendikten sonra okumak genellikle nispeten kolaydır ve bazen tipik ayrıştırıcı jeneratöründen okumak kolaydır. araçlar, bununla birlikte, dilbilgisine ve her iki araç setinde sahip olduğunuz deneyim düzeyine de bağlıdır. Ayrıca testler yazmak oldukça kolay. Tabii ki, en kötü senaryolarda (ya da Packrat ile çok fazla bellek tüketimi) oldukça kötü ayrıştırma performansı ile sonuçlanabilecek bazı dilbilgisi belirsizlikleri var, ancak ortalama bir durum oldukça iyi ve aslında bazı dilbilgisi belirsizlikleri PEG ile LALR'den daha iyi ele alınıyor. Hatırlıyorum.

Bölünmüş ve yığın kullanmak, bir PEG'den daha basit gramerlerle çalışır veya destekleyebilir, ancak zamanla yinelemeli inişi kötü bir şekilde yeniden keşfedeceğiniz veya bantlatacağınız lapa lapa bir davranış grubuna sahip olacağınız büyük olasılıkla son derece yapılandırılmamış kod pahasına sunulmasına yardım. Eğer sadece basit tokenizasyon kurallarınız varsa, muhtemelen o kadar da kötü değil, fakat karmaşıklık eklediğiniz için, muhtemelen en az korunan çözüm olacaktır. Bunun yerine bir ayrıştırıcı jeneratörüne ulaşırdım.

Şahsen, DSL kurmam gerektiğindeki ilk eğilimim, mevcut bir programlama dilinin gücünü ve makrolar ve basit ayarlamalar yaparak inanılmaz özelleştirilebilirlik elde ettiğim için Boo (.Net) veya Groovy (JVM) gibi bir şey kullanmak olacaktı. derleyici boru hattına, sıfırdan başlarsam (döngüler, değişkenler, nesne modeli, vb.) başaracağım sıkıcı şeyleri uygulamak zorunda kalmadan. Ruby ya da Lisp'i geliştiren bir dükkanda olsaydım, sadece orada anlam ifade eden deyimleri kullanırdım (metaprogramlama, vs.).

Ama asıl meselenin kültür ya da ego ile ilgili olduğundan şüpheleniyorum. Eğer iş arkadaşınızın Antlr veya Flex / Bison kullanıyor olsaydınız, aynı derecede çıldırmayacağından emin misiniz? Çözümünüz için "tartışmanın" kaybedilen bir savaş olabileceğinden şüpheleniyorum; Yerel yönetim yetkilinize hitap etmek yerine, fikir birliği oluşturma tekniklerini kullanan daha yumuşak bir yaklaşım uygulamak için daha fazla zaman harcamanız gerekebilir. Programlamayı eşleştirin ve bakımı yapılabilirlikten ödün vermeden dilbilgisi ayarlarının ne kadar hızlı yapabileceğinizi ve tekniği, tarihçesini vb. Açıklamak için bir kahverengi torba yaparak ne kadar çabuk olabileceğinizi gösterin. yüzleşme toplantısı.


9

Algoritma algoritmalarında ve benzerlerinde çok iyi bilgili değilim ama bence pudingin ispatı yemek yiyor. Bu nedenle, diğerleri başarısız olursa, çözümleyiciyi kendi yöntemiyle uygulaması için teklif verebilirsiniz. Sonra

  • Her iki çözüme yapılan yatırım süresini karşılaştırmak,
  • hangisinin daha az böceğe sahip olduğunu görmek için her iki çözümü de kapsamlı bir kabul testinden geçirin ve
  • Bağımsız bir yargıcın sonuç kodunu kendinizle ölçün ve netleştirin.

Testin gerçekten adil olması için, her iki çözümün de aynı API'yi uygulamasını ve ortak bir test platformu (veya her ikiniz tarafından bilinen bir birim test çerçevesi) kullanmasını isteyebilirsiniz. Her ikiniz de istediğiniz sayıda ve türde işlevsel test senaryoları yazabilir ve kendi çözümünün hepsini geçtiğinden emin olabilirsiniz. Ve elbette, ideal olarak ikinizin de son başvuru tarihinden önce diğerinin uygulamasına erişebilmelisiniz. Belirleyici test, diğer geliştirici tarafından geliştirilen test takımını kullanarak her iki çözümü de çapraz test etmek olacaktır .


bu harika bir fikir! Bir commont birim test çerçevesi kullanmak da kolay olurdu.
smarmy53

1
İş arkadaşınızın bölünmüş versiyonu yapması için +1 ... OP, onu oluşturma görevini üstlendi, bu nedenle iş arkadaşı değil, desteklemesi gereken muhtemelen o. Sadece diğer çalışmalarının başında ona önermek, onu arkanızdan çıkarmak için yeterli olabilir.
Izkata

7

Bunu teknik bir sorunuz varmış gibi soruyorsunuz, ancak muhtemelen zaten bildiğiniz gibi burada teknik bir soru yok. Yaklaşımınız, karakter seviyesinde bir şeyi kırmaktan çok daha üstün.

Asıl sorun şudur ki (muhtemelen daha deneyimli) meslektaşınız güvensizdir ve bilginiz tarafından tehdit altında hissediyordur. Onu teknik argümanlarla ikna etmeyeceksiniz ; Bu sadece onu daha savunmacı hale getirecek. Bunun yerine korkularını hafifletmenin bir yolunu bulmanız gerekecek. Çok fazla öneride bulunamıyorum, ancak eski kod konusundaki bilgisine büyük saygı göstermeyi deneyebilirsiniz.

Son olarak, eğer menajeriniz onun teknik konusundaki argümanlarını kabul ederse ve çözümünüzü alamazsa, o zaman başka bir pozisyon aramanız gerekeceğini düşünüyorum. Açıkçası daha sofistike bir organizasyonda daha değerli ve daha değerli olacaksınız.


Haklısın, yaklaşımımın üstün olduğunu zaten biliyordum, ancak iyi ve inandırıcı bir açıklama yapamadım - aradığım teknik bilgi bu. Sorunun "insan etkileşimi" tarafının teknik olan kadar önemli (kabul edilmediyse) kabul edildi.
smarmy53

4

Kısa olacağım:

Cthulhu yolunu ayrıştırmak zor. Buna karşı en basit ve en inandırıcı argüman bu.

Basit diller için hile yapabilir; normal diller diyelim. Yine de, muhtemelen normal bir ifadeden daha kolay olmayacak.

Aynı zamanda biraz daha karmaşık diller için hile yapabilir.

Bununla birlikte, iç içe geçmiş herhangi bir dil için bir Cthulhu çözümleyici veya yalnızca "önemli ölçüde durumsal" olan matematiksel ifadeler veya örneğin (iç içe geçmiş işlev çağrıları) görmek isterim.

Birisi böyle (önemsiz bağlamsız) bir dil için bir ayrıştırıcı cthulhu yapmaya çalıştığında ne olacağını bir düşünün . Doğru bir çözümleyici yazacak kadar akıllı olması şartıyla, kodlama sırasında ilk belirteçleri "keşfedeceğini" ve sonra da özyinelemeli iniş ayrıştırmalarını - bir biçimde "bulacağını" iddia ediyorum.

Ondan sonra, şey basit: "Hey bak, özyinelemeli iniş ayrıştırıcı denilen bir şey yazdın! Bunun normal ifadeler gibi, basit bir gramer tanımından otomatik olarak oluşturulabileceğini biliyor musunuz?


Uzun lafın kısası:
Birinin medeni yaklaşımı kullanmasını engelleyebilecek tek şey, onların cehaletleridir.


1

Belki de iyi bir DSL anlambilimi üzerinde çalışmak da önemlidir (sözdizimi önemlidir, fakat aynı zamanda anlambilim). Bu konulara aşina değilseniz, Programming Languages ​​Pragmatics (M.Scott tarafından) ve Christian Queinnec gibi bazı kitapları okumanızı öneririm. Küçük Parçalar halinde Lisp . Cambridge Üniversitesi Yayınları, 1996.

DSL konferanslarında son makaleleri okumak, örneğin DSL2011 de yardımcı olacaktır.

Bir Etki Alanına Özgü Dil Tasarlamak ve uygulamak zordur (ve zorluğun çoğu ayrıştırma değildir !).

Cthulhu yolunu gizleyerek ne demek istediğini anlamıyorum ; Sanırım sadece bir şekilde tuhaf bir şekilde ayrıştırmak istiyorsun.


İyi bağlantılar Cthulhu gelince, üzgünüm, bağlantıyı unuttum. Klasik bir kodlayıcı makalesine referans: codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html . Orijinal yazıyı güncelledim.
smarmy53
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.