Какие языки программирования не зависят от контекста? - PullRequest
57 голосов
/ 22 мая 2009

Или, если быть более точным: какие языки программирования определяются грамматикой без контекста?

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

Дополнительный представитель для кратких примеров: -)

Ответы [ 8 ]

41 голосов
/ 17 июля 2013

Какие языки программирования не зависят от контекста? [...]

Моя интуиция говорит мне, что функциональные языки могут быть контекстно-свободными [...]

Краткая версия: Вряд ли есть какие-либо языки программирования реального мира, которые не имеют контекста в любом значении этого слова. Независимо от того, является ли язык контекстным или нет, это не имеет никакого отношения к его функциональности. Это просто вопрос того, насколько сложны языковые правила и функции для анализа.

Вот CFG для императив язык Brainfuck :

Program → Instr Program | ε
Instr → '+' | '-' | '>' | '<' | ',' | '.' | '[' Program ']'

А вот CFG для функционала исчисление комбинатора SKI :

Program → E
E → 'S' E E E
E → 'K' E E
E → 'I'
E → '(' E ')'

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


Более длинная версия: Обычно контекстно-свободные грамматики (CFG) используются только для примерно определения синтаксиса языка. Следует различать синтаксически правильные программы и программы, которые компилируют . Чаще всего компиляторы разделяют анализ языка на синтаксический анализ , который строит и проверяет общую структуру фрагмента кода, и семантический анализ , который проверяет значение программа.

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

Если, с другой стороны, «контекстно-свободный язык» означает только « ..., для которого все программы проходят синтаксический анализ », ответ заключается в том, насколько сложен только синтаксис. Есть много синтаксических особенностей, которые трудно или невозможно описать одним CFG. Некоторые из них преодолеваются путем добавления дополнительного состояния к анализаторам для отслеживания счетчиков, таблиц поиска и т. Д.

Примеры синтаксических признаков, которые невозможно выразить с помощью CFG:

  • Языки, чувствительные к отступам и пробелам, такие как Python и Haskell. Отслеживание произвольно вложенных уровней отступа по существу зависит от контекста и требует отдельных счетчиков для уровня отступа; и сколько пробелов, которые используются для каждого уровня и сколько уровней.

    Разрешение только фиксированного уровня отступа с использованием фиксированного количества пробелов будет работать путем дублирования грамматики для каждого уровня отступа, но на практике это неудобно.

  • Проблема синтаксического анализа Typedef говорит, что программы на C неоднозначны во время лексического анализа, потому что из одной только грамматики невозможно узнать, является ли что-то обычным идентификатором или псевдонимом typedef для существующего типа.

    Пример:

      typedef int my_int;
      my_int x;
    

    В точке с запятой необходимо обновить среду типов с помощью записи для my_int. Но если лексер уже посмотрел вперед на my_int, он будет использовать его как идентификатор, а не как имя типа.

  • Языки макросов и шаблонов, такие как Lisp, C ++, Template Haskell, Nim и т. Д. Поскольку синтаксис изменяется по мере его синтаксического анализа, одним из решений является преобразование синтаксического анализатора в самоизменяющуюся программу. Смотрите также " Является ли C ++ контекстно-зависимым или контекстно-зависимым? "

  • Часто приоритет оператора и ассоциативность не выражаются непосредственно в CFG, даже если это возможно . Например, CFG для грамматики небольшого выражения, где ^ связывает сильнее, чем ×, а × связывает сильнее, чем +, может выглядеть так:

    E → E ^ E
    E → E × E
    E → E + E
    E → (E)
    E → num
    

    Этот CFG является неоднозначным , однако, и часто сопровождается таблицей приоритетов / ассоциативности , например, например. ^ связывает сильнее, × связывает сильнее +, ^ ассоциируется справа, а × и + левоассоциативны.

    Приоритет и ассоциативность могут быть закодированы в CFG механическим способом, так что он однозначен и создает только синтаксические деревья, где операторы ведут себя правильно. Пример этого для грамматики выше:

    E₀ → EA E₁
    EA → E₁ + EA
    EA → ε
    E₁ → EM E₂
    EM → E₂ × EM
    EM → ε
    E₂ → E₃ EP
    EP → ^ E₃ EP
    E₃ → num
    E₃ → (E₀)
    

    Но неоднозначные CFG + таблицы приоритетов / ассоциативности являются общими, потому что они более читабельны и потому что различные типы LR parser библиотек генератора могут производить более эффективные синтаксические анализаторы за счет , устраняя конфликты сдвига / уменьшения вместо того, чтобы иметь дело с однозначной, преобразованной грамматикой большего размера.

