Bir “tokenizer”, “ayrıştırıcı” ve “lexers” ın ne olduğunu ve birbirleriyle nasıl ilişkili ve nasıl kullanıldıklarına dair net bir tanım mı arıyorsunuz?


151

Ben bir "tokenizer", "ayrıştırıcı" ve "lexer" ne olduğunu ve birbirleri ile nasıl açık bir tanımını arıyorum (örneğin, bir ayrıştırıcı bir tokenizer kullanır veya tam tersi)? Veri beyanı ve tanımları ayıklamak için c / h kaynak dosyaları üzerinden gidecek bir program oluşturmak gerekir.

Örnekler arıyordum ve bazı bilgiler bulabilirim, ancak gramer kuralları, ayrıştırma ağaçları ve soyut sözdizimi ağacı gibi temel kavramları ve birbirleriyle nasıl ilişki kurduklarını gerçekten kavramak için uğraşıyorum. Sonunda bu kavramların gerçek bir programda saklanması gerekir, ancak 1) neye benziyorlar, 2) ortak uygulamalar var.

Lex ve Yacc gibi bu konular ve programlar hakkında Wikipedia'ya bakıyordum, ancak hiçbir zaman bir derleyici sınıfından (EE major) geçmedim, neler olduğunu tam olarak anlamakta zorlanıyorum.

Yanıtlar:


166

Bir belirteç, genellikle boşluk (sekmeler, boşluklar, yeni satırlar) arayarak bir metin akışını belirteçlere böler.

Bir lexer temel olarak bir tokenleştiricidir, ancak genellikle belirteçlere ekstra bağlam ekler - bu belirteç bir sayıdır, bu belirteç bir dizgi değişmezidir, bu diğer belirteç bir eşitlik operatörüdür.

Bir ayrıştırıcı, belirteç akışını lexer'dan alır ve orijinal metnin temsil ettiği (genellikle) programı temsil eden soyut bir sözdizimi ağacına dönüştürür.

En son kontrol ettiğimde, konuyla ilgili en iyi kitap genellikle "Ejderha Kitabı" olarak bilinen "Derleyiciler: İlkeler, Teknikler ve Araçlar " idi.


8
Kuşkusuz "Ejderha Kitabı" iyi bir kitaptır, ancak okuyucunun CS'de iyi bir topraklamaya sahip olmasını gerektirir. Daha pratik çekiciliği olan bazı kitaplar Ronald Mak, "Modern Derleyici Uygulaması", Andrew Appel tarafından yazılan "Derleyiciler ve Tercümanlar Yazmak" olacaktır; "Derleyici Yapımı", Niklaus Wirth; Pat Terry tarafından "C # ve Java ile Derleme" ve "Derleyiciler ve Derleyici Üreteçleri: C ++ ile Giriş"; ve elbette, Terrence Parr tarafından "Kesin ANTLR Referansı".
Andre Artus

5
Sadece emin olmak için tavsiyeni çalmıyorum. "Ejderha Kitabı" derleyici teknolojisiyle ilgili ilk kitabımdı, ancak Wirth'in birkaç saat içinde okuyabileceğiniz bir kitabı olan kitabına kıyasla çok zordu. O zamanlar elimden alabileceğim tek kitap olduğu için birkaç seçeneğim vardı (1991, Amazon ve WWW'den önce). Bunu ve Jack W. Crenshaw tarafından "DAHA FAZLASI OLUŞTURUN" adlı bir metin dosyaları koleksiyonum vardı (teşekkürler Jack!). Bu hala ilkelerin daha iyi anlaşılması için bir kitap, ancak çoğu programcı pragmatik bir girişe ihtiyaç duyuyor.
Andre Artus

10
Bir ayrıştırıcının / tanım gereği / soyut bir sözdizimi ağacı ürettiğini kabul etmem. Ayrıştırıcılar her türlü farklı çıktı üretebilir. Örneğin, bir ayrıştırıcının bazı oluşturucu arabirimlerine bir dizi çağrı üretmesi yaygındır - Dörtlü Çete kalıpları kitabındaki Oluşturucu Kalıbı'na bakın. Kilit nokta, ayrıştırıcının, dizinin bazı (genellikle bağlamsız) dilbilgisine uygun olup olmadığını ve dizinin gramer yapısına bağlı olarak bir çıktı üretip üretemeyeceğini belirlemek için bir dizi diziyi analiz etmesidir.
Theodore Norvell

2
"Bir Derleyici Yapalım" burada: compilers.iecc.com/crenshaw . Bağlantıyı buradan buldum: prog21.dadgum.com/30.html
Roger Lipscombe

