Учебный транслятор

Методы грамматического разбора. Разработка структуры учебного транслятора на базовом языке программирования Object Pascal в среде объектно-ориентированного визуального программирования Borland DELPHI 6.0 с использованием операционной системы Windows XP.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 12.05.2013
Размер файла 493,8 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

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

ПЕНЗЕНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

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

Пояснительная записка

к курсовой работе по дисциплине

«Теория языков программирования и методы трансляции»

на тему:»Учебный транслятор»

Пенза 2004г.

ЗАДАНИЕ

на курсовое проектирование по курсу

«Теория языков программирования и методы трансляции»

Тема проекта “Учебный транслятор”

Исходные данные (технические требования) на проектирование

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

Разработка должна проводиться на базовом языке программирования Object Pascal в среде объектно-ориентированного визуального программирования Borland DELPHI 6.0. Осуществить функциональное тестирование разработанного транслятора.

Разработку провести с использованием операционной системы Windows 98 и выше на ЭВМ, совместимых с IBM PC Intel Pentium II и выше.

Вариант № 2

Тип переменных

Вид <Ун. оп.>

Вид <Бин. оп.>

Вид <конст.>

Максимальная длина идентификатора

LOGICAL

.NOT

.AND.|

.OR. |

.IMP.

0|1

12

Операторы

Распознаватель

READ, WHILE, WRITE

Детерминированный нисходящий

Распознаватель (магазинный авто-мат) для грамматики типа LL(1)

Реферат

Целью курсового проекта является разработка учебного транслятора с заданного языка.

Разработка проводилась на базовом языке программирования Object Pascal в среде объектно-ориентированного визуального программирования Borland DELPHI 6.0 с использованием операционной системы Windows XP на персональном компьютере IBM PC с процессором Intel Pentium III.

Осуществлено функциональное тестирование разработанного транслятора, которое показало корректность его работы.

Личный вклад заключается в разработке лексического и синтаксического анализаторов.

Введение

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

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

Языки программирования предназначены для решения задач в различных предметных областях, что определяет специфику их организации и различия по назначению. В качестве примера можно привести такие языки как Фортран, применяемый для научных расчетов, C, ориентированный на системное программирование, Prolog, эффективно описывающий задачи логического вывода. Каждая из предметных областей выдвигает свои требования к организации языка. Поэтому можно отметить разнообразие форм представления операторов и выражений, различие в наборе базовых операций и типов данных, а также снижение эффективности программирования при решении задач, не связанных с данной предметной областью. Языковые различия отражаются и в структуре трансляторов. Лисп и Пролог чаще всего выполняются в режиме интерпретации из-за того, что используют динамическое формирование типов данных в ходе вычислений. Для трансляторов с языка Фортран характерна агрессивная оптимизация результирующего машинного кода, которая становится возможной благодаря относительно простой семантике конструкций языка - в частности, благодаря отсутствию механизмов альтернативного именования переменных через указатели или ссылки. Наличие же указателей в языке C предъявляет специфические требования к динамическому распределению памяти.

Структура языка характеризует иерархические отношения между его понятиями, которые описываются синтаксическими правилами. Языки программирования могут сильно отличаться друг от друга по организации отдельных понятий и по отношениям между ними. Язык программирования PL/1 допускает произвольное вложение процедур и функций, тогда как в C все функции должны находиться на внешнем уровне вложенности. Язык C++ допускает описание переменных в любой точке программы перед первым ее использованием, а в Паскале переменные должны быть определены в специальной области описания. Еще дальше в этом вопросе идет PL/1, который допускает описание переменной после ее использования. Или описание можно вообще опустить и руководствоваться правилами, принятыми по умолчанию. В зависимости от принятого решения, транслятор может анализировать программу за один или несколько проходов, что влияет на скорость трансляции.

Семантика языков программирования имеет очень широкий диапазон изменений. Они отличаются не только по особенностям реализации отдельных операций, но и по парадигмам программирования, определяющим принципиальные различия в методах разработки программ. Специфика реализации операций может касаться как структуры обрабатываемых данных, так и правил обработки одних и тех же типов данных. Такие языки, как PL/1 и APL поддерживают выполнение матричных и векторных операций. Большинство же языков работают в основном со скалярами, предоставляя для обработки массивов процедуры и функции, написанные программистами. Но даже при выполнении операции сложения двух целых чисел такие языки, как C и Паскаль могут вести себя по-разному.

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

Даже один и тот же язык может быть реализован нескольким способами. Это связано с тем, что теория формальных грамматик допускает различные методы разбора одних и тех же предложений. В соответствии с этим трансляторы разными способами могут получать один и тот же результат (объектную программу) по первоначальному исходному тексту.

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

Языки программирования предназначены для облегчения программирования. Поэтому их операторы и структуры данных более мощные, чем в машинных языках.

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

Для любого языка определяется:

· Множество символов, которые можно использовать для записи правильных программ (алфавит), основные элементы.

· Множество правильных программ (синтаксис).

· "Смысл" каждой правильной программы (семантика).

Независимо от специфики языка любой транслятор можно считать функциональным преобразователем F, обеспечивающим однозначное отображение X в Y, где X - программа на исходном языке, Y - программа на выходном языке. Поэтому сам процесс трансляции формально можно представить достаточно просто и понятно: Y = F(X).

Формально каждая правильная программа X - это цепочка символов из некоторого алфавита A, преобразуемая в соответствующую ей цепочку Y, составленную из символов алфавита B.

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

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

Другой характерной особенностью всех языков является их семантика. Она определяет смысл операций языка, корректность операндов. Цепочки, имеющие одинаковую синтаксическую структуру в различных языках программирования, могут различаться по семантике (что, например, наблюдается в C++, Pascal, Basic). Знание семантики языка позволяет отделить ее от его синтаксиса и использовать для преобразования в другой язык (осуществить генерацию кода).

Целью данной работы является разработка учебного транслятора с заданного языка.

1. Методы грамматического разбора

1.1 Разбор сверху - вниз

1.1.1 LL(k) - языки и грамматики

