
методические указания для выполнения лабораторных работ / kWork / ssw_cw
.pdf
Разработка компонентов транслятора
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
матрицы А> | ;<строка элементов матрицы А> | ]<остаток задачи2> <элемент матрицы А>::= 0<элемент матрицы А> | 1<элемент матрицы А> | 2<элемент
матрицы А> | 3<элемент матрицы А> | 4<элемент матрицы А> | 5<элемент матрицы А> | 6<элемент матрицы А> | 7<элемент матрицы А> | 8<элемент матрицы А> | 9<элемент
матрицы А> |.<дробь элемента матрицы А> |,<дробь элемента матрицы А> | <строка
элементов матрицы А> | ;<строка элементов матрицы А> | ]<остаток задачи2> <дробь элемента матрицы А> ::= 0<дробь элемента матрицы А> | 1<дробь элемента матрицы А> | 2<дробь элемента матрицы А> | 3<дробь элемента матрицы А> | 4<дробь элемента матрицы А> | 5<дробь элемента матрицы А> | 6<дробь элемента матрицы А> | 7<дробь элемента матрицы А> | 8<дробь элемента матрицы А> | 9<дробь элемента матрицы А> | -<элемент матрицы А> | +<элемент матрицы А> | ;<строка элементов
матрицы А> | <строка элементов матрицы А> | ]<остаток задачи2>
<остаток задачи2>::=;<остаток задачи3> <остаток задачи3>::=x<остаток задачи4> <остаток задачи4>::=0<остаток задачи5> <остаток задачи5>::= =<x0> <x0>::=[<строка элементов x0>
<строка элементов x0>::= <элемент x0> | -<элемент x0> | +<элемент x0> |
0<элемент x0> | 1<элемент x0> | 2<элемент x0> | 3<элемент x0> | 4<элемент x0> | 5<элемент x0> | 6<элемент x0> | 7<элемент x0> | 8<элемент x0> | 9<элемент x0> | ;<все элементы x0> | ]<остаток задачи 6>
<элемент x0>::= 0<элемент x0> | 1<элемент x0> | 2<элемент x0> | 3<элемент x0> | 4<элемент x0> | 5<элемент x0> | 6<элемент x0> | 7<элемент x0> | 8<элемент x0> |
9<элемент x0> | .<дробь элемента x0> | ,<дробь элемента x0> | <строка
элементов x0> | ;<строка элементов x0> | ]<остаток задачи 6>
<дробь элемента x0>::=0<дробь элемента x0> | 1<дробь элемента x0> | 2<дробь элемента x0> | 3<дробь элемента x0> | 4<дробь элемента x0> | 5<дробь элемента x0> | 6<дробь элемента x0> | 7<дробь элемента x0> | 8<дробь элемента x0> |
9<дробь элемента x0> | -<элемент x0> | +<элемент x0> | <строка элементов x0>
| ;<строка элементов x0> | ]<остаток задачи 6> <остаток задачи 6>::=;<остаток задачи 7> <остаток задачи 7>::=t<остаток задачи 8> <остаток задачи 8>::=0<остаток задачи 9> <остаток задачи 9>::= =<t0>
<t0>::= <значение t0> | -<значение t0> | +<значение t0> | 0<значение t0> |
1<значение t0> | 2<значение t0> | 3<значение t0> | 4<значение t0> | 5<значение t0> | 6<значение t0> | 7<значение t0> | 8<значение t0> | 9<значение t0>
<значение t0>::= <значение t0> | 0<значение t0> | 1<значение t0> | 2<значение t0> | 3<значение t0> | 4<значение t0> | 5<значение t0> | 6<значение t0> | 7<значение t0> | 8<значение t0> | 9<значение t0> | .<дробь значения t0> | ,<дробь значения t0> | ;<остаток задачи 10>
<дробь значения t0> ::= 0<дробь значения t0> | 1<дробь значения t0> | 2<дробь значения t0> | 3<дробь значения t0> | 4<дробь значения t0> | 5<дробь значения t0> | 6<дробь значения t0> | 7<дробь значения t0> | 8<дробь значения t0> | 9<дробь значения t0> | ;<остаток задачи 10>
<остаток задачи 10>::=t<остаток задачи 11> <остаток задачи 11>::=k<остаток задачи 12> <остаток задачи 12>::= =<tk>
<tk>::= <значение tk> | -<значение tk> | +<значение tk> | 0<значение tk> |
1<значение tk> | 2<значение tk> | 3<значение tk> | 4<значение tk> | 5<значение tk> | 6<значение tk> | 7<значение tk> | 8<значение tk> | 9<значение tk>
<значение tk>::= <значение tk> | 0<значение tk> | 1<значение tk> | 2<значение tk> | 3<значение tk> | 4<значение tk> | 5<значение tk> | 6<значение tk> | 7<значение tk> | 8<значение tk> | 9<значение tk> | .<дробь значения tk> | ,<дробь значения tk> | ;<остаток задачи 13>
<дробь значения tk> ::= 0<дробь значения tk> | 1<дробь значения tk> | 2<дробь
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
М.Ф.Степанов |
31 |

