Apa sebenarnya bahasa pemrograman? Apa yang memungkinkan kita menulis dalam bahasa seperti itu?

26

Baiklah saya baru dalam pemrograman dan saya akui ini adalah pertanyaan yang cukup abstrak.

Bahasa alami yang kita ucapkan setiap hari ada karena orang dapat saling memahami. Bagaimana komputer dapat memahami kode saya yang ditulis dalam bahasa tertentu?

Katakanlah Tuan A menciptakan bahasa baru. Bagaimana itu diterima oleh mesin? Haruskah pencipta berkomunikasi dengan mesin menggunakan bahasa mesin untuk membuat bahasa baru? Apa yang menjamin bahwa kami dapat menulis dalam bahasa sambil dipahami oleh mesin dengan benar?

Erica Xu
sumber
1
Apa yang memungkinkan kita menulis dalam bahasa seperti itu? - "Otak: pengisi kepala keajaiban baru!" - Spike Milligan.
Stephen C
6
Agak luas, tapi tetap saja pertanyaan yang bagus. Terlalu banyak orang yang menggunakan bahasa tanpa pernah bertanya-tanya bagaimana cara kerjanya. Bagus kalau kamu penasaran.
riwalk
4
Ini adalah pertanyaan referensi umum , mudah dan sepele dijawab oleh Wikipedia .
Aaronaught

Jawaban:

39

Anda dapat meringkas seluruh jawaban untuk set pertanyaan Anda dengan kata "compiler" . Kompiler adalah program khusus yang fungsinya mengambil kode sumber sebagai input, menerapkan aturan bahasa yang ditentukan oleh perancang bahasa untuk mengetahui apa arti kode tersebut, dan menghasilkan kode dengan makna yang sama dalam bahasa lain sebagai output. Ini umumnya kode mesin atau beberapa bentuk bytecode ("kode mesin" untuk mesin virtual), meskipun kompiler khusus yang menerjemahkan kode ke bahasa tingkat tinggi lainnya memang ada. Mereka berada di luar cakupan pertanyaan ini.

Tidak semua bahasa memiliki kompiler. Beberapa dari mereka memiliki penerjemah sebagai gantinya, yang melakukan semua hal yang sama seperti yang dilakukan kompiler, kecuali bahwa alih-alih menghasilkan kode mesin setelah menentukan apa arti program, ia hanya menjalankan program dengan segera. Tetapi prinsip dasar parsing (membaca) kode dan menentukan artinya adalah sama.

Menjawab lebih mendalam dari ini akan masuk ke teori kompiler, yang merupakan subjek yang sangat luas. Jika Anda tertarik dengan topik ini, Anda harus mulai dengan membaca artikel Wikipedia untuk "kompiler" dan memeriksa tautannya, dan jika Anda memiliki pertanyaan spesifik, jangan ragu untuk bertanya di sini.

