Що саме є програмуванням? Що дозволяє нам писати такою мовою?


26

Гаразд, я новачок у програмуванні, і визнаю, це досить абстрактне питання.

Природна мова, якою ми говоримо щодня, існує тому, що люди можуть зрозуміти один одного. Як комп'ютери можуть зрозуміти мій код, написаний певною мовою?

Скажімо, пан А створює нову мову. Як це прийнято машинами? Чи повинен творець спілкуватися з машиною, використовуючи машинну мову, щоб створити нову мову? Що гарантує, що ми можемо писати мовою, розуміючи машину правильно?


1
Що дозволяє нам писати такою мовою? - "Мізки: новий наповнювач головки диво!" - Спайк Мілліган.
Стівен C

6
Трохи широке, але все-таки гарне запитання. Занадто багато людей просто використовують мови, не замислюючись, як вони працюють. Добре, що вам цікаво.
riwalk

4
Це загальне довідкове запитання, на яке Вікіпедія легко і тривіально відповідає .
Aaronaught

Відповіді:


39

Ви можете узагальнити всю відповідь на свій набір питань зі словом "компілятор" . Компілятор - це спеціальна програма, функцією якої є прийняття вихідного коду як введення, застосування мовних правил, визначених дизайнером мови, для того, щоб з'ясувати, що означає код, і створити код з тим же значенням на іншій мові, що і вихідний. Це, як правило, машинний код або якась форма байт-коду ("машинний код" для віртуальних машин), хоча існують спеціалізовані компілятори, які переводять код на інші мови високого рівня. Однак вони виходять за рамки цього питання.

Не всі мови мають компілятор. Деякі з них натомість мають інтерпретатор , який робить все ті ж речі, що і компілятор, за винятком того, що замість того, щоб виробляти машинний код після визначення того, що означає програма, він просто виконує програму негайно. Але основні принципи розбору (читання) коду та визначення того, що він означає, однакові.

Відповіді на більш глибокі, ніж на це, потраплять у теорію компілятора, що є дуже широкою темою. Якщо вас зацікавила тема, спершу слід прочитати статтю у Вікіпедії для "компілятора" та перевірити посилання з неї, і якщо у вас є конкретні питання, не соромтеся їх задати тут.


11
+1 - Я також додам, що коли ви пишете нову мову, ви повинні написати компілятор чи перекладач якоюсь іншою мовою. Пізніші версії компілятора або інтерпретатора можуть бути записані в більш ранніх версіях мови та зібрані зі старшим компілятором. Найперший асемблер був написаний у машинному коді. Перший компілятор С був написаний на зборах (найімовірніше) тощо
Скотт Вітлок

1
Я б змінив визначення компілятора. Вони не всі випромінюють машинний код. Особливо нині з такою кількістю компіляторів, що випромінюють "проміжний код", наприклад, MSIL. Є навіть компілятори, які видають JavaScript!
Ніл N

3
Я б не вагався заявити, що компілятори виробляють машинний код за визначенням, навіть коли пояснюють початківцю. Це як би сказати, що функції повертають реальні числа, безглузде спрощення. Вся конструкція компілятора виконується при створенні коду, який не призначений для комп'ютера, який фактично побудований з кремнію, але визначений лише абстрактно (будь то віртуальний комп'ютер або мова високого рівня; є причина, за якою сказано, що стандарт C визначає абстрактну машину , і там є компілятором від дуже низького рівня LLVM IR до friggin 'JavaScript). Початківцям потрібно це досягти, чим швидше, тим краще.

2
Спрощення, яке використовує більшість книг-компіляторів, полягає в тому, що компілятор застосовує мовні правила для перетворення з вихідної мови в цільову мову як вихід. (Не рідкість компілювати на C, наприклад, особливо для вступного курсу).
JasonTrue

4
@delnan, ще більше - кожна мова є машинним кодом , для своєї абстрактної машини. Незалежно від того, наскільки високий рівень мови.
SK-логіка

11

Як ви вказали, люди спілкуються між собою "природною" мовою, такою як англійська, французька, німецька. Їх називають природними, тому що ми, природно, набуваємо їх, а не навмисно їх вигадуємо (есперанто є винятком).

Формальна мова - це винайдена з тією чи іншою метою. Наприклад, мова програмування, така як C, - це формальна мова, придумана з метою програмування комп'ютерів.

Усі мови можна описати за допомогою граматики. Ієрархію граматик описав Ноам Хомський у 1956 р. Він складається з таких рівнів:

