Щоб мова була програмованою, чи обов'язково вона базуватися на вільній контекстній граматиці


23

Практично, для мови, яка в кінцевому підсумку може бути складена / перетворена в інструкції на системному рівні, чи потрібно, щоб це була граматика без контексту?

напр .: Чи всі мови програмування / сценаріїв є вільними граматиками? Java заснована на CFG, але чи справді так, що всі мови програмування базуються на CFG?

Це не здається обов'язковим, але в моєму розумінні є прогалини.

Деякий контекст для запитання: я розглядав специфікацію мови Java, яка також містить правила граматики . Це змусило мене задуматися над цим питанням.


1
Взагалі, я думаю, що ви просто хочете, щоб проблема компіляції була обчислюваною, і розбір CFG є приємним і простим. Хоча я чув деякі твердження, що, наприклад, розпізнавання дійсних програм perl насправді є проблемою, яку не можна обчислити.
Janne H. Korhonen

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

@ratchet, ви припускаєте, що синтаксис повинен бути рекурсивно перелічуваним?
Девід Харріс

4
@JanneKorhonen: Зокрема, Perl неможливо статично проаналізувати, тобто його неможливо проаналізувати, не будучи також виконаним; оскільки зазначене виконання може бути неперервним, розбір Perl статично означатиме вирішення проблеми зупинки.
Джон Перді

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

Відповіді:


20

Два рази ні.

По-перше, більшість ВПЛ не є контекстними. Хоча вони зазвичай мають синтаксис на основі CFG, вони також мають те, що люди називають статичною семантикою (що також часто включається в термін синтаксис). Сюди можна віднести імена та типи, які повинні перевірити правильність програми. Наприклад,

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

є синтаксично правильною програмою Java, але не буде компілюватися, оскільки dне визначена та aне має відповідного типу.

По-друге, ви можете розбирати мови, які не є контекстними (як це очевидно доведено існуванням компіляторів). Справа лише в тому, що CFG можна ефективно аналізувати, тоді як CSG взагалі не можна. Однак ви можете додати певні безконтекстні функції, залишаючись ефективними.

Компілятори часто виконують по фазах: спочатку токенізація (регулярна), потім без контекстного розбору, потім аналіз імен та типів (залежно від контексту, іноді навіть складніше). Ви можете спостерігати за такою поведінкою за типом повідомлень про помилки, які ви отримуєте.


3
Не забувайте public class Program { public static void main(String[] args) { ... } }... Java не дозволить вам так легко зійти. :-)
Рой Тінкер

Технічно class A { ... }цілком достатньо, оскільки javacзбирає речі, які ви фактично не можете виконати (через відсутність точки входу). Але так.
Рафаель

20

6
Я відчуваю, що це повинно бути пунктиром жарту Perl :)
Suresh Venkat

5
Суреш: Я вже виступив з цим жартом, хоча це не виявилося дуже гарним жартом, у статті "Про нерозбірливі мови програмування" у SIGBOVIK 2011 ( sigbovik.org/2011/proceedings.pdf - сторінка 79- 82).
Роб Сіммонс

1
Примітка: перекладач Perl ще не є детермінованим, якщо це комусь комфорт :)
Рой Тінкер

15

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

Точніше, виявляється гомоморфізм з мови блоків форми Python

якщо стан:
     рядок1
     рядок2
     рядок3
ще:
     рядок4

0n10n10n


4
Суворо ви маєте рацію, але в контексті мов програмування ми намагаємося зробити без контексту мову, що виходить після кроку попередньої обробки під назвою токенізація . Я думаю, що відступ перевіряється до цього.
Дієго де Естрада

7
Так, лексер Python (токенізатор) має степу глибин відступу; потік токена містить символ INDENT на початку кожного блоку та символ DEDENT в кінці, який можна проаналізувати у вільному контексті (INDENT та DEDENT діють так само, як дужки у C). C має проблему "не можу сказати, чи декларація чи вираз": це foo * bar;оголошення fooяк вказівник на barчи множення fooразів bar?
Макс

8
Гаразд, звичайно, але тоді ви просто приховуєте ту саму складність у лексері, а не робите це перетворювач кінцевого стану, як це часто є.
Девід Еппштейн

1
@DavidEppstein: Чесно кажучи, складність у цьому не велика.
Джон Перді

1
Крім обробки INDENT / DEDENT у лексері, Python має дуже просту граматику LL (1).
rmmh

13

Бодо Мантей та Мартін Бьоме показують, що кожен компілятор C ++ обов'язково є Turing завершеним, тобто він може обчислити будь-яку часткову рекурсивну функцію під час компіляції . Тож це набагато гірше, ніж просто залежно від контексту.

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


Так, але компілятор ніколи не є лише контекстними граматиками. Ви повинні обговорити саму граматику, а не компілятор.
Jeff Burdges

@Jeff: "Час компіляції" у моїй відповіді означає "перевірити, чи вказаний вихідний код C + правильний". Невелика модифікація конструкції в статті випливає, що ви можете звести кожну мову, що вирішується, до набору всіх правильних програм C ++.
Markus Bläser

7

Я думаю, що декларація перед використанням змінних та функціональний поліморфізм мов OOP - це інші приклади специфікацій мов програмування, які не можуть бути оброблені контекстними граматиками:

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);
...

Я здійснив невеликий пошук у Google і знайшов цю статтю: " Булева граматика простої булевої мови " А.Охотіна (2004); За його словами, справжня проблема полягає у пошуку мови програмування, яка повністю описана формальною граматикою:

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

Вступний розділ статті короткий, але дуже уточнюючий.


6

Я вважаю, що граматика C лише технічно без контексту, оскільки парсери завжди використовують безконтекстні методи для підтримки пристрою Даффа .

Мови, що базуються на відступи, природно не є контекстними, як сказав Девід, але вони стають контекстними щодо параметризованого маркера відступу.

Haskell дозволяє змінити пріоритет оператора за допомогою infix і infixl. Модуль суворої прагми Perl реалізований з використанням лексичних параметрів $ ^ H і% ^ H, які роблять це не контекстним, можливо, і іншими параметрами.

Існують мови розширювачів макроконтролерів на зразок TeX, в яких розбір afaik не має сенсу без виконання.

Напевно, є навіть дві безконтекстні граматики, перетин яких не є контекстним, але все ж описує машину Тюрінга.

Java і асемблер, ймовірно , і , природно , контекстно-вільний.


2
Чи не багатозначність (a)-bробить C контекстно-чутливим? ( aможе бути змінною або typedef - деякі інші мови з цієї причини не дозволяють
видавати

Прошу вибачення за дуже затриманий коментар, але пристрій Даффа не передбачає синтаксичних відхилень. Дужки правильно врівноважуються. Особливість C найчастіше ігнорується в дискусіях про те, чи є C без контексту, є препроцесором. Я скептично налаштований на те, що існує будь-яка інтерпретація "без контексту" інтерпретації, яка дозволяє використовувати її для опису мови з макропроцесором, навіть добре сприйнятого. А препроцесор С - це що завгодно, але добре себе поводить.
rici

4

Ні, і багато практичних мов не є контекстними. Наприклад, граматика C ++ ні, тому що в деяких контекстах роздільна здатність граматики залежить від введення інформації, яка не є контекстною.


4

Спершу дозвольте мені розрізнити синтаксис мови програмування та самої мови.

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

Однак багато мов насправді не містять контексту (коли використовуються символи оголошення перед вживанням, наприклад, у java, C (++), D).

Приємний факт: D має оцінку функції компіляції-часу компіляції-часу та розширення шаблону, що робить мову самою, що не можна визначити Тюрінгом. Однак творець мови намагався зробити синтаксис CFG.


Аналіз імен та типів, як правило, формується безконтекстними завданнями.
Рафаель

Метапрограмування шаблонів на C ++ завершено Turing.
Джефф Бурджес

3

Що стосується "Чи всі контекстні мови програмування / сценаріїв вільні граматики?" частина стосується, відповідь - це визначений ні.

Що стосується: головне питання "для мови, яка згодом може бути складена / перетворена в інструкції на системному рівні", я не знаю, чому вона обов'язково повинна бути CFG. Однак можливі кращі пояснення.


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

3

Мова програмування має базуватися на певному граматичному формалізмі, прикладом якого є CFG. Хоча CFG є найпоширенішими (і це звичайна річ, яку викладають на курсах компіляторів на університетах), існують інші формалізми, такі як граматики виразного розбору, про які ви можете ознайомитися більше тут (pdf) або у Вікіпедії, щоб прочитати більший розмір укусу.

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