Mason Wheeler
sumber
11
+1 - Saya juga akan menambahkan bahwa ketika Anda sedang menulis bahasa baru, Anda harus menulis kompiler atau juru bahasa dalam bahasa lain. Versi kompiler atau interpreter yang lebih baru kemudian dapat ditulis dalam versi bahasa yang lebih lama dan dikompilasi dengan kompiler yang lebih lama. Assembler pertama ditulis dalam kode mesin. Kompiler C pertama ditulis dalam assembly (kemungkinan besar) dll.
Scott Whitlock
1
Saya akan mengubah definisi kompiler. Mereka tidak semua mengeluarkan kode mesin. Apalagi saat ini dengan begitu banyak kompiler memancarkan "kode perantara", seperti MSIL. Bahkan ada kompiler yang memancarkan JavaScript!
Neil N
3
Saya akan ragu untuk menyatakan bahwa kompiler menghasilkan kode mesin menurut definisi, bahkan ketika menjelaskan kepada seorang pemula. Itu seperti mengatakan fungsi mengembalikan bilangan real, penyederhanaan yang tidak berguna. Semua konstruksi kompiler berlaku ketika memproduksi kode yang bukan untuk komputer yang benar-benar dibangun dari silikon tetapi hanya didefinisikan secara abstrak (baik itu VM atau bahasa tingkat tinggi; ada alasan mengapa standar C mendefinisikan mesin abstrak , dan ada adalah kompiler dari LLVM IR level sangat rendah ke friggin 'JavaScript). Pemula perlu mendapatkan itu, semakin cepat semakin baik.
2
Penyederhanaan yang digunakan kebanyakan buku kompiler adalah bahwa kompiler menerapkan aturan bahasa untuk mengkonversi dari bahasa sumber ke bahasa target sebagai output. (Tidak jarang mengkompilasi ke C, misalnya, terutama untuk kursus pengantar).
JasonTrue
4
@delnan, bahkan lebih - setiap bahasa adalah kode mesin , untuk mesin abstraknya sendiri. Tidak peduli seberapa tinggi level bahasanya.
SK-logic
11

Seperti yang Anda tunjukkan, manusia berkomunikasi melalui bahasa "alami" seperti Inggris, Prancis, Jerman, antara satu sama lain. Mereka disebut alami karena kita secara alami mendapatkannya daripada sengaja menciptakannya (Esperanto menjadi pengecualian).

Bahasa formal adalah bahasa yang diciptakan untuk beberapa tujuan atau lainnya. Bahasa pemrograman seperti C, misalnya, adalah bahasa formal yang diciptakan untuk tujuan pemrograman komputer.

Semua bahasa, bisa dideskripsikan menggunakan tata bahasa. Hirarki tata bahasa dijelaskan oleh Noam Chomsky pada tahun 1956. Ini terdiri dari tingkatan-tingkatan berikut:

Tata bahasa Tipe-0 (tata bahasa tidak terbatas). Mereka adalah yang paling umum, dan setara dengan Mesin Turing. Dengan demikian, masalah memutuskan apakah string yang diberikan adalah bagian dari tata bahasa tidak dibatasi tidak dapat diputuskan.

Tata bahasa tipe-1 (tata bahasa konteks-sensitif). Hampir semua bahasa alami seperti bahasa Inggris peka terhadap konteks. Contoh sensitivitas konteks dalam bahasa Inggris adalah dua frasa: "Waktu berlalu seperti panah." dan "Buah terbang seperti pisang." Secara umum, sulit bagi komputer untuk memahami bahasa yang peka konteks.

Tata bahasa tipe-2 (bebas konteks). Bahasa bebas konteks adalah dasar teoretis untuk sintaksis sebagian besar bahasa pemrograman.

Tata bahasa tipe-3 (tata bahasa biasa). Keluarga bahasa reguler dapat diperoleh dengan ekspresi reguler. Bahasa reguler biasanya digunakan untuk menentukan pola pencarian dan struktur leksikal bahasa pemrograman.

Tata bahasa Tipe 2 (bebas konteks) dan tipe 3 (biasa) paling sering oleh komputer karena parser untuk mereka dapat diimplementasikan secara efisien.

BNF (Backus Normal Form atau Backus-Naur Form) adalah teknik notasi untuk tata bahasa bebas konteks, sering digunakan untuk menggambarkan sintaks bahasa yang digunakan dalam komputasi.

Misalnya pengidentifikasi dapat digambarkan sebagai:

<identifier> ::= <letter> { <letter> | <digit> }

yang artinya harus dimulai dengan huruf dan dapat berisi huruf atau angka tambahan.

Sebelumnya, surat didefinisikan sebagai 'a' | 'b' | 'c' dll., dan digit didefinisikan sebagai '0' hingga '9' menggunakan jenis notasi yang sama.

Pernyataan AC "untuk" dapat didefinisikan sebagai:

 <for_statement> ::=
    'for' '(' <expression> ';' <expression> ';' <expression> ')' <statement> 

Analisis leksikal dan parser (tahap pertama dari kompiler atau juru bahasa) kemudian dibangun untuk menerima tata bahasa spesifik yang dijelaskan oleh BNF untuk bahasa tertentu. Analisis leksikal biasanya digunakan untuk memisahkan berbagai token suatu bahasa (seperti kata kunci, pengidentifikasi, atau angka), dan pengurai digunakan untuk mengetahui bagaimana token bekerja bersama, seperti bagaimana pernyataan "untuk" dikonstruksi. .

tcrosley
sumber
+1 artikel bagus. Tapi saya tidak terkejut ini tidak diterima sebagai jawabannya. Inilah yang saya pikir OP tanyakan, tetapi berdasarkan jawaban yang mereka pilih, sepertinya mereka menginginkan sesuatu yang jauh lebih tinggi.
Matius Rodatus
5

Pertama, mari kita mendefinisikan "bahasa" dalam hal apa itu. Bahasa pertama-tama membutuhkan kosa kata (daftar kata yang mendefinisikan konsep yang merupakan objek komunikasi), dan kemudian sintaksis ("primer" atau seperangkat aturan yang menentukan struktur komunikasi).

Pada level paling dasar ini, C # tidak jauh berbeda dari bahasa Inggris. Apa yang menjadikan C # "bahasa pemrograman" adalah tujuannya, dan oleh karena itu desainnya; itu dirancang untuk dicerna menjadi perintah tingkat rendah individu. Dengan demikian, kosakata yang telah ditentukan terbatas, sintaksisnya ditegakkan dengan sangat kaku, dan seluruh bahasa dirancang untuk dikonsumsi dengan cara yang telah dikenal sangat dikenal oleh "audiens" -nya (komputer; lebih tepatnya kompiler, yang akan mencerna kode sumber menjadi "bahasa perantara" dari perintah sederhana yang kemudian dapat diterjemahkan lebih lanjut ke dalam kode mesin oleh "runtime"). Anda tidak menulis prosa atau puisi dalam C #; Anda memberi tahu komputer untuk melakukan pekerjaan dengan cara yang paling jelas.

Untuk komputer, ya, alat, biasanya disebut kompiler, diperlukan untuk mengambil apa yang Anda tulis dalam kode dan mengubahnya menjadi instruksi yang dapat digunakan komputer. Ilmu komputer, seperti halnya kebanyakan teknologi, adalah proses yang "berulang". Ketika komputer pertama kali ditemukan, mereka diprogram dengan memasukkan instruksi biner secara manual. Instruksi tersebut menjadi standar untuk setiap prosesor menjadi "kode mesin" heksadesimal; perbedaannya hanya pada bagaimana digit biner dikelompokkan untuk ditampilkan kepada manusia. Kemudian, dalam kode assembler, daftar perintah dan beberapa pengidentifikasi dasar seperti nama register diganti untuk kode heksadesimal mereka ketika menulis program; ASM masih dapat dikonversi 1: 1 menjadi kode mesin asli. Lompatan kuantum adalah pemrograman "imperatif" generasi ke-3, yang pada dasarnya mengambil konsep abstrak yang lebih dapat dipahami manusia seperti variabel dan loop logika dan mencerna mereka ke dalam instruksi asli, menggunakan pola berdasarkan kata kunci dan sintaksis. Bahasa awal seperti COBOL, FORTRAN, Pascal, dan C masih dapat "diterjemahkan" oleh manusia ke dalam bahasa mesin tertentu (biasanya 8086 ASM). Kemudian muncul revolusi pemrograman berorientasi objek, yang pada dasarnya adalah aturan sintaksis tambahan yang mendefinisikan kode sebagai secara konsep dikemas dalam "objek" yang memiliki beberapa kombinasi state dan logika. oleh manusia ke dalam bahasa mesin tertentu (biasanya 8086 ASM). Kemudian muncul revolusi pemrograman berorientasi objek, yang pada dasarnya adalah aturan sintaksis tambahan yang mendefinisikan kode sebagai secara konsep dikemas dalam "objek" yang memiliki beberapa kombinasi state dan logika. oleh manusia ke dalam bahasa mesin tertentu (biasanya 8086 ASM). Kemudian muncul revolusi pemrograman berorientasi objek, yang pada dasarnya adalah aturan sintaksis tambahan yang mendefinisikan kode sebagai secara konsep dikemas dalam "objek" yang memiliki beberapa kombinasi state dan logika.

Saat ini, kami memasuki "generasi ke-4" bahasa, yang merupakan bahasa yang ditulis untuk mendefinisikan komunikasi dengan program lain, bukan langsung ke mesin. Didefinisikan secara luas, ini termasuk bahasa "markup" seperti XML / HTML, "scripting" bahasa seperti JavaScript dan SQL, dan sebagian besar bahasa "kotak pasir" seperti Java dan .NET Framework (yang menyusun menjadi IL yang kemudian ditafsirkan lebih lanjut oleh runtime yang memisahkan mesin dan detail khusus platform). Anda juga bisa mengatakan itu mencakup ranah bahasa pemrograman fungsional, yang sangat tergantung pada runtime untuk memberikan abstraksi tidak hanya perincian khusus mesin, tetapi perincian khusus operasi. Bahasa generasi ke-4 ini kurang lebih tidak mungkin bagi manusia untuk diterjemahkan ke dalam instruksi mesin asli, dan intinya adalah bahwa itu bukan upaya yang bermanfaat; kekuatan bahasa-bahasa ini adalah proses berlapis di mana mereka digunakan pada akhirnya memberitahu komputer apa yang harus dilakukan pada tingkat rendah.

KeithS
sumber
Terima kasih. Saya melihat sekilas sejarah perkembangan bahasa pemrograman.
Erica Xu
2
@KeithS: Anda mungkin ingin memformat ulang paragraf terakhir agar lebih mudah dibaca.
Ivan Vučica
4

Ini adalah pertanyaan yang bagus. Jawaban yang tepat membentuk setengah dari apa yang disebut "Ilmu Komputer".

Sebagai permulaan, saya akan merekomendasikan membaca semantik denotasional dan operasional , dan kemudian membaca buku ini . Ini akan memberi Anda pemahaman yang kurang lebih solid tentang apa bahasa pemrograman itu, dan bagaimana bahasa itu dapat didefinisikan secara formal.

Jika hal di atas agak terlalu akademis, Anda bisa mulai dengan Petzold, "Kode" , dan kemudian kembali ke semantik.

Logika SK
sumber
1
Anda benar-benar berharap 18 tahun untuk membaca beberapa teori berat hanya untuk menjawab pertanyaan ini?
Pekerjaan
2
@ Bob, menurut pertanyaan sebelumnya, dia mendapatkan dosis Skema (dan, mungkin, SICP) di universitas. Harus baik-baik saja dengan sedikit semantik. Bagaimanapun, tidak ada jawaban yang tepat untuk pertanyaan ini tanpa teori yang berat.
SK-logic
+1 untuk menyebutkan "Kode". Buku itu harus menjadi bacaan wajib untuk setiap siswa CS tingkat pemula.
Daniel Pryden
4

Jika Anda menulis sebuah program dalam bahasa pemrograman, program lain akan mengubah simbol dalam program Anda menjadi simbol yang dipahami komputer. Terkadang ini membutuhkan beberapa langkah. Misalnya dalam C:

  1. Pengguna menulis program dalam bahasa tingkat tinggi (C) yang tidak dimengerti oleh CPU, tetapi dipahami langsung oleh programmer (kami harap!).

  2. Compiler mengonversi C menjadi bahasa Assmebly, yang tidak secara langsung dipahami oleh CPU tetapi mudah untuk dikonversi menjadi sesuatu yang lain.

  3. Assempler mengubah Majelis menjadi urutan kode biner yang langsung dipahami oleh CPU. Beberapa kompiler melewatkan langkah di atas (langkah 2) dan menghasilkan biner yang dikompilasi langsung dari kode sumber.

Untuk menjamin bahwa komputer memahami program Anda, kompiler atau juru bahasa akan memberi Anda kesalahan dan biasanya berhenti jika menemui sesuatu yang tidak dapat dikompilasi, seperti kesalahan sintaksis. Jika program Anda tidak dapat dikompilasi, itu tidak akan pernah bisa sampai ke tahap di mana program Anda akan mencoba menjalankannya dan gagal karena tidak "memahaminya".

Untuk membuat bahasa baru, pertama-tama Anda merancang bahasa tingkat tinggi Anda dan kemudian Anda harus menemukan cara untuk memetakan simbol-simbol bahasa baru Anda ke perintah bahasa assembly yang dimengerti CPU Anda.

FrustratedWithFormsDesigner
sumber
2
Tidak juga; kompiler modern tidak melakukan langkah 2 dan hanya menghasilkan kode biner secara langsung. Tapi kode assembly dan binary hampir sama; Anda dapat membongkar (mengkonversi kode biner kembali ke perakitan) dengan kesetiaan yang sangat tinggi.
MSalters