Системное программное обеспечение
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
значения tk> | 3<дробь значения tk> | 4<дробь значения tk> | 5<дробь значения tk> | 6<дробь значения tk> | 7<дробь значения tk> | 8<дробь значения tk> | 9<дробь значения tk> | ;<остаток задачи 13>
<остаток задачи 13>::=h<остаток задачи 14> <остаток задачи 14>::= =<h>
<h>::= <значение h> | -<значение h> | +<значение h> | 0<значение h> |
1<значение h> | 2<значение h> | 3<значение h> | 4<значение h> | 5<значение h> | 6<значение h> | 7<значение h> | 8<значение h> | 9<значение h>
<значение h>::= <значение h> | 0<значение h> | 1<значение h> | 2<значение h> |
3<значение h> | 4<значение h> | 5<значение h> | 6<значение h> | 7<значение h> | 8<значение h> | 9<значение h> | .<дробь значения h> | ,<дробь значения h> | ;<Успех>
<дробь значения h> ::= 0<дробь значения h> | 1<дробь значения h> | 2<дробь значения h> | 3<дробь значения h> | 4<дробь значения h> | 5<дробь значения h> | 6<дробь значения h> | 7<дробь значения h> | 8<дробь значения h> | 9<дробь значения h> | ;<Успех>
Анализ построенной грамматики показывает, что все правила подстановки имеют вид S::=t|tN, t VT, S,N VN, а, следовательно, удовлетворяют требованиям, предъявляемым к грамматикам 3-го типа, т.е. грамматика относится к типу регулярных грамматик.
На этапе лексического анализа распознаются и выделяются в исходном тексте все лексемы. В рассматриваемом примере лексемами являются:
¾Тип 1: идентификаторы компонентов постановки задачи – в данном случае это фактически ключевые слова: "n", "A", "x0", "t0", "tk", "h".
¾Тип 2: разделитель: точка с запятой ";".
¾Тип 3: вещественные десятичные константы со знаком - произвольная последовательность цифр (от "0" до "9"), начинающаяся с любой цифры или знаков "+" или "-", в составе которой может присутствовать десятичная точка "." или запятая ",".
¾Тип 4: целые десятичные константы без знака – произвольная последовательность цифр (от "0" до "9"), начинающаяся с любой цифры.
¾Тип 5: знак операции присваивания "=".
¾Тип 6: открывающаяся квадратная скобка "[".
¾Тип 7: закрывающаяся квадратная скобка "]".
Всвязи с тем, что входной язык описывается регулярной грамматикой, то на этапе лексического анализа в качестве распознавателя лексем можно использовать конечный автомат.
Конечный автомат может быть задан с помощью пяти параметров: M ( Q,Σ,δ,q0 ,F ),
где Q – конечное множество состояний автомата;
Σ – конечное множество допустимых входных символов (входной алфавит);
δ – заданное отображение множества Q×Σ во множество подмножеств P(Q), т.е. δ: Q×Σ → P(Q) – функция переходов автомата;
q0 Q – начальное состояние автомата;
F Q – множество заключительных состояний автомата.
Другим способом задания конечного автомата является граф переходов – графическое представление множества состояний и функций переходов. Граф переходов – это нагруженный однонаправленный граф, в котором вершины представляют состояния конечного автомата, дуги изображают переходы из одного состояния в другое, а символы пометки (нагрузки) дуг соответствуют функции перехода конечного автомата. Если функция перехода конечного автомата предусматривает переход из состояния q в q' по нескольким символам, то между ними строится одна дуга, которая помечается всеми символами, по которым происходит переход из состояния q в q'.
Границами лексем для данного распознавателя служат " " – пробел, знаки перевода строки "\n" и возврата каретки "\r", "," – запятая, ";" – точка с запятой, открывающаяся и закрывающаяся квадратные скобки "[", "]", знак равенства "=", которые, в свою очередь также являются лексемами (кроме пробела, знаков перевода строки и возврата каретки).
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
32 |
М.Ф.Степанов |
Разработка компонентов транслятора
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
В связи с этим границы лексем являются эффективно распознаваемыми, а, следовательно, нет необходимости во взаимодействии с синтаксическим анализатором.
Построим конечный автомат, эквивалентный грамматике G1.
Шаг 1. Строим множество состояний автомата. Начальное состояние автомата – Н=<задача>. Q = VN {H}= {<задача> | <размерность> | <значение размерности> | <матрица А> | <элементы матрицы А> | <все элементы матрицы А> | <элемент матрицы А> | <дробь элемента матрицы А> | <x0> | <все элементы x0> | <элемент x0> | <дробь элемента x0> | <t0> | <значение t0> | <дробь значения t0> | <tk> | <значение tk> | <дробь значения tk> | <h> | <значение h> | <дробь значения h> | <остаток задачи1> |<остаток задачи2> | <остаток задачи3> | <остаток задачи4> | <остаток задачи5> | <остаток задачи6> | <остаток задачи7> | <остаток задачи8> | <остаток задачи9> | <остаток задачи10> |
<остаток задачи11> | <остаток задачи12> | <остаток задачи13> | <остаток задачи14> | <Успех>}.
Шаг 2. В качестве алфавита входных символов берем множество терминальных символов грамматики.
Σ = {"A"|"x"|"t"|"0"|"k"|"h"|"E"|"0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"|"."|"+"|"-"|"["|"]"| ";"|","|" "}.
Шаг 3. Рассматриваем множество правил грамматики и строим функцию переходов автомата. Для начального правила <задача>::=n<размерность>
δ(Н,"n")={<размерность>}.
Для правила <размерность>::= =<значение размерности> δ(<размерность>,"=")={<значение размерности>}.
Для правил <значение размерности>::=0<значение размерности> | 1<значение размерности> | 2<значение
размерности> | 3<значение размерности> | 4<значение размерности> | 5<значение размерности> | 6<значение размерности> | 7<значение размерности> | 8<значение размерности> | 9<значение размерности> | ;<остаток задачи1>
δ(<значение размерности>,"0")={<значение размерности>}. δ(<значение размерности>,"1")={<значение размерности>}. δ(<значение размерности>,"2")={<значение размерности>}. δ(<значение размерности>,"3")={<значение размерности>}. δ(<значение размерности>,"4")={<значение размерности>}. δ(<значение размерности>,"5")={<значение размерности>}. δ(<значение размерности>,"6")={<значение размерности>}. δ(<значение размерности>,"7")={<значение размерности>}. δ(<значение размерности>,"8")={<значение размерности>}. δ(<значение размерности>,"9")={<значение размерности>}. δ(<значение размерности>,";")={<остаток задачи1>}.
И так далее для всех правил грамматики.
Построенный конечный автомат, очевидно, является детерминированным. Поэтому его преобразование не требуется.
На основании этого конечного автомата несложно построить программную реализацию лексического анализатора.
На этапе синтаксического анализа требуется более строгое описание синтаксических конструкций, которое часто может быть получено лишь с использованием более сложных КСграмматик.
В рассматриваемом примере уточним параметры входного языка и для описания его синтаксиса воспользуемся КС-грамматикой.
Вспомним, что на этапе лексического анализа идентификаторы, целые и вещественные числа, разделители (скобки, пробел) выделены как отдельные лексемы и сохранены в таблице лексем. Поэтому на этапе синтаксического анализа рассматривать их терминальные символы не будем.
Проведем анализ типов лексем. Тогда грамматика входного языка, используемая на этапе синтаксического анализа примет вид: G2(VT,VN,P, <задача>),
где <задача> - начальный символ грамматики,
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
М.Ф.Степанов |
33 |

