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

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

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

Extra rep для кратких примеров : -)

8 ответов


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

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

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

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


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

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

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

вот CFG для важно язык Brainfuck:

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

и вот CFG для функциональное Лыжное комбинаторное исчисление:

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

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


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

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

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

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

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

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

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

    пример:

      typedef int my_int;
      my_int x;
    

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

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

  • часто приоритет оператора и ассоциативность не выражаются непосредственно в CFGs, даже если это *возможно. Например, 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₀)
    

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

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

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

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

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

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

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


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


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


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

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

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

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


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


VHDL несколько зависит от контекста.

(Google: разбор-vhdl-очень-трудно)


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

пример:

int fa; // w
fa=1; // ww as parser treat it like this