Моделирование работы недетерминированных магазинных распознавателей связано с поиском последовательности переходов из начального в одно из конечных состояний. Поиск состоит из отдельных шагов, каждый из которых может окончиться неудачно и привести к возврату в исходное состояние для выполнения следующего шага. Такой поиск с возвратом связан со значительными затратами времени, поэтому на практике используют более экономичные детерминированные распознаватели, работающие без возвратов. Эти распознаватели допускают только ограниченные классы КС-языков, которые однако отражают все синтаксические черты языков программирования. Распознаватели можно разделить на две категории: нисходящие и восходящие. Каждая категория характеризуется порядком, в котором располагаются правила в дереве вывода. Нисходящие распознаватели обрабатывают правила сверху вниз, верхние правила раньше нижних, в то время как восходящие анализаторы используют нижние правила раньше тех, что расположены выше.

Чтобы показать возможности детерминированных автоматов и способы их построения, в настоящем разделе рассматриваются нисходящие распознаватели, допускающие языки, порождаемые грамматиками вида LL(K).

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

Название LL произошло от слова Left, поскольку анализатор просматривает входную цепочку слева-направо, и слова Leftmost, поскольку он обнаруживает появление правила по одному или группе символов, образующих левый край цепочки. На практике наибольшее применение имеет класс LL(1) грамматик, для которых детерминированный распознаватель работает по дному входному символу, расположенному в текущей позиции. В качестве первого шага изучения нисходящих распознавателей рассмотрим их построение для одного из подклассов LL(1) грамматик.

1.1.2 Метод рекурсивного спуска

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

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

2. Разработка транслятора

2.1 Анализ требований

Необходимо разработать транслятор с заданного языка с использованием детерминированного нисходящего распознавателя (магазины автомат) для грамматики типа LL(1), осуществить программную реализацию и тестирование. Возможность построения для LL(1) грамматики детерминированного автомата определяет значение этих грамматик для практических применений. Однако, при построении грамматики для заданного языка не всегда удается получить грамматику, принадлежащую классу LL(1). Это может случиться потому, что неудачно выбраны правила грамматики, или потому, что для заданного языка принципиально нельзя построить LL(1) грамматику. В первом случае полученную грамматику можно попытаться преобразовать таким образом, чтобы она удовлетворяла условиям LL(1) грамматики. Известно несколько приемов преобразований, которые в некоторых случаях, но не всегда, позволяют получить грамматику требуемого вида. Первый вид преобразований заключается в исключении правил, содержащих левую рекурсию. Второй вид преобразований, который называют выделением общих частей, применяют для устранения правил с одинаковыми левыми частями, правые части которых начинаются одинаковыми последовательностями символов. Далее необходимо проверить является ли полученная грамматика LL(1) грамматикой. Затем нужно разработать лексический анализатор, на вход которого подается исходный текст транслируемой программы, а на выходе формируется последовательность лексем. Далее следует разработать синтаксический анализатор, на вход которого поступает последовательность лексем, которая подвергается соответствующему синтаксическому разбору. Основной же частью разработки синтаксического анализатора является проектирование и разработка соответствующего магазинного автомата. Затем необходимо разработать модуль интерпретации. В заключении нужно провести тестирование транслятора.

2.2 Проектирование

Введем обозначения (см. таблицу № 1).

Таблица №1-список обозначений

Условное обозначение

Наименование

I

A

B

C

D

E

G

J

L

K

M

N

O

BEGIN

END

VAR

P

<Программа>

<Объявление переменных>

<Описание вычислений>

<Список присваиваний>

<Список переменных>

<Идентификатор>

<Присваивание>

<Выражение>

<Унарная операция>

<Подвыражение>

<Операнд>

<Бинарная операция>

<Константа>

BEGIN

END

VAR

<Буква>

Итак, имеем следующее базовое описание базового языка:

VA={I,A,B,C,D,E,G,J,L,K,M,N,O,P}

VT={=,begin, end, var, not, and, or, imp, 0, 1, :, logical, do, read, (, ), while, while_end, write,a..z}

R={

IAB

DED

KNK

AvarD:logical;

DE

MO

BbeginCend

EE

ME

CG

EPE

Nimp

CGC

GE=J;

Nor

Cread(D);

JK

Nand

Cread(D)C;

JLK

O1

CwhileJdoCwhile_end;

Lnot

O0

CwhileJdoCwhile_endC;

K(J)

Pa|..|z

Cwrite(D);

KM

Cwrite(D)C;

KK

Введем обозначения для лексем (см. Таблицу № 2).

Таблица № 2 - представление лексем

begin

end

var

:

logical

;

not

and

or

imp

1

0

read

write

(

)

while

do

while_end

<идентификатор>

=

20

21

22

37

23

38

24

25

26

27

1

0

28

29

30

31

32

33

34

35

36

Устраним прямую левую рекурсию:

До устранения левой рекурсии

После устранения левой рекурсии

K(J)

KM

KK

KNK

K'(J) K'(J)K'

K(J) K(J)K'

KM KMK'

KNK KNKK'

K'M K'MK'

K'NK K'NKK'

EE

EPE

EPE

EPEE'

E'PE

E'PEE'

После устранения прямой левой рекурсии получим следующую грамматику:

VA={I,A,B,C,D,E,E',G,J,L,K,K',M,N,O,P}

VT={=,begin, end, var, not, and, or, imp, 0, 1, :, logical, do, read, (, ), while, while_end, write,a..z}

R'={

IAB

DED

KNK

K(J)K'

AvarD:logical;

DE

K(J)

ME

BbeginCend

EPE

KM

MO

CG

E'PE

KMK'

Nor

CGC

EPEE'

KNKK'

Nand

Cread(D)

E'PEE'

K'(J)

Nimp

Cread(D)C;

GE=J;

K'(J)K'

O0

CwhileJdoCwhile_end;

JLK

K'M

O1

CwhileJdoCwhile_endC;

JK

K'MK'

Pa|..|z

Cwrite(D);

Lnot

K'NK

Cwrite(D)C;

KK

K'NKK'

Далее следует процесс факторизации.

До факторизации

После факторизации

DE

DED

DED'

D'D

D'e

CG

CGC

Cread(D);

Cread(D)C;

Cwrite(D);

Cwrite(D)C;

CwhileJdoCwhile_end;

CwhileJdoCwhile_endC;

CGC'

C'C

C'e

Cread(D)C';

Cwrite(D)C';

CwhileJdoCwhile_endC';

K(J)

K(J)K'

KM

KMK'

KNK

KNKK'

K(J)K''

K''K'

KMK''

KNKK''

K''e

K'(J)

K'(J)K'

K'M

K'MK'

K'NK

K'NKK'

K'(J)K''

K'MK''

K'NKK''

EPE

EPEE'

EPEE''

E''E'

E''e

E'PE

E'PEE'

E'PEE''

После факторизации получим следующую грамматику:

VA={I,A,B,C,D,E,E', E''G,J,L,K,K'', K',M,N,O,P}

VT={=,begin, end, var, not, and, or, imp, 0, 1, :, logical, do, read, (, ), while, while_end, write,a..z}

IAB

D'e

K(J)K''

O0

AvarD:logical;

EPEE''

K'(J)K''

O1

BbeginCend

E'PEE''

K''e

P(a|..|z)*

C'C

E''E'

K'MK''

CGC'

E''e

K'NKK''

CwhileJdoCwhile_end;C'

GE=J;

KMK''

Cread(D);C'

JLK

ME

C'e

JK

MO

Cwrite(D);C'

Lnot

Nor

DED'

KNKK''

Nand

D'D

K''K'

Nimp

Проверим, является ли данная грамматика LL(1) грамматикой:

a) Для D'