Системное программное обеспечение
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
VT = {n|A|x|t|k|h|0|1|2|3|4|5|6|7|8|9|.|+|-|[|]|;|,|=| } – словарь терминальных символов, где " " –
обозначает пробел,
VN = {<задача> |<>} – словарь нетерминальных символов,
P– правила подстановки:
1:<задача>::=<массивыCразмерностью><началоАнализа><разделитель_";">
<конецАнализа><разделитель_";"><шаг><разделитель_";">
2:<размерность>::=<идентификатор_"n"><равно><целоеЧисло><разделитель_";">
3:<началоАнализа>::=<идентификатор_"t0"><равно><вещественноеЧисло>
<разделитель_";">
4:<конецАнализа>::=<идентификатор_"tk"><равно><вещественноеЧисло> <разделитель_";">
5:<шаг>::=<идентификатор_"h"><равно><вещественноеЧисло>
6:<матрицаА>::=<идентификатор_"A"><равно><матрица><разделитель_";">
7:<векторX0>::= <идентификатор_"x0"><равно><матрица><разделитель_";">
8:<строкиМатрицы>::= <строкиМатрицы><строкаМатрицы><разделитель_";">
9:<строкиМатрицы>::= <строкиМатрицы><строкиМатрицы><строкаМатрицы>
10:<матрица>::=[<строкиМатрицы>]
11:<матрица>::=[<строкаМатрицы>]
12:<строкиМатрицы>::= <строкиМатрицы><строкиМатрицы>
13:<строкиМатрицы>::= <строкиМатрицы><строкаМатрицы>
14:<строкиМатрицы>::= <строкаМатрицы><разделитель_";">
15:<строкаМатрицы>::=<строкаМатрицы><вещественноеЧисло>
16:<массивыCразмерностью>::=<размерность><разделитель_";"><массивы>
17:<массивы>::=<матрицаА><векторX0>
18:<строкаМатрицы>::=<вещественноеЧисло>
19:<строкиМатрицы>::=<строкаМатрицы>
<идентификатор_"n">::=n <идентификатор_"t0">::=t0 <идентификатор_"tk">::=tk <идентификатор_"h">::=h <идентификатор_"A">::=A <идентификатор_"X0">::=x0 <открывающаясяСкобка>::=[ <закрывающаясяСкобка>::=] <разделитель_";">::=; <равно>::==
Пусть для этапа синтаксического анализа необходимо описать входной язык грамматикой предшествования. Такие грамматики используются для синтаксического разбора цепочек входного языка с помощью модификации алгоритма "сдвиг-свертка".
Распознаватель на основе грамматики предшествования исходит из того, что для каждой упорядоченной пары символов в грамматике устанавливается отношение, называемое отношением предшествования.
Впроцессе разбора автомат с магазинной памятью (МП-автомат) сравнивает текущий символ входной цепочки с одним из символов, находящихся на верхушке стека автомата.
Впроцессе сравнения проверяется, какое из возможных отношений предшествования существует между этими двумя символами. В зависимости от найденного отношения выполняется либо сдвиг, либо свертка. При отсутствии отношения предшествования между символами алгоритм сигнализирует об ошибке. Необходимо непротиворечивым образом определить отношения предшествования между символами грамматики.
Отношения предшествования будем обозначать знаками "=.", "<.", ".>". Отношение предшествования единственно для каждой пары символов. Если между какими-либо двумя символами не установлено отношение предшествования, то это значит, что они не могут находиться рядом ни в одном элементе синтаксически правильной цепочки.
Метод предшествования основан на том, что отношения предшествования между двумя соседними символами распознаваемой строки соответствуют трем следующим вариантам:
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
34 |
М.Ф.Степанов |