1
@Pithkos: eğer bunlar sadece kısıtlamalarsa, tüm söylediğiniz tek şey fonksiyonun isimsiz (matematiksel) bir alanda bir girdi alması ve başka bir isimsiz alanda üretip çıkmasıdır, örneğin, F (X) -> Y Hemen hemen bu demektir buna sadece "işlev" diyebilirsiniz. X alanının <StreamOfCharacter, Grammar> ve Y alanının, gramer şeklini yansıttığı özelliğe sahip olduğu konusunda ısrar ederseniz, F (X, G) -> T, ayrıştırıcı. Genellikle F'yi G'ye göre köriyoruz, çünkü G sık değişmez, bu nedenle F [G] (X) -> T yaygın olarak ayrıştırıcı olarak gördüğünüz şeydir.
Ira Baxter

18

Misal:

int x = 1;

Bir lexer veya tokenizer bunu 'int', 'x', '=', '1', ';' jetonlarına böler.

Bir ayrıştırıcı bu belirteçleri alacak ve bunları bir şekilde anlamak için kullanacaktır:

  • bir sözümüz var
  • tamsayı tanımı
  • tamsayıya 'x' denir
  • 'x' 1 değeriyle başlatılmalıdır.

9
Bir lexer "int", "=" ve ";" "x" bir tanımlayıcı adı ya da bir şey, "x" değeri ve "1" bir tamsayı ya da sayı, "1" değeri. Bir belirteç mutlaka bunu yapmaz.
David Thornley

5

Bir lexer ve tokenizatörün temelde aynı şey olduğunu ve metni bileşen parçalarına ('jetonlar') parçaladığını söyleyebilirim. Ayrıştırıcı daha sonra simgeleri bir dilbilgisi kullanarak yorumlar.

Bununla birlikte, kesin terminolojik kullanıma çok fazla asılmayacağım - insanlar genellikle bir metin parçasını yorumlama eylemini tanımlamak için 'ayrıştırma' kullanırlar.


1
PEG ayrıştırıcıları ile tokenizer ve ayrıştırıcı arasındaki fark daha da az açıktır.
Andre Artus

0

( verilen cevaplara ekleme )

  • Tokenizer ayrıca yorumları kaldıracak ve yalnızca jetonları iade edecek Lexer'a .
  • Lexer ayrıca bu belirteçlerin kapsamlarını da tanımlayacaktır (değişkenler / işlevler)
  • Ayrıştırıcı daha sonra kod / program yapısını oluşturur

1
Merhaba @downvoter, neden gerçekten aşağı oy kullandığınızı açıklayabilir misiniz?
Koray Tugay

1
Ben downvoter değilim, ama bence downvote cevabınız doğru görünmüyor olabilir. Bir tokenizer paraziti kaldırabilir (genellikle boşluk ancak belki de yorumlar), ancak genellikle lexer'ı beslemez. DFA tabanlı bir lexer, tokenlerin ne olduğunu (örneğin bir sayı, bir dize, bir tanımlayıcı, aynı zamanda bir boşluk veya yorum) tokenleştirecek ve tanımlayacaktır, ancak daha sonra tarafından oluşturulacak sözdizimi ağacını gerektireceği için bunları kapsamlayamaz. ayrıştırıcı.
Lucero

1) "lexer" ve "tokenizer" arasındaki belirgin farkınızı anlamıyorum. 50+ dil için ayrıştırıcılar oluşturdum ve kaynak metni atomlara ayıran iki ayrı mekanizma olmadı, bu yüzden benim için bunlar sadece eşanlamlı. 2) Derleme yapıyorsanız, yorumlarda ve boşlukların kaldırılması sözlükte anlamlıdır. Kaynaktan kaynağa dönüştürme araçları oluşturuyorsanız, dönüştürülen metinde yeniden görünmeleri gerektiği için yorumları kaybedemezsiniz. Bu yüzden HER ZAMAN yorumları kaldırmak yanlıştır; boşlukları nasıl koruyabileceğini tartışabiliriz. ...
Ira Baxter

1
... [Oluşturduğum araçlar (biyografimi görün) dönüştürülmüş kodda yeniden üretmek için her ikisini de uygun bir şekilde yakalar; daha da ileri gidiyoruz ve karakter dizelerinde kullanılan tırnaklar ve sayılarda sayı tabanı / baştaki sıfır sayımı gibi garip şeyler de dahil olmak üzere atomların biçimini yakaladık , bunların tümü kullanıcının dönüştürülmüş sonucu reddetmesini önlemeye hizmet ediyor. Yani ne cevapsız sadece lexers mutlaka yapmak değildir şerit bilgilerini, ama aslında onlar] ham belirteci üstünde ve ötesinde yakalama bilgilerine gerekebilir. ....
Ira Baxter

... 3) Lexers, sözdizimsel belirsizlikleri ele almakta zorlanan umutsuzca garip ayrıştırıcılarda "kapsamları" tanımlar. C ve C ++ ayrıştırıcıları kanonik örnektir; stackoverflow.com/a/1004737/120163 adresindeki tartışmamı inceleyin ). Kişi bunu (çirkin) şekilde yapmak zorunda değildir. Bu yüzden cevabınızı yanlış yönlendirilmiş buluyorum.
Ira Baxter
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.