Programlama Dilleri, Normal İfadeler ve Biçimsel Diller Arasındaki İlişki Nedir?


25

Bu sorunun cevabını net olarak araştırdım ve görünüşe göre cevabı benden başka herkes biliyormuş gibi görünüyor. Muhtemelen bunun nedeni, umursayan tek insanın konuyla ilgili yükseköğretim eğitimi almış olmasıdır. Öte yandan, lise ödevi için derinlere atıldım.

Benim sorum şu, biçimsel dillerle ilgili programlama dilleri tam olarak nasıl? Okuduğum her yerde "programlama dillerinin gramerini tanımlamak için biçimsel diller kullanılıyor" satırları boyunca bir şey söyleniyor.

Şimdi, toplayabildiklerime göre, resmi bir dil, belirli bir sembol grubuna (dilin alfabesi) uygulanan bir dizi üretim kuralıdır. Bu üretim kuralları, aşağıdakiler gibi bir dizi dönüşüm tanımlar:

b -> a

aaa->c

Bu, şöyle uygulanabilir:

abab->aaaa aaaa-> ca

Tıpkı bir not olarak, biçimsel dilimizin alfabesini {a, b, c} olarak tanımlarsak, o zaman a ve b, terminal değildir ve c, dönüştürülemeyeceği için terminaldir (lütfen hatalıysam beni düzeltin) ) o.

Bütün bunlar göz önüne alındığında, bu nasıl dünyadaki programlama dilleri için geçerlidir? Genellikle, regex'in dilbilgisinin doğru olduğundan emin olmak için metin biçimindeki bir dili ayrıştırmak için kullanıldığı da belirtilir. Bu mantıklı. Daha sonra regex'in resmi dillerle tanımlandığı belirtiliyor. Regex, regex'i temsil eden sonlu durum otomatının hedef noktaya ulaşıp ulaşmamasına bağlı olarak (en azından benim deneyimime göre) doğru veya yanlış. Görebildiğim kadarıyla, bunun dönüşümlerle hiçbir ilgisi yok *.

Programın kendisini derlemek için, biçimsel bir dilin kodu ardışık olarak daha düşük seviyeli bir koda dönüştürebildiğini ve sonunda donanımın daha sonra anlayabileceği karmaşık bir kurallar kümesi yoluyla derlemeye ulaşabileceğini tahmin ediyorum.

Bu benim kafamdaki bakış açımdan şeyler. Muhtemelen söylediklerimde temelde yanlış olan birçok şey var ve bu yüzden yardım istiyorum.


* (a|b)*b*c->trueBir üretim kuralı gibi bir şey düşünmüyorsanız , bu durumda kural sonlu durumlu bir otomata (yani: regex) gerektirir. Söylediğimiz gibi bu hiçbir anlam ifade etmiyor.


2
Resmi gramerleri resmi dillerle mahfettiniz . Bir gramer dil açıklanır yeniden yazma kuralları kümesidir. Dil, gramer tarafından tanımlanan dizi dizisidir. Dolayısıyla, dilbilgisi normal bir ifadeye bir alternatiftir: bir dili tanımlamanın bir yoludur.
reinierpost

@reinierpost Tamamen haklısın, üniversite ders notlarına baktıktan sonra bu bilgilerin bir kısmını aldım, hatamı görüyorum.
Zwander

Başladığımda kafan karışmıştı. Elbette, gramerler de bir dil oluşturur ve düzenli ifadeler de öyledir. Ancak biçimsel dil kuramı, dillerin sözdiziminin (formunun) nasıl tanımlanabileceğini incelemeye adanmıştır, bu nedenle, genellikle tanımlayan şey için değil, tarif edilenler için 'dil' terimini kullanır.
reinierpost

Yanıtlar:


24

Her kim size düzenli ifadelerin kodu ayrıştırmak için kullanıldığını söyleyen dezenformasyon yayıyordu. Klasik olarak (modern derleyicilerde bunun ne kadar doğru olduğunu bilmiyorum), kod ayrıştırma - kodun metinden bir sözdizimi ağacına dönüştürülmesi - iki aşamadan oluşur:

  1. Sözcük analiz: içine ham metni Süreçleri parçalar gibi anahtar kelimeler , sayısal sabitler , dizeleri , tanımlayıcılar vb vb. Bu, klasik olarak deterministik bir sonlu otomatona (DFA) benzeyen bir çeşit sonlu durum makinesi kullanılarak gerçekleştirilir.

  2. Ayrıştırıcı: Sözcüksel analizden sonra çalıştırın ve ham metni açıklamalı bir sözdizimi ağacına dönüştürür. Programlama dillerinin dilbilgisi (ilk yaklaşıma kadar) bağlamsızdır (aslında bir tane daha katı bir altküme ihtiyaç duyar) ve bu, belirli verimli algoritmaların sözcük kodunu bir sözdizimi ağacında ayrıştırmasını sağlar. Bu, verilen bir dizgenin bazı bağlamsız gramerlere ait olup olmadığını tanıma sorununa benzer , fark da sözdizimi ağacı şeklinde ispat istememizdir .