Теоретически все конечные наборы строк являются регулярными языками, и поэтому все легальные программы ограниченного размера являются регулярными. Поскольку обычные языки являются подмножеством контекстно-свободных языков, все программы ограниченного размера не зависят от контекста. Аргумент продолжается,

Хотя можно утверждать, что приемлемым ограничением для языка будет разрешать только программы длиной менее миллиона строк, нецелесообразно описывать язык программирования как обычный язык: описание будет слишком большим .
- Основы проектирования компиляторов Торбена Моргенсена, гл. 2.10.2

То же самое касается CFG. Чтобы ответить на ваш подвопрос немного по-другому,

Какие языки программирования определены грамматикой без контекста?

Большинство реальных языков программирования определяются своими реализациями, и большинство синтаксических анализаторов для реальных языков программирования написаны от руки или используют генератор синтаксических анализаторов, который расширяет контекстный анализ. К сожалению, не часто можно найти точный CFG для вашего любимого языка. Когда вы это делаете, обычно это форма Бэкуса-Наура (BNF) или спецификация синтаксического анализатора, которая, скорее всего, не является чисто контекстно-свободной.

Примеры грамматических спецификаций из дикой природы:

33 голосов
/ 22 мая 2009

Набор программ, которые синтаксически верны, не зависит от контекста почти для всех языков.

Набор программ, которые компилируются, не является контекстно-зависимым почти для всех языков. Например, если набор всех компилируемых программ на Си был свободен от контекста, то путем пересечения с обычным языком (также известным как регулярное выражение) набор всех компилируемых программ на Си, соответствующих

^int main\(void\) { int a+; a+ = a+; return 0; }$

будет контекстно-свободным, но это явно изоморфно языку a ^ kba ^ kba ^ k, который хорошо известен , а не как контекстно-свободный.

8 голосов
/ 02 августа 2011

В зависимости от того, как вы понимаете вопрос, ответ меняется. Но IMNSHO, правильный ответ заключается в том, что все современные языки программирования на самом деле чувствительны к контексту. Например, не существует контекстно-свободной грамматики, которая принимает только синтаксически правильные программы на Си. Люди, которые указывают на контекстно-свободные грамматики yacc / bison для C, упускают суть.

3 голосов
/ 25 июня 2012

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

Я считаю, что большинство (если не все) современные языки программирования не являются контекстно-свободными. Например, если у вас есть пользовательские типы (что очень часто встречается в современных языках), вы автоматически учитываете контекст.

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

Это, однако, не означает, что такой язык не может существовать. Например, нетипизированный лямбда-исчисление можно описать с помощью контекстно-свободной грамматики и, конечно, по Тьюрингу.

3 голосов
/ 18 августа 2009

Чтобы перейти к самому драматическому примеру неконтекстно-свободной грамматики, грамматика Perl, насколько я понимаю, turing-complete .

2 голосов
/ 01 апреля 2013

Большинство современных языков программирования не являются контекстно-свободными языками. В качестве доказательства, если я вникну в корень CFL, соответствующий ему карманный компьютер не сможет обработать совпадения строк, например {ww | w is a string}. Так что большинство языков программирования требуют этого.

Пример:

int fa; // w
fa=1; // ww as parser treat it like this
2 голосов
/ 22 июня 2012

Я думаю, Haskell и ML поддерживают контекстно-свободный. Смотрите эту ссылку для Haskell.

2 голосов
/ 22 мая 2009

VHDL является несколько контекстно-зависимым:

VHDL является контекстно-зависимым способом. Рассмотрим это утверждение внутри Процесс:

jinx := foo(1);

Ну, в зависимости от объектов, определенных в рамках процесса (и его ), это может быть:

  • вызов функции
  • Индексирование массива
  • Индексирование массива, возвращенного вызовом функции без параметров

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

Это всего лишь пример. Система VHDL типа / подтипа аналогично контекстно-зависимый беспорядок, который очень трудно разобрать.

(Эли Бендерский, «Парсинг VHDL [очень] труден» , 2009)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...