Скачиваний:
60
Добавлен:
11.02.2014
Размер:
581.97 Кб
Скачать

Министерство образования и науки Российской Федерации Саратовский государственный технический университет

М.Ф.Степанов

РАЗРАБОТКА ВХОДНОГО ЯЗЫКА ПОСТАНОВКИ ФУНКЦИОНАЛЬНОЙ ЗАДАЧИ

Методические указания к выполнению лабораторной работы

по дисциплине

Системное программное обеспечение

для студентов специальности 210100 ("Управление и информатика в технических системах")

Одобрено редакционно–издательским Советом Саратовского государственного технического университета

Саратов 2007

xR xn x* x+

Системное программное обеспечение

_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

Цель работы: освоение методов разработки входного языка системы решения задач.

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 , VtVn= , где 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):

vw,

если для некоторых цепочек x и y можно записать v=xUy и w=xuy, где U::=u - правило грамматики.

Цепочка v порождает цепочку w (или w выводима из v): v+w ,

если существует последовательность непосредственных выводов v v1 v2 w .

Обозначим v*w, если vw или 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' добавляются правила:

AAn-1an

An-1An-2an-1

A2A1a2 A1Ba1

Если встречаются правила вида

А a1a2…an, n> 1, A VN, n > i > 0: aj VT,

то во множество нетерминальных символов VN' грамматики G' добавляются символы A1,A2,…,An-1, а во множество правил Р' грамматики G' добавляются правила:

А Аn-1an

An-1An-2an-1

A2A1a2 A1a1

_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

10

М.Ф.Степанов