Опубликован: 23.07.2006 | Доступ: свободный | Студентов: 2215 / 889 | Оценка: 4.28 / 4.17 | Длительность: 21:37:00
Специальности: Системный архитектор
Лекция 4:

Теория языков

Некоторые свойства грамматик

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

Во-первых, различные грамматики могут порождать один и тот же язык (такие грамматики называются эквивалентными ). Например, приведенная выше грамматика G_{1} эквивалентна следующей грамматике G_{2}=(\{a,b\},\{S,Y\},P,S), где правила из P определены следующим образом: P = {\{}{S \to aS, S \to a, S \to b, S \to bY, Y \to b, Y \to bY, S \to \varepsilon }{\}}.

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

Во-вторых, необходимо отметить, что определение грамматик не накладывает никаких ограничений на количество нетерминалов в левой части правил и приведенные выше примеры не должны создавать обманчивого впечатления, что все грамматики содержат один и только один нетерминал в левой части каждого правила. В качестве иллюстрации приведем следующий пример: G_{3}=(\{a,b,c\},\{S,B,C\},P,S) , где P содержит следующие правила: P = {\{}{S \to aSBC, S \to abC, CB \to BC, bB \to bb, bC \to bc, cC \to cc}{\}}. Это абсолютно законная грамматика, порождающая язык {\{} a^{n}b^{n}c^{n} {, n \ge 1}{\}}.

В качестве другого примера приведем еще одну грамматику, эквивалентную грамматике G_{1}: G_{4}=(\{0,1\},\{A,S\},P,S) , где P = {\{}{S \to 0A1, 0A \to 00A1, S \to \varepsilon }{\}}. В этом варианте левая часть одного из правил содержит пару из терминального и нетерминального символа.

В-третьих, упомянем одно соглашение, которое нам пригодится впоследствии: для обозначения n правил вида { \alpha \to \beta }_{1} {,  \alpha \to \beta }_{2} {, ..., \alpha \to \beta }_{n} мы будем использовать следующую запись: { \alpha \to  \quad \beta }_{1} { \vert  \quad \beta }_{2 } { \vert ... \vert  \quad \beta }_{n}. В правилах такого вида вертикальная черта читается как "или".

Иерархия Хомского

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

Грамматика G называется:

  • выровненной вправо (праволинейной) , если любое правило из P имеет вид A \to xB или A \to x , где A, B - нетерминалы, а x - терминал (возможно, пустой).
  • контекстно-свободной (бесконтекстной) , если любое правило из P имеет вид A \to \alpha , где A - нетерминал, \alpha - нетерминал или терминал
  • контекстно-зависимой (неукорачивающей) , если все правила из Р имеют вид \alpha \to \beta , где \vert {\alpha } \vert  \quad \le  \quad \vert {\beta } \vert
  • общего вида (без ограничений) , если грамматика не удовлетворяет ни одному из указанных выше ограничений.

Иногда приведенные выше классы нумеруют от трех до нуля и называют каждый класс "грамматикой типа n", например, грамматика общего вида называется грамматикой типа 0. Мы будем избегать этого обозначения, так как оно не проясняет суть вопроса.

Очевидно, что эта классификация - включающая, т.е. все контекстно-свободные грамматики являются и контекстно-зависимыми, все контекстно-зависимые грамматики являются грамматиками общего вида и т.д. Кроме того, можно показать, что существуют языки, принадлежащие к типу i, но не к типу i+1. Например, язык G_{3} является контекстно-зависимым, но не контекстно-свободным, т.е. не существует контекстно-свободной грамматики, порождающий этот язык. С другой стороны, некоторые нерегулярные грамматики могут порождать регулярные языки (например, грамматика G_{1} - нерегулярная, но порождаемый ею язык регулярен, т.к. эквивалентная G_{1} грамматика G_{2} регулярна). Наконец, отметим, что определение контекстно-зависимой грамматики запрещает использование правил вида A \to \varepsilon . Это сделано для того, чтобы алгоритм, определяющий принадлежность цепочки языку, не мог бы зациклиться.