Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
36
Добавлен:
02.05.2014
Размер:
189.44 Кб
Скачать

Грамматики предшествования

Программирование работы недетерминированного МП-автомата - это сложная задача. Разработан алгоритм, позволяющий для произвольной КС-грамматики определить, принадлежит ли ей заданная входная цепочка (алгоритм Кока-Янгера-Касами).

Доказано, что время работы этого алгоритма пропорционально n3, где n - длина входной цепочки. Для однозначной КС-грамматики при использовании другого алгоритма (алгоритм Эрли) это время пропорционально n2. Подобная зависимость делает эти алгоритмы требовательными к вычислительным ресурсам, а потому мало пригодными для практических целей. Но на практике и не требуется анализ цепочки произвольного КС-языка - большинство конструкций языков программирования может быть отнесено в один из классов КС-языков, для которых разработаны алгоритмы разбора, линейно зависящие от длины входной цепочки.

КС-языки делятся на классы в соответствии со структурой правил их грамматик. В каждом из классов налагаются дополнительные ограничения на допустимые правила грамматики.

Одним из таких классов является класс грамматик предшествования. Они используются для синтаксического разбора цепочек с помощью алгоритма “сдвиг-свертка”. Выделяют следующие типы грамматик предшествования:

  • простого предшествования;

  • расширенного предшествования;

  • слабого предшествования;

  • смешанной стратегии предшествования;

  • операторного предшествования.

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

Грамматикой простого предшествованияназывают такую КС-грамматикуG(VT,VN,P,S),V=VTÈVNв которой:

  1. Для каждой упорядоченной пары терминальных и нетерминальных символов выполняется не более чем одно из трех отношений предшествования:

  • Si=Sj("Si,SjÎV), если и только если$правило U®xSiSjP, гдеUÎVN,x,yÎV*;

  • Si<Sj("Si,SjÎV), если и только если$правило U®xSiDyÎPи вывод DÞ*Sjz, гдеU,DÎVN,x,y,zÎV*;

  • Si>Sj("Si,SjÎV) , если и только если$правило U®xCSjPи выводCÞ*zSiили$правило U®xCDyÎPи выводыCÞ*zSiи DÞ*Sjw, гдеU,C,DÎVN,x,y,z,wÎV*.

  1. Различные порождающие правила имеют разные правые части.

Отношения =, < и > называют отношениями предшествования для символов. Отношение предшествования единственно для каждой упорядоченной пары символов. При этом между какими-либо двумя символами может и не быть отношения предшествования - это значит, что они не могут находиться рядом ни в одном элементе разбора синтаксически правильной цепочки. Отношения предшествования зависят от порядка, в котором стоят символы, и в этом смысле их нельзя путать со знаками математических операций - например, если Si>Sj, то не обязательно, чтоSj<Si(поэтому знаки предшествования иногда помечают специальной точкой: =×, <×,×>)

Метод предшествования основан на том факте, что отношения предшествования между двумя соседними символами распознаваемой строки соответствуют трем следующим вариантам:

  • Si<Si+1, если символSi+1- крайний левый символ некоторой основы;

  • Si>Si+1, если символSi- крайний правый символ некоторой основы;

  • Si=Si+1, если символыSiиSi+1принадлежат одной основе.

Исходя из этих соотношений выполняется разбор строки для грамматики предшествования.

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

Матрицу предшествования грамматики можно построить, опираясь непосредственно на определения отношений предшествования, но удобнее воспользоваться двумя дополнительными множествами - множеством крайних левых и множеством крайних правых символов относительно нетерминалов грамматики. Эти множества определяются следующим образом:

  • L(U) = {T |$UÞ*Tz}, U,TÎV, zÎV*- множество крайних левых символов относительно нетерминального символа U (цепочка z может быть и пустой цепочкой);

  • R(U) = {T |$UÞ*zT}, U,TÎV, zÎV*- множество крайних правых символов относительно нетерминального символа U.

Тогда отношения предшествования можно определить так:

  • Si=Sj("Si,SjÎV), если$правило U®xSiSjP, гдеUÎVN,x,yÎV*;

  • Si<Sj("Si,SjÎV), если$правило U®xSiDyÎPиSjÎL(D), гдеU,DÎVN,x,yÎV*;

  • Si>Sj("Si,SjÎV) , если$правило U®xCSjPиSiÎR(C) или$правило U®xCDyÎPиSiÎR(C),SjÎL(D), гдеU,C,DÎVN,x,yÎV*.

Такое определение отношений удобнее на практике, так как не требует построения выводов, а множества L(U) иR(U) могут быть построены для каждого нетерминального символаUÎVNпо очень простому алгоритму:

Шаг 1.Для каждого нетерминального символа U ищем все правила, содержащие U в левой части. Во множествоL(U) включаем самый левый символ из правой части правил, а во множествоR(U) - самый крайний символ правой части. Переходи к шагу 2.

Шаг 2.Для каждого нетерминального символа U: если множествоL(U) содержит нетерминальные символы грамматики U’,U”,..., то его надо дополнить символами, входящими в соответствующие множестваL(U’), L(U”), ... и не входящими вL(U). Ту же операцию надо выполнить дляR(U).

Шаг 3.Если на предыдущем шаге хотя бы одно множествоL(U) илиR(U) для некоторого символа грамматики изменилось, то надо вернуться к шагу 2, иначе построение закончено.

После построения множеств L(U) иR(U) по правилам грамматики создается матрица предшествования. Матрицу предшествования дополняют символами^ни^к(начало и конец цепочки). Для них определены следующие отношения предшествования:

^н< a,"aÎV, если$SÞ*ax, гдеSÎVN,xÎV*или (с другой стороны) еслиaÎL(S);

^к> a,"aÎV, если$SÞ*xa, гдеSÎVN,xÎV*или (с другой стороны) еслиaÎR(S).

Грамматикой операторного предшествованияназывается приведенная КС-грамматика безl-правил (e-правил), в которой правые части продукций не содержат смежных нетерминальных символов. Для грамматики операторного предшествования отношения предшествования можно задать на множестве терминальных символов (включая символы^ни^к).

Отношения предшествования для грамматики операторного предшествования G(VN,VT,P,S) задаются следующим образом:

  • a=b, если и только если существует правило U®xabyÎPили правило U®xaCby, гдеa,bÎVT,U,CÎVN,x,yÎV*;

  • a<b, если и только если существует правилоU®xaCyÎPи выводCÞ*bzили выводCÞ*Dbz, гдеa,bÎVT,U,C,DÎVN,x,y,zÎV*;

  • a>b, если и только если существует правило U®xCbyÎPи вывод CÞ*zaили вывод CÞ*zaD, гдеa,bÎVT,U,C,DÎVN,x,y,zÎV*.

В грамматике операторного предшествования различные порождающие правила имеют разные правые части. Для грамматики операторного предшествования тоже строится матрица предшествования, но она содержит только терминальные символы грамматики.

Для построения этой матрицы удобно ввести множества крайних левых и крайних правых терминальных символов относительно нетерминального символа U - Lt(U) илиRt(U):

  • Lt(U) = {t|$UÞ*tzили$UÞ*Ctz}, где tÎVT,U,CÎVN,zÎV*;

  • Rt(U) = {t|$UÞ*ztили$UÞ*ztC}, где tÎVT,U,CÎVN,zÎV*.

Тогда определения отношений операторного предшествования будут выглядеть так:

  • a=b, если$правило U®xabyÎPили правило U®xaCby, гдеa,bÎVT,U,CÎVN,x,yÎV*;

  • a<b, если$правилоU®xaCyÎPиbÎLt(C), гдеa,bÎVT,U,CÎVN,x,yÎV*;

  • a>b, если$правило U®xCbyÎPиaÎRt(C), гдеa,bÎVT,U,CÎVN,x,yÎV*.

В данных определениях цепочки символов x,y,zмогут быть и пустыми цепочками.

Для нахождения множеств Lt(U) иRt(U) используется следующий алгоритм:

Шаг 1.Для каждого нетерминального символа грамматикиUстроятся множестваL(U) иR(U).

Шаг 2.Для каждого нетерминального символа грамматики U ищутся правила вида U®tzи U®Ctz, гдеtÎVT,CÎVN, zÎV*; терминальные символы t включаются во множествоLt(U). Аналогично для множестваRt(U) ищутся правила вида U®ztи U®ztC.

Шаг 3.Просматривается множествоL(U), в которое входят символы U’,U”,... МножествоLt(U) дополняется символами, входящими вLt(U’), Lt(U”), ... и не входящими вLt(U). Аналогичная операция выполняется и для множестваRt(U) на основе множестваR(U).

Для практического использования матрицу предшествования дополняют символами ^ни^к(начало и конец цепочки). Для них определены следующие отношения предшествования:

^н < a, " aÎVT, если $ SÞ*ax или $ SÞ*Cax, где S,CÎVN, xÎV* или если aÎLt(S);

^к > a, " aÎVT, если $ SÞ*xa или $ SÞ*xaC, где S,CÎVN, xÎV* или если aÎRt(S).