Разработка компонентов транслятора
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
¾Bi <. Bi+1, если символ Bi+1 - крайний левый символ некоторой основы (это отношение можно назвать "предшествует основе" или просто "предшествует");
¾Bi .> Bi+1, если символ Bi - крайний правый символ некоторой основы (это отношение можно назвать "следует за основой" или просто "следует");
¾Bi =. Bi+1, если символы Bi и Bi+1 – принадлежат одной основе (это отношение можно назвать
"составляют основу").
Разберем суть принципа разбора входной цепочки αγβδ в тот момент, когда выполняется свертка цепочки γ (см. рис. 11).
н |
α |
a |
|
γ |
|
b |
β |
δ |
к |
|
|
|
<. |
<. |
=. |
=. |
=. |
.> |
|
|
|
Рисунок 11. Отношения между символами входной цепочки в грамматике предшествования Символ a является последним символом подцепочки α, а символ b – первым символом
подцепочки β.
Тогда, если в грамматике удастся установить непротиворечивые отношения предшествования, то в процессе выполнения разбора по алгоритму "сдвиг-свертка" можно всегда выполнять сдвиг до тех пор, пока между символом на верхушке стека и текущим символом входной цепочки существует отношение <. или =..
А как только между этими символами будет обнаружено отношение .>, сразу надо выполнять свертку. Причем для выполнения свертки из стека следует выбирать все символы, связанные отношением =.. Все различные правила в грамматике предшествования должны иметь различные правые части – это гарантирует непротиворечивость выбора правила при выполнении свертки.
На основании отношений предшествования строится матрица предшествования.
Строки матрицы предшествования помечаются первыми (левыми) символами, столбцы – вторыми (правыми) символами отношений предшествования. В клетки матрицы на пересечении соотвествующих столбца и строки помещаются знаки отношений. При этом пустые клетки матрицы говорят о том, что между данными символами нет ни одного отношения предшествования.
Выделяются следующие виды грамматик предшествования:
¾Простого предшествования;
¾Расширенного предшествования;
¾Слабого предшествования;
¾Смешанной стратегии предшествования;
¾Операторного предшествования.
Построим матрицу предшествования, воспользовавшись двумя дополнительными типами множеств символов – множествами крайних левых и крайних правых символов, а также множествами крайних левых терминальных и крайних правых терминальных символов для всех нетерминальных символов грамматики.
Для грамматики G(VT,VN,P,S) :
¾L(U)={ T | U * Tz} – множество крайних левых символов относительно нетерминального символа U;
¾R(U)={ T | U * zT} – множество крайних правых символов относительно нетерминального символа U;
¾Lт(U)={ t | U * tz или U * Сtz } – множество крайних левых терминальных символов относительно нетерминального символа U;
¾Rт(U)={ t | U * zt или U * ztC } – множество крайних правых терминальных символов относительно нетерминального символа U,
где U,C VN , T V , z V*, t VТ.
Множества L(U) и R(U) могут быть построены для каждого нетерминального символа U VN по следующему алгоритму:
1. Для каждого U VN ищем все правила, содержащие U в левой части. Во множество L(U) включаем самый левый символ из правой части правил, а во множество R(U) - самый правый символ
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
М.Ф.Степанов |
35 |
Системное программное обеспечение
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
из правой части. Если в правой части правила для символа U имеется только один символ, то он должен быть записан в оба множества.
2.Для каждого U VN выполняем следующее преобразование: если множество L(U) содержит нетерминальные символы грамматики U', U'', … , то его надо дополнить символами, входящими в соответствующие множества L(U'), L(U''), … и не входящими в L(U). Аналогичные действия следует выполнить и для R(U).
3.Если на предыдущем шаге хотя бы одно множество L(U) или R(U) для некоторого символа грамматики изменилось, то следует вернуться к шагу 2, иначе – построение закончено.
Для нахождения множеств Lт(U) и Rт(U) используется следующий алгоритм:
1.Для каждого нетерминального символа грамматики U VN строятся множества L(U) и R(U).
2.Для каждого нетерминального символа грамматики U VN ищутся правила вида U→tz и U→Сtz, где t VТ, C VN, z V*; терминальные символы t включаются во множество Lт(U). Аналогично для множества Rт(U) ищутся правила вида U→zt и U→ztС. Один и тот же терминальный символ t может быть записан в оба множества Lт(U) и Rт(U).
3.Просматривается множество L(U), в которое входят символы U', U'', … . Множество Lт(U) дополняется терминальными символами, входящими в L(U'), L(U''), … и не входящими в Lт(U). Аналогичная операция выполняется и для множества Rт(U) на основе множества R(U).
Для практического использования матрицу предшествования дополняют терминальными
символами н и к (начало и конец цепочки). Для них определены следующие отношения предшествования:
н <. a, если а Lт(U);к .> a, если а Rт(U);
На основе множеств Lт(U) и Rт(U) заполнение матрицы операторного предшествования для КС-грамматики G(VT,VN,P,S) можно выполнить по следующему алгоритму:
1.Взять первый терминальный символ ai VТ, i=1. Считаем этот символ текущим терминальным символом.
2.Во всем множестве правил P ищем правила вида C→xaiby или C→xaiUby, где ai - текущий терминальный символ, b VТ - произвольный терминальный символ, U,C VN, а x,y V*. Фактически производится поиск таких правил, в которых в правой части символы ai и bj стоят рядом или между ними есть не более одного нетерминального символа, причем символ ai обязательно стоит слева от bj.
3.Для всех символов bj, найденных на шаге 2, ставим знак "=." ("составляет основу") в клетки матрицы операторного предшествования на пересечении строки, помеченной символом ai, и столбца, помеченного символом bj.
4.Во всем множестве правил P ищем правила вида C→xaiUjy, где ai - текущий терминальный символ, Uj,C VN, а x,y V*. Фактически производится поиск таких правил, в которых в правой части символ ai стоит слева от нетерминального символа Uj.
5.Для всех символов Uj, найденных на шаге 4, берем множество символов Lт(Uj). Для всех
терминальных символов ck, входящих в это множество, ставим знак "<." ("предшествует") в клетки матрицы предшествования на пересечении строки, помеченной символом ai, и столбца, помеченного символом ck.
6.Во всем множестве правил P ищем правила вида C→xUjaiy, где ai - текущий терминальный символ, Uj,C VN, а x,y V*. Фактически производится поиск таких правил, в которых в правой части символ ai стоит справа от нетерминального символа Uj.
7.Для всех символов Uj, найденных на шаге 6, берем множество символов Rт(Uj). Для всех
терминальных символов ck, входящих в это множество, ставим знак ".>" ("следует") в клетки матрицы предшествования на пересечении строки, помеченной символом ck, и столбца, помеченного символом ai.
8.Если рассмотрены все терминальные символы ai VТ, то переходим к шагу 9, иначе – берем очередной символ ai VТ, i=i+1, делаем его текущим терминальным символом и возвращаетмся к шагу 2.
9.Берем множество Lт(S) для целевого символа грамматики S. Для всех терминальных
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
36 |
М.Ф.Степанов |
Разработка компонентов транслятора
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
символов ck Lт(S) ставим знак "<." ("предшествует") в клетки матрицы операторного предшествования на пересечении строки, помеченной символом н ("начало цепочки") и столбца, помеченного символом ck.
10. Берем множество Rт(S) для целевого символа грамматики S. Для всех терминальных символов ck Rт(S) ставим знак ".>" ("следует") в клетки матрицы операторного предшествования на пересечении строки, помеченной символом ck и столбца, помеченного символом к ("конец цепочки").
Построение закончено.
Если на всех шагах алгоритма построения матрицы предшествования не возникло противоречий, когда в одну и ту же клетку матрицы надо записать несколько различных символов предшествования, то матрица построена правильно (в каждой клетке правильно построенной матрицы присутствует один из символов предшествования либо клетка пуста).
Если возникли противоречия, то исходная грамматика не является грамматикой предшествования. В этом случае можно попробовать преобразовать грамматику так, что она станет удовлетворять требованиям предшествования, либо необходимо использовать другой тип распознавателя.
Построим для грамматики G2(VT,VN,P, <задача>) вначале множества крайних левых и крайних правых символов.
Далее условно будем считать нетерминальные символы:
<идентификатор_"n">, <идентификатор_"t0">, <идентификатор_"tk">, <идентификатор_"h">, <идентификатор_"A">, <идентификатор_"x0">,
<целоеЧисло>, <вещественноеЧисло> "условно" терминальными, поскольку на этапе синтаксического анализа они выступают в качестве
неделимой лексемы и отдельные символы в них не рассматриваются. Представлять их будем их собственными значениями.
Шаг 1.
Таблица 1
Множества символов (результаты выполнения шага 1)
Символ U |
Множество L(U) |
Множество R(U) |
<задача> |
<массивыCразмерностью> |
<разделитель_";"> |
<размерность> |
<идентификатор_"n"> |
<разделитель_";"> |
<началоАнализа> |
<идентификатор_"t0"> |
<вещественноеЧисло> |
<конецАнализа> |
<идентификатор_"tk"> |
<вещественноеЧисло> |
<шаг> |
<идентификатор_"h"> |
<вещественноеЧисло> |
<матрицаА> |
<идентификатор_"A"> |
<разделитель_";"> |
<векторX0> |
<идентификатор_"x0"> |
<разделитель_";"> |
<строкиМатрицы> |
<строкиМатрицы>, |
<разделитель_";">, |
|
<строкаМатрицы>, |
<строкаМатрицы>, |
|
|
<строкиМатрицы>, |
|
|
<вещественноеЧисло> |
<матрица> |
[ |
] |
<массивыCразмерностью> |
<размерность> |
<массивы> |
<массивы> |
<матрицаА> |
<векторX0> |
<строкаМатрицы> |
<вещественноеЧисло> |
<вещественноеЧисло> |
Шаг 2. Дополним множества L(U) и R(U) символами для всех промежуточных нетерминальных символов аналогично шагу 1.
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
М.Ф.Степанов |
37 |