Programlama dilleri için gramerler bağlamsız gramerler olarak yazılmıştır ve bu gösterim ayrıştırıcı üreticiler tarafından hızlı ayrıştırıcılar oluşturmak için kullanılır. Basit bir örnek, bazı terminal dışı BİLDİRİME ve sonra DURUM IF-STATEMENT' e, kurallarsa, IF-STATEMENT DURDURULMADAN sonra BLOK '' veya 'BLOK' ifadesinin (BLOCK STATEMENT | BLOCK; örnek). Genellikle bu gramerler Backus-Naur formunda (BNF) belirtilir.

Programlama dillerinin gerçek özellikleri bağlamsız değildir. Örneğin, birçok dilde bildirilmemişse bir değişken görünemez ve katı yazmalı diller bir dize değişkenine tam sayı atamanıza izin vermeyebilir. Ayrıştırıcının görevi yalnızca ham kodu işlenmesi kolay bir forma dönüştürmektir.

Ayrıştırma ağacı oluşturmayan özyinelemeli iniş ayrıştırma gibi başka yaklaşımlar olduğunu belirtmeliyim , ancak kodunuzu ayrıştırırken işler. Ağacın üretilmesi zahmet etmemesine rağmen, diğer tüm açılardan yukarıda anlatıldığı gibi çalışır.


Cevabınız için teşekkür ederim, kesinlikle bir kaç şeyi çözdü. Aynı zamanda çok daha fazla soru getirdi. Onları soruma eklemeli miyim, yoksa burada mı sormalıyım?
Zwander

5
@Zwander - aslında, ikisi de değil. Bu sitede, soru başına bir soru yazmanızı istiyoruz. Bir tartışma forumu değil: bir soru-cevap sitesi ve her sorunun ayrı bir konu içinde olmasını istiyoruz. Bu cevap yeni bir soru ortaya çıkarsa, o zaman bu takip sorusunu araştırmak için biraz zaman harcayın ve standart kaynakların hiçbirinde bir cevap bulamazsanız, yeni bir soru gönderin. (Ancak önce standart kaynaklara bakın.)
DW

1
@DW Gotcha, şerefe.
Zwander

3
Bahsettiğiniz iki aşamadan ilki, genellikle normal ifadeler kullanılarak yapılır. Her belirtecin biçimi genellikle normal bir ifade ile verilir. Bu düzenli ifade tek bir DFA'da derlenir, DFA daha sonra gerçek koda uygulanır.
kasperd

2
@Zwander Özyinelemeli iniş ayrıştırma sadece bir ayrıştırma tekniğidir. Ayrıştırma ağacı oluşturabilir veya oluşturmayabilir. Genel olarak, ayrıştırma algoritması, program metnindeki sözdizimi ağacı örtüsünü keşfetmek için hesaplamalı bir strateji geliştirmeye tutar. Bu sözdizimi / ayrıştırma ağacı, derleme stratejisine (aşama sayısı) bağlı olarak işlem sırasında açıklanabilir veya olmayabilir. Yine de gerekli olan, nihayetinde, hesaplama yapısında açık veya kapalı bırakılmak üzere, en azından bir ayrıştırma ağacının aşağıdan yukarıya doğru keşfedilmesidir.
babou

12

Bu bir lise ödevi için bazı ağır şeyler.

Yuval Filmus'un cevabı gerçekten iyi, bu yüzden yaptığı bazı noktaları açıklığa kavuşturmak için ek bir cevap niteliğinde.

Resmi bir dil matematiksel bir yapıdır. Programlama dilleri için kullanımı birçok olası kullanımdan yalnızca biridir; Aslında, dilbilimci Noam Chomsky, biçimsel dillerin ilk teorisine önemli katkılarda bulunmuştur. Chomsky Hiyerarşisini icat ettibiçimsel dilleri düzenli, bağlamsız vb. olarak sınıflandırır. Biçimsel diller, İngilizce gibi doğal dillerin sözdizimini tanımlamak için dilbilimde de uygulanır. Gerçek sayılar gibi düşünün: gerçek sayıları hem Los Angeles'tan New York'a olan mesafe gibi somut şeyleri hem de bir dairenin çevresinin çapına oranı gibi soyut şeyleri tanımlamak için kullanabiliriz. Her iki şeyin de gerçek sayılardan bağımsız olarak bulunmasına rağmen, gerçek sayılar onları tanımlamak için yararlı bir sistemdir. Biçimsel diller hem İngilizce'yi hem de Python'u tanımlamak için yararlı bir sistemdir, çünkü her ikisi de benzer bir yapılandırılmış formata sahiptir.