Граматики типу 0 (граматики без обмежень). Вони найбільш загальні і еквівалентні машині Тьюрінга. Отже, проблема вирішення питання про те, чи є даний рядок частиною необмеженої граматики, не можна вирішити.

Граматики типу 1 (граматики, що залежать від контексту). Майже всі природні мови, такі як англійська, залежать від контексту. Прикладом контекстної чутливості в англійській мові є дві фрази: "Час летить як стріла". і "Фруктові мухи, як банан". Загалом, комп'ютерам важко зрозуміти контекстно-чутливі мови.

Граматики типу 2 (без контексту). Безтекстові мови є теоретичною основою для синтаксису більшості мов програмування.

Граматики типу 3 (звичайні граматики). Сімейство регулярних мов можна отримати регулярними виразами. Звичайні мови зазвичай використовуються для визначення шаблонів пошуку та лексичної структури мов програмування.

Граматики типу 2 (без контексту) та 3 (звичайні) найчастіше є комп’ютерами, оскільки парсери для них можуть бути ефективно реалізовані.

BNF (Backus Normal Form або Backus – Naur Form) - це метод позначення граматів без контексту, які часто використовуються для опису синтаксису мов, що використовуються в обчисленні.

Наприклад, ідентифікатор може бути описаний як:

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

що означає, що він повинен починатися з літери і може містити додаткові літери або цифри.

Раніше в літері було визначено "a" | 'b' | 'c' тощо, і цифра визначається як '0' до '9', використовуючи однотипні позначення.

Оператор AC "for" може бути визначений як:

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

Лексичні аналізатори та аналізатори (перші етапи компілятора чи інтерпретатора) потім будуються для прийняття конкретної граматики, описаної BNF для певної мови. Лексичні аналізатори зазвичай використовуються для відокремлення різних лексем мови (наприклад, ключового слова, ідентифікатора чи числа), і аналізатор використовується для з'ясування того, як лексеми працюють разом, наприклад, як побудований оператор "для" .


+1 відмінна підписка. Але я не здивований, що це не було прийнято як відповідь. Це те, що я думав, що ОП запитує, але виходячи з відповіді, яку вони обрали, здається, вони хотіли чогось набагато вищого рівня.
Матвій Родатус

5

Спочатку давайте визначимо "мову" з точки зору того, що це таке. Мова вимагає спочатку словникового запасу (перелік слів, що визначають поняття, що є об’єктами спілкування), а потім синтаксису («букваря» або набору правил, що визначають структуру спілкування).

На цьому самому базовому рівні C # не все так відрізняється від англійської. Те, що робить C # "мовою програмування", - це її наміри, а отже, і її дизайн; він призначений для перетравлення в окремі команди низького рівня. Як такий, попередньо визначений словник обмежений, синтаксис дуже жорстко виконується, і вся мова призначена для споживання дуже відомим заздалегідь визначеним способом його "аудиторією" (комп'ютер; точніше компілятор, який переварить вихідний код на "проміжну мову" простих команд, які потім можуть бути переведені в машинний код шляхом "виконання"). Ви не пишете прозу чи поезію на C #; ви скажете комп’ютеру виконувати роботу максимально однозначно.

Так, для комп'ютерів потрібен інструмент, який зазвичай називають компілятором, щоб взяти те, що ви пишете в коді, і перетворити його на інструкції, якими може користуватися комп'ютер. Інформатика, як і більшість технологій, є суттєво ітераційним, «шаруватим» процесом. Коли комп'ютери були вперше винайдені, вони були запрограмовані ручним введенням двійкових інструкцій. Ці інструкції стали стандартизованими для кожного процесора в шістнадцятковий "машинний код"; Різниця полягає лише в тому, як групуються двійкові цифри для відображення людині. Потім у коді асемблера список команд та деякі основні ідентифікатори, такі як імена регістрів, були замінені їх шістнадцятковими кодами під час написання програм; ASM все ще може бути перетворений 1: 1 у нативний машинний код. Квантовий стрибок стався до "імперативного" програмування третього покоління, яка в основному приймає більш зрозумілі для людини абстрактні поняття, такі як змінні та логічні петлі, і перетравлює їх у рідні інструкції, використовуючи шаблони на основі ключових слів та синтаксису. Ранні мови, такі як COBOL, FORTRAN, Pascal і C, все ще можуть бути "переведені" людиною на певну машинну мову (зазвичай це 8086 ASM). Потім відбулася революція об'єктно-орієнтованого програмування, яка в основному є додатковими синтаксичними правилами, що визначають код як концептуально інкапсульований в "об'єкти", які мають певне поєднання стану та логіки. людиною на певну машинну мову (зазвичай це 8086 ASM). Потім відбулася революція об'єктно-орієнтованого програмування, яка в основному є додатковими синтаксичними правилами, що визначають код як концептуально інкапсульований в "об'єкти", які мають певне поєднання стану та логіки. людиною на певну машинну мову (зазвичай це 8086 ASM). Потім відбулася революція об'єктно-орієнтованого програмування, яка в основному є додатковими синтаксичними правилами, що визначають код як концептуально інкапсульований в "об'єкти", які мають певне поєднання стану та логіки.