Системное программное обеспечение
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Таблица 2
Множества символов (результаты выполнения шага 2)
Символ U |
Множество L(U) |
Множество R(U) |
<задача> |
<массивыCразмерностью>, |
; |
|
<размерность> |
<массивы> |
<размерность> |
n |
; |
<началоАнализа> |
t0 |
<вещественноеЧисло> |
<конецАнализа> |
tk |
<вещественноеЧисло> |
<шаг> |
h |
<вещественноеЧисло> |
<матрицаА> |
A |
; |
<векторX0> |
x0 |
; |
<строкиМатрицы> |
<строкиМатрицы>, |
;, <строкаМатрицы>, |
|
<строкаМатрицы>, |
<строкиМатрицы>, |
|
<вещественноеЧисло> |
<вещественноеЧисло> |
<матрица> |
[ |
] |
<массивыCразмерностью> |
<размерность>, |
<массивы>, |
|
n |
<векторX0>, ; |
<массивы> |
<матрицаА>, A |
<векторX0>, ; |
<строкаМатрицы> |
<вещественноеЧисло> |
<вещественноеЧисло> |
Здесь возьмем все крайние правые и крайние левые терминальные символы из правил грамматики G2. Получим множества, представленные в таблице 3.
Таблица 3
Множества терминальных символов
Символ U |
Множество LТ(U) |
Множество RТ(U) |
<задача> |
n |
; |
<размерность> |
n |
; |
<началоАнализа> |
t0 |
<вещественноеЧисло> |
<конецАнализа> |
tk |
<вещественноеЧисло> |
<шаг> |
h |
<вещественноеЧисло> |
<матрицаА> |
A |
; |
<векторX0> |
x0 |
; |
<строкиМатрицы> |
<вещественноеЧисло> |
; |
|
|
<вещественноеЧисло> |
<матрица> |
[ |
] |
<массивыCразмерностью> |
n |
; |
<массивы> |
A |
; |
<строкаМатрицы> |
<вещественноеЧисло> |
<вещественноеЧисло> |
Вновь вспомним, что на этапе лексического анализа идентификаторы, целые и вещественные числа, разделители (скобки, точка с запятой) выделены как отдельные лексемы и сохранены в таблице лексем. Поэтому на этапе синтаксического анализа рассматривать их терминальные символы не будем. Проведем анализ типов лексем.
1:<задача> ::= <массивыCразмерностью><началоАнализа>;<конецАнализа>;<шаг>;
2:<размерность> ::= n=<целоеЧисло>;
3:<началоАнализа> ::= t0=<вещественноеЧисло>
4:<конецАнализа> ::= tk=<вещественноеЧисло>
5:<шаг> ::= h=<вещественноеЧисло>
6:<матрицаА> ::= A=<матрица>;
7:<векторX0> ::= x0=<матрица>;
8:<строкиМатрицы> ::= <строкиМатрицы><строкаМатрицы>;
9:<строкиМатрицы> ::= <строкиМатрицы><строкиМатрицы><строкаМатрицы>
10:<матрица> ::= [<строкиМатрицы>]
11:<матрица> ::= [<строкаМатрицы>]
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
38 |
М.Ф.Степанов |

