методические указания для выполнения лабораторных работ / lab04 / SSW_w04
.pdfМинистерство образования и науки Российской Федерации Саратовский государственный технический университет
М.Ф.Степанов
РАЗРАБОТКА ВХОДНОГО ЯЗЫКА ПОСТАНОВКИ ФУНКЦИОНАЛЬНОЙ ЗАДАЧИ
Методические указания к выполнению лабораторной работы
по дисциплине
Системное программное обеспечение
для студентов специальности 210100 ("Управление и информатика в технических системах")
Одобрено редакционно–издательским Советом Саратовского государственного технического университета
Саратов 2007
Системное программное обеспечение
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Цель работы: освоение методов разработки входного языка системы решения задач.
1. ОСНОВНЫЕ ПОНЯТИЯ
Анализ входного языка включает несколько этапов:
•лексический анализ,
•синтаксический анализ,
•семантический анализ,
•подготовка к генерации выходного текста,
•генерация выходного текста.
Лексема (лексическая единица языка) – это структурная единица языка, которая состоит из элементарных символов языка и не содержит в своем составе других структурных единиц языка.
Лексемами языков программирования являются идентификаторы, константы, ключевые слова языка, знаки операций и т.п. Состав возможных лексем каждого конкретного языка определяется синтаксисом этого языка.
1.1.Основные понятия, используемые в теории формальных языков
Алфавит - непустое конечное множество элементов. Символы - элементы алфавита.
Цепочка - конечная последовательность символов алфавита. Например, если A = {a, b, c} - алфавит, то a, b, с, ab, aaca -цепочки. В цепочках важен порядок символов ab и ba - разные цепочки.
Λ, λ или e - пустая цепочка. Другие обозначения:
- цепочка x с символами в обратном порядке - цепочка x, повторенная n раз
- цепочка x, повторенная 0 или более раз - цепочка x, повторенная 1 или более раз
Длина цепочки равна числу символов в цепочке.
Если x - цепочка, то |x| - ее длина. |λ|= 0, |a| = 1, |aaa|= 3. Конкатенация цепочек. Если X и Y - цепочки, то их конкатенацией
XY является цепочка, полученная путем дописывания символов цепочки Y вслед за символами цепочки X.
Если X = ab и Y = сd, то XY = abcd, |λx|=|xλ|=x.
Буквы x, y, z, u, v, w, t будем применять для обозначения цепочек.
Произведение цепочек.
Произведение двух множеств цепочек А и В есть AB={xy|x A,y B}.
Если A={xy} и B={yz}, то AB={xy,xz,yy,yz}.
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
2 |
М.Ф.Степанов |
Разработка входного языка постановки функциональной задачи
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Степени цепочек. Если x - цепочка, то
x0=Λ; x1=x; x2=xx; |
...; |
xn=xn-1x |
для n>0. |
Степени алфавита. Если А - алфавит, то |
|
A0={Λ}, An=An-1A, для n>0.
Итерация. Используя понятие степени алфавита определим итера-
цию A* множества А:
A*=A0 A1 A2 … An …
Усеченная итерация.
A+=A1 A2 … An …
Например, если А = {a,b,c}, то
A+={a, b, c, aa, ab, ac, ba, bb, bc, ca, cb, cc, aaa,…} A*={Λ, a, b, c, aa, ab, ac, ba, bb, bc, ca, cb, cc, aaa,…}.
Формальное определение грамматики и языка
Правило подстановки (или продукция) - упорядоченная пара (U,x),
которая записывается так
U ::= x, или U : x, или U → x,
где U - символ; x - конечная цепочка символов; знаки "::=", ":", "→" оз-
начают фразу "может состоять из".
Грамматика G[z] - конечное непустое множество правил подстановки, где z - начальный символ (или аксиома). Этот символ должен встретиться в левой части, по крайней мере, одного правила подстановки.
Символы, которые встречаются в левых и правых частях правил подстановки, образуют словарь.
Символы, которые встречаются в левых частях правил подстановки,
называются нетерминальными.
Символы, которые не входят в множество нетерминальных символов, называются терминальными.
Таким образом, словарь V есть V=Vt Vn , Vt∩Vn= , где Vt - множество терминальных символов; Vn - множество нетерминальных симво-
лов; - пустое множество.
Как правило, нетерминальные символы заключают в угловые скобки <u>, чтобы отличить их от терминалов.
Если множество терминальных символов не содержит заглавных букв, то их используют для обозначения нетерминальных символов. В этом случае уголковые скобки не используют.
Множество правил U::=x , U::=y , U::=z с одинаковыми левыми частями сокращенно записывают как U::=x|y|z.
Пример. Грамматика целого числа G1[число]:
<число>::=<чис> <чис>::=<чис><цифра>|<цифра> <цифра>::=0|1|2|3|4|5|6|7|8|9
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Методические указания к выполнению лабораторной работы |
3 |
|
Системное программное обеспечение
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Такая форма записи грамматики называется нормальной формой Бэкуса-Наура.
Основное назначение грамматики - порождение синтаксически правильных предложений языка.
Рассмотрим порождение цепочек.
Цепочка v непосредственно порождает цепочку w (или, иначе говоря, w непосредственно выводится из v):
v→w,
если для некоторых цепочек x и y можно записать v=xUy и w=xuy, где U::=u - правило грамматики.
Цепочка v порождает цепочку w (или w выводима из v): v+→w ,
если существует последовательность непосредственных выводов v → v1 → v2 → … → w .
Обозначим v*→w, если v→w или v+→w.
Цепочка x называется сентенциальной формой, если x выводима из начального символа грамматики G[z], т.е. z*→x.
Предложением называется сентенциальная форма, состоящая только из терминальных символов.
Языком L называется множество предложений, порождаемых грам-
матикой G[z], т.е.
L(G[z])={x|z*→x , x Vt+}
Грамматика рекурсивна по отношению к U, если U+→…U… . Если U+→U…, то имеет место левая рекурсия.
Если U+→…U, то имеет место правая рекурсия. Правило подстановки называется
¾леворекурсивным, если оно имеет вид U::= U… ,
¾праворекурсивным, если оно имеет вид U::= …U .
Рекурсивная грамматика описывает бесконечный язык, то есть поро-
ждает бесконечное число предложений.
Грамматика целого числа G1[<число>] описывает бесконечный язык, так как имеет леворекурсивное правило
<чис>::=<чис><цифра>|<цифра> .
Классификация формальных языков
С помощью грамматик можно определить четыре основных класса языков в терминах V, Vt , G, Z, где V - алфавит; Vt - множество терми-
нальных символов; G - конечный набор правил подстановки; z - начальный символ.
Грамматики типа 0 не накладывают никаких ограничений на правила подстановки.
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
4 |
М.Ф.Степанов |
Разработка входного языка постановки функциональной задачи
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Грамматики типа 1, или контекстно - зависимые, накладывают следующие ограничения на правила подстановки
xUy ::= xuy ,
где u Vn ; u V+ ; x,y V* .
Это означает, что подстановка U ::= u имеет место только в контексте между x и y.
Грамматики типа 2 или контекстно-свободные, содержат в левой части правил подстановки только один нетерминальный символ; его применение не будет зависеть от контекста:
U ::= u ,
где u Vn ; u V+ .
Большинство языков программирования удовлетворяют этому требованию или достаточно хорошо аппроксимируются некоторым контекст- но-свободным языком.
Грамматики типа 3 имеют языки, задаваемые посредством регулярных грамматик, допускающих только правила подстановки вида:
U::=t или U::=tN ,
где t Vt ; N Vn .
Сентенциальные формы, генерируемые регулярными грамматиками,
могут обрабатываться автоматом с конечным числом состояний, поэтому данные грамматики называют также автоматными.
Контекстно-свободные и регулярные грамматики широко используют для определения языков САПР и при разработке трансляторов.
Языки и грамматики
Множество всех цепочек из элементов множества E естественно обозначить через E*.
Язык - это подмножество E*. Примеры языков:
Си, русский, { 0n 1n | n >= 0 }.
Язык можно задать:
¾перечислив все цепочки;
¾написав программу-распознаватель, которая получает на вход цепочку символов и выдает ответ "да", если цепочка принадлежит языку и "нет" в противном случае;
¾с помощью механизма порождения - грамматики. Чтобы задать грамматику, требуется указать:
¾множество E символов алфавита (или терминальных символов). Будем обозначать их строчными символами алфавита и цифрами;
¾множество нетерминальных символов (или метасимволов), не пересекающееся с E, со специально выделенным начальным символом S. Будем обозначать их прописными буквами;
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Методические указания к выполнению лабораторной работы |
5 |
|
Системное программное обеспечение
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
¾множество правил вывода, определяющих правила подстановки для цепочек. Каждое правило состоит из двух цепочек (например, x и y), причем x должна содержать, по крайней мере, один нетерминал, и означает, что цепочку x в процессе вывода можно заменить на y. Вывод цепочек языка начинается с нетерминала S.
Примеры:
а) S |
: |
e |
б) S : e |
|
S |
: |
0S1 |
S |
: (S) |
|
|
|
S |
: SS |
Для сокращения записи принято использовать символ "или" - "|". Короткая форма записи предыдущих примеров:
а) S : e | 0S1
б) S : e | (S) | SS
Более сложный пример:
в) S : aSBC | abC CB : BC
bB : bb cC : cc bC : bc
Эта грамматика порождает язык an bn cn.
Грамматики в свою очередь образуют т.н. метаязык. Выше была описана "академическая" форма записи метаязыка. На практике применяется также другая форма записи, традиционно называемая нормальными формами Бэкуса-Наура (НФБН). Терминалы в НФБН записываются как обычные символы алфавита, а нетерминалы - как имена в угловых скобках < >. Например, грамматику целых чисел без знака можно записать в виде:
<число> : <цифра> | <цифра> <число> <цифра> : 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Лирическое отступление. Можно ли записать грамматику какоголибо метаязыка на нем самом? Ответ - да.
Рассмотрим язык простейших арифметических формул:
<формула>:(<формула>)|<число>|<формула><знак><формула> <знак> : + | *
Почему "3+5*2" является формулой? Приведем последовательность преобразований цепочек (так называемый "разбор" или "вывод"):
<формула> : <формула><знак><формула> : <формула><знак><формула><знак><формула> :
<число> |
<знак><формула><знак><формула> : |
||||
3 |
<знак><формула><знак><формула> : |
||||
3 |
+ |
<формула><знак><формула> : |
|||
3 |
+ |
<число> |
<знак><формула> : |
||
3 |
+ |
5 |
<знак><формула> : |
||
3 |
+ |
5 |
* |
<формула> : |
|
3 |
+ |
5 |
* |
<число> |
: |
3 |
+ |
5 |
* |
2 |
|
Сокращенно наличие вывода (цепочки преобразований) будем записывать в виде
<формула>::3+5*2.
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
6 |
М.Ф.Степанов |
Разработка входного языка постановки функциональной задачи
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Большинство грамматик допускают несколько различных выводов для одной и той же цепочки из языка. Постройте другой вывод для цепочки "3+5*2".
Если в процессе вывода цепочки правила грамматики применяются только к самому левому нетерминалу, говорят, что получен левый вывод цепочки. Аналогично определяется правый вывод. Какой вывод построен в предыдущем примере?
Изобразим выполняемые замены цепочек в виде т.н. "дерева разбо-
ра" (или дерева вывода).
По традиции дерево изображается |
"вверх ногами": |
||||
|
|
/ |
<формула> |
\ |
|
<формула> |
|
\ |
|||
\ |
|
\ |
<формула> |
||
/ |
| |
|
\ |
| |
|
<формула> <знак> |
<формула> | |
| |
|||
/ |
| |
|
| |
| |
| |
| |
| |
|
| |
| |
| |
<число> <знак> |
<число> <знак> <число> |
||||
| |
| |
|
| |
| |
| |
3 |
+ |
|
5 |
* |
2 |
Нарисованное дерево имеет ветви (линии) и узлы (помечены терминалами и нетерминалами), из которых растут ветви. Конечные узлы (тер-
миналы) называются листьями. Понятия "поддерево", "корень дерева",
видимо, не нуждаются в определении.
Одно и то же дерево разбора может описывать различные выводы (в дереве не фиксирован порядок применения правил). Однако, между левыми (или правыми) выводами и деревьями разбора для цепочек существует однозначное соответствие (упражнение).
Если для одной и той же цепочки можно изобразить два разных дерева разбора (или, что то же самое, построить, два разных правых вывода), грамматика называется неоднозначной. Описанная грамматика неоднозначна (почему? - упражнение). Тот же самый язык можно описать однозначной грамматикой:
<формула> : <терм> | <терм><знак><формула>
<терм> |
: |
(<формула>) | <число> |
<знак> |
: |
+ | * |
Как изменится дерево разбора?. Дерево разбора определяет некоторую структуру цепочки языка. Так, мы видим, что подцепочка "3+5" является "формулой". Это противоречит нашим (интуитивным) понятиям о смысле исходной формулы: 3+5 в отличие от 5*2 не является подвыражением. Мы можем учесть приоритет операций, изменив грамматику:
<формула> : <терм> | <формула> + <терм> <терм> : <элемент> | <терм> * <элемент> <элемент> : (<формула>) | <число>
Как добавить в язык операции вычитания и деления?
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Методические указания к выполнению лабораторной работы |
7 |
|
Системное программное обеспечение
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Кроме привычной формы записи арифметических формул (т.н. "инфиксной", т.е. со знаком операции между операндами), широко распространена "постфиксная" (или обратная польская) форма записи, в которой операция расположена после операндов. Примеры:
2+3 |
2 |
3 |
+ |
|
+ |
2*3+4 |
2 |
3 |
* 4 |
||
2*(3+4) |
2 |
3 |
4 |
+ |
* |
Вобратной польской записи скобки не требуются, а значение формулы очень легко вычислить при использовании стека чисел.
Впрефиксной форме записи формулы знак операции предшествует операндам, например, 1+2*3 записывается в виде + 1 * 2 3 .
(Именно эта форма записи была предложена Я.Лукасевичем и получила название "польской").
1.2. Регулярные языки и грамматики
Чтобы перейти к примерам реализации лексических анализаторов, необходимо более подробно рассмотреть регулярные языки и грамматики, лежащие в их основе.
Регулярные грамматики
Крегулярным, как уже было сказано, относятся два типа грамматик:
¾леволинейные (левоассоциативные);
¾праволинейные (правоассоциативные).
Леволинейные грамматики G(VT,VN,P,S), V = VN VT могут иметь правила двух видов:
А→Bγ или А→γ,
где A,B VN, γ VT*.
Всвою очередь, праволинейные грамматики G(VT,VN,P,S),
V=VN VT могут иметь правила также двух видов:
А→γB или А→γ,
где A,B VN, γ VT*.
Доказано, что эти два класса грамматик эквивалентны. Для любого регулярного языка, заданного праволинейной грамматикой, может быть построена леволинейная грамматика, определяющая эквивалентный язык; и наоборот — для любого регулярного языка, заданного леволинейной грамматикой, может быть построена праволинейная грамматика, задающая эквивалентный язык.
Разница между леволинейными и праволинейными грамматиками заключается в основном в том, в каком порядке строятся предложения языка: слева направо для леволинейных, либо справа налево для праволинейных. Поскольку предложения языков программирования строятся, как правило, в порядке слева направо, то в дальнейшем в разделе регулярных
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
8 |
М.Ф.Степанов |
Разработка входного языка постановки функциональной задачи
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
грамматик будет идти речь в первую очередь о леволинейных грамматиках.
Автоматные грамматики
Среди всех регулярных грамматик можно выделить отдельный класс
— автоматные грамматики. Они также могут быть леволинейными и праволинейными.
Леволинейные автоматные грамматики G(VT,VN,P,S), V=VN VT
могут иметь правила двух видов:
А→Bt или А→t,
где A,B VN, t VT.
Праволинейные автоматные грамматики G(VT,VN,P,S), V=VN VT
могут иметь правила двух видов:
А→tB или А→t,
где A,B VN, t VT.
Разница между автоматными грамматиками и обычными регулярными грамматиками заключается в следующем: там, где в правилах обычных регулярных грамматик может присутствовать цепочка терминальных символов, в автоматных грамматиках может присутствовать только один терминальный символ. Любая автоматная грамматика является регулярной, но не наоборот — не всякая регулярная грамматика является автоматной.
Доказано, что классы обычных регулярных грамматик и автоматных грамматик почти эквивалентны. Это значит, что для любого языка, который задан регулярной грамматикой, можно построить автоматную грамматику, определяющую почти эквивалентный язык (обратное утверждение очевидно).
Чтобы классы автоматных и регулярных грамматик были полностью эквивалентны, в автоматных грамматиках разрешается дополнительное правило вида
S→λ,
где S — целевой символ грамматики.
При этом символ S не должен встречаться в правых частях других правил грамматики.
Тогда язык, заданный автоматной грамматикой G, может включать в себя пустую цепочку:
λ L(G).
Автоматные грамматики, так же как обычные леволинейные и праволинейные грамматики, задают регулярные языки. Поскольку реально используемые языки, как правило, не содержат пустую цепочку символов, разница на пустую цепочку между этими двумя типами грамматик значения не имеет, и правила вида S→λ далее рассматриваться не будут.
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Методические указания к выполнению лабораторной работы |
9 |
|
Системное программное обеспечение
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Существует алгоритм, который позволяет преобразовать произвольную регулярную грамматику к автоматному виду — то есть построить эквивалентную ей автоматную грамматику. Этот алгоритм рассмотрен далее. Он является исключительно полезным, поскольку позволяет существенно облегчить построение распознавателей для регулярных грамматик.
Преобразование регулярной грамматики к автоматному виду
Имеется регулярная грамматика G(VT,VN,P,S), необходимо преобразовать ее в почти эквивалентную автоматную грамматику G'(VT,VN',P',S'). Как уже было сказано, будем рассматривать леволинейные грамматики (для праволинейных грамматик можно легко построить аналогичный алгоритм).
Алгоритм преобразования прост и заключается он в следующей последовательности действий:
Шаг 1. Все нетерминальные символы из множества VN грамматики G переносятся во множество VN' грамматики G'.
Шаг 2. Необходимо просматривать все множество правил Р грамма-
тики G. |
|
|
|
Если встречаются правила вида |
|
||
А → Ba1, |
A,B VN, |
a1 VT |
или |
А → a1, |
A VN, |
a1 VT, |
|
то они переносятся во множество Р' правил грамматики G' без изменений. |
|||
Если встречаются правила вида |
|
||
А → Ba1a2…an , n> 1, |
A,B VN, n > i > 0: ai VT, |
то во множество нетерминальных символов VN' грамматики G' добавляются символы A1,A2,…,An-1, а во множество правил Р' грамматики G' добавляются правила:
A→An-1an
An-1→An-2an-1
…
A2→A1a2 A1→Ba1
Если встречаются правила вида
А → a1a2…an, n> 1, A VN, n > i > 0: aj VT,
то во множество нетерминальных символов VN' грамматики G' добавляются символы A1,A2,…,An-1, а во множество правил Р' грамматики G' добавляются правила:
А → Аn-1an
An-1→An-2an-1
…
A2→A1a2 A1→a1
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
10 |
М.Ф.Степанов |