Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
shpora1_Kalabin.doc
Скачиваний:
2
Добавлен:
01.04.2025
Размер:
755.2 Кб
Скачать

Любой язык может быть порожден бесконечным числом грамматик.

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

Двусмысленные порождающие грамматики.

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

Пример V4={a,b}; L4={ α | в цепочке α количества вхождений а и b равны}.

Можно придумать различные грамматики, порождающие этот язык. Каждая грамматика отражает некоторую глубинную идею порождения цепочек с указанными свойствами. Поэтому можно использовать грамматику G2 ( G2: S→ aSb ; S→ ε) для порождения цепочек аnbn, и добавить в нее правило, позволяющее произвольную перестановку символов: G4: S→ aSb; S→ε abba Вывод цепочки aаbbаb: S→ aSb aaSbb aaaSbbb aaabbbaababbaаbbаb.

Попытаемся по другому построить грамматику, порождающую этот язык. Если в любой цепочке с совпадающим числом символов a и b первый символ – а, то во всей остальной части цепочки число символов b на единицу больше числа символов а. Пусть В – нетерминал, из которого порождаются все цепочки с этим свойством. Если первый символ такой цепочки b, то в оставшейся части цепочки количества символов a и b одинаковы, и эта часть порождается из S. Если первый символ такой цепочки тоже а, то это значит, что в оставшейся части цепочки число символов b уже на два больше, чем число символов a, и, следовательно, этот остаток всегда можно представить, как две стоящие рядом подцепочки, каждая из которых содержит на одно вхождение символа b больше, чем символа а. Окончательно, G'4: S→aB  bA  ε; В→ bS  aBB; A→ aS  bAA Вывод цепочки aаbbаb: S→ aB → aaBB → aabSB → aabB → aabbS→ aabbaB→ aаbbаbS→ aаbbаb. В этой грамматике возможен и другой вывод той же самой цепочки: S→ aB → aaBB → aabSB → aabbAB→ aabbaSB → aabbaB → aаbbаbS→ aаbbаb. Грамматика G'4 – контекстно-свободная, оба приведенные вывода канонические правые, и им соответствуют совершенно различные деревья вывода (рис. 2.5). Это как раз тот случай, когда одной и той же цепочке в одной и той же грамматике соответствуют различные структуры, а поскольку именно со структурой мы связываем смысл (значение) цепочки, то мы построили пример двусмысленной грамматики.

  1. Проблема разбора.

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

1. Е Е + Т 2. Е T 3. T T * F 4. T F 5. F (Е) 6. F x 7. F y

Ясно, что строка (x + y) * x принадлежит данному языку. В частности, это можно вывести следующим образом (для каждого шага вывода указан номер применяемого правила): 2) E T 3) ⇒ T * F 4) ⇒ F * F 5) ⇒ (E)* F

1) ⇒ (E + T) * F 2) ⇒ (T + T) * F 4) ⇒ (F + T) * F 6) ⇒ (x + T)*F 4) ⇒ (x + F) * F 7) ⇒ (x + y) * F 6) ⇒ (x + y) * x

Или же это можно вывести так: 2) E T 3) ⇒ T * F 6) ⇒ T * x 4) ⇒ F * x 5) ⇒ (E) * x

1) ⇒ (E + T) * x 4) ⇒ (E + F) * x 7) ⇒ (E + y) * x 2) ⇒ (T + y) * x 4) ⇒ (F + y) * x 6) ⇒ (x + y) * x

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

правил, применяемая для генерирования предложения посредством левостороннего вывода. В данном случае левосторонний разбор можно записать как 2,3,4,5,1,2,4,6,4,7,6.

Правосторонний разбор предложения является обратной последовательностью порождающих правил, используемых для генерирования предложения посредством правостороннего вывода; например, в вышеприведенном случае правосторонний разбор запишется в виде 6,4,2,7,4,1,5,4,6,3,2. Обратный порядок последовательности порождающих правил связан с тем, что правосторонний разбор обычно ассоциируется с приведением предложения к начальному символу, а не с генерированием предложения из начального символа (см. ниже разбор снизу вверх). Заметим, что каждое порождающее правило используется в обоих выводах (или разборах) одинаковое число раз.

Дерево разбора. Вывод может быть описан также в терминах построения дерева, известного как синтаксическое дерево (или дерево разбора). В случае со строкой (x + y) * x

синтаксическое дерево будет таким, как показано на рис. 4.1.

Проблему разбора можно свести к: 1) нахождению левостороннего разбора; 2) нахождению правостороннего разбора; 3) построению синтаксического дерева.

Неоднозначные грамматики. В большинстве случаев левосторонний и правосторонний разборы и синтаксическое дерево являются уникальными. Однако для грамматики с порождающими правилами: S S+S | x предложение x + x + x имеет два синтаксических дерева (рис. 4.2) и два левосторонних (и правосторонних) разбора:

S S + S S S + S

S + S + S x + S

x + S + S x + S + S

x + x + S x + x + S

x + x + x x + x + x

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]