Agar suatu bahasa dapat diprogram, apakah wajib didasarkan pada tata bahasa bebas konteks

23

Secara praktis, untuk bahasa yang pada akhirnya dapat dikompilasi / diubah menjadi instruksi tingkat sistem, apakah perlu bahwa itu adalah tata bahasa bebas konteks?

mis: Apakah semua bahasa pemrograman / scripting konteks tata bahasa gratis? Java didasarkan pada CFG, tetapi apakah sebenarnya semua bahasa pemrograman didasarkan pada CFG?

Tampaknya tidak wajib, tetapi ada kesenjangan dalam pemahaman saya.

Beberapa konteks untuk pertanyaan: Saya melihat spesifikasi bahasa Jawa, yang juga menyediakan aturan tata bahasa . Ini membuat saya berpikir tentang pertanyaan ini.

sandeepkunkunuru
sumber
1
Secara umum saya pikir itu hanya bahwa Anda ingin masalah kompilasi dapat dihitung, dan parsing CFG bagus dan mudah. Meskipun saya telah mendengar beberapa klaim bahwa, misalnya, mengenali program perl yang valid sebenarnya merupakan masalah yang tidak dapat dihitung.
Janne H. Korhonen
2
sebenarnya yang Anda butuhkan hanyalah sintaks turing-decidable (yang semua CFGnya). Anda juga bisa membuat bahasa pemrograman yang sintaksnya tidak dapat didekati, tetapi ketika Anda membuat kesalahan ketik, kompiler mungkin tidak akan pernah berhenti saat sedang mencoba memutuskan apakah itu sintaks yang valid. ini tidak terlalu berguna
ratchet freak
@ scratchet, apakah Anda mengasumsikan sintaks harus berulang secara berulang?
David Harris
4
@JanneKorhonen: Secara khusus, Perl tidak dapat diuraikan secara statis , yaitu, tidak dapat diuraikan tanpa juga dieksekusi; karena eksekusi tersebut bisa non-terminating, parsing Perl secara statis akan menyiratkan penyelesaian Masalah Pemutusan Hubungan.
Jon Purdy
@janne Maksudku, pasca-pemrosesan yang mungkin memerlukan masalah yang mungkin atau mungkin tidak dapat dihitung, apakah pada umumnya kasus bahwa tata bahasa terakhir yang menjadi dasar program divalidasi bebas konteks. Untuk lebih spesifik, pasca pemrosesan, untuk mengidentifikasi aturan yang sesuai dengan urutan token, kita perlu melihat token lain di sekitar urutan. Saya tidak tahu apakah saya masuk akal, maaf tentang itu. Sebenarnya saya agak bingung.
sandeepkunkunuru

Jawaban:

20

Dua kali tidak.

Pertama, sebagian besar HPL tidak bebas konteks. Walaupun mereka biasanya memiliki sintaksis berdasarkan CFG, mereka juga memiliki apa yang disebut orang dengan semantik statis (yang juga sering dimasukkan dalam sintaksis istilah). Ini dapat mencakup nama dan tipe yang harus memeriksa program yang benar. Contohnya,

class A {
  String a = "a";
  int b = a + d;
}

adalah program Java yang secara sintaksis benar tetapi tidak akan dikompilasi karena dtidak didefinisikan dan atidak memiliki tipe pemasangan.

Kedua, Anda dapat mem - parsing bahasa yang tidak bebas konteks (seperti yang jelas dibuktikan dengan keberadaan kompiler). Hanya CFG yang dapat diurai secara efisien, sedangkan CSG tidak bisa, secara umum. Namun, Anda dapat menambahkan fitur-fitur non-konteks-bebas tertentu sambil tetap efisien.

Compiler sering dijalankan dalam fase: tokenization pertama (reguler), kemudian parsing bebas konteks, kemudian analisis nama dan tipe (peka konteks, kadang-kadang bahkan lebih sulit). Anda dapat mengamati perilaku itu dengan jenis pesan kesalahan yang Anda dapatkan.

Raphael
sumber
3
Jangan lupa public class Program { public static void main(String[] args) { ... } }... Java tidak akan membiarkan Anda turun semudah itu. :-)
Roy Tinker
Secara teknis, class A { ... }benar-benar cukup sebagai javackompilasi hal-hal yang Anda tidak dapat benar-benar mengeksekusi (karena tidak ada titik masuk), juga. Tapi ya
Raphael
20

Parsing perl tidak dapat ditentukan.

http://www.jeffreykegler.com/Home/perl-and-undecidability/perl-and-undecidability-files/TPR3.pdf?attredirects=0

http://www.perlmonks.org/?node_id=663393

