Saya telah mencari-cari jawaban untuk pertanyaan ini dan kelihatannya semua orang secara implisit tahu jawabannya kecuali saya. Agaknya ini karena satu-satunya orang yang peduli adalah mereka yang pernah memiliki pendidikan tinggi tentang hal itu. Saya, di sisi lain, telah dilemparkan ke dalam untuk tugas sekolah menengah.
Pertanyaan saya adalah, bagaimana tepatnya bahasa pemrograman terkait dengan bahasa formal? Di mana-mana saya membaca, sesuatu di sepanjang baris "bahasa formal digunakan untuk mendefinisikan tata bahasa bahasa pemrograman" dikatakan.
Sekarang dari apa yang saya dapat kumpulkan, bahasa formal adalah serangkaian aturan produksi yang berlaku untuk serangkaian simbol tertentu (alfabet bahasa). Aturan produksi ini menentukan serangkaian transformasi, seperti:
b -> a
aaa->c
Ini dapat diterapkan sedemikian rupa sehingga:
abab->aaaa
aaaa-> ca
Sama seperti catatan tambahan, jika kita mendefinisikan bahwa alfabet bahasa formal kita sebagai {a, b, c}, maka a dan b adalah bukan terminal dan c adalah terminal karena tidak dapat diubah (perbaiki saya jika saya salah tentang bahwa).
Jadi mengingat semua itu, bagaimana mungkin ini berlaku untuk bahasa pemrograman? Seringkali juga dinyatakan bahwa regex digunakan untuk mengurai bahasa dalam bentuk teks untuk memastikan tata bahasa benar. Ini masuk akal. Kemudian dinyatakan bahwa regex didefinisikan oleh bahasa formal. Regex mengembalikan benar atau salah (setidaknya dalam pengalaman saya) tergantung pada apakah automata keadaan terbatas yang mewakili regex mencapai titik tujuan. Sejauh yang saya bisa lihat, itu tidak ada hubungannya dengan transformasi *.
Untuk mengkompilasi program itu sendiri, saya kira bahasa formal akan dapat mengubah kode menjadi kode tingkat yang lebih rendah secara berurutan, akhirnya mencapai perakitan melalui seperangkat aturan yang kompleks, yang kemudian dapat dipahami oleh perangkat keras.
Jadi itu hal-hal dari sudut pandang saya yang bingung. Mungkin ada banyak hal yang secara fundamental salah dengan apa yang saya katakan, dan itulah sebabnya saya meminta bantuan.
* Kecuali Anda menganggap sesuatu seperti (a|b)*b*c->true
aturan produksi, dalam hal ini aturan tersebut memerlukan automata keadaan terbatas (yaitu: regex). Ini tidak masuk akal karena kami baru saja mengatakan itu
Jawaban:
Siapa pun yang memberi tahu Anda bahwa ekspresi reguler yang digunakan untuk mem-parsing kode menyebarkan disinformasi. Secara klasik (saya tidak tahu sampai sejauh mana ini benar dalam kompiler modern), parsing kode - konversi kode dari teks ke pohon sintaks - terdiri dari dua tahap:
Analisis leksikal: Memproses teks mentah menjadi potongan - potongan seperti kata kunci , konstanta numerik , string , pengidentifikasi dan sebagainya. Ini diimplementasikan secara klasik menggunakan semacam mesin keadaan terbatas, serupa semangatnya dengan robot terbatas deterministik (DFA).
Parser: Jalankan setelah analisis leksikal, dan mengubah teks mentah menjadi pohon sintaksis beranotasi. Tata bahasa bahasa pemrograman (untuk perkiraan pertama) bebas konteks (sebenarnya, seseorang membutuhkan subset yang lebih ketat), dan ini memungkinkan algoritma efisien tertentu untuk mem-parsing kode lexified ke dalam pohon sintaksis. Ini mirip dengan masalah mengenali apakah string yang diberikan milik tata bahasa bebas konteks, perbedaannya adalah bahwa kita juga menginginkan bukti dalam bentuk pohon sintaksis.
Tata bahasa untuk bahasa pemrograman ditulis sebagai tata bahasa bebas konteks, dan representasi ini digunakan oleh generator parser untuk membuat parser cepat untuk mereka. Contoh sederhana akan memiliki beberapa PERNYATAAN non-terminal dan kemudian aturan bentuk PERNYATAAN IF-PERNYATAAN, di mana IF-PERNYATAAN jika KONDISI maka BLOK endif, atau sejenisnya (di mana BLOK PERNYATAAN BLOK; PERNYATAAN, untuk contoh). Biasanya tata bahasa ini ditentukan dalam bentuk Backus-Naur (BNF).→ → →
Spesifikasi aktual bahasa pemrograman tidak bebas konteks. Misalnya, variabel tidak dapat muncul jika belum dideklarasikan dalam banyak bahasa, dan bahasa dengan pengetikan yang ketat mungkin tidak memungkinkan Anda untuk menetapkan bilangan bulat ke variabel string. Pekerjaan parser hanya mengubah kode mentah menjadi bentuk yang lebih mudah diproses.
Saya harus menyebutkan bahwa ada pendekatan lain seperti parsing keturunan rekursif yang tidak benar-benar menghasilkan pohon parse, tetapi proses kode Anda saat mem-parsingnya. Meskipun tidak mengganggu untuk menghasilkan pohon, dalam semua hal lain ia beroperasi pada tingkat yang sama seperti yang dijelaskan di atas.
sumber
Ini adalah beberapa hal yang berat untuk tugas sekolah menengah.
Jawaban Yuval Filmus sangat bagus, jadi ini lebih merupakan jawaban tambahan untuk memperjelas beberapa poin yang dia buat.
Bahasa formal adalah konstruksi matematika. Penggunaannya untuk bahasa pemrograman hanyalah salah satu dari banyak kegunaan yang mungkin; pada kenyataannya, ahli bahasa Noam Chomsky membuat kontribusi signifikan pada teori awal bahasa formal. Dia menemukan Hierarki Chomsky, yang mengklasifikasikan bahasa formal ke dalam bahasa reguler, bebas konteks, dll. Bahasa formal juga diterapkan dalam linguistik untuk menggambarkan sintaksis bahasa alami seperti bahasa Inggris. Pikirkan itu seperti bilangan real: kita dapat menggunakan bilangan real untuk menggambarkan kedua hal nyata seperti jarak dari Los Angeles ke New York, dan hal-hal abstrak seperti rasio keliling lingkaran dengan diameternya. Meskipun kedua hal itu ada terlepas dari bilangan real, bilangan real adalah sistem yang membantu untuk menggambarkan mereka. Bahasa formal adalah sistem yang membantu untuk menggambarkan bahasa Inggris dan Python, karena keduanya memiliki format terstruktur yang sama.
Secara klasik, bahasa pemrograman akan memiliki dua tata bahasa: tata bahasa leksikal dan tata bahasa sintaksis. Tata bahasa leksikal berkaitan dengan karakter seperti huruf, titik koma, kawat gigi, dan tanda kurung. Ini biasanya tata bahasa biasa, sehingga dapat diekspresikan dengan ekspresi reguler atau DFA atau NFA. (Ada bukti dalam teori bahasa formal yang menunjukkan ketiganya setara dalam kekuasaan — yang berarti mereka menerima serangkaian bahasa yang sama.) Fase pengeksposan dari kompiler atau juru bahasa adalah semacam juru bahasa mini untuk tata bahasa bahasa biasa. Itu membaca aturan tata bahasa, dan mengikuti aturan itu, itu menggumpalkan karakter individu menjadi token. Misalnya, jika bahasa tersebut memiliki
if
pernyataan yang kurang lebih mirip dengan C, lexer mungkin menyamakan karakteri
danf
ke dalam token tunggal.IF
, kemudian cari tanda kurung buka dan beri tanda tokenOPEN_PAREN
, lalu pegang apa pun yang ada di antara tanda kurung, dan kemudian temukan tanda kurung penutup dan keluaran aCLOSE_PAREN
. Ketika lexer selesai membuat token, ia menyerahkannya ke parser, yang menentukan apakah token tersebut benar-benar membentuk pernyataan yang valid dari bahasa pemrograman. Jadi jika Anda menulisip a == b
dengan Python, lexer hanya melakukan yang terbaik untuk menebak token seperti apaip
(mungkin itu akan diambil untuk pengenal oleh kebanyakan lexers), dan meneruskannya ke parser, yang mengeluh karena Anda tidak dapat memiliki pengidentifikasi di posisi itu.Mari kita lihat aturan tata bahasa untuk
if
pernyataan Python . Ini aturannya:if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
Aturan itu memberi tahu kita bagaimana parser akan mencari tahu apakah serangkaian token yang dikirim dari lexer adalah
if
pernyataan. Setiap kata dalam tanda kutip tunggal harus muncul, begitu saja, dalam kode sumber, sehingga pengurai akan mencari kata yang sederhanaif
. Parser kemudian akan mencoba mencocokkan beberapa token dengan aturan untuktest
:test: or_test ['if' or_test 'else' test] | lambdef
test
didefinisikan dalam hal aturan lain dalam tata bahasa. Perhatikan bagaimanatest
juga memasukkan dirinya dalam definisinya; itu disebut definisi rekursif. Ini adalah kekuatan besar bahasa bebas konteks yang tidak dimiliki bahasa reguler, dan memungkinkan hal-hal seperti loop bersarang untuk didefinisikan untuk sintaksis bahasa pemrograman.Jika parser berhasil mencocokkan beberapa token
test
, ia akan mencoba mencocokkan titik dua. Jika itu berhasil, itu akan mencoba mencocokkan beberapa token lainnya menggunakan aturan untuksuite
. Bagian ini('elif' test ':' suite)*
berarti bahwa kita dapat memiliki sejumlah pengulangan teks literalelif
, diikuti oleh sesuatu yang cocoktest
, diikuti oleh titik dua, diikuti oleh sesuatu yang cocoksuite
. Kami juga dapat memiliki nol pengulangan; tanda bintang pada akhirnya berarti "nol atau sebanyak yang kita inginkan".Pada akhirnya adalah
['else' ':' suite]
. Bagian itu tertutup tanda kurung; itu berarti kita dapat memiliki nol atau satu, tetapi tidak lebih. Untuk mencocokkan ini, parser perlu mencocokkan teks literalelse
, titik dua, dan kemudian asuite
. Inilah aturan untuksuite
:suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
Ini pada dasarnya adalah blok dalam bahasa C-like. Sejak Python menggunakan baris dan lekukan pada hal-hal yang berarti, output lexer
NEWLINE
,INDENT
danDEDENT
token untuk memberitahu parser di mana baris baru dimulai, di mana kode mulai menjorok, dan di mana ia kembali ke tingkat luar lekukan.Jika salah satu dari upaya pencocokan ini gagal, parser menandai kesalahan dan berhenti. Jika parsing seluruh program berhasil, parser biasanya akan membangun pohon parse seperti Yuval tercakup dalam jawabannya, dan mungkin tabel simbol dan struktur data lain yang menyimpan informasi semantik. Jika bahasa diketik secara statis, kompiler akan memandu pohon parse dan mencari kesalahan ketik. Itu juga berjalan pohon parse untuk menghasilkan kode tingkat rendah (bahasa assembly, bytecode Java, .Net Intermediate Language, atau yang serupa) yang merupakan apa yang sebenarnya berjalan.
Sebagai latihan, saya akan merekomendasikan mengambil tata bahasa dari beberapa bahasa pemrograman yang Anda kenal (sekali lagi, Python , Java , dan inilah C # , Javascript , C ) dan mencoba untuk mengurai sesuatu yang sederhana, seperti mungkin
x = a + b;
atauif (True): print("Yay!")
. Jika Anda mencari sesuatu yang lebih sederhana, ada juga tata bahasa yang bagus untuk JSON , yang pada dasarnya hanya mencakup sintaks untuk objek literal dalam Javascript (seperti{'a': 1, 'b': 2}
). Semoga beruntung, ini adalah hal-hal yang membekukan otak tetapi ternyata benar-benar menarik ketika Anda tidak berada di tenggat waktu yang gila.sumber
Pendeknya
Bahasa pemrograman terdiri dari sintaks yang mewakili program sebagai string karakter, dan semantik yang merupakan makna yang dimaksud dari program.
Bahasa formal adalah sintaksis tanpa makna. Ini dimaksudkan untuk mempelajari struktur set string yang didefinisikan secara formal, tanpa biasanya menempelkan makna pada string tersebut.
Ekspresi reguler dan formalisme lainnya (seperti Context-Free Grammars) digunakan untuk mendefinisikan bahasa formal, digunakan sebagai komponen sintaksis pemrograman dan bahasa alami, yaitu untuk merepresentasikan kalimat dengan cara terstruktur. Mekanisme lain digunakan untuk menghubungkan struktur itu dengan semantik bahasa pemrograman.
Banyak di sini sangat disederhanakan, terutama mengenai bahasa alami.
Dengan lebih banyak detail
Untuk menjawab pertanyaan Anda, kami harus mulai dari awal. Bahasa dalam arti biasa, secara informal, merupakan sarana untuk menyampaikan informasi atau ide. Dalam suatu bahasa, orang biasanya membedakan antara sintaks dan semantik. Semantik adalah apa yang ingin Anda bicarakan / tulis. informasi yang ingin Anda sampaikan. Sintaks adalah cara yang Anda gunakan untuk menyampaikannya, yaitu representasi konvensional yang dapat dipertukarkan antara orang, dan sekarang juga antara orang dan perangkat, atau antara perangkat (komputer).
Biasanya, Anda akan menggunakan kata itu
dog
untuk menyampaikan ide tentang seekor anjing. Katadog
itu terbuat dari tiga huruf, atau suara yang setara, dan dimaksudkan untuk menjadi representasi dari beberapa jenis hewan. Gagasan utamanya adalah bahwa komunikasi dilakukan melalui representasi dari apa yang harus dikomunikasikan. Struktur representasi biasanya disebut sintaksis, sedangkan yang direpresentasikan disebut semantik. Ini berlaku lebih atau kurang untuk bahasa alami serta untuk bahasa pemrograman.Kata-kata adalah entitas sintaksis untuk mewakili konsep semantik yang kurang lebih elementer. Tetapi konsep-konsep dasar ini harus disatukan dalam berbagai cara untuk memberikan makna yang lebih kompleks. Kami menulis
the dog
untuk menyampaikan bahwa yang kami maksud adalah anjing tertentu, danthe dog bites the cat
untuk menyampaikan ide yang lebih kompleks. Tetapi cara mengatur kata-kata harus diperbaiki dengan aturan, sehingga kita dapat mengetahui anjing dan kucing mana yang benar-benar menggigit.Jadi kami memiliki aturan seperti
sentence -> subject verb complement
yang seharusnya cocok dengan kalimat dan memberi tahu kami bagaimana ide yang terkait dengan masing-masing bagian diartikulasikan. Aturan-aturan ini adalah aturan sintaksis, karena aturan tersebut memberi tahu kita bagaimana representasi pesan kita diatur. Thesubject
sendiri bisa didefinisikan oleh aturansubject -> article noun
, dan sebagainya.Struktur bahasa pemrogramannya sama. Bahasa pemrograman secara semantik khusus dalam mengekspresikan perhitungan yang harus dilakukan, daripada mengungkapkan masalah yang harus dipecahkan, bukti teorema atau hubungan persahabatan antara hewan. Tapi itulah perbedaan utama.
Representasi yang digunakan dalam sintaksis biasanya string karakter, atau suara untuk bahasa yang diucapkan. Semantik biasanya milik domain abstrak, atau mungkin realitas, tetapi masih diabstraksikan dalam proses pemikiran kita, atau pada domain perilaku perangkat. Komunikasi memerlukan pengodean informasi / ide ke dalam sintaksis, yang ditransmisikan dan diterjemahkan oleh penerima. Hasilnya kemudian diartikan dengan cara apa pun oleh penerima.
Jadi apa yang kita lihat dari bahasa ini sebagian besar sintaks dan strukturnya. Contoh di atas hanya salah satu cara paling umum untuk mendefinisikan string sintaksis dan organisasi strukturalnya. Ada yang lain. Untuk bahasa tertentu, beberapa string dapat diberi struktur, dan dikatakan milik bahasa, sementara yang lain tidak.
Hal yang sama berlaku untuk kata-kata. Beberapa urutan huruf (atau suara) adalah kata-kata yang sah, sementara yang lain tidak.
Bahasa formal hanya sintaksis tanpa semantik. Mereka mendefinisikan dengan seperangkat aturan urutan apa yang dapat dibangun, menggunakan elemen dasar alfabet. Apa aturannya bisa sangat bervariasi, terkadang rumit. Tetapi bahasa formal digunakan untuk banyak tujuan matematika di luar komunikasi linguistik, baik untuk bahasa pemrograman alami. Seperangkat aturan yang menentukan string dalam bahasa disebut tata bahasa. Tetapi ada banyak cara lain untuk mendefinisikan bahasa.
Dalam praktiknya, sebuah bahasa disusun dalam dua tingkat. Tingkat leksikal mendefinisikan kata-kata yang dibangun dari alfabet karakter. Tingkat sintaksis mendefinisikan kalimat, atau program yang dibangun dari alfabet kata (atau lebih tepatnya dari keluarga kata, sehingga tetap menjadi alfabet terbatas). Ini tentu agak disederhanakan.
Struktur kata-kata cukup sederhana di sebagian besar bahasa (pemrograman atau alami) sehingga biasanya didefinisikan dengan apa yang biasanya dianggap sebagai jenis bahasa formal yang paling sederhana: bahasa biasa. Mereka dapat didefinisikan dengan ekspresi reguler (regexp), dan cukup mudah diidentifikasi dengan perangkat yang diprogram yang disebut automata keadaan terbatas. Dalam kasus bahasa pemrograman, contoh kata adalah pengidentifikasi, integer, string, bilangan real, kata yang dicadangkan seperti
if
ataurepeat
, simbol tanda baca atau tanda kurung terbuka. Contoh keluarga kata adalah identifier, string, integer.Tingkat sintaksis biasanya ditentukan oleh jenis bahasa formal yang sedikit lebih kompleks: bahasa bebas konteks, menggunakan kata-kata sebagai alfabet. Aturan yang telah kita lihat di atas adalah aturan bebas konteks untuk bahasa alami. Dalam hal aturan bahasa pemrograman dapat:
Dengan aturan seperti itu, Anda dapat menulis:
while aaa /= bbb do aaa = aaa + bbb / 6
yang merupakan pernyataan.Dan cara itu diproduksi dapat diwakili oleh struktur pohon yang disebut pohon parse atau pohon sintaks (tidak lengkap di sini):
Nama-nama yang muncul di sebelah kiri aturan disebut non-terminal, sedangkan kata-katanya disebut juga terminal, karena mereka berada dalam alfabet untuk bahasa (di atas tingkat leksikal). Non-terminal mewakili struktur sintaksis yang berbeda, yang dapat digunakan untuk menyusun program.
Aturan seperti itu disebut bebas konteks, karena non-terminal dapat diganti secara sewenang-wenang menggunakan salah satu aturan yang sesuai, terlepas dari konteks di mana ia muncul. Seperangkat aturan yang mendefinisikan bahasa disebut tata bahasa bebas konteks.
Sebenarnya ada batasan untuk itu, ketika pengidentifikasi harus dideklarasikan pertama kali, atau ketika ekspresi harus memenuhi batasan tipe. Tetapi pembatasan semacam itu dapat dianggap semantik, bukan sintaksis. Sebenarnya beberapa profesional menempatkan mereka dalam apa yang mereka sebut semantik statis .
Diberikan kalimat apa pun, program apa pun, makna kalimat itu diekstraksi dengan menganalisis struktur yang diberikan oleh pohon parse untuk kalimat ini. Oleh karena itu sangat penting untuk mengembangkan algoritma, yang disebut parser, yang dapat memulihkan struktur pohon yang sesuai dengan program, ketika diberikan program.
Pengurai didahului oleh penganalisa leksikal yang mengenali kata-kata, dan menentukan keluarga tempatnya. Kemudian urutan kata-kata, atau elemen leksikal, diberikan kepada parser yang mengambil struktur pohon yang mendasarinya. Dari struktur ini kompiler kemudian dapat menentukan bagaimana menghasilkan kode, yang merupakan bagian semantik dari pemrosesan program di sisi kompiler.
Parser dari kompiler dapat benar-benar membangun struktur data yang sesuai dengan parse-tree dan meneruskannya ke tahap selanjutnya dari proses kompilasi, tetapi tidak harus. Menjalankan jumlah algoritma parsing untuk mengembangkan strategi komputasi untuk mengeksplorasi pohon sintaksis yang tersirat dalam teks program. Sintaks / parse tree ini dapat atau tidak dapat dieksplorasi dalam proses, tergantung pada strategi kompilasi (jumlah tahapan). Apa yang diperlukan adalah bahwa pada akhirnya ada setidaknya satu eksplorasi bottom-up dari pohon parse, baik yang dieksplisit atau dibiarkan tersirat dalam struktur perhitungan.
Alasan untuk itu, secara intuitif, adalah bahwa cara formal standar untuk mendefinisikan semantik yang terkait dengan struktur pohon sintaksis adalah melalui apa yang disebut homomorfisme. Jangan takut kata besar. Idenya adalah hanya untuk mempertimbangkan makna keseluruhan dibangun dari makna bagian-bagian, atas dasar operator yang menghubungkan mereka
Misalnya, kalimatnya
the dog bites the cat
bisa dianalisis dengan aturansentence -> subject verb complement
. Mengetahui makna dari ketiga sub pohonsubject
,,verb
dancomplement
, aturan yang menyusunnya memberi tahu kita bahwa subjek sedang melakukan tindakan, dan bahwa kucinglah yang digigit.Ini hanya penjelasan intuitif, tetapi bisa diformalkan. Semantik dibangun ke atas dari konstituen. Tapi ini menyembunyikan banyak kerumitan.
Kerja internal kompiler dapat didekomposisi menjadi beberapa tahap. Kompiler yang sebenarnya dapat bekerja tahap demi tahap, menggunakan representasi perantara. Mungkin juga menggabungkan beberapa tahapan. Ini tergantung pada teknologi yang digunakan dan pada kerumitan kompilasi bahasa yang ada.
sumber
"[^"]*"
dalam bentuknya yang paling sederhana, mengabaikan chars escape dll), tetapi apakah itu juga digunakan dalam membuat pohon sintaks (Berbicara dalam istilah bahasa pemrograman)? Saya kira tidak, sebagai automata keadaan terbatas, oleh definisi terbatas. Sebuah sintaksis pohon, bahkan untuk satuif
pernyataan, dapat secara teoritis tidak terbatas karena bersarang. Oleh karena itu regex, menjadi automata keadaan terbatas tidak dapat digunakan untuk tujuan menghasilkan pohon sintaks.if
pernyataan tak terbatas (sewenang-wenang besar) tapi selalu terbatas. Infinite yang didefinisikan secara terbatasif
adalah awhile
. Perbedaan antara CF dan reguler adalah bahwa CF mengontrol / memungkinkan penyatuan (mis. Kuretisasi) sementara reguler tidak. Namun keduanya dijelaskan secara halus dan memungkinkan string tidak terbatas.Ada perbedaan yang signifikan. Yang paling utama di antara mereka, saya akan mengatakan, adalah parsing bahasa pemrograman nyata adalah semua tentang penanganan kesalahan sintaksis. Dengan bahasa formal Anda hanya akan mengatakan "baik itu tidak dalam bahasa", tetapi kompiler yang mengatakan itu tidak terlalu berguna - itu akan memberi tahu Anda apa yang salah, dan jika itu adalah kesalahan kecil, idealnya tetap parsing sehingga bisa laporkan lebih banyak kesalahan. Banyak penelitian (dan upaya implementasi) membahas hal itu. Jadi Anda benar-benar tidak terlalu peduli dengan hasil benar / salah, Anda hanya ingin menganalisis struktur input. Bahasa formal digunakan sebagai alat di sana, dan ada banyak tumpang tindih, tetapi Anda benar-benar memecahkan masalah yang berbeda.
Juga, dalam sebagian besar bahasa telah dipilih untuk tidak menegakkan hal-hal tertentu dalam tata bahasa , misalnya contoh yang Anda sebutkan, "variabel tidak dapat muncul jika belum dideklarasikan". Itu biasanya hal yang akan sepenuhnya diabaikan oleh parser, dan kemudian terperangkap dalam analisis terpisah (analisis semantik) yang melihat hal semacam itu dan tidak terpengaruh oleh pertimbangan seperti kelayakan konteks. Tetapi tidak selalu - misalnya untuk mem-parsing C, hack lexer sering digunakan, dan C ++ adalah contoh terkenal dari bahasa yang tidak dapat diuraikan tanpa secara bersamaan melakukan beberapa analisis semantik yang serius (sebenarnya mem-parsing C ++ tidak dapat diputuskan, karena templat Turing lengkap) ). Namun dalam bahasa yang lebih sederhana cenderung terpecah, lebih mudah seperti itu.
sumber
Bahasa formal adalah sekumpulan kata - kata adalah rangkaian simbol dari beberapa alfabet.
Ini berarti kopling Anda dari aturan produksi dan bahasa formal terlalu kuat. Itu tidak benar bahwa bahasa formal adalah aturan produksi. Sebaliknya aturan produksi menentukan bahasa formal. Bahasa formal adalah kata-kata yang dapat diproduksi oleh aturan produksi. (Ini mensyaratkan bahwa bahasa formal adalah jenis yang dapat didefinisikan oleh aturan produksi, misalnya bahasa reguler dapat didefinisikan oleh tata bahasa bebas konteks)
Jadi bahasa reguler yang sesuai dengan ekspresi
(a|b)*c*d
didefinisikan oleh aturan produksi;Kata-kata yang dihasilkan oleh aturan produksi ini dari simbol awal S adalah string yang diterima oleh ekspresi reguler.
sumber
Ada hubungan lain antara ekspresi reguler dan bahasa pemrograman yang berkaitan dengan semantik. Konstruksi kontrol dasar bahasa imperatif adalah komposisi berurutan (lakukan A dan kemudian B), pilihan (lakukan A atau B), dan pengulangan (lakukan A lagi dan lagi).
Tiga cara yang sama untuk menggabungkan perilaku ditemukan dalam ekspresi reguler. Lemparkan panggilan subrutin dan Anda memiliki analogi dengan EBNF.
Jadi ada banyak kesamaan antara aljabar ekspresi reguler dan aljabar perintah. Ini dieksplorasi secara rinci oleh Dijkstra dalam "The Unification of Three Calculi". Ini juga merupakan dasar dari CCS Milner, yang memberikan jawaban atas pertanyaan: bagaimana jika kita menambahkan paralelisme?
sumber