Biçimsel diller sadece sembollerin manipülasyonudur; sembollerin ne anlama geldiği hakkında hiçbir şey söylemiyorlar. gibi bir cebir problemini düşünün . Bu denklemin içsel bir anlamı yoktur, ancak sembolleri cebir kurallarına göre hala değiştirebiliriz; örneğin, sembollerin ne anlama geldiği hakkında hiçbir fikrimiz olmasa da, bunu olarak yeniden yazabiliriz . Bir sistem içindeki sembollere anlam vermenin bir yolu anlambilim olarak adlandırılır (hem doğal hem de programlama dilinde). Böylece , , ve dolar olarak değerlendirebiliriz, ve sonra denklemin anlamı vardır.a + b = d - c a b ca+b+c=da+b=dcabc

Klasik olarak, bir programlama dili iki dilbilgisine sahip olacaktır: sözcüksel dilbilgisi ve sözdizimsel dilbilgisi. Sözlüksel dilbilgisi harf, noktalı virgül, ayraç ve parantez gibi karakterlerle ilgilidir. Bu genellikle normal bir dilbilgisidir, bu nedenle düzenli ifadelerle veya bir DFA veya NFA ile ifade edilebilir. (Resmi dil teorisinde, üçünün iktidarda eşdeğer olduğunu gösteren kanıtlar vardır - yani aynı dil grubunu kabul ederler.) Dilbilgisi kurallarını okur ve bu kurallara uyarak, bireysel karakterleri belirteçlere toplar. Örneğin, dilin ifC'lere benzeyen bir ifadeye sahip olması durumunda, sözcü karakterleri ive ftek simgeyi toplayabilirIFdaha sonra bir açılış parantezi arayın ve bir token çıktılayın OPEN_PAREN, ardından parantezler arasındakileri kullanın ve ardından parantez içindeki parantezleri bulun ve a CLOSE_PAREN. Dilekçi belirteçleri hazırladığında, belirteçlerin gerçekte programlama dilinin geçerli ifadelerini oluşturup oluşturmadığını belirleyen ayrıştırıcıya verir. Yani ip a == bPython'da yazarsanız , ne tür bir jeton ipolduğunu tahmin etmek için elinden gelenin en iyisini yapar (büyük olasılıkla çoğu kişi tarafından bir tanımlayıcı için alınacaktır) ve bunu, ayrıştırıcıya iletir; tanımlayıcı bu konumda.

Ayrıştırıcı, genellikle bağlamsız olan sözdizimsel dilbilgisini uygular, ancak Yuval'ın cevabından bahsedildiği gibi, günümüzde çoğu programlama dili, aslında ayrıştırmayı daha basit ve daha verimli hale getirmek için bağlam içermeyen dilbilgilerinin tam yeteneklerini kullanmamaktadır. İşte Python'un sözde dilbilgisi , bir OP . Java dili spesifikasyonu ayrıca Java'nın sözcük ve sözdizim gramerlerin örnekler vardır.ab

Python'un ififadesi için gramer kurallarına bakalım . Kural budur:

if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]

Bu kural bize, çözümleyiciden gönderilen bir belirteç dizisinin bir durum ifbelirtici olup olmadığını nasıl çözeceğini söyler. Tek tırnak içindeki herhangi bir kelimenin kaynak kodda olduğu gibi görünmesi gerekir, böylece ayrıştırıcı düz kelimeyi arar if. Ayrıştırıcı daha sonra bazı belirteçleri kuralla eşleştirmeye çalışır test:

test: or_test ['if' or_test 'else' test] | lambdef

testgramerdeki diğer kurallar açısından tanımlanır. testKendisinin tanımında nasıl yer aldığına dikkat edin ; buna özyinelemeli bir tanım denir. Normal dillerin sahip olmadığı bağlamsız dillerin büyük gücüdür ve dil sözdizimini programlama için iç içe döngüler gibi şeylerin tanımlanmasına izin verir.

Ayrıştırıcı bazı belirteçlerle eşleşmeyi başarırsa test, iki nokta üst üste eşlemeye çalışır. Bu başarılı olursa, kuralını kullanarak bazı belirteçlerle eşleşmeye çalışır suite. Bu bölüm ('elif' test ':' suite)*, edebi metnin herhangi bir sayıda tekrarına sahip olabileceğimiz anlamına gelir; bunu elifeşleşen test, ardından iki nokta üst üste, ardından eşleşen bir şey izler suite. Ayrıca sıfır tekrar yapabiliriz; sonunda yıldız işareti "sıfır veya istediğimiz kadar" anlamına gelir.

En sonunda ['else' ':' suite]. Bu kısım köşeli parantez içine alınmış; Bu, sıfır veya bir olabilir, ancak daha fazla olabilir anlamına gelir. Bunu eşleştirmek için, ayrıştırıcının hazır bilgi metni else, iki nokta üst üste ve ardından a ile eşleşmesi gerekir suite. İşte bir kural suite:

suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT

Temelde C benzeri dillerde bir blok. Python, lexer çıkışları ortalama şeylere yeni satır ve girinti kullandığından NEWLINE, INDENTve DEDENTkod başladı başlatılan yeni bir satır, girintili edilecek ayrıştırıcı anlatmak için belirteçleri ve girinti dış seviyesine döndü nerede.

Bu eşleşme denemelerinden herhangi biri başarısız olursa, çözümleyici bir hatayı işaretler ve durur. Tüm programın ayrıştırılması başarılı olursa, ayrıştırıcı genellikle cevabında Yuval'ın olduğu gibi bir ayrıştırma ağacı ve muhtemelen bir semantik bilgi depolayan bir sembol tablosu ve diğer veri yapıları yapacaktır. Dil statik olarak yazılırsa, derleyici ayrıştırma ağacında yürüyecek ve yazım hatalarını arayacaktır. Ayrıca, ayrıştırma ağacında, alt düzey kod (derleme dili, Java bayt kodu, .Net Orta Dil veya benzer bir şey) oluşturmak için yürür.