Niall Murphy
sumber
6
Saya merasa ini harus menjadi lucunya lelucon Perl
Suresh Venkat
5
Suresh: Saya sudah membuat lelucon itu, meskipun itu tidak menjadi lelucon yang sangat baik, di koran "Tentang bahasa pemrograman yang tidak fleksibel" di SIGBOVIK 2011 ( sigbovik.org/2011/proceedings.pdf - halaman 79- 82).
Rob Simmons
1
Catatan: penerjemah Perl belum non-deterministik, jika itu kenyamanan bagi siapa pun :)
Roy Tinker
15

Saya tidak percaya bahwa tata bahasa Python bebas konteks. Persyaratan bahwa baris dalam blok kode yang sama memiliki jumlah indentasi yang sama bukanlah hal yang dapat ditangani dengan baik oleh tata bahasa bebas konteks.

Lebih tepatnya, tampaknya ada homomorfisme dari bahasa Python blok formulir

jika kondisi:
     line1
     line2
     line3
lain:
     line4

ke bahasa bebas-konteks mana blok nol pertama berasal dari set spasi di awal line1, blok kedua datang set spasi di awal line2, blok ketiga berasal dari himpunan ruang pada awal line3, dan baris yang tersisa dengan yang lain dll ada untuk memaksa line1, line2, dan line3 menjadi milik blok yang sama.0n10n10n

David Eppstein
sumber
4
Sebenarnya Anda benar, tetapi dalam konteks bahasa pemrograman kami mencoba membuat bahasa bebas konteks yang dihasilkan setelah langkah preprocessing yang disebut tokenization . Saya pikir lekukan diperiksa sebelum itu.
Diego de Estrada
7
Ya, Python lexer (tokenizer) memiliki setumpuk kedalaman indentasi; token stream memiliki simbol INDENT di awal setiap blok dan simbol DEDENT di akhir yang dapat diuraikan dalam konteks cara bebas (INDENT dan DEDENT bertindak seperti kawat gigi di C). C memiliki masalah "tidak tahu apakah deklarasi atau ekspresi": apakah foo * bar;deklarasi foosebagai penunjuk ke baratau penggandaan fookali bar?
Maks.
8
Ok, tentu, tapi kemudian Anda hanya menyembunyikan kompleksitas yang sama di lexer, daripada menjadikannya transduser keadaan terbatas seperti yang sering terjadi.
David Eppstein
1
@ Davidvidpstein: Agar adil, kata kompleksitas tidak bagus dengan cara apa pun.
Jon Purdy
1
Terlepas dari penanganan INDENT / DEDENT di lexer, Python memiliki tata bahasa LL (1) yang sangat sederhana.
rmmh
13

Bodo Manthey dan Martin Böhme menunjukkan bahwa setiap C ++ Compiler adalah Turing yang lengkap, yaitu, ia dapat menghitung fungsi rekursif parsial pada waktu kompilasi . Jadi itu jauh lebih buruk daripada hanya peka konteks.

http://wwwhome.math.utwente.nl/~mantheyb/journals/BotEATCS_BoehmeManthey_CompilingCPP.pdf

Markus Bläser
sumber
Ya, tetapi kompiler tidak pernah hanya tata bahasa bebas konteks. Anda harus mendiskusikan tata bahasa itu sendiri, bukan kompilernya.
Jeff Burdges
@ Jeff: "Waktu kompilasi" dalam jawaban saya berarti "memeriksa apakah kode sumber C + yang diberikan sudah benar". Dengan sedikit modifikasi konstruksi dalam makalah, berarti Anda dapat mengurangi setiap bahasa yang dapat dipilih ke set semua program C ++ yang benar.
Markus Bläser
7

Saya pikir deklarasi sebelum penggunaan variabel dan polimorfisme fungsi dari bahasa OOP adalah contoh lain dari spesifikasi bahasa pemrograman yang tidak dapat ditangani oleh tata bahasa bebas konteks:

int myfun(int a) { ... }
int myfun(int a, int b) { ... }
int myfun(int a, int b, int c, ...) { ... }
...
int I_m_I_cfg = myfun(1,2);
...

Saya membuat sedikit pencarian Google dan saya menemukan artikel ini: " Tata Bahasa Boolean untuk Bahasa Boolean Sederhana " oleh A.Okhotin (2004); menurutnya, masalah sebenarnya adalah menemukan bahasa pemrograman yang sepenuhnya dijelaskan oleh tata bahasa formal:

Bahasa pemrograman prosedural mainan didefinisikan, dan tata bahasa Boolean untuk sekumpulan program yang terbentuk dengan baik dalam bahasa ini dibangun. Ini rupanya spesifikasi pertama dari bahasa pemrograman sepenuhnya oleh tata bahasa formal.

