Формальная грамматика описывает, какие строки из алфавита формального языка являются допустимыми в соответствии с синтаксисом языка . Грамматика не описывает значение строк или то, что можно сделать с ними в любом контексте — только их форму. Формальная грамматика определяется как набор правил производства для таких строк в формальном языке.
Формальная теория языка, дисциплина, изучающая формальные грамматики и языки, является разделом прикладной математики . Её приложения встречаются в теоретической информатике , теоретической лингвистике , формальной семантике , математической логике и других областях.
Формальная грамматика — это набор правил для переписывания строк вместе с «начальным символом», с которого начинается переписывание. Поэтому грамматику обычно считают генератором языка. Однако иногда ее также можно использовать в качестве основы для « распознавателя » — функции в вычислениях, которая определяет, принадлежит ли данная строка языку или является грамматически неправильной. Для описания таких распознавателей формальная теория языка использует отдельные формализмы, известные как теория автоматов . Одним из интересных результатов теории автоматов является то, что невозможно разработать распознаватель для определенных формальных языков. [1] Синтаксический анализ — это процесс распознавания высказывания (строки в естественных языках) путем разбиения его на набор символов и анализа каждого из них в соответствии с грамматикой языка. Большинство языков имеют значения своих высказываний, структурированные в соответствии с их синтаксисом — практика, известная как композиционная семантика . В результате первым шагом к описанию смысла высказывания в языке является его разбиение на части и рассмотрение его проанализированной формы (известной как дерево синтаксического анализа в информатике и как его глубокая структура в генеративной грамматике ).
Грамматика в основном состоит из набора правил производства , правил переписывания для преобразования строк. Каждое правило определяет замену определенной строки (ее левой части ) на другую (ее правую часть ). Правило может быть применено к каждой строке, содержащей ее левую часть, и создает строку, в которой вхождение этой левой части было заменено ее правой частью.
В отличие от полусистемы Туэ , которая полностью определяется этими правилами, грамматика далее различает два вида символов: нетерминальные и терминальные символы ; каждая левая часть должна содержать по крайней мере один нетерминальный символ. Она также различает специальный нетерминальный символ, называемый начальным символом .
Язык, генерируемый грамматикой, определяется как множество всех строк без каких-либо нетерминальных символов, которые могут быть сгенерированы из строки, состоящей из одного начального символа, путем (возможно, повторного) применения ее правил любым возможным способом. Если существуют существенно различные способы генерации одной и той же строки, грамматика называется неоднозначной .
В следующих примерах конечными символами являются a и b , а начальным символом — S.
Предположим, у нас есть следующие правила производства:
затем мы начинаем с S и можем выбрать правило, которое будет к нему применено. Если мы выберем правило 1, то получим строку aSb . Если мы затем снова выберем правило 1, то заменим S на aSb и получим строку aaSbb . Если мы теперь выберем правило 2, то заменим S на ba и получим строку aababb , и все готово. Мы можем записать эту серию выборов более кратко, используя символы: .
Язык грамматики — бесконечное множество , где повторяется раз (и, в частности, представляет собой количество раз, когда было применено правило производства 1). Эта грамматика является контекстно-свободной (только отдельные нетерминалы появляются в качестве левых частей) и однозначной.
Предположим, что правила таковы:
Эта грамматика не является контекстно-свободной из-за правила 3 и неоднозначна из-за множественных способов использования правила 2 для генерации последовательностей s.
Однако язык, который он генерирует, — это просто набор всех непустых строк, состоящих из s и/или s. Это легко увидеть: чтобы сгенерировать a из an , дважды используйте правило 2 для генерации , затем дважды правило 1 и один раз правило 3 для генерации . Это означает, что мы можем генерировать произвольные непустые последовательности s, а затем заменять каждую из них на или по своему усмотрению.
Этот же язык может быть альтернативно сгенерирован с помощью контекстно-свободной, однозначной грамматики; например, регулярной грамматики с правилами
В классической формализации генеративных грамматик, впервые предложенной Ноамом Хомским в 1950-х годах, [2] [3] грамматика G состоит из следующих компонентов:
Грамматика формально определяется как кортеж . Такая формальная грамматика часто называется в литературе системой переписывания или грамматикой фразовой структуры . [5] [6]
Действие грамматики можно определить в терминах отношений на строках:
Грамматика фактически представляет собой полусистему Туэ , перезаписывающую строки точно таким же образом; единственное отличие состоит в том, что мы выделяем определенные нетерминальные символы, которые должны быть перезаписаны в правилах перезаписи, и интересуемся только перезаписями от обозначенного начального символа до строк без нетерминальных символов.
В этих примерах формальные языки определяются с использованием нотации конструктора множеств .
Рассмотрим грамматику , где , , — начальный символ, и она состоит из следующих правил продукций:
Эта грамматика определяет язык , где обозначает строку из n последовательных '. Таким образом, язык — это набор строк, которые состоят из 1 или более ', за которыми следует такое же количество ', за которым следует такое же количество '.
Вот несколько примеров вывода строк :
Когда Ноам Хомский впервые формализовал генеративные грамматики в 1956 году, [2] он классифицировал их по типам, которые сейчас известны как иерархия Хомского . Разница между этими типами заключается в том, что они имеют все более строгие правила производства и, следовательно, могут выражать меньше формальных языков. Два важных типа — это контекстно-свободные грамматики (тип 2) и регулярные грамматики (тип 3). Языки, которые можно описать с помощью такой грамматики, называются контекстно-свободными языками и регулярными языками соответственно. Хотя они гораздо менее мощные, чем неограниченные грамматики (тип 0), которые фактически могут выражать любой язык, который может быть принят машиной Тьюринга , эти два ограниченных типа грамматик используются чаще всего, поскольку синтаксические анализаторы для них могут быть эффективно реализованы. [8] Например, все регулярные языки могут быть распознаны конечным автоматом , и для полезных подмножеств контекстно-свободных грамматик существуют хорошо известные алгоритмы для генерации эффективных LL-анализаторов и LR-анализаторов для распознавания соответствующих языков, которые генерируют эти грамматики.
Контекстно -свободная грамматика — это грамматика, в которой левая часть каждого правила производства состоит только из одного нетерминального символа. Это ограничение нетривиально; не все языки могут быть сгенерированы контекстно-свободными грамматиками. Те, которые могут, называются контекстно-свободными языками .
Определенный выше язык не является контекстно-свободным языком, и это можно строго доказать с помощью леммы о накачке для контекстно-свободных языков , но, например, язык (по крайней мере 1, за которым следует такое же количество символов ') является контекстно-свободным, поскольку его можно определить с помощью грамматики с , , начальным символом и следующими правилами вывода:
Контекстно-свободный язык может быть распознан со временем ( см. обозначение Big O ) с помощью алгоритма, такого как распознаватель Эрли . То есть, для каждого контекстно-свободного языка можно построить машину, которая принимает строку в качестве входных данных и определяет со временем, является ли строка членом языка, где — длина строки. [9] Детерминированные контекстно-свободные языки — это подмножество контекстно-свободных языков, которые могут быть распознаны за линейное время. [10] Существуют различные алгоритмы, которые нацелены либо на этот набор языков, либо на некоторое его подмножество.
В обычных грамматиках левая сторона снова представляет собой только один нетерминальный символ, но теперь правая сторона также ограничена. Правая сторона может быть пустой строкой, или одиночным терминальным символом, или одиночным терминальным символом, за которым следует нетерминальный символ, но ничего больше. (Иногда используется более широкое определение: можно разрешить более длинные строки терминалов или одиночные нетерминалы без чего-либо еще, что упрощает обозначение языков , при этом определяя тот же класс языков.)
Определенный выше язык не является регулярным, но язык (по крайней мере 1, за которым следует по крайней мере 1 , где числа могут быть разными) является регулярным, поскольку его можно определить с помощью грамматики с , , начальным символом и следующими правилами производства:
Все языки, сгенерированные регулярной грамматикой, могут быть распознаны со временем конечным автоматом. Хотя на практике регулярные грамматики обычно выражаются с помощью регулярных выражений , некоторые формы регулярных выражений, используемые на практике, не генерируют строго регулярные языки и не показывают линейной производительности распознавания из-за этих отклонений.
Было разработано много расширений и вариаций оригинальной иерархии формальных грамматик Хомского, как лингвистами, так и специалистами по информатике, обычно либо для того, чтобы увеличить их выразительную силу, либо для того, чтобы сделать их более легкими для анализа или разбора. Некоторые формы разработанных грамматик включают:
Рекурсивная грамматика — это грамматика, которая содержит правила производства, которые являются рекурсивными . Например, грамматика для контекстно-свободного языка является леворекурсивной, если существует нетерминальный символ A , который может быть пропущен через правила производства для получения строки с A в качестве самого левого символа. [15] Примером рекурсивной грамматики является предложение внутри предложения, разделенное двумя запятыми. [16] Все типы грамматик в иерархии Хомского могут быть рекурсивными.
Хотя существует огромное количество литературы по алгоритмам синтаксического анализа , большинство этих алгоритмов предполагают, что язык, который нужно проанализировать, изначально описан с помощью генеративной формальной грамматики, и что цель состоит в том, чтобы преобразовать эту генеративную грамматику в работающий синтаксический анализатор. Строго говоря, генеративная грамматика никоим образом не соответствует алгоритму, используемому для синтаксического анализа языка, и различные алгоритмы имеют различные ограничения на форму правил производства, которые считаются правильно сформированными.
Альтернативный подход заключается в формализации языка в терминах аналитической грамматики в первую очередь, что более непосредственно соответствует структуре и семантике парсера для языка. Примеры формализмов аналитической грамматики включают в себя следующее: