2011-09-19 25 views
6

Basit bir YAML ayrıştırıcısı yazmaya çalışıyorum, başlamadan önce yaml.org, 'dan gelen özellikleri okuyordum, el ile ayrıştırılmış bir ayrıştırıcı yazmak daha iyi mi, yoksa lex (flex/bison) kullanın. libyaml (C kütüphanesi) 'e baktı - lex/yacc kullanıyor görünmüyor. YAML (akış biçemleri hariç), daha fazla çizgi odaklı görünüyor, bu nedenle elle işlenmiş ayrıştırıcı yazmak veya flex/bison kullanın.YAML ayrıştırma - lex veya el yapımı?

+1

Sadece standart YAML ayrıştırıcısı kullanmayı düşündünüz mü? Yoksa özellikle kendi başınıza inşa etmekle ilgileniyor musunuz? Ayrıca, lex 've' flex' * tarayıcı jeneratörler *, değil * ayrıştırıcı jeneratörler * olduğunu unutmayın; ayrıştırma yapmak için 'yacc' veya 'bizon' kullanmak istersiniz. – templatetypedef

+0

@templatetypedef Kendi kendime inşa etmekle ilgileniyorum. – vyom

+1

@templatetypedef Muhtemelen sorumu netleştirmedim. Anlıyorum 'lex' sadece bir tokenizer. YAML yapısının 'flex/bison' veya elle yuvarlanmış ayrıştırıcıya daha iyi uyup uymadığını bilmek istedim – vyom

cevap

3

Bu yanıt temelde şu soruya bir cevaptır: "Kendi çözümleyicimi mi döndürmeli yoksa çözümleyici üreteci kullanmalı mıyım?" ve YAML ile ilgisi yoktur. Ama yine de sorunuza "cevap" edecek.

Sormanız gereken soru "bu, bu verilen dil/dilbilgisiyle çalışır" değil, "bunu uygulamak için kendimi emin hissediyorum" değil. Konunun gerçekliği, ayrıştırmak istediğiniz çoğu biçimin, yalnızca oluşturulan bir ayrıştırıcıyla çalışacak olmasıdır. Diğer gerçek ise, recursive descent parser numaralı basit bir el ile karmaşık dilleri bile ayrıştırmanın mümkün olmasıdır.

Diğerlerinin yanı sıra, EDDL (C ve yapılandırılmış öğeler) için yinelemeli bir soy ayrıştırıcısı ve INI için bir bison/flex ayrıştırıcısı yazdım. Bu örnekleri seçtim, çünkü sezgiye ve dış gereksinimlere karşı çıktıkları kararını dikte ettiler.

Teknik bir seviyede kurduğumdan beri, neden diğerini seçersiniz? Cevap vermek gerçekten zor bir soru, konuyla ilgili bazı düşünceler:

  • İyi bir lexer yazmak gerçekten çok zor. Çoğu durumda lexeri üretmek için esnek kullanmak mantıklıdır. Gerçekten egzotik girdi formatlarınız olmadığı sürece, kendi lexer'ınızı elle kullanmanın az bir yolu vardır.
  • Bizon veya benzer jeneratörler kullanarak, dilimlemeyi açıkça görünür kılmak için kullanılır. Buradaki birincil kazanç, geliştiricinizi beş yıl içinde muhafaza eden geliştiricinin, kullanılan dilbilgisini hemen görecek ve herhangi bir özellik ile karşılaştırabileceğidir.
  • Yinelemeli bir yoklayıcı ayrıştırıcısı kullanmak, ayrıştırıcıda ne olduğunu açıkça belirtti. Bu, harry çatışmalarını incelikle işlemek için kolay araçlar sağlar. Tüm dilbilgisini LALR1 olacak şekilde yeniden düzenlemek yerine, basit bir şekilde yazabilirsiniz.
  • Ayrıştırıcıyı geliştirirken, elle yazılmış bir ayrıştırıcı ile "detaylar üzerinde parlaklık" yaratabilirsiniz, bizonu kullanarak bu neredeyse imkansızdır. Bizonda gramer çalışmalı veya jeneratör hiçbir şey yapmayacaktır.
  • Bizon, gramerdeki resmi kusurları işaret etmede harikadır. Ne yazık ki onları düzeltmek için yalnız kalıyorsun. Bir ayrıştırıcıyı el ile çalışırken, çözümleyici anlamsız bir şekilde okuduğunda yalnızca kusurları bulacaksınız.

Bu, biri veya diğeri için kesin bir yanıt değil, ancak size doğru yönde işaret ediyor. Ayrıştırıcıyı eğlence için yazdığınıza göre, her iki çözümleyiciyi de yazmış olmalısınız.