Bir alıştırma olarak, aşina olduğunuz bazı programlama dillerinin gramerini almanızı öneririm (yine Python , Java ve işte C # , Javascript , C ) ve belki x = a + b;veya gibi basit bir şeyi elden çıkarmaya çalışın if (True): print("Yay!"). Daha basit bir şey arıyorsanız , temel olarak Javascript'teki nesne değişmezleri sözdizimini kapsayan JSON için hoş bir gramer de var {'a': 1, 'b': 2}. İyi şanslar, bu beyin bükme olayı ama çılgın bir son tarihte olmadığınızda gerçekten ilginç olduğu ortaya çıkıyor.


Buraya "teşekkür" yazmamam gerektiğini biliyorum, ancak tüm bunları açıklamak için zaman ayırdığın için şerefe. “Bu bir lise ödevi için bazı ağır şeyler.” Ödevin amacı, üste göz atmak ve düzenli ifadelerden bahsetmektir, ama hevesli bir bilgisayar bilimi öğrencisi olarak, bütün resmi görmek istedim. Bütün konu büyüleyici.
Zwander

1
@Zwander Kolejden yeni mezun oldum ve seçmeli derslerimin çoğu böyle oldu. Kafamın tamamen karıştığını ve tamamen emildiğini hatırlıyorum. Olabilir de belirtilen derleyici tasarımı kağıtları gibi bu blog veya kitap Hesaplama Teorisine Giriş Michael Sipser tarafından, ve John C. Martin, Dillerine Giriş ve Hesaplama Teorisi . Kullanılmış ucuz kopyaları Amazon'da bulabilirsiniz. Her ikisi de biçimsel dil teorisini alacağı kadar basit hale getiriyor.
tsleyson

10

Kısaca

Programlama dilleri, programı karakter dizileri olarak temsil eden bir sözdiziminden ve programın amaçlanan anlamı olan bir anlambiliminden oluşur.

Biçimsel diller anlamsız sözdizimidir. Bu dizgelere genellikle anlam ifade etmeden, resmen tanımlanmış dizgilerin kümelerinin yapısının incelenmesi amaçlanmaktadır.

Düzenli ifade ve diğer formaliteler (Bağlamsız Gramerler gibi), programlama dillerini ve doğal dillerin sözdizimsel bileşeni olarak kullanılan örgün dilleri tanımlamak, yani cümleleri yapılandırılmış bir şekilde göstermek için kullanılır. Bu yapıyı programlama dillerinin anlamlarıyla ilişkilendirmek için başka mekanizmalar kullanılır.

Buradakilerin çoğu, özellikle doğal dil konusunda oldukça basitleştirilmiştir.

Çok daha fazla ayrıntı ile

Sorunuzu cevaplamak için baştan başlamalıyız. Alışılmış anlamda bir dil, gayrı resmi olarak bilgi ya da fikir iletme aracıdır. Bir dilde, genellikle sözdizimi ile anlambilim arasında ayrım yapılır. Anlambilim, hakkında konuşmak / yazmak istediğiniz şeydir. iletmek istediğiniz bilgiyi Sözdizimi, onu iletmek için kullandığınız, yani insanlar arasında ve şimdi insanlar ve cihazlar arasında veya cihazlar (bilgisayarlar) arasında değiştirilebilecek geleneksel bir temsildir.

Genellikle, dogbir köpeğin fikrini iletmek için bu sözcüğü kullanırsınız. Kelime dog, üç harften veya bazı eşdeğer seslerden oluşur ve bir tür hayvanın temsili olması amaçlanmıştır. Anahtar fikir, iletişimin neyin iletileceğinin temsili ile yapılmasıdır. Temsilcilik yapılarına genellikle sözdizimi, temsil edilenlere semantik denir. Bu, doğal dilin yanı sıra programlama dilleri için aşağı yukarı gider.

Kelimeler az ya da çok temel anlamsal kavramları temsil eden sözdizimsel varlıklardır. Ancak bu temel kavramların daha karmaşık bir anlam vermek için çeşitli şekillerde bir araya getirilmesi gerekir. the dogBelirli bir köpeği kastettiğimizi the dog bites the catiletmek ve daha karmaşık bir fikir iletmek için yazıyoruz . Ancak kelimelerin düzenlenme şekli kurallarla sabitlenmelidir, böylece köpeğin ve kedinin hangisinin diğerini ısırdığını söyleyebiliriz.

Öyleyse sentence -> subject verb complement, cümlelerle eşleşmesi ve bize her bölümle ilgili fikirlerin nasıl ifade edildiğini söylemesi gibi kurallarımız var . Bu kurallar sözdizimsel kurallardır, çünkü bize mesajımızın temsilinin nasıl organize edileceğini söylerler. subjectKendisi bir kural tanımlanabilir subject -> article nounvb, vb.

Aynısı matematikte de geçerlidir. Çok resmi bir sözdizimi ile yazılmış matematiksel ifadeniz var. ve ifadenin anlamı, sözdizimsel yapı analiz edilerek elde edilebilir. Örneğin , bağlama bağlı olarak , iki katını alırsanız ve eklerseniz , aynı olması gerektiğini belirten bir denklem olarak okunabilir . Kurallardan bazıları: x 1 232x+1=23x123

equation -> expression "=" expression  
expression -> expression "+" expression 
expression -> number

Programlama dillerinin yapısı aynıdır. Programlama dilleri, çözülmesi gereken problemleri, teoremlerin kanıtını veya hayvan arasındaki dostane ilişkileri ifade etmek yerine, yapılacak hesaplamaları ifade etmede anlamsal olarak uzmanlaşmıştır. Ancak bu ana farktır.

Sözdiziminde kullanılan gösterimler genellikle karakter dizeleri veya sözlü diller için kullanılan seslerdir. Anlambilim genellikle soyut alana veya muhtemelen gerçeğe aittir, ancak düşünce süreçlerimizde veya cihazların davranışsal alanında hala soyutlanır. İletişim, bilgiyi / fikri, alıcı tarafından iletilen ve kodunu çözen sözdizimine kodlamayı gerektirir. Sonuçta alıcı tarafından ne şekilde olursa olsun yorumlanır.

Yani dilin gördüğümüz çoğunlukla sözdizimi ve yapısı. Yukarıdaki örnek, sözdizimsel dizeleri ve yapısal organizasyonlarını tanımlamanın en yaygın yollarından sadece bir tanesidir. Diğerleri var. Belirli bir dil için, bazı dizgilere bir yapı atanabilir ve diğerleri diline ait olmadığı söylenir.

Aynısı kelimeler için de geçerlidir. Bazı harf dizileri (veya ses) meşru kelimelerdir, diğerleri değildir.

Biçimsel diller anlambilimsiz sadece sözdizimidir. Bir alfabenin temel öğelerini kullanarak hangi dizilerin oluşturulabileceğini bir kural kümesi ile tanımlarlar. Kuralların neler olduğu, bazen karmaşık, çok değişken olabilir. Ancak biçimsel diller, programlama dilleri için doğal olsun olmasa da, dilsel iletişimin ötesinde birçok matematiksel amaç için kullanılır. Dizeleri bir dilde tanımlayan kural kümesine dilbilgisi denir. Ancak dilleri tanımlamanın başka bir yolu var.

Uygulamada, bir dil iki düzeyde yapılandırılmıştır. Sözlüksel seviye, bir karakter alfabesinden oluşturulmuş kelimeleri tanımlar. Sözdizimsel seviye, bir sözcük alfabesinden (veya daha kesin olarak sözcük ailelerinin, yani sonlu bir alfabe olarak kalması için) oluşturulan cümleleri veya programları tanımlar. Bu mutlaka bir şekilde basitleştirilmiştir.

Kelimelerin yapısı çoğu dilde (programlama veya doğal) oldukça basittir, bu nedenle genellikle genellikle en basit biçimsel dil olan şeyle tanımlanırlar: normal diller. Düzenli ifadelerle (regexp) tanımlanabilirler ve sonlu durum otomatları adı verilen programlanmış cihazlarla kolayca tanımlanabilirler. Programlama dillerinin durumlarda, bir kelimenin örnekler bir tanımlayıcı, bir tamsayı, dize, gerçek sayı, ayrılmış bir sözcük gibi olan if ya da repeatbir noktalama sembol veya açık parantez. Word familyası örnekleri tanımlayıcı, string, integer.

Sözdizimsel seviye genellikle biraz daha karmaşık bir biçimsel dil dili tarafından tanımlanır: bağlamsız diller, sözcükleri alfabe olarak kullanır. Yukarıda gördüğümüz kurallar, doğal dil için bağlamsız kurallardır. Programlama dilleri durumunda kurallar şunlar olabilir:

statement -> assignment
statement -> loop
loop ->  "while" expression "do" statement
assignment -> "identifier" "=" expression
expression -> "identifier"
expression -> "integer"
expression -> expression "operator" expression

Bu tür kurallarla yazabilirsiniz:

while aaa /= bbb do aaa = aaa + bbb / 6 Bu bir ifadedir.

Ve üretilme şekli, ayrıştırma ağacı ya da sözdizimi ağacı olarak adlandırılan bir ağaç yapısıyla temsil edilebilir (burada tamamlanmadı):

                          statement
                              |
            _______________  loop _______________
           /      /                 \            \
      "while" expression           "do"       statement
       __________|_________                       |
      /          |         \                  assignment
 expression "operator" expression          _______|_______
     |           |          |             /       |       \
"identifier"   "/="   "identifier" "identifier"  "="   expression
     |                      |            |                 |
    aaa                    bbb          aaa             ... ...

Bir kuralın solunda görünen isimlere terminal olmayanlar, kelimeler ise dil alfabesinde olduğu gibi (sözlük seviyesinin üzerinde) terminaller olarak da adlandırılır. Terminal olmayan bir programı oluşturmak için kullanılabilecek farklı sözdizimsel yapıları temsil eder.

Bu tür kurallara bağlamsız denir, çünkü terminal olmayan, göründüğü bağlamdan bağımsız olarak ilgili kurallardan herhangi biri kullanılarak keyfi bir şekilde değiştirilebilir. Dili tanımlayan kurallara bağlamsız dilbilgisi denir.

Aslında, tanımlayıcıların ilk kez bildirilmesi gerektiğinde veya bir ifadenin tür kısıtlamalarını sağlaması gerektiğinde bununla ilgili kısıtlamalar vardır. Ancak bu kısıtlama sözdizimsel olmaktan ziyade anlamsal olarak düşünülebilir. Aslında bazı profesyoneller onları statik anlambilim dedikleri şeye yerleştirir .

Herhangi bir cümleye, herhangi bir program göz önüne alındığında, cümlenin ağacı tarafından verilen yapı analiz edilerek bu cümlenin anlamı çıkarılır. Bu nedenle, program verildiğinde, bir programa karşılık gelen ağaç yapısını kurtarabilecek ayrıştırıcılar adı verilen algoritmalar geliştirmek çok önemlidir.

Ayrıştırıcı, sözcükleri tanıyan ve ait oldukları aileyi belirleyen sözcüksel analizörden önce gelir. Ardından, kelimelerin veya sözcüksel öğelerin sırası, alttaki ağaç yapısını alan ayrıştırıcıya verilir. Bu yapıdan derleyici daha sonra programın anlamsal bölümünün derleyici tarafında işlem yaptığı kodun nasıl oluşturulacağını belirleyebilir.

Bir derleyicinin ayrıştırıcısı, aslında, ayrıştırma ağacına karşılık gelen bir veri yapısı oluşturabilir ve bunu derleme işleminin sonraki aşamalarına geçirebilir, ancak buna gerek yoktur. Ayrıştırma algoritması miktarını, program metninde örtülü olan sözdizimi ağacını keşfetmek için hesaplamalı bir strateji geliştirmek üzere çalıştırmak. Bu sözdizimi / ayrıştırma ağacı, derleme stratejisine (aşama sayısı) bağlı olarak süreçte açıklanabilir veya olmayabilir. Yine de gerekli olan, nihayetinde, hesaplama yapısında açık veya kapalı bırakılmak üzere, en azından bir ayrıştırma ağacının aşağıdan yukarıya doğru keşfedilmesidir.

Bunun nedeni, sezgisel olarak, sözdizimsel bir ağaç yapısına ilişkin anlambilimi tanımlamanın standart bir biçimsel yolunun, homomorfizm denilen şeydir. Büyük kelimeden korkma. Buradaki fikir yalnızca bütünün anlamını göz önünde bulundurmak, onları birbirine bağlayan operatöre dayanarak, parçaların anlamından yapılmıştır.

Örneğin, cümle the dog bites the catkural ile analiz edilebilir sentence -> subject verb complement. Bilerek 3 alt ağaçlar anlam subject, verbve complementonları özne eylemi yaptığını ve kedi Isırılan biri olduğunu söyler taneciklerini, kural.

Bu sadece sezgisel bir açıklamadır, ancak resmileştirilebilir. Anlambilim, seçmenlerden yukarı doğru kurulur. Ancak bu çok karmaşıklığı gizler.

Bir derleyicinin dahili çalışması birkaç aşamada ayrıştırılabilir. Asıl derleyici, ara gösterimleri kullanarak aşama aşama çalışabilir. Ayrıca bazı aşamaları birleştirebilir. Bu, kullanılan teknolojiye ve eldeki dili derlemenin karmaşıklığına bağlıdır.


Harika, çok faydalı. Düzenleme işleminde regex'in kullanıldığını anlıyorum (örneğin bir dize değişmezi "[^"]*"en basit şekliyle kaçış karakterlerini yok sayarak vb. Sonlu bir durum otomatı olduğu gibi, sonlu olarak tanımlamıyorum. Bir sözdizimi ağacı, tek bir ififade için bile , yuvalama nedeniyle teorik olarak sonsuz olabilir. Bu nedenle, regex, sonlu bir durum otomatı olmak, bir sözdizimi ağacı oluşturmak amacıyla kullanılamaz.
Zwander

@Zwander thx 4 düzenleme - Düzenli ifade örneğiniz doğrudur (bazı örnekler vermeliydim). BTW, Regex ayrıca, dizi kümeleri dünyasında kendi semantiğine ve İçerik İçermeyen ( CF ) bir sözdizimine sahip bir dildir . Genişletilmiş BNF'de (EBNF) kısa el hariç, sadece dize dizgisinin belirtilmesi için, en azından programlama dilleri için, genellikle sözdizimi ağaçları için kullanılan daha büyük sözdizimi tanımlanmasında kullanılmaz. Regex'i bir biçimde daha karmaşık formalitelere eklemek, çoğu durumda ifade gücünü değiştirmez. Sonsuzlukla ilgili düşünceleriniz tam olarak doğru değil. Bir sonraki yoruma bakınız.
babou

@Zwander Tüm formaliteler (biçimsel diller) son derece açıklanmıştır. Bu temel bir hipotezdir. Sınırsız sayıda kuralla CF dilbilgisi ile ilgileniyor olsanız bile, kuralların sonsuzluğunun sınırlı bir tanımını yapmalısınız. Ayrıca sonsuzluk sana numaralar oynar (bunun için yer yok). Bir ififade sınırsız (keyfi olarak büyük), ancak her zaman sonlu. Bir sonlu tanımlanan sonsuz ifa, while. CF ve normal arasındaki fark, CF'nin düzenli değilken yuvalamayı kontrol etmesine / izin vermesine (yani parantezlenmeye) izin vermesidir. Ancak her ikisi de sonlu şekilde tanımlanmıştır ve sınırlanmamış dizgilere izin vermektedir.
babou

1
@Zwander Formalism, iyi biçimlendirilmiş herhangi bir cümleyi (program) temsil edebilmelidir, ancak sadece iyi biçimlendirilmiş cümleleri temsil edebilmelidir . Basitçe söylemek gerekirse, ÖSO sınırsız sayılmaz. Böylece, kapatılması gereken kaç parantezin açıldığını veya iki farklı parantez türünü düzgün şekilde yuvalayamadıklarını bilemezler. Birçok dilsel yapı "gizli" parantez içindedir. Bu sadece bir sözdizimi kontrolü meselesi değildir, fakat esas olarak anlam ağacı türetmek için uygun ağaç yapısının ifade edilemediği ve inşa edilemediği anlamına gelir. Yeterli ağaç yapısının kurtarılması saymanın yapılmasını gerektirir.
babou

1
@Zwander Daha sonra sizin için yararlı olabilecek bir söz, ağaçların parantez kullanarak sicim şeklinde doğrusallaştırılabileceğidir. Her operatörün uygun alt ağacı (alt ifadeyi) aldığından emin olmak için gibi bir aritmetik ifadeyi tamamen parantezlerken yaptığınız şey genellikle budur . Pashdown yığınları (pushdown otomata bakınız), bağlamsız diller ve ağaçlar arasında yakın bir ilişki vardır. (((AB)+3)×C)
babou

2

Önemli farklılıklar var. Bunların arasında şef, gerçek programlama dillerini ayrıştırmanın, sözdizimi hatalarını ele almakla ilgili olduğunu söyleyebilirim. Resmi bir dille, "dilde iyi değil" diyeceksiniz, ancak bunun çok kullanışlı olmadığını söyleyen bir derleyici - size neyin yanlış olduğunu söylemeli ve küçük bir hata olsaydı, ideal olarak ayrıştırmaya devam etsin. daha fazla hata bildirin. Çok fazla araştırma (ve uygulama çabası) buna giriyor. Bu yüzden gerçekten doğru / yanlış sonucu umursamıyor bile, sadece girdi yapısını analiz etmek istiyorsun. Resmi diller orada bir araç olarak kullanılıyor ve çok fazla örtüşme var, ancak gerçekten farklı bir sorunu çözüyorsunuz.

Ayrıca, çoğu dilde, gramerdeki bazı şeyleri zorlamamak için seçilmiştir , örneğin, bahsettiğiniz örnekte, "bildirilmemişse bir değişken görünemez". Bu genellikle çözümleyici tarafından tamamen göz ardı edilebilecek bir şeydir ve daha sonra bu tür bir şeye bakan ve bağlam-inceliği gibi düşüncelerden etkilenmeyen ayrı bir analizde (anlamsal analiz) yakalanır. Ancak her zaman değil - örneğin C'yi ayrıştırmak için , lexer hack sık kullanılır ve C ++ aynı anda bazı ciddi semantik analizler yapmadan ayrıştırılamayan bir dilin örneğidir (aslında C ++ ayrıştırma işlemi kararsızdır, çünkü şablonlar tamamlanıyor. ). Daha basit dillerde, bölünme eğilimindedir, bu şekilde daha kolaydır.


1

Biçimsel dil bir kelime kümesidir - bir kelime bazı alfabelerden oluşan bir simgeler dizisidir.

Bu, üretim kurallarını ve biçimsel dili birleştirmenizin çok güçlü olduğu anlamına gelir. Resmi dilin üretim kuralları olduğu doğru değil. Aksine, üretim kuralları biçimsel dili tanımlar. Biçim dili, üretim kuralı tarafından üretilebilecek kelimelerdir. (Bu biçimsel dilin üretim kuralları tarafından tanımlanabilecek türden olmasını gerektirir; örneğin, normal diller bağlamsız bir gramer ile tanımlanabilir)

Dolayısıyla, ifadeye karşılık gelen normal dil (a|b)*c*d, üretim kuralları tarafından tanımlanır;

S->ACd
A->
A->aA
A->bA
C->
C->cC

Bu üretim kurallarının S başlangıç ​​sembolünden ürettiği kelimeler, tam olarak normal ifadenin kabul ettiği karakter dizileridir.


0

Düzenli ifadeler ile anlam dilleriyle ilgili olan programlama dilleri arasında başka bir ilişki daha vardır. Bir zorunlu dilin temel kontrol yapıları sıralı kompozisyon (A ve sonra B'yi yapın), seçim (A veya B'yi yapın) ve tekrarlamadır (A'yı tekrar tekrar yapın).

Davranışları birleştirmenin aynı üç yolu düzenli ifadelerde bulunur. Alt rutin çağrıları atın ve EBNF'ye benzetin.

Dolayısıyla, düzenli ifadelerin cebiri ile komutların cebiri arasında çok fazla benzerlik vardır. Bu, "Üç Calculi'nin Birleşmesi" nde Dijkstra tarafından ayrıntılı olarak incelenmiştir. Aynı zamanda, soruya bir cevap veren Milner CCS'nin de temelidir: Ya paralellik eklersek?

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.