хомская иерархия и языки программирования - PullRequest
15 голосов
/ 28 мая 2010

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

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

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

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

Ответы [ 3 ]

23 голосов
/ 01 июня 2010

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

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

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

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

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

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

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

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

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

CFG ничего не "держит" - он просто описывает язык.

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

Вы пропускаете некоторые важные уровни косвенности здесь.

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

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

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

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

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

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

1 голос
/ 31 мая 2010

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

1 голос
/ 28 мая 2010

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

...