Курсовая работа: Конструирование моделей лексического и синтаксического анализа

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

МИНОБРНАУКИ РОССИИ

Федеральное государственное бюджетное образовательное учреждение высшего образования

«ЧЕРЕПОВЕЦКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ»

Институт (факультет) Информационных технологий

Кафедра Математического и программного обеспечения ЭВМ

КУРСОВАЯ РАБОТА

по дисциплине Теория автоматов и формальных языков

на тему Конструирование моделей лексического и синтаксического анализа

Выполнил студент группы

ИСб-00-21оп

Дьяков Максим Сергеевич

Руководитель

Ганичева Оксана Георгиевна

Череповец, 2017год

Аннотация

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

В техническом задании говорится о непосредственной разработке программы. Руководство пользователя содержит подробные инструкции, необходимые пользователю.

Введение

Лексический анализ представляет собой первую фазу компиляции. Его основная задача состоит в чтении новых символов и выдачи последовательности лексем, используемых синтаксическим анализатором в своей работе. Лексической единицей языка является лексема.

Лексема - это структурная единица языка, которая состоит из элементарных символов языка и не содержит в своем составе других структурных единиц языка.

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

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

Лексический анализатор только позволяет избавить сложный по структуре синтаксический анализатор от решения примитивных задач по выявлению и запоминанию лексем входной программы. Выходом лексического анализатора является таблица лексем (или цепочка лексем). Эта таблица образует вход синтаксического анализатора, который исследует только один компонент каждой лексемы -- ее тип. Остальная информация о лексемах используется на более поздних фазах компиляции при семантическом анализе, подготовке к генерации и генерации кода результирующей программы. Синтаксический анализ -- процесс, в котором исследуется таблица лексем и устанавливается, удовлетворяет ли она структурным условиям, явно сформулированным в определении синтаксиса языка.

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

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

Изучение и описание предметной области

Лексический анализатор - это часть компилятора, которая читает исходную программу и выделяет в ее тексте лексемы.

На вход лексического анализатора поступает текст исходной программы, а выходная информация передается для дальнейшей обработки компилятором на этапе синтаксического анализа и разбора. Применение лексического анализатора упрощает работу с текстом исходной программы на этапе синтаксического разбора и сокращает объем обрабатываемой информации. Для выделения в тексте и разбора лексем применяется простая и эффективная техника анализа.

Основные функции:

1)исключение из текста исходной программы комментариев

2)исключение из текста исходной программы незначащих пробелов, символов-табуляций и перевода строки

3)выделение лексем следующих типов: идентификаторов, строковых, символьных и числовых констант, ключевых (служебных) слов входного языка, знаков операций и разделителей.

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

Анализатор должен выполнить следующие действия:

- четко определить границы лексемы, которые в исходном тексте явно не заданы

- выполнить действия для сохранения информации об обнаруженной лексеме

Для большинства входных языков границы лексем распознаются по заданным терминальным символам. ( пробелы, запятые, точки с запятой и т.п.) Набор таких терминальных символов может варьироваться в зависимости от синтаксиса входного языка.

Лексические анализаторы действуют по следующему принципу:

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

2)если символ не может быть отнесен к лексемам, то он является границей лексемы и началом следующей.

При этом от пользователя явно требуется указать с помощью пробелов (или других незначащих символов) границы лексем. Такой подход возможен для большинства входных языков.

Постановка задачи

I. Разработайте грамматику для моделирования работы компилятора согласно своему варианту. Для синтаксического анализа - КС-грамматику, для лексического анализа - регулярную грамматику.

II.Постройте лексический анализатор, который решает следующие задачи: выделяет из текста входной программы все лексемы, входящие в заданную языковую конструкцию операторов for и do-while, удаляет лишние пробелы и комментарии из входной строки. Построение лексического анализатора выполнить на основе конечного автомата. По конечному автомату построить соответствующую ему регулярную грамматику.

III. Постройте КС-грамматику, описывающую синтаксис инструкции языка программирования для оператора операторов for и do-while.