Bagian Pendahuluan dari artikel ini singkat tetapi sangat menjelaskan.

Marzio De Biasi
sumber
6

Saya percaya bahwa tata bahasa C hanya bebas konteks teknis karena parser selalu menggunakan teknik bebas konteks untuk mendukung perangkat Duff .

Bahasa berbasis indentasi juga tidak bebas konteks seperti yang dikatakan David, tetapi mereka menjadi bebas konteks dibandingkan dengan token indentasi parameter.

Haskell memungkinkan Anda mengubah prioritas operator dengan infix dan infixl. Modul pragma ketat Perl diimplementasikan menggunakan pengaturan leksikal $ ^ H dan% ^ H, yang membuatnya tidak bebas konteks, mungkin juga pengaturan lain.

Ada bahasa expander makro seperti TeX di mana afaik parsing tidak masuk akal tanpa mengeksekusi.

Bahkan mungkin ada dua tata bahasa bebas konteks yang persimpangannya tidak bebas konteks tetapi masih menggambarkan mesin Turing.

Java dan assembler mungkin secara alami bebas konteks.

Jeff Burdges
sumber
2
Bukankah ambiguitas (a)-bmembuat konteks C sensitif? ( abisa berupa variabel atau typedef - beberapa bahasa lain tidak mengizinkan casting ekspresi minus unary karena alasan ini)
Random832
Saya minta maaf atas komentar yang sangat tertunda tetapi perangkat Duff tidak melibatkan penyimpangan sintaksis. Kawat gigi menyeimbangkan dengan benar. Fitur C yang paling sering diabaikan dalam diskusi tentang apakah C bebas konteks adalah preprosesor. Saya skeptis bahwa ada interpretasi, bagaimanapun informal, dari "bebas konteks" yang memungkinkan menggunakannya untuk menggambarkan bahasa dengan prosesor makro, bahkan yang berperilaku baik. Dan preprosesor C sama sekali tidak berperilaku baik.
rici
4

Tidak, dan banyak bahasa praktis tidak bebas konteks. Misalnya tata bahasa C ++ tidak, karena dalam beberapa konteks resolusi tata bahasa tergantung pada pengetikan informasi yang tidak bebas konteks.

antti.huima
sumber
4

Pertama-tama izinkan saya membuat perbedaan antara sintaksis bahasa pemrograman dan bahasa itu sendiri.

Sintaks banyak bahasa (setidaknya didasarkan pada) Tata Bahasa Konteks Gratis (CFG) karena ini dipelajari dengan baik dan ada algoritma yang dapat secara efisien mengurai CFG dan kasus tepi yang tidak dapat diselesaikan oleh CFG dapat ditangani secara khusus

Namun banyak bahasa sebenarnya bukan Bebas-Konteks (ketika simbol menyatakan sebelum digunakan digunakan, misalnya dalam java, C (++), D).

Fakta asyik: D memiliki evaluasi fungsi kompilasi-waktu-kompilasi Turing-lengkap dan perluasan membuat bahasa itu sendiri tidak bisa-Turing-bisa dipilih Namun pencipta bahasa berusaha keras untuk membuat sintaksis menjadi CFG.

ratchet freak
sumber
Analisis nama dan tipe biasanya melakukan tugas-tugas bebas yang tidak terkait konteks.
Raphael
Meta-pemrograman template dalam C ++ sudah selesai selesai.
Jeff Burdges
3

Sejauh "Apakah semua bahasa pemrograman / scripting konteks tata bahasa gratis?" bagian yang bersangkutan, jawabannya adalah TIDAK.

Re: pertanyaan utama "untuk bahasa yang pada akhirnya dapat dikompilasi / diubah menjadi instruksi tingkat sistem," Saya tidak tahu mengapa perlu menjadi CFG. Namun, mungkin ada penjelasan yang lebih baik.

Keris
sumber
1
Kris, dapatkah Anda memberikan beberapa contoh bahasa pemrograman berbasis tata bahasa gratis non-konteks. Maksud saya, pasca-pemrosesan yang mungkin memerlukan masalah yang mungkin atau mungkin tidak dapat dihitung, tata bahasa terakhir yang menjadi sandaran program.
sandeepkunkunuru
3

Bahasa pemrograman perlu didasarkan pada semacam formalisme tata bahasa, yang contohnya adalah CFG. Meskipun CFG adalah yang paling umum (dan merupakan hal yang biasa diajarkan dalam kursus penyusun di universitas), ada formalisme lain seperti Parsing Expression Grammars, yang dapat Anda baca lebih lanjut di sini (pdf) atau di Wikipedia untuk bacaan berukuran lebih besar.

evilcandybag
sumber