При восходящем грамматическом разборе правила подстановки применяются для свертки (приведения) всего исходного предложения к начальному символу грамматики. С этой целью в приводимой строке последовательно отыскивается основа - самая левая часть строки, которая по одному из правил подстановки может быть заменена на нетерминал, и выполняется эта замена.
Между любыми двумя соседними символами приводимой строки p и q могут существовать три отношения:
p<q, | если q - самый левый символ некоторой основы: |
| ||||
p>q, | если p - самый правый символ некоторой основы: |
| ||||
p=q, | если символы принадлежат одной основе: |
|
Отношения <,>, = называются отношениями предшествования.
Пусть p, q - любые символы (терминальные или нетерминальные), U, C, D - нетерминальные символы, x,y,z,w - любые строки, возможно пустые. Грамматика называется грамматикой с простым предшествованием, если для каждой упорядоченной пары символов выполняется не более чем одно из трех отношений предшествования:
p=q, | если существует правило U -> xpqy; |
p<q, | если существует правило U -> xpDy и вывод D =>+ qz; |
p>q, | если существует правило U -> xCqy и вывод C =>+ zp или правило U -> xCDy и выводы C =>+ zp, D =>+ qw. |
Для определения отношений предшествования предварительно для каждого нетерминального символа U находятся два множества:
L(U) - | множество самых левых символов в разложениях U, т.е. множество таких символов q, что существует вывод U =>+ qz; |
R(U) - | множество самых правых символов в разложениях U, т.е. множество таких символов p, что существует вывод U =>+ zp. |
Построение множеств L(U), R(U) состоит из следующих шагов:
Z -> bMb M -> (N | a N -> Ma) |
Грамматика определяет цепочки символов bab, b(aa)b, b((aa)a)b, b(((aa)a)a)b и т.д. |
L(U), R(U) после первого шага | окончательно | ||||||||||||
|
|
Вывод отношений между символами:
|
Например:
|
Разбор предложений в грамматиках с простым предшествованием ведется с
использованием стека терминальных и нетерминальных символов.
Пусть необходимо выполнить грамматический разбор для некоторой
входной строки терминальных символов t(1)...t(n). Строка ограничивается
с двух сторон терминальным символом ┴, при этом считается, что
для любого терминала t(j) ┴<t(j) и t(j)>┴. Формируется стек S,
элементы которого s(i) - терминальные и нетерминальные символы. В стек
заносится символ ┴ (s(1)=┴). Далее, на каждом промежуточном этапе
действия определяются состоянием стека - s(1)...s(k) и остатком
входного предложения - t(j)...t(n)┴. Проверяется отношение между
верхним элементом стека s(k) и очередным символом строки t(j). Если
отношения нет, то входная строка некорректна. Если s(k)<t(j) или
s(k)=t(j), то t(j) заносится в стек. Если s(k)>t(j), то отыскивается
множество символов в вершине стека, удовлетворяющих отношению:
s(i-1)<s(i)=s(i+1)=...=s(k)>t(j). Элементы s(i)...s(k) принадлежат
одной основе и могут быть свернуты по некоторому правилу грамматики:
U -> s(i)...s(k). Выполняется свертка: отыскивается это правило,
символы s(i)...s(k) удаляются из стека, а U - заносится. Процесс
повторяется: символ U, как верхний элемент стека, сравнивается с
t(j) и т.д. По концу разбора правильного предложения в стеке должны
остаться символы ┴Z, где Z - начальный символ грамматики.
Пример разбора предложения ┴b((aa)a)b┴
Стек | Остаток | Отношение | Основа | Правило |
┴ ┴b ┴b( ┴b(( ┴b((a ┴b((M ┴b((Ma ┴b((Ma) ┴b((N ┴b(M ┴b(Ma ┴b(Ma) ┴b(N ┴bM ┴bMb ┴Z |
b((aa)a))b┴ ((aa)a)b┴ (aa)a)b┴ aa)a)b┴ a)a)b┴ a)a)b┴ )a)b┴ a)b┴ a)b┴ a)b┴ )b┴ b┴ b┴ b┴ ┴ ┴ |
┴ < b b < ( ( < ( ( < a a > a M = a a = ) ) > a N > a M = a a = ) ) > b N > b M = b b >┴ конец |
( < a > a ( < M=a=) > a ( < (=N > a ( < M=a=) > b b < (=N > b ┴ < b=M=b > ┴ |
M -> a N -> Ma) M -> (N N -> Ma) M -> (N Z -> bMb |
Операторной грамматикой называется грамматика, не содержащая правил
вида A -> xBCy, где x, y - произвольные строки, B, C -
нетерминалы.
Пусть U, C, D - нетерминалы. Грамматикой с операторным предшествованием
называется операторная грамматика, в которой между двумя любыми терминальными
символами p, q выполняется не более, чем одно из следующих отношений предшествования:
p=q, | если существует правило U -> xpqy или U -> xpСqy; |
p<q, | если существует правило U -> xpCy и вывод C=>+qz или C=>+Dqz; |
p>q, | если существует правило U -> xCqy и вывод C=>+zp или C=>+zpD. |
LT(U) - | множество левых терминалов в разложениях U, т.е. множество таких терминалов q, что существует вывод U=>+qz или U=>+Dqz; |
RT(U) - | множество правых терминалов в разложениях U, т.е. множество таких терминалов p, что существует вывод U=>+zp или U=>+zpD. |
Пример:
S -> T | S+T T -> ид | T*ид | Грамматика для выражений, состоящих из идентификаторов и знаков +, *. |
L(U), R(U) после первого шага | окончательно |
|
|
LT(U), RT(U) после второго шага | окончательно |
|
|
Вывод отношений между терминалами:
p=q | в правилах отыскиваются сочетания pq и pCq; |
p<q | для сочетаний pC проверяется, что q принадлежит LT(C); |
p>q | для сочетаний Cq проверяется, что p принадлежит RT(C). |
|
Например:
|
Разбор в грамматиках с операторным предшествованием выполняется так же, как в грамматиках с простым предшествованием, но отношения проверяются только между терминалами. Пусть стек содержит символы s(1)...s(k), t(j)...t(n)┴ - остаток входной строки, p=s(m) - верхний терминал стека (m<=k). Если p=t(j) или p<t(j), то t(j) заносится в стек. Если p>t(j), то отыскивается множество терминалов в вершине стека, удовлетворяющих отношениям s(a)<s(b)=s(c)=...=s(m)>t(j). Тогда все элементы стека от s(a+1) до s(k) составляют основу и могут быть свернуты в некоторый нетерминал U.
Пример разбора предложения ┴a+b*c┴
Стек | Остаток | Отношение | Выбор основы | Основа | Правило |
┴ ┴a ┴T ┴T+ ┴T+b ┴T+T ┴T+T* ┴T+T*C ┴T+T ┴S |
a+b*c┴ +b*c┴ +b*c┴ b*c┴ *c┴ *c┴ c┴ ┴ ┴ ┴ |
┴ < a a > + ┴ < + + < b b > * + < * * = c c > ┴ + > ┴ конец |
┴ < a > + + < b > * + < *=c > ┴ ┴ < + > ┴ |
a b T*c T+T |
T->ид T->ид T->T*ид S->T, S->S+T |