IV. Докажите возможность вывода заданной синтаксической конструкции с помощью грамматики разработанной в п.III. на основе заданного варианта распознавателя. Результатом работы синтаксического анализатора должно быть дерево вывода и соответствующее ему порождение рассматриваемой цепочки.

V. Путем эквивалентных преобразований получите приведенную грамматику.

Примечание 1:

1. Все конструкции должны предусматривать наличие следующих операторов: составного оператора, оператора присваивания, операторов сравнения, операторы ввода - вывода, разделителей операторов, арифметические и (или) логические операции. В тех вариантах, где это возможно, должны допускаться разные уровни вложенности.

2. В задании I заданную грамматику представить в виде: правил КС-грамматики, в форме БНФ и регулярной грамматики.

3. Работа лексического анализатора должна моделироваться конечным автоматом, граф переходов которого должен быть представлен в пояснительной записке.

Примечание 2:

1. Выход лексического анализатора - дескрипторый код и псевдокод, таблица классов лексем, сообщения об ошибках: тип ошибки и в какой строке.

2. В ходе работы ЛА должны удаляться лишние пробелы и комментарии

Описание конечного автомата

other-любая цифра и буква английского алфавита

б- английская буква (любого регистра), ц- цифра

M=(Q, V, R, q0, P) ), где:

Q - конечное множество состояний автомата; V - конечное множество допустимых входных символов; P - функция переходов автомата; S0 - начальное состояние автомата; R - непустое множество конечных состояний автомата