ПЕРВ(D)e=0

Для C

{read}{write}{if}{(a||z)*}=0

Для C'

ПЕРВ(C) e=0

Для J

ПЕРВ(L) ПЕРВ(K)={not}{(0,1,(a||z)*,and,or,equ)}=0

Для K и K'

ПЕРВ(M) {(}ПЕРВ(N)={0,1,(a||z)*} {(}{and,or,equ }=0

Для K''

ПЕРВ(K') e=0

Для N

{or}{and}{ equ }=0

Для M

ПЕРВ(Е) ПЕРВ(О)={(a||z)*} {1,0}=0

Для О

{1}{0}=0

Для Е''

ПЕРВ(E') e=0

b) Для D'

ПЕРВ(D')=ПЕРВ(D)=ПЕРВ(E)={(a||z)*}

СЛЕД(D')=СЛЕД(O)={)}

СЛЕД(D') ПЕРВ(D')=0

Для C'

ПЕРВ(C')=ПЕРВ(C)={(a||z)*,read,write,if}

СЛЕД(C')=СЛЕД(C)={e}

ПЕРВ(C') СЛЕД(C')=0

Для K''

ПЕРВ(K'')=ПЕРВ(K')={0,1,(a||z)*,(,and,or, equ }

СЛЕД(K'')=СЛЕД(K)СЛЕД(K')={e}

ПЕРВ(K'') СЛЕД(K'')=0

Для E''

ПЕРВ(E'')=ПЕРВ(E')={(a||z)*}

СЛЕД(E'')=СЛЕД(E')СЛЕД(E)={e}

ПЕРВ(E'') СЛЕД(E'')=0

Данная грамматика действительно является LL(1) грамматикой.

Построим детерминированный нисходящий распознаватель:

А) 1.(s0, begin, B)=( s0,end 'C)

2. (s0, var, A)= (s0, ;logical:D)

3. (s0, read, C)= (s0, C';)D( )

4. (s0, write, C)= (s0, C';)D( )

5. (s0, while, C)= (s0, 'C ; While_end C do J)

6. (s0, not, L)=(s0, e)

7. (s0, and, N)=(s0, e)

8. (s0, or, N)=(s0, e)

9. (s0, imp, N)=(s0, e)

10. (s0, 1, O)=(s0, e)

11. (s0, 0, O)=(s0, e)

12. (s0, (a||z)*, P)=(s0, e)

13. (s0, (, K)=(s0, K'')J)

14. (s0, (, K')=(s0, K'')J)

B) 1.(s0, var, I)=(s0, BA)

2.(s0, (a||z)*, D)=(s0, D'E)

3.(s0, (a||z)*, D')=(s0, D)

4.(s0, (a||z)*, C)=(s0, C'G)

5.(s0, (a||z)*, C')=(s0, C)

6.(s0, read, C')=(s0, C)

7.(s0, write, C')=(s0, C)

8.(s0, while, C')=(s0, C)

9.(s0, (a||z)*, G)=(s0, ;J=E)

10.(s0, not, J)=(s0, KL)

11.(s0, (, J)=(s0, K)

12.(s0, (a||z)*, J)=(s0, K)

13.(s0, 0, J)=(s0, K)

14.(s0, 1, J)=(s0, K)

15.(s0, and, J)=(s0, K)

16.(s0, or, J)=(s0, K)

17.(s0, imp, J)=(s0, K)

18.(s0, (a||z)*, K)=(s0, K''M)

19.(s0, 0, K)=(s0, K''M)

20.(s0, 1, K)=(s0, K''M)

21.(s0, and, K)=(s0, K''KN)

22.(s0, or, K)=(s0, K''KN)

23.(s0, imp, K)=(s0, K''KN)

24.(s0, (, K'')=(s0, K')

25.(s0, (a||z)*, K'')=(s0, K')

26.(s0, 0, K'')=(s0, K')

27.(s0, 1, K'')=(s0, K')

28.(s0, and, K'')=(s0, K')

29.(s0, or, K'')=(s0, K')

30.(s0, imp, K'')=(s0, K')

31.(s0, (a||z)*, K')=(s0, K''M)

32.(s0, 0, K')=(s0, K''M)

33.(s0, 1, K')=(s0, K''M)

34.(s0, and, K')=(s0, K''KN)

35.(s0, or, K')=(s0, K''KN)

36.(s0, imp, K')=(s0, K''KN)

37.(s0, (a||z)*, M)=(s0, E)

38.(s0, 0, M)=(s0, O)

39.(s0, 1, M)=(s0, O)

40.(s0, (a||z)*, E)=(s0, E''EP)

41.(s0, (a||z)*, E')=(s0, E''EP)

C) 1.(s0, ), D')=(s0, e)

2.(s0, e, C')=(s0, e)

3.(s0, e, E'')=(s0, e)

4.(s0, e, K'')=(s0, e)

5.(s0, :, D')=(s0, e)

6.(s0, ;, K'')=(s0, e)

7.(s0, ), K'')=(s0, e)

8.(s0, do, K'')=(s0, e)

9.(s0, end, K'')=(s0, e)

10.(s0, while_end, C')=(s0, e)

D) 1. (s0, end, end)=(s0, e)

2. (s0, :, :)=(s0, e)

3. (s0, logical , logical)=(s0, e)

4. (s0, do, do)=(s0, e)

5. (s0, while_end, while_end)=(s0, e)

6. (s0, ), ))=(s0, e)

7. (s0, ;, ;)=(s0, e)

8. (s0, =, =)=(s0, e)

2.3 Кодирование

В процедуре TForm1.FormCreate(Sender: TObject) задаются функции переходов магазинного автомата. В процедуре TForm1.analyze1Click(Sender: TObject) реализованы синтаксический и лексический анализаторы. Процедура postfix формирует список, представляющий из себя постфиксную польскую запись вычисляемого выражения, а функция cntr:byte вычисляет значение выражения по данному списку.

Процедура TForm1.Make1Click(Sender: TObject) выполняет непосредственную интерпретацию. Процедура TForm1.Memo3KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState) отвечает за ввод данных пользователем при выполнении программы. Также программа предоставляет возможность просмотреть функции, использованные при синтаксическом анализе, увидеть значение всех переменных после выполнения программ, просмотреть представления лексем. Текст программы приведен в приложении А.

2.3.1 Разработка анализатора

При разработке анализатора была использована следующая схема

Рисунок 1 - Схема работы анализатора

Анализатор состоит из двух частей:

- П1 - блок лексического анализатора

- П2 - блок синтаксического анализатора.

Исходный текст, подаваемый на вход П1, подвергается лексическому разбору, и на выходе из П1 формируется список лексем. Полученная последовательность лексем подается на вход П2. Синтаксический анализатор по полученному списку лексем проверяет корректно ли составлена программа и нет ли в исходном тексте синтаксических ошибок.

Для создания лексического анализатора была реализована следующие списочные структуры:

Vrb=^VarList; - список идентификаторов

VarList=record

id:string;

value:byte;

right:Vrb;

end;

Lex=^Lexem; - список лексем

Lexem=record

id:byte;

up:Vrb;

right:Lex;

end;

Mag=^Magazin; - список используемый при построении магазина

Magazin=record

id:string;

mleft:Mag;

end;

2.3.1 Лексический анализатор

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

Все лексемы можно разделить на зарезервированные лексемы и лексемы-идентификаторы (таблица № 2). Получив на вход исходный текст, лексический анализатор обращается поочередно к каждой строке. При разборе каждой строки выделяются отдельные лексемы, а соответствующие им номера заносятся в созданный список. Если текущая лексема не равна ни одной зарезервированной, она является идентификатором (номер, соответствующий идентификатору - 35). Лексема такого рода проверяется на длину, она не должна превышать 12, и на то, чтобы в имени идентификатора содержались только буквы. Если все требования выполняются, номер лексемы добавляется к списку. Так как номер, соответствующий идентификатору один, параллельно основному списку создается список непосредственно самих идентификаторов. В результате работы лексического анализатора на выходе получим следующую списочную структуру

object pascal грамматический транслятор

Рисунок № 2 - схема структуры на выходе лексического анализатора

В тексте программы идентификаторы встречаются в двух местах: объявление переменных и основной блок программы. Именно поэтому и была организована структура, представленная на рисунке №2. Идентификатор Ид.2 встречается два раза, а Ид.1 один раз. Поэтому на второй идентификатор ссылаются две лексемы, а на первый одна.

2.3.2 Синтаксический анализатор

Работа синтаксического анализатора заключается в грамматическом разборе, поиске синтаксических ошибок и выдаче сообщений о них. Если программа составлена корректно, то управление передается интерпретатору, если же в тексте найдены синтаксические ошибки, выполнение программы невозможно. Для синтаксического анализатора необходимы функции переходов, которые задаются в процедуре создания формы TForm1.FormCreate(Sender: TObject).

2.4 Тестирование

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

Далее программа была запущена на выполнение. Результат на рисунке 2.

Также в этом тесте были просмотрены таблица со значениями переменных (рисунок 3), таблица использованных функций переходов (рисунок 4) и таблица представления лексем (рисунок 5).

Во втором тесте введенная программа противоречила заданному языку и лексический анализатор выдал ошибку (рисунок 6).

В третьем тесте в веденном тексте программы не были закрыты операторные скобки цикла while и синтаксический анализатор выдал ошибку.

Заключение

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

Разработка проводилась на базовом языке программирования Object Pascal в среде объектно-ориентированного визуального программирования Borland Delphi 6.0 .

Разработка проведена с использованием операционной системы Windows 2000 на персональном компьютере IBM PC с процессором Intel Pentium III.

Осуществлено функциональное тестирование разработанного транслятора, которое показало корректность его работы.

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

Список использованных источников

1. Хантер Р. Проектирование и конструирование компиляторов. - М.: Финансы и статистика, 1984. - 232 с.

Приложение А

Листинг программного текста транслятора

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, Menus;

type

TForm1 = class(TForm)

GroupBox1: TGroupBox;

Memo1: TMemo;

Label1: TLabel;

MainMenu1: TMainMenu;

Run1: TMenuItem;

analyze1: TMenuItem;

Make1: TMenuItem;

View1: TMenuItem;

Valuesofvariables1: TMenuItem;

Functionsoftransition1: TMenuItem;

ableofdisignations1: TMenuItem;

Label2: TLabel;

Memo3: TMemo;

procedure FormClose(Sender: TObject; var Action: TCloseAction);

procedure FormCreate(Sender: TObject);

procedure analyze1Click(Sender: TObject);

procedure Functionsoftransition1Click(Sender: TObject);

procedure Make1Click(Sender: TObject);

procedure Memo3KeyUp(Sender: TObject; var Key: Word;

Shift: TShiftState);

procedure Memo1Change(Sender: TObject);

procedure ableofdisignations1Click(Sender: TObject);

procedure Valuesofvariables1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

Vrb=^VarList;

VarList=record

id:string;

value:byte;

right:Vrb;

end;

Lex=^Lexem;

Lexem=record

id:byte;

up:Vrb;

right:Lex;

end;

Mag=^Magazin;

Magazin=record

id:string;

mleft:Mag;

end;

whl=^ptrWh;

ptrWh=record

beg:Lex;

wend:Lex;

mleft:whl;

end;

procedure ClrLst;

procedure postfix;

const count=71;

var

Form1: TForm1;

kon,curr,mleft,vir1,vir2,vir3,ptr:Lex;

vkon,vcurr,vleft:Vrb;

mkon,mcurr,mright:Mag;

cwhl,kwhl,pwhl:whl;

func:array [1..count,1..4]of string;

make:boolean;

implementation

{$R *.DFM}

uses unit2;

procedure ClrLst;

begin

Form2.Memo1.Lines.Clear;

curr:=mleft;

while curr<>nil do

begin

kon:=curr^.right;

Dispose(curr);

curr:=kon;

end;

vcurr:=vleft;

while vcurr<>nil do

begin

vkon:=vcurr^.right;

Dispose(vcurr);

vcurr:=vkon;

end;

mcurr:=mright;

while mcurr<>nil do

begin

mright:=mcurr^.mleft;

Dispose(mcurr);

mcurr:=mright;

end;

mleft:=nil;

vleft:=nil;

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

begin

ClrLst;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

mleft:=nil;

vleft:=nil;

mright:=nil;

ptr:=nil;

pwhl:=nil;

Form1.Make1.Enabled:=false;

Form1.Functionsoftransition1.Enabled:=false;

Form1.Valuesofvariables1.Enabled:=false;

make:=false;

func[1,1]:='20';func[1,2]:='B';func[1,3]:='21 H';func[1,4]:='+';

func[2,1]:='22';func[2,2]:='A';func[2,3]:='38 23 37 D';func[2,4]:='+';

func[3,1]:='28';func[3,2]:='C';func[3,3]:='H 38 31 D 30';func[3,4]:='+';

func[4,1]:='29';func[4,2]:='C';func[4,3]:='H 38 31 D 30';func[4,4]:='+';

func[5,1]:='32';func[5,2]:='C';func[5,3]:='H 38 34 C 33 J';func[5,4]:='+';

func[6,1]:='24';func[6,2]:='L';func[6,3]:='';func[6,4]:='+';

func[7,1]:='25';func[7,2]:='N';func[7,3]:='';func[7,4]:='+';

func[8,1]:='26';func[8,2]:='N';func[8,3]:='';func[8,4]:='+';

func[9,1]:='27';func[9,2]:='N';func[9,3]:='';func[9,4]:='+';

func[10,1]:='1';func[10,2]:='O';func[10,3]:='';func[10,4]:='+';

func[11,1]:='0';func[11,2]:='O';func[11,3]:='';func[11,4]:='+';

func[12,1]:='35';func[12,2]:='E';func[12,3]:='';func[12,4]:='+';

func[13,1]:='30';func[13,2]:='K';func[13,3]:='R 31 J';func[13,4]:='+';

func[14,1]:='30';func[14,2]:='Q';func[14,3]:='R 31 J';func[14,4]:='+';

func[15,1]:='22';func[15,2]:='I';func[15,3]:='B A';func[15,4]:='-';

func[16,1]:='35';func[16,2]:='D';func[16,3]:='F E';func[16,4]:='-';

func[17,1]:='35';func[17,2]:='F';func[17,3]:='D';func[17,4]:='-';

func[18,1]:='35';func[18,2]:='C';func[18,3]:='H G';func[18,4]:='-';

func[19,1]:='35';func[19,2]:='H';func[19,3]:='C';func[19,4]:='-';

func[20,1]:='28';func[20,2]:='H';func[20,3]:='C';func[20,4]:='-';

func[21,1]:='29';func[21,2]:='H';func[21,3]:='C';func[21,4]:='-';

func[22,1]:='32';func[22,2]:='H';func[22,3]:='C';func[22,4]:='-';

func[23,1]:='35';func[23,2]:='G';func[23,3]:='38 J 36 E';func[23,4]:='-';

func[24,1]:='24';func[24,2]:='J';func[24,3]:='K L';func[24,4]:='-';

func[25,1]:='30';func[25,2]:='J';func[25,3]:='K';func[25,4]:='-';

func[26,1]:='35';func[26,2]:='J';func[26,3]:='K';func[26,4]:='-';

func[27,1]:='25';func[27,2]:='J';func[27,3]:='K';func[27,4]:='-';

func[28,1]:='26';func[28,2]:='J';func[28,3]:='K';func[28,4]:='-';

func[29,1]:='27';func[29,2]:='J';func[29,3]:='K';func[29,4]:='-';

func[30,1]:='1';func[30,2]:='J';func[30,3]:='K';func[30,4]:='-';

func[31,1]:='0';func[31,2]:='J';func[31,3]:='K';func[31,4]:='-';

func[32,1]:='1';func[32,2]:='K';func[32,3]:='R M';func[32,4]:='-';

func[33,1]:='0';func[33,2]:='K';func[33,3]:='R M';func[33,4]:='-';

func[34,1]:='35';func[34,2]:='K';func[34,3]:='R M';func[34,4]:='-';

func[35,1]:='25';func[35,2]:='K';func[35,3]:='R K N';func[35,4]:='-';

func[36,1]:='26';func[36,2]:='K';func[36,3]:='R K N';func[36,4]:='-';

func[37,1]:='27';func[37,2]:='K';func[37,3]:='R K N';func[37,4]:='-';

func[38,1]:='30';func[38,2]:='R';func[38,3]:='Q';func[38,4]:='-';

func[39,1]:='35';func[39,2]:='R';func[39,3]:='Q';func[39,4]:='-';

func[40,1]:='0';func[40,2]:='R';func[40,3]:='Q';func[40,4]:='-';

func[41,1]:='1';func[41,2]:='R';func[41,3]:='Q';func[41,4]:='-';

func[42,1]:='25';func[42,2]:='R';func[42,3]:='Q';func[42,4]:='-';

func[43,1]:='26';func[43,2]:='R';func[43,3]:='Q';func[43,4]:='-';

func[44,1]:='27';func[44,2]:='R';func[44,3]:='Q';func[44,4]:='-';

func[45,1]:='35';func[45,2]:='Q';func[45,3]:='R M';func[45,4]:='-';

func[46,1]:='0';func[46,2]:='Q';func[46,3]:='R M';func[46,4]:='-';

func[47,1]:='1';func[47,2]:='Q';func[47,3]:='R M';func[47,4]:='-';

func[48,1]:='25';func[48,2]:='Q';func[48,3]:='R K N';func[48,4]:='-';

func[49,1]:='26';func[49,2]:='Q';func[49,3]:='R K N';func[49,4]:='-';

func[50,1]:='27';func[50,2]:='Q';func[50,3]:='R K N';func[50,4]:='-';

func[51,1]:='1';func[51,2]:='M';func[51,3]:='O';func[51,4]:='-';

func[52,1]:='0';func[52,2]:='M';func[52,3]:='O';func[52,4]:='-';

func[53,1]:='35';func[53,2]:='M';func[53,3]:='E';func[53,4]:='-';

func[54,1]:='31';func[54,2]:='F';func[54,3]:='';func[54,4]:='-';

func[55,1]:='';func[55,2]:='H';func[55,3]:='';func[55,4]:='-';

func[56,1]:='';func[56,2]:='R';func[56,3]:='';func[56,4]:='-';

func[57,1]:='21';func[57,2]:='21';func[57,3]:='';func[57,4]:='+';

func[58,1]:='37';func[58,2]:='37';func[58,3]:='';func[58,4]:='+';

func[59,1]:='23';func[59,2]:='23';func[59,3]:='';func[59,4]:='+';

func[60,1]:='33';func[60,2]:='33';func[60,3]:='';func[60,4]:='+';

func[61,1]:='34';func[61,2]:='34';func[61,3]:='';func[61,4]:='+';

func[62,1]:='31';func[62,2]:='31';func[62,3]:='';func[62,4]:='+';

func[63,1]:='38';func[63,2]:='38';func[63,3]:='';func[63,4]:='+';

func[64,1]:='36';func[64,2]:='36';func[64,3]:='';func[64,4]:='+';

func[65,1]:='37';func[65,2]:='F';func[65,3]:='';func[65,4]:='-';

func[66,1]:='38';func[66,2]:='R';func[66,3]:='';func[66,4]:='-';

func[67,1]:='31';func[67,2]:='R';func[67,3]:='';func[67,4]:='-';

func[68,1]:='33';func[68,2]:='R';func[68,3]:='';func[68,4]:='-';

func[69,1]:='30';func[69,2]:='30';func[69,3]:='';func[69,4]:='+';

func[70,1]:='21';func[70,2]:='H';func[70,3]:='';func[70,4]:='-';

func[71,1]:='34';func[71,2]:='H';func[71,3]:='';func[71,4]:='-';

end;

procedure TForm1.analyze1Click(Sender: TObject);

var

i,k,l,m,j,o,p:integer;

str1,str2:string;

vr,fnd:boolean;

begin

ClrLst;

//Лексический анализатор

vr:=true;

k:=Memo1.Lines.Count;

for i:=0 to k-1 do

begin

str1:=Memo1.Lines[i];

j:=Length(str1);

Delete(str2,1,Length(str2));

for l:=1 to j do

begin

if str1[l]<>' ' then

str2:=str2+str1[l];

if ((str1[l]=' ') or (l=j)) and (str2<>'') then

begin

if str2='begin' then

begin

m:=20;

vr:=false;

end

else if str2='end' then m:=21

else if str2='var' then m:=22

else if str2='logical' then m:=23

else if str2='not' then m:=24

else if str2='and' then m:=25

else if str2='or' then m:=26

else if str2='imp' then m:=27

else if str2='1' then m:=1

else if str2='0' then m:=0

else if str2='read' then m:=28

else if str2='write' then m:=29

else if str2='(' then m:=30

else if str2=')' then m:=31

else if str2='while' then m:=32

else if str2='do' then m:=33

else if str2='while_end' then m:=34

else if str2='=' then m:=36

else if str2=':' then m:=37

else if str2=';' then m:=38

else

begin

if Length(str2)>12 then

begin

ShowMessage('Слишком длинный идентификатор '+str2);

ClrLst;

exit;

end;

p:=Length(str2);

for o:=1 to p do

if ((ord(str2[o])<65)or(ord(str2[o])>90))and((ord(str2[o])<97)or(ord(str2[o])>122)) then

begin

ShowMessage('Наименование идентификатора должно содержать только буквы');

ClrLst;

exit;

end;

m:=35;

end;

if (m=35) and (vr) then

begin

new(vcurr);

vcurr^.id:=str2;

vcurr^.value:=0;

vcurr^.right:=nil;

if vleft=nil then vleft:=vcurr

else

begin

vkon:=vleft;

while vkon^.right<>nil do

vkon:=vkon^.right;

vkon^.right:=vcurr;

end;

new(curr);

curr^.id:=m;

curr^.up:=vcurr;

curr^.right:=nil;

if mleft=nil then mleft:=curr

else

begin

kon:=mleft;

while kon^.right<>nil do

kon:=kon^.right;

kon^.right:=curr;

end;

end

else if (m=35) and (not vr) then

begin

fnd:=false;

vcurr:=vleft;

while vcurr<>nil do

begin

if vcurr^.id=str2 then

begin

fnd:=true;

break;

end;

vcurr:=vcurr^.right;

end;

if fnd then

begin

new(curr);

curr^.id:=m;

curr.up:=vcurr;

curr^.right:=nil;

if mleft=nil then mleft:=curr

else

begin

kon:=mleft;

while kon^.right<>nil do

kon:=kon^.right;

kon^.right:=curr;

end;

end

else

begin

ShowMessage('Неизвестный идентификатор '+str2);

ClrLst;

exit;

end;

end

else

begin

new(curr);

curr^.id:=m;

curr.up:=nil;

curr^.right:=nil;

if mleft=nil then mleft:=curr

else

begin

kon:=mleft;

while kon^.right<>nil do

kon:=kon^.right;

kon^.right:=curr;

end;

end;

Delete(str2,1,Length(str2));

end;

end;

end;

//Синтаксический анализатор

curr:=mleft;

new(mright);

mright^.id:='I';

mright^.mleft:=nil;

while true do

begin

for i:=1 to count do

begin

if (curr=nil)and (func[i,1]='')and (func[i,2]=mright^.id) then

begin Form2.Memo1.Lines.Add('(s0,'+func[i,1]+','+func[i,2]+')=(s0,'+func[i,3]+')');

mcurr:=mright;

mright:=mright^.mleft;

Dispose(mcurr);

break;

end

else if (func[i,1]=IntToStr(curr^.id))and(func[i,2]=mright^.id) then

begin

k:=length(func[i,3]);

str1:=func[i,3]; Form2.Memo1.Lines.Add('(s0,'+func[i,1]+','+func[i,2]+')=(s0,'+func[i,3]+')');

mkon:=mright;

Delete(str2,1,Length(str2));

if k>0 then

for j:=1 to k do

begin

if str1[j]<>' ' then

str2:=str2+str1[j];

if ((str1[j]=' ') or (j=k)) and (str2<>'') then

begin

mcurr:=mright;

new(mright);

mright^.id:=str2;

mright^.mleft:=mcurr;

Delete(str2,1,Length(str2));

end;

end;

if mkon=mright then

begin

mright:=mright^.mleft;

Dispose(mkon);

end

else

begin

mcurr:=mright;

while mcurr^.mleft<>mkon do

mcurr:=mcurr^.mleft;

mcurr^.mleft:=mkon^.mleft;

Dispose(mkon);

end;

if func[i,4]='+' then

curr:=curr^.right;

break;

end;

end;

if (curr=nil)and(mright=nil) then

begin

ShowMessage('Синтаксических и лексических ошибок в тексте программы не найдено');

Form1.Make1.Enabled:=true;

Form1.Functionsoftransition1.Enabled:=true;

Form1.Valuesofvariables1.Enabled:=false;

break;

end;

if i>count then

begin

ShowMessage('В тексте программы найдена ошибка');

break;

end;

end;

end;

procedure TForm1.Functionsoftransition1Click(Sender: TObject);

begin

Form2.Memo1.Visible:=true;

Form2.Memo2.Visible:=false;

Form2.StringGrid1.Visible:=false;

Form2.Show;

end;

procedure postfix;

var

lex1,lex2:Lex;

begin

while (vir2^.id<>38) and (vir2^.id<>33) do

begin

if vir2^.id=31 then

exit;

if (vir2^.id=35)or(vir2^.id=0)or(vir2^.id=1) then

begin

new(vir1);

vir1^.id:=vir2^.id;

vir1^.up:=vir2^.up;

if ptr=nil then

ptr:=vir1

else

vir3^.right:=vir1;

vir1^.right:=nil;

vir3:=vir1;

end;

if (vir2^.id=25) or (vir2^.id=26) or (vir2^.id=27)or (vir2^.id=24) then

begin

lex1:=vir2;

lex2:=vir2^.right;

if (lex2^.id=35)or(lex2^.id=0)or(lex2^.id=1) then

begin

new(vir1);

vir1^.id:=lex2^.id;

vir1^.up:=lex2^.up;

if ptr=nil then

ptr:=vir1

else

vir3^.right:=vir1;

vir1^.right:=nil;

vir3:=vir1;

new(vir1);

vir1^.id:=vir2^.id;

vir1^.up:=vir2^.up;

vir3^.right:=vir1;

vir1^.right:=nil;

vir3:=vir1;

vir2:=vir2^.right;

end

else if lex2^.id=30 then

begin

vir2:=lex2^.right;

postfix;

new(vir1);

vir1^.id:=lex2^.id;

vir1^.up:=lex2^.up;

vir1^.right:=nil;

vir3^.right:=vir1;

vir3:=vir1;

end;

end;

if lex2^.id=30 then

begin

vir2:=lex2^.right;

postfix;

new(vir1);

vir1^.id:=lex2^.id;

vir1^.up:=lex2^.up;

vir1^.right:=nil;

vir3^.right:=vir1;

vir3:=vir1;

end;

vir2:=vir2^.right;

end;

end;

function cntr:byte;

var

lex1,lex2:Lex;

v3,v2:byte;

begin

vir1:=ptr;

while (vir1<>ptr) or (vir1^.right<>nil) do

begin

if (vir1^.id=35) or (vir1^.id=0) or (vir1^.id=1) then vir1:=vir1^.right;

if (vir1^.id=25) or (vir1^.id=26) or (vir1^.id=27) then

begin

vir2:=ptr;

while vir2^.right<>vir1 do

vir2:=vir2^.right;

vir3:=ptr;

while vir3^.right<>vir2 do

vir3:=vir3^.right;

new(lex1);

lex1^.right:=vir1^.right;

lex1^.up:=nil;

if vir2^.id=0 then v2:=0

else if vir2^.id=1 then v2:=1

else

begin

vcurr:=vir2^.up;

v2:=vcurr^.value;

end;

if vir3^.id=0 then v3:=0

else if vir3^.id=1 then v3:=1

else

begin

vcurr:=vir3^.up;

v3:=vcurr^.value;

end;

if vir1^.id=25 then

if (v2=0) or (v3=0) then lex1^.id:=0

else lex1^.id:=1;

if vir1^.id=26 then

if (v2=1) or (v3=1) then lex1^.id:=1

else lex1^.id:=0;

if vir1^.id=27 then

if (v2=0) or (v3=1) then lex1^.id:=0

else lex1^.id:=1;

if vir3=ptr then ptr:=lex1

else

begin

lex2:=ptr;

while lex2^.right<>vir3 do

lex2:=lex2^.right;

lex2^.right:=lex1;

end;

Dispose(vir1);

Dispose(vir2);

Dispose(vir3);

vir1:=lex1;

end;

if vir1^.id=24 then

begin

vir2:=ptr;

while vir2^.right<>vir1 do

vir2:=vir2^.right;

new(lex1);

lex1^.right:=vir1^.right;

lex1^.up:=nil;

if vir2^.id=0 then v2:=0

else if vir2^.id=1 then v2:=1

else

begin

vcurr:=vir2^.up;

v2:=vcurr^.value;

end;

if v2=1 then lex1^.id:=0

else lex1^.id:=1;

if vir2=ptr then ptr:=lex1

else

begin

lex2:=ptr;

while lex2^.right<>vir2 do

lex2:=lex2^.right;

lex2^.right:=lex1;

end;

Dispose(vir1);

Dispose(vir2);

vir1:=lex1;

end;

end;

if vir1^.id=0 then cntr:=0

else if vir1^.id=1 then cntr:=1

else

begin

vcurr:=vir1^.up;

cntr:=vcurr^.value;

end;

ptr:=nil;

Dispose(vir1);

end;

procedure TForm1.Make1Click(Sender: TObject);

var

value,cicl:byte;

begin

if not make then

begin

curr:=mleft;

make:=true;

Memo1.Enabled:=false;

end;

while curr<>nil do

begin

if curr^.id=28 then

begin

curr:=curr^.right;

curr:=curr^.right;

Memo3.SetFocus;

exit;

end;

if curr^.id=29 then

begin

curr:=curr^.right;

curr:=curr^.right;

while curr^.id=35 do

begin

vcurr:=curr^.up;

Memo3.Lines.Add(IntToStr(vcurr^.value)+' ');

curr:=curr^.right;

end;

end;

if curr^.id=32 then

begin

vir2:=curr^.right;

postfix;

value:=cntr;

cicl:=1;

if value=1 then

begin

new(cwhl);

cwhl^.beg:=curr^.right;

while (curr^.id<>34)or(cicl<>2)do

begin

if curr^.id=32 then cicl:=cicl+1;

if curr^.id=34 then cicl:=cicl-1;

curr:=curr^.right;

end;

cwhl^.wend:=curr^.right;

curr:=cwhl^.beg;

cwhl^.mleft:=pwhl;

pwhl:=cwhl;

end

else

begin

cicl:=1;

while (curr^.id<>34)or(cicl<>2)do

begin

if curr^.id=32 then cicl:=cicl+1;

if curr^.id=34 then cicl:=cicl-1;

curr:=curr^.right;

end;

curr:=curr^.right;

end;

end;

if curr^.id=34 then

begin

vir2:=pwhl^.beg;

postfix;

value:=cntr;

if value=1 then

curr:=pwhl^.beg

else

begin

curr:=pwhl^.wend;

cwhl:=pwhl;

pwhl:=pwhl^.mleft;

Dispose(cwhl);

end;

end;

if curr^.id=36 then

begin

vir2:=curr^.right;

postfix;

value:=cntr;

kon:=mleft;

While kon^.right<>curr do

kon:=kon^.right;

vcurr:=kon^.up;

vcurr^.value:=value;

end;

curr:=curr^.right;

end;

make:=false;

Memo1.Enabled:=true;

Form1.Valuesofvariables1.Enabled:=true;

end;

procedure TForm1.Memo3KeyUp(Sender: TObject; var Key: Word;

Shift: TShiftState);

var

str1,str2:string;

j,l:integer;

begin

if (key=13)and(make) then

begin

str1:=Memo3.Lines.Strings[Memo3.Lines.Count-1];

j:=Length(str1);

Delete(str2,1,Length(str2));

for l:=1 to j do

begin

if str1[l]<>' ' then

str2:=str2+str1[l];

if ((str1[l]=' ') or (l=j)) and (str2<>'')and((str2='0')or(str2='1')) then

begin

vcurr:=curr^.up;

vcurr^.value:=StrToInt(str2);

curr:=curr^.right;

if curr^.id<>35 then

begin

TForm1.Make1Click(Sender);

exit;

end;

end

else if(str2<>'0')and(str2<>'1') then

begin

ShowMessage('Вводимые числа должны быть 0 или 1. Выполнение программы остановено.');

make:=false;

Memo1.Enabled:=true;

exit;

end;

end;

Memo3.SetFocus;

end;

end;

procedure TForm1.Memo1Change(Sender: TObject);

begin

Form1.Valuesofvariables1.Enabled:=false;

Form1.Functionsoftransition1.Enabled:=false;

end;

procedure TForm1.ableofdisignations1Click(Sender: TObject);

begin

Form2.Memo1.Visible:=false;

Form2.Memo2.Visible:=false;

Form2.StringGrid1.Visible:=true;

Form2.Show;

end;

procedure TForm1.Valuesofvariables1Click(Sender: TObject);

begin

Form2.Memo1.Visible:=false;

Form2.Memo2.Visible:=true;

Form2.StringGrid1.Visible:=false;

vcurr:=vleft;

Form2.Memo2.Lines.Clear;

Form2.Memo2.Lines.Add('Значение Идентификатор');

while vcurr<>nil do

begin

Form2.Memo2.Lines.Add(IntToStr(vcurr^.value)+' '+vcurr^.id);

vcurr:=vcurr^.right;

end;

Form2.Show;

end;

end.

Приложение Б

Результаты тестирования

Рисунок 1

Рисунок 2

Рисунок 3

Рисунок 4

Рисунок 5

Рисунок 6

Рисунок 7

Размещено на Allbest.ru


Подобные документы

  • Разработка учебного транслятора на языке программирования C# в среде объектно-ориентированного программирования Visual Studio 2012. Выделение лексем и построение цепочки символов на этапе синтаксического анализа. Функциональное тестирование программы.

    курсовая работа [406,8 K], добавлен 07.08.2013

  • Создание Windows-приложения на алгоритмическом языке Object Pascal в среде визуального программирования Delphi, которое, как планируется, будет обеспечивать решение специализированных задач по формированию, обработке на ЭВМ и выводу информации.

    курсовая работа [967,6 K], добавлен 20.05.2008

  • Основные понятия и структура обработчика на языке Pascal. Элективные курсы по информатике в системе профильного обучения. Элективный курс "Программирование в среде Delphi". Методические материалы по изучению программирования на языке Object Pascal.

    методичка [55,4 K], добавлен 08.12.2010

  • Описания объектов, свойств, методов, формы и основных модулей текста программы в среде Delphi. Создание Windows-приложения на алгоритмическом языке Object Pascal в среде визуального программирования. Анализ результатов тестирования программного продукта.

    курсовая работа [2,4 M], добавлен 27.08.2012

  • Разработка Windows-приложений с использованием библиотеки MFC. Базовый набор классов, написанных на языке С++ и предназначенных для упрощения процесса программирования под Windows. Фундаментальные идеи объектно-ориентированного программирования.

    курсовая работа [348,1 K], добавлен 02.07.2011

  • Принципы разработки алгоритмов и программ на основе процедурного подхода и на основе объектно-ориентированного подхода. Реализация программы Borland Pascal 7.0, ее интерфейс. Разработка простой программы в среде визуального программирования Delphi.

    отчет по практике [934,7 K], добавлен 25.03.2012

  • Особенности разработки приложений для операционной системы с помощью императивного, структурированного, объектно-ориентированного языка программирования Delphi. Формальное начало программы. Выделение конца программного блока. Листинг и описание программы.

    курсовая работа [1,2 M], добавлен 04.08.2014

  • Методы грамматического разбора при разработке учебного транслятора. Проектирование лексического анализатора и магазинного автомата. Программная реализация синтаксического анализатора текстового языка высокого уровня. Разработка модуля интерпретации.

    курсовая работа [697,2 K], добавлен 06.01.2013

  • Понятие объектно-ориентированного программирования, характеристика используемых языков. Практическая разработка средств объектно-ориентированного программирования в задачах защиты информации: программная реализация на языке С++, а также Turbo Pascal.

    курсовая работа [275,9 K], добавлен 22.12.2011

  • Обзор основных используемых языков программирования (С++, Java, Pascal). Анализ существующих методов шифрования паролей. Основные понятия объектно-ориентированного программирования. Реализация приложения для генерирования паролей на языке Object Pascal.

    курсовая работа [822,4 K], добавлен 07.07.2012

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.