Сьогодні ми добре перебуваємо в мовах "четвертого покоління", які є мовами, написаними для визначення зв'язку з іншими програмами, а не безпосередньо до машини. Широко визначені, це включає мови "розмітки", такі як XML / HTML, "скриптові" мови, такі як JavaScript і SQL, і більшість мов "пісочниці", таких як Java і .NET Framework (які компілюються в IL, що потім інтерпретується далі час виконання, який абстрагує деталі щодо машин та платформи). Ви також можете сказати, що вона охоплює сферу функціональних мов програмування, які ВИГОТОВО залежать від часу виконання, щоб забезпечити абстрагування не лише конкретних деталей, а саме для конкретних операцій. Ці мови четвертого покоління людині більш-менш нездійсненно перекладати на інструкції до рідної машини, і справа в тому, що це не було б вагомим починанням; міцність цих мов - це багатошаровий процес, в якому вони використовуються, щоб врешті сказати комп’ютеру, що робити на низьких рівнях.


Спасибі. Я маю огляд на історію розвитку мови програмування.
Еріка Сю

2
@KeithS: Ви можете переформатувати останній абзац, щоб зробити його трохи читабельнішим.
Іван Вучиця

4

Це гарне запитання. Правильна відповідь утворює добру половину того, що називається "Інформатика".

Для початку я порекомендував би провести орієнтацію через денотаційну та оперативну семантику, а потім прочитати цю книгу . Це дасть вам більш-менш ґрунтовне розуміння того, що таке мова програмування, і як її можна формально визначити.

Якщо вищезазначене трохи надто академічне, ви можете почати з «Коду» Петцольда , а потім повернутися до семантики.


1
Ви дійсно очікуєте, що 18 років ноб прочитає важку теорію, щоб відповісти на це питання?
робота

2
@Job, відповідно до його попереднього запитання, він отримує дози схеми (і, імовірно, SICP) в університеті. Тоді має бути добре з трохи семантики. У всякому разі, без важкої теорії відповіді на це питання немає.
SK-логіка

+1 для згадки "Код". Цю книгу потрібно прочитати для кожного студента CS початкового рівня.
Даніель Приден

4

Якщо ви пишете програму мовою програмування, інша програма перетворить символи у вашій програмі в символи, які комп'ютер розуміє. Іноді для цього потрібно кілька кроків. Наприклад в C:

  1. Користувач пише програму мовою високого рівня (C), яка не зрозуміла процесором, але безпосередньо розуміється програмістом (сподіваємось!).

  2. Компілятор перетворює C на мову Assambly, яку ЦП не розуміє безпосередньо, але легко перетворити на щось інше.

  3. Assempler перетворює збірку в послідовність двійкових кодів, які безпосередньо розуміються процесором. Деякі компілятори пропускають вищевказаний крок (крок 2) і виробляють скомпільований двійковий файл безпосередньо з вихідного коду.

Щоб гарантувати, що комп’ютер розуміє вашу програму, компілятор або інтерпретатор видасть вам помилку і зазвичай зупиняється, якщо в ній трапляється щось, що не можна компілювати, наприклад, синтаксичну помилку. Якщо ваша програма не може бути скомпільована, вона ніколи не може дійти до етапу, коли ваша програма спробує запустити її і не вдасться, оскільки вона не «зрозуміла» її.

Щоб створити нову мову, ви спершу спроектуєте свою мову високого рівня, а потім вам доведеться знайти спосіб зіставлення символів вашої нової мови з командами мови складання, які розуміє ваш процесор.


2
Не зовсім; сучасні компілятори не роблять кроку 2 і просто виробляють бінарний код безпосередньо. Але збірка та двійковий код так чи інакше рівнозначні; ви можете розібрати (перетворити бінарний код назад у збірку) з дуже високою достовірністю.
MSalters
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.