V={a..z, A..Z, 0..9, -, +, /, *, =, ;,:, , , , #, &, !, (, ), {, }, <, >, [, ], |}

Q={S0, S1, ..S89}

R={ S3, S8, S15, S19, S24, S30, S34, S39, S44S47, S50, S54, S60, S65, S70, S71, S76, S78, S82, S85, S89} P:

(S0, i)>S1

(S1, n)>S2

(S7, e)>S8

(S13, other)>S85

(S21, o)>S22

(S27, other)>S85

(S0, v)>S86

(S1, o)>S9

(S7, other)>S85

(S14, m)>S15

(S21, other)>S85

(S28, l)>S29

(S0, s)>S48

(S1, other)>S85

(S8, other)>S85

(S15, other)>S85

(S22, a)>S23

(S28, other)>S85

(S0, f)>S20

(S2, t)>S3

(S9, s)>S10

(S16, a)>S17

(S22, other)>S85

(S29, e)>S30

(S0, n)>S66

(S2, c)>S4

(S9, other)>S85

(S16, other)>S85

(S23, t)>S24

(S29, other)>S85

(S0, u)>S61

(S2, other)>S85

(S10, t)>S11

(S17, i)>S18

(S23, other)>S85

(S30, other)>S85

(S0, r)>S55

(S3, other)>S85

(S10, other)>S85

(S17, other)>S85

(S24, other)>S85

(S31, h)>S32

(S0, w)>S40

(S4, l)>S5

(S11, r)>S12

(S18, n)>S19

(S25, o)>S26

(S31, i)>S35

(S0, d)>S25

(S4, other)>S85

(S11, other)>S85

(S19, other)>S85

(S25, other)>S85

(S31, o)>S37

(S0, f)>S20

(S5, u)>S6

(S12, e)>S13

(S20, l)>S21

(S26, u)>S27

(S31, other)>S85

(S0, m)>S16

(S5, other)>S85

(S12, other)>S85

(S20, f)>S46

(S26, other)>S85

(S32, a)>S33

(S0, c)>S31

(S6, d)>S7

(S13, a)>S14

(S20, other)>S85

(S27, b)>S28

(S32, other)>S85

(S0, б)>S85

(S6, other)>S85

(S0, .)>S70

(S72, =)>S78

(S75, ц)>S76

(S80, =)>S82

(S33, r)>S34

(S52, s)>S53

(S0, , )>S70

(S72, -)>S78

(S76, ц)>S76

(S85, other)>S85

(S33, other)>S85

(S52, other)>S85

(S0, ;)>S70

(S71, ц)>S71

(S77, +)>S78

(S86, o)>S87

(S34, other)>S85

(S53, e)>S54

(S0,:)>S70

(S71, .)>S73

(S77, =)>S78

(S86, other)>S85

(S35, n)>S36

(S53, other)>S85

(S0, ')>S70

(S71, E)>S74

(S83, <)>S78

(S87, i)>S88

(S35, other)>S85

(S54, other)>S85

(S0, '')>S70

(S71, e)>S74

(S84, >)>S78

(S87, other)>S85

(S36, other)>S85

(S55, e)>S56

(S0, ()>S70

(S73, ц)>S76

(S83, =)>S82

(S88, d)>S89

(S32, other)>S85

(S55, other)>S85

(S0, ))>S70

(S74, +)>S75

(S84, =)>S82

(S88, other)>S85

(S37, u)>S38

(S56, t)>S57

(S0, [)>S70

(S74, -)>S75

(S79, =)>S82

(S89, other)>S85

(S37, other)>S85

(S56, other)>S85

(S0, ])>S70

(S43, other)>S85

(S63, n)>S64

(S0, *)>S77

(S38, t)>S39

(S57, u)>S85

(S0, {)>S70

(S44, other)>S85

(S63, other)>S85

(S0, +)>S78

(S38, other)>S85

(S57, other)>S85

(S0, })>S70

(S46, r)>S47

(S64, g)>S65

(S0, +)>S77

(S32, other)>S85

(S58, r)>S59

(S0, ц)>S71

(S46, other)>S85

(S64, other)>S85

(S0, -)>S78

(S39, other)>S85

(S58, other)>S85

(S0, -)>S72

(S47, other)>S85

(S65, other)>S85

(S0, =)>S78

(S40, h)>S41

(S59, n)>S60

(S0, &)>S78

(S48, t)>S49

(S66, a)>S67

(S0, =)>S79

(S40, other)>S85

(S59, other)>S85

(S0, &)>S77

(S48, p)>S51

(S66, other)>S85

(S0, <)>S83

(S41, i)>S42

(S60, other)>S85

(S0, /)>S78

(S48, other)>S85

(S67, m)>S68

(S0, >)>S84

(S41, other)>S85

(S61, s)>S62

(S0, /)>S77

(S49, d)>S50

(S67, other)>S85

(S0, <)>S82

(S42, l)>S43

(S61, other)>S85

(S0, %)>S78

(S49, other)>S85

(S68, e)>S69

(S0, >)>S82

(S42, other)>S85

(S62, i)>S63

(S0, %)>S77

(S51, a)>S52

(S68, other)>S85

(S0, !)>S80

(S45, other)>S85

(S69, s)>S45

(S45, p)>S51

(S51, other)>S85

(S69, other)>S85

(S72, ц)>S71

(S43, e)>S44

(S62, other)>S85

(S0, *)>S78

Регулярная грамматика для лексического анализа

регулярная грамматика -- формальная грамматика типа 3 по иерархии Хомского. Регулярные грамматики определяют в точности все регулярные языки, и поэтому эквивалентны конечным автоматам и регулярным выражениям.

Регулярная грамматика может быть задана набором правил как левая или правая регулярная грамматика.

правая регулярная грамматика - все правила могут быть в одной из следующих форм:

1. A > a

2. A > aB

левая регулярная грамматика - все правила могут быть в одной из следующих форм:

1. A > a

2. A > Ba

Где заглавные буквы (A, B) обозначают нетерминалы, строчные буквы (a, b) обозначают терминалы

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

Регулярная грамматика по конечному автомату:

G=(N, T, P, S)

N={Q}={S0, S1, … S89}

T={V}={a..z, A..Z, 0..9, -, +, /, *, =, ;,:, , , , , &, !, (, ), {, }, <, >, [, ]}

S={q0}={S0}

P:

S0>iS1

S1>nS2

S7>eS8

S13>otherS85

(S21, o)>oS22

S27>otherS85

S0>vS86

S1>oS9

S7>otherS85

S14>mS15

S21>otherS85

S28>lS29

S0>sS48

S1>otherS85

S8>otherS85

S15>otherS85

S22>aS23

S28>otherS85

S0>fS20

S2>tS3

S9>sS10

S16>aS17

S22>otherS85

S29>eS30

S0>nS66

S2>cS4

S9>otherS85

S16>otherS85

S23>tS24

S29>otherS85

S0>uS61

S2>otherS85

S10>tS11

S17>iS18

S23>otherS85

S30>otherS85

S0>rS55

S3>otherS85

S10>otherS85

S17>otherS85

S24> otherS85

S31>hS32

S0>wS40

S4>lS5

S11>rS12

S18>nS19

S25>oS26

S31>iS35

S0>dS25

S4> otherS85

S11> otherS85

S19>otherS85

S25>otherS85

S31>oS37

S0>fS20

S5>uS6

S12>eS13

S20>lS21

S26>uS27

S31>otherS85

S0>mS16

S5>otherS85

S12>otherS85

S20>fS46

S26>otherS85

S32>aS33

S0>cS31

S6>dS7

S13>aS14

S20> otherS85

S27>bS28

S32>otherS85

S0>бS85

S6>otherS85

S0>.S70

S72>=S78

S75>цS76

S80>=S82

S33>rS34

S52>sS53

S0>, S70

S72>-S78

S76>цS76

S85>otherS85

S33>otherS85

S52>otherS85

S0>;S70

S71>цS71

S77>+S78

S86>oS87

S34>otherS85

S53>eS54

S0>:S70

S71>.S73

S77>=S78

S86>otherS85

S35>nS36

S53> other S85

S0>'S70

S71>ES74

S83><S78

S87>iS88

S35>otherS85

S54>otherS85

S0>”S70

S71>eS74

S84>>S78

S87>otherS85

S36>otherS85

S55>eS56

S0>(S70

S73>цS76

S83>=S82

S88>dS89

S32>otherS85

S55>otherS85

S0>)S70

S74>+S75

S84>=S82

S88>otherS85

S37>uS38

S56>tS57

S0>[S70

S74>-S75

S79>=S82

S89>otherS85

S37>otherS85

S56>otherS85

S0>]S70

S43>otherS85

S63>nS64

S0>*S77

S38>tS39

S57>uS85

S0>{S70

S44>otherS85

S63>otherS85

S0>+S78

S38>otherS85

S57>otherS85

S0>}S70

S46>rS47

S64>gS65

S0>+S77

S32>otherS85

S58>rS59

S0>цS71

S46>otherS85

S64>otherS85

S0>-S78

S39>otherS85

S58>otherS85

S0>-S72

S47>otherS85

S65>otherS85

S0>=S78

S40>hS41

S59>nS60

S0>&S78

S48>tS49

S66>aS67

S0>=S79

S40>otherS85

S59>otherS85

S0>&S77

S48>pS51

S66>otherS85

S0><S83

S41>iS42

S60>otherS85

S0>/S78

S48>otherS85

S67>mS68

S0>>S84

S41>otherS85

S61>sS62

S0>/S77

S49>dS50

S67>otherS85

S0><S82

S42>lS43

S61>otherS85

S0>%S78

S49>otherS85

S68>eS69

S0>>S82

S42>otherS85

S62>iS63

S0>%S77

S51>aS52

S68>otherS85

S0>!S80

S45>otherS85

S69>sS45

S45>pS51

S51>otherS85

S69>otherS85

S72>цS71

S43>eS44

S62>otherS85

S0>*S78

S78>е

S82>е

S85>е

S70>е

S71>е

S76>е

S19>е

S24>е

S47>е

S34>е

S36>е

S39>е

S69>е

S65>е

S3>е

S30>е

S26>е

S44>е

S50>е

S54>е

S85>е

S8>е

S15>е

S89>е

S70>е

S71>е

S76>е

S70>е

S70>е

S70>е

S70>е

S70>е

S70>е

S70>е

S70>е

S70>е