Разработка компонентов транслятора
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
12:<строкиМатрицы> ::= <строкиМатрицы><строкиМатрицы>
13:<строкиМатрицы> ::= <строкиМатрицы><строкаМатрицы>
14:<строкиМатрицы> ::= <строкаМатрицы>;
15:<строкаМатрицы> ::= <строкаМатрицы><вещественноеЧисло>
16:<массивыCразмерностью> ::= <размерность><массивы>
17:<массивы> ::= <матрицаА><векторX0>
18:<строкаМатрицы>::=<вещественноеЧисло>
19:<строкиМатрицы>::=<строкаМатрицы>
Введем сокращения имен нетерминальных символов:
1:<Z> ::= <R><B>;<E>;<H>;
2:<R> ::= n=<целоеЧисло>;
3:<B> ::= t0=<вещественноеЧисло>
4:<E> ::= tk=<вещественноеЧисло>
5:<H> ::= h=<вещественноеЧисло>
6:<S> ::= A=<M>;
7:<X> ::= x0=<M>;
8:<C> ::= <C><c>;
9:<C> ::= <C><C><c>
10:<M> ::= [<C>]
11:<M> ::= [<c>]
12:<C> ::= <C><C>
13:<C> ::= <C><c>
14:<C> ::= <c>;
15:<c> ::= <c><вещественноеЧисло>
16:<R> ::= <r><D>
17:<D> ::= <S><X>
18:<c>::=<вещественноеЧисло>
19:<C>::=<c>
C учетом кодов лексем: |
|
Или, опустив уголковые скобки: |
1: <Z> ::= <R><B>2<E>2<H>2 |
|
1: Z ::= RB2E2H2 |
2: <R> ::= 1n542 |
|
2: R ::= 1n542 |
3: <B> ::= 1t053 |
|
3: B ::= 1t053 |
4: <E> ::= 1tk53 |
|
4: E ::= 1tk53 |
5: <H> ::= 1h53 |
|
5: H ::= 1h53 |
6: <S> ::= 1A5<M>2 |
|
6: S ::= 1A5M2 |
7: <X> ::= 1x05<M>2 |
|
7: X ::= 1x05M2 |
8: <C> ::= <C><c>2 |
|
8: C ::= Cc2 |
9: <C> ::= <C><C><c> |
|
9: C ::= CCc |
10: <M> ::= 6<C>7 |
|
10: M ::= 6C7 |
11: <M> ::= 6<c>7 |
|
11: M ::= 6c7 |
12: <C> ::= <C><C> |
|
12: C ::= CC |
13: <C> ::= <C><c> |
|
13: C ::= Cc |
14: <C> ::= <c>2 |
|
14: C ::= c2 |
15: <c> ::= <c>3 |
|
15: c ::= c3 |
16: <R> ::= <r><D> |
|
16: R ::= rD |
17: <D> ::= <S><X> |
|
17: D ::= SX |
18: <c> ::= 3 |
|
18: c ::= 3 |
19: <C> ::= <c> |
|
19: C ::= c |
Таким образом, словарь терминальных символов (лексем) на этапе синтаксического анализа включает 12 символов: VT={n|t0|tk|h|A|x0|;|вч|цч|=|[|]}
или, с учетом кодов лексем: VT={1n|1t0|1tk|1h|1A|1x0|2|3|4|5|6|7}.
Словарь нетерминальных символов включает 12 символов: VH={Z|R|D|r|B|E|H|S|M|C|c|X}
В словарь добавим терминальные символы н и к (начало и конец цепочки), введя для них коды лексем 0 и 8 соответственно.
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
М.Ф.Степанов |
39 |

Системное программное обеспечение
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Следовательно, матрица предшествования будет иметь размер 25×25.
Рассмотрим процесс ее построения на примере строки для терминального символа "n" Символ "n" должен стоять слева от символов "=" "<целоеЧисло>" ";" в одном предложении.
Следовательно, в строке, помеченной символом "n", на пересечении со столбцами, помеченными символами "=" "<целоеЧисло>" ";" поставим знак "=." ("составляет основу").
Символ "n" должен стоять слева от нетерминального символа <массивы> в правиле <массивыCразмерностью>::=<размерность><массивы>.
Вмножество Lт(<массивы>) входит символ "А". Поэтому в строке, помеченной символом "n", на пересечении со столбцом, помеченным символом "А" поставим знак "<." ("предшествует").
Всилу первого правила грамматики символ "n" не может находиться правее любого символа грамматики. Поэтому построение матрицы для него закончено.
Матрица предшествования для рассмотренной грамматики приведена в таблице 4.
|
|
|
|
|
|
|
|
|
Матрица предшествования |
|
|
|
|
|
|
Таблица 4 |
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
Сим. |
1A |
1h |
1n |
1t0 |
1tk |
1x0 |
2; |
3вч |
4цч |
5= |
6[ |
7] |
Z |
R |
D |
r |
B |
E |
H |
S |
M |
C |
c |
X |
8 к |
0 н |
|
|
<. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
=. |
1A |
|
|
|
|
|
|
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1h |
|
|
|
|
|
|
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1n |
|
|
|
|
|
|
=. |
|
=. |
=. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1t0 |
|
|
|
|
|
|
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1tk |
|
|
|
|
|
|
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1x0 |
|
|
|
|
|
|
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2; |
>. |
=. |
|
>. |
=. |
>. |
=. |
>. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>. |
3вч |
|
|
|
|
|
|
>. |
>. |
|
|
|
>. |
|
|
|
|
|
|
|
|
|
|
|
|
|
4цч |
|
|
|
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5= |
|
|
|
|
|
|
=. |
=. |
=. |
|
=. |
|
|
|
|
|
|
|
|
|
=. |
|
|
|
|
6[ |
|
|
|
|
|
|
|
=. |
|
|
|
=. |
|
|
|
|
|
|
|
|
|
=. |
|
|
|
7] |
|
|
|
|
|
|
>. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Z |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>. |
R |
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
|
|
=. |
|
|
|
|
|
|
|
|
D |
|
|
|
>. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r |
=. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
B |
|
|
|
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
=. |
|
|
|
|
|
|
|
E |
|
|
|
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
|
=. |
|
|
|
|
|
|
H |
|
|
|
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>. |
S |
|
|
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
M |
|
|
|
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C |
|
|
|
|
|
|
|
=. |
|
|
|
=. |
|
|
|
|
|
|
|
|
|
|
|
|
|
c |
|
|
|
|
|
|
=. |
=. |
|
|
|
>. |
|
|
|
|
|
|
|
|
|
|
|
|
|
X |
|
|
|
>. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Пример выполнения разбора предложений входного языка.
Синтаксический разбор осуществляет МП-автомат с одним состоянием <E>. Для иллюстрации работы МП-автомата будем записывать каждую его конфигурацию в виде трех составляющих {α|β|γ}, где
¾- непрочитанная часть входной цепочки;
¾- содержимое стека МП-автомата;
¾- последовательность номеров примененных правил.
Вначальном состоянии вся входная цепочка не прочитана, стек автомата содержит только лексему типа "начало входной цепочки", последовательность номеров правил пуста.
Пусть, например, входная цепочка имеет вид:
n=3;A=[0 1 0; 0 0 1; -1,5 -2,6 -3,7];x0=[-1,9;0;0];t0=-1,1;tk=+10,5;h=0,01;
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
40 |
М.Ф.Степанов |