иерархия Хомского и языки программирования

Я пытаюсь изучить некоторые аспекты Иерархии Хомского, связанные с языками программирования, и мне все еще нужно прочитать Книгу Дракона.

Я читал, что большинство языков программирования можно анализировать как контекстно-свободную грамматику (CFG). С точки зрения вычислительной мощности он равен мощности недетерминированного автомата с выталкиванием вниз. Я прав?

Если это правда, то как CFG может содержать неограниченную грамматику (UG), которая является полной по Тьюрингу? Я спрашиваю, потому что, даже если языки программирования описываются с помощью CFG, они фактически используются для описания машин Тьюринга, то есть с помощью UG.

Я думаю, что это связано как минимум с двумя разными уровнями вычислений, первый, который представляет собой синтаксический анализ CFG, фокусируется на синтаксисе, связанном со структурой (представлением?) Языка, в то время как другой фокусируется на семантике (смысл, интерпретация самих данных?), связанных с возможностями языка программирования, который является полным по Тьюрингу. Опять же, верны ли эти предположения?




Ответы (3)


Я читал, что большинство языков программирования можно анализировать как контекстно-свободную грамматику (CFG). С точки зрения вычислительной мощности он равен мощности недетерминированного автомата с выталкиванием вниз. Я прав?

Технически да. Полезно - нет.

Есть как минимум два полезных способа подумать над этими вопросами:

  • Если вы думаете о наборе строк, у вас есть язык.
  • Если вы думаете об алгоритме определения того, является ли строка языком или нет, у вас возникает проблема принятия решения.

Сложность состоит в том, что, хотя большинство языков программирования имеют базовую структуру, которая легко описывается контекстно-свободной грамматикой (интересным исключением является Tcl), многие предложения, описываемые контекстно-свободной грамматикой, на самом деле не находятся "в language ", где под" на языке "я имею в виду" действующая программа на рассматриваемом языке ". Эти лишние предложения обычно исключаются некоторой формой статической семантики. Например, следующее высказывание является предложением в контекстно-свободной грамматике программ C, но оно не входит в набор допустимых программ C:

int f(void) { return n + 1; }

Проблема здесь в том, что n не входит в сферу охвата. C требует «объявления перед использованием», и это свойство не может быть выражено с помощью контекстно-свободной грамматики.

Типичная процедура принятия решения для реального языка программирования является частью внешнего интерфейса компилятора или интерпретатора и состоит как минимум из двух частей: первая, синтаксический анализатор, эквивалентна по мощности принятия решения к автомату с опусканием вниз; но второй выполняет дополнительные проверки, которые исключают многие высказывания как недействительные. Если для этих проверок требуется какое-либо свойство определения перед использованием, они не могут быть выполнены автоматом выталкивания или контекстно-свободной грамматикой.

Если это правда, то как CFG может содержать неограниченную грамматику (UG), которая является полной по Тьюрингу?

CFG ничего не «хранит», он просто описывает язык.

... даже если языки программирования описываются с помощью CFG, они фактически используются для описания машин Тьюринга, то есть с помощью UG.

Здесь вы пропускаете некоторые важные уровни косвенного обращения.

Я думаю, что это связано как минимум с двумя разными уровнями вычислений, первый, который представляет собой синтаксический анализ CFG, фокусируется на синтаксисе, связанном со структурой (представлением?) Языка, в то время как другой фокусируется на семантике (смысл, интерпретация самих данных?), связанных с возможностями языка программирования, который является полным по Тьюрингу. Опять же, верны ли эти предположения?

Мне они кажутся немного запутанными, но вы на правильном пути. Ключевой вопрос: «В чем разница между языком и языком программирования?» Ответ заключается в том, что язык программирования имеет вычислительную интерпретацию. Вычислительные интерпретации бывают множества прекрасных разновидностей, и не все из них являются полными по Тьюрингу. Но магия заключается в интерпретации, а не в синтаксисе, поэтому иерархия Хомского здесь не очень актуальна.

Чтобы доказать мою точку зрения, приведу крайний пример: регулярный язык [1-9][0-9]* является полным по Тьюрингу при следующей интерпретации:

  • Язык SK-комбинаторов полон по Тьюрингу.
  • Есть только счетное количество программ SK.
  • Их легко однозначно и детерминированно перечислить.
  • Следовательно, мы можем связать каждое положительное целое число с программой SK.
  • Если мы интерпретируем последовательность цифр как положительное целое число стандартным способом, мы можем одинаково хорошо интерпретировать ту же последовательность цифр, что и программа SK, и, более того, любая программа SK может быть выражена с использованием конечного последовательность цифр.

Следовательно, язык целочисленных литералов является полным по Тьюрингу.

Если сейчас голова не болит, значит, должно.

person Norman Ramsey    schedule 01.06.2010
comment
К вашему сведению, вы можете создать BNF для Tcl. Это просто менее информативно, чем в большинстве языков, потому что обычные рекурсивные термины (if, while, программные блоки в целом) полностью определены на семантическом уровне. То есть это стандартные библиотечные функции, не более того. (Обратной стороной этого является то, что действительно легко встраивать чужой синтаксис в программы Tcl, при условии, что они сбалансированы в скобках. Практически все ...) - person Donal Fellows; 01.06.2010
comment
@Donal: Да, за исключением того, что любая программа может динамически добавлять произвольные новые произведения в грамматику. На практике от синтаксического анализатора мало пользы - на самом деле вы не можете анализировать программу на Tcl - да и в Tcl не так уж много синтаксического анализатора. Но встраивать странности действительно очень, очень легко. - person Norman Ramsey; 01.06.2010
comment
Большое спасибо ! Это был тот ответ, который я ожидал. Не уверен, что с этим все понятно, но яснее. Думаю, я понял, что волшебство заключается в интерпретации, а не в синтаксисе. - person dader; 01.06.2010
comment
Хорошо, теперь все ясно. программы SK-комбинаторов, отображаемые в целые числа, являются таким мощным примером, я думаю, это более или менее нумерация Гёделя. спасибо, Рэмси! - person dader; 16.02.2014
comment
Ключевой вопрос - в чем разница между языком и языком программирования? Ответ в том, что у языка программирования есть вычислительная интерпретация. - Так думают лингвисты о языке, но это неверно. Предложения на разговорном языке не просто генерируют дерево синтаксического анализа или структуру данных. У них есть вычислительная интерпретация, иначе они не повлияли бы на своих слушателей. Очевидно, это верно для императивов. - person Phil Goetz; 12.06.2015
comment
Для Perl нет BNF, потому что он был специально разработан с учетом контекста. На самом деле есть части кода компилятора (например, для интерпретации оператора smartmatch и нотации косвенных объектов), которые пытаются угадать, чего хочет программист. К сожалению, это не дает языку большей вычислительной мощности; это только усложняет использование. - person Phil Goetz; 12.06.2015

Это абсолютно не так. Большинство языков программирования имеют синтаксис, который можно описать с помощью CFG или BNG, но соответствие синтаксису не гарантирует законной программы. Есть всевозможные дополнительные условия, такие как «переменные должны быть объявлены перед использованием» или «типы в этом выражении должны быть объединены законным способом», которые не охватываются грамматикой, и это что делает языки неконтекстно-свободными. (Это немного похоже на XML, который имеет формально проверяемое определение, но обычно также имеет дополнительные ограничения, которые анализатор не может проверить.)

person Kilian Foth    schedule 28.05.2010

Хорошим примером языка, не имеющего CFG для синтаксиса, является C ++. Вы, кажется, не совсем понимаете УГ. Универсальная грамматика - это проблема интерпретации, описываемая как язык слов, содержащих код для машины Тьюринга и слово, которое принимается этой машиной Тьюринга. Таким образом, вы кодируете не сам язык (набор слов), а машину Тьюринга. Теперь самое главное - у вас может быть язык из бесконечного количества слов, но вы не можете иметь слово из бесконечного числа символов. Это означает, что UG также содержит конечные слова и, следовательно, все описания машин Тьюринга конечны. Таким образом, описание машины Тьюринга (программы на языке программирования) имеет конечное число символов (операторов), поэтому язык описаний (синтаксическая грамматика языка программирования) может быть даже регулярным. Взгляните, например, на двоичную комбинаторную логику.

person Gabriel Ščerbák    schedule 30.05.2010