Bu ayki yazımızda çok fazla kullanılan BNF gösteriminden bahsedeceğim. BNF gösterimi, genellikle dil tanımlamada ve o dilin söz dizim kurallarını belirtmekte kullanılır. BNF'in iki farklı açılımı vardır: Backus Naur Form ve Backus Normal Form. John Backus'ün ALGOL'un söz dizimini belirtmek için oluşturduğu gösterim Backus Normal Form olarak anılırken, daha sonradan Peter Naur tarafından yapılan değişikliklerin ardından Backus Naur Form ismi kullanılmıştır.

BNF' gösteriminin temeli:
<etiket> ::= __ifade__

Tanımlanan ifade (örnekteki etiket) her zaman ::= işaretinin solunda yer alır. Sağ taraf ise bir veya birden fazla etiketle tanımlanabilir. 'ya da' anlamı için '|' kullanılır.

BNF gösterimini bir dilin söz dizimini göstermede kullanıldığını bildiğimiz için kendisini kendisiyle tanımlamaya çalışırsak:

<BNF>::= <kural> | <kural> <BNF>
<kural>::= <zorunlu-olmayan-boşluk> '<' <kural-adı> <zorunlu-olmayan-boşluk> '::=' <zorunlu-olmayan-boşluk> <ifade>
 <satır-sonu>
<zorunlu-olmayan-boşluk> ::= ' ' <zorunlu-olmayan-boşluk> | '' (boşluk durumu)
<ifade> ::= <liste> | <liste> '|' <ifade>
<satır-sonu> ::= <zorunlu-olmayan-boşluk> <EOL (satır sonu karakteri)> | <satır-sonu> <satır-sonu>
<liste>::= <terim> | <terim> <zorunlu-olmayan-boşluk> <liste>
<terim>::= <sabit> | '<' <kural-adı> '>'
<sabit>::= ' ' ' <metin> ' ' '

Aşağıdaki örnek her zaman kullandığımız sayılar için yazım kuralını anlatıyor:

<sayı> ::= '-' <kayan-noktalı-sayı> | <kayan-noktalı-sayı>
<kayan-noktalı-sayı> ::= <doğal-sayı> | <doğal-sayı> '.' <doğal-sayı>
<doğal-sayı> :: <rakam> | <rakam> <doğal-sayı>
<rakam> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'

En küçük olan birimden başlamak gerekirse rakam 10 tane alternatifi olan bir sabittir. '|' işareti kullanıldığı için sadece bir tanesini seçebiliriz. Doğal sayı rakamdan farklı şekilde özyinelemeyle tanımlanmıştır. Bir doğal sayı rakam olabileceği gibi rakam ve doğal sayının birleşimi olabilir. Örnek olarak 984'ü ele aldığımızda ilk etapta 984'ün rakam olmadığını gördükten sonra 9 ve 84 olarak ayırırız. 9 rakam tanımımıza uyuyor. 84'ün de doğal sayı olup olmadığına bakmamız gerekir bu durumda. 84 de rakam mı diye baktığımızda doğal sayı olabilmesi için <rakam><doğal-sayı> tanımına uyması gerektiğini görürüz. 8 rakamdı ve geriye 4'ün doğal sayı olup olmadığını kontrol etmek kalır, bu da ilk ilk koşulu (<rakam> olma şartı) sağladığı için kontrolümüz hatasız şekilde bitmiştir. <kayan-noktalı-sayı> tanımımız da <doğal-sayı> tanımına çok benzemektedir. Tek farkı ikinci koşulda iki <doğal-sayı>nın arasına '.' sabiti konulmasıdır. Son olarak da <sayı> negatif ya da pozitif <kayan-noktalı-sayı>dır.

BNF gösterimi bir dilin sadece söz dizimsel özellikleriyle ilgilenir. Kullanılan söz diziminin doğru ya da yanlış olduğunu anlamada kullanılsa da anlamsal yanlışlarını fark etmede hiçbir yardımı yoktur. Karşılaşılabilecek başka bir olumsuzluk da tanımların belirsizlik taşımasıdır. Bunu en büyük nedeni de özyinelemelerin belli bir sırada olmamasıdır. Bunu önlemenin yolu da tanımlamada özyinelemenin hep aynı sırada kullanılmasıdır (ya her zaman ifadenin sağ tarafında ya da her zaman solunda kullanılması).

Zamanla BNF gösteriminin ihtiyaçların artmasıyla birçok türevi de oluşmuştur. Örnek olarak orijinalinden farklı olarak birçok türevinde düzenli ifade operatörleri olan + ve * eklenmiştir. EBNF (Extented Backus-Naur Form) ve ABNF (Augmented Backus-Naur Form'dur)dir.

Bu gösterim söz dizimini tanımlamada ve doğrulamada kullanılabilir olduğundan çeşitli derleyicilerde kullanılmaktadır. Kullanılan programlama dilinin söz dizimi BNF gösterimiyle tanımlanmasından sonra derleryiciye verilen girdilerin söz dizimsel hatalarını bulunur. Bunu kullanan önemli yazılımlar:

  • ANTLR (ANother Tool for Language Recognition – PCCTS'nin öncüsü olan dil tanımlayıcı)
  • GOLD (BNF ayrıştırıcısı)
  • YACC (Yet Another Compiler Compiler – bir çeşit derleyici derleyici)
  • GNU bison (YACC'nin GNU versiyonu)

Bu şekilde kullanımını YACC'ın çalışma yapısı üzerinden C derleyicisiyle anlatacak olursak:

Kural olarak her açılan { ve ( lerin olması gerekir. Ayrıca dilin tanımladığı özel anlamları olan anahtar kelimeler vardır. Bunların başka anlamda kullanılmaması gerekir. Örnek verirsek:

{
char char;
char='A';
}

İlk olarak açılan {in eşi son satırda var. Her ifadenin sonunda ; olması da uyulan başka bir kural. Ama C dilinin anahtar kelimelerinden biri olan 'char'ın ilk kullanımı doğru olsa da ikinci ve üçüncü kullanımda değişken adlandırılması yerine kullanılmıştır. Bu kullanım öncede belirtilen BNF gösterimine uymadığı için derleyici hata verecektir.

Bu yazımdan BNF nedir, nasıl ve nerelerde kullanıldığını anlatmaya çalıştım. Faydalı olacağını umarak e-bergi'yle kalmanızı dilerim.

Kaynaklar: