Проектирование лексического анализатора
Характеристика особенностей организации таблицы идентификаторов. Анализ принципов работы лексического анализатора. Изучение схемы распознавателя. Характеристика методов проектирования синтаксического анализатора. Матрица операторного предшествования.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 09.11.2017 |
Размер файла | 407,9 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Содержание
Введение
1. Организация таблицы идентификаторов
1.1 Исходные данные
1.2 Назначение таблиц идентификаторов
1.3 Метод простого рехэширования
1.4 Метод цепочек
1.5 Результаты
2. Проектирование лексического анализатора
2.1 Исходные данные
2.2 Принципы работы лексического анализатора
2.3 Схема распознавателя
2.4 Результаты
3. Проектирование синтаксического анализатора
3.1 Исходные данные
3.2 Построение синтаксического анализатора
3.3 Результаты
Заключение
Список использованной литературы
Приложение А Исходный текст программы
Приложение Б Граф состояний лексического анализатора
Приложение В Матрица операторного предшествования
распознаватель анализатор лексический
Введение
Компилятор - программный модуль, задачей которого является перевод программы, написанной на одном из языков программирования (исходный язык) в программу на языке ассемблера или языке машинных команд.
Целью данной курсовой работы является изучение составных частей, основных принципов построения и функционирования компилятора, практическое освоение методов построения составных частей компилятора для заданного входного языка.
Курсовая работа заключается в реализации отдельных фаз компиляции заданного языка.
В первой части работы требуется разработать программный модуль, который получает на входе набор идентификаторов, организует таблицу идентификаторов по заданным методам и позволяет осуществить многократный поиск идентификатора в этой таблице. Программа должна подсчитывать число коллизий и среднее количество сравнений, выполняемых для поиска идентификатора.
Во второй части работы требуется разработать программный модуль, выполняющий лексический анализ входного текста по заданной грамматике и порождающий таблицу лексем с указанием их типов.
В третьей части работы требуется разработать программу, которая на основании таблицы лексем выполняет синтаксический разбор текста по заданной грамматике с построением цепочки вывода и дерева разбора.
В качестве среды разработки для реализации приложения использован язык программирования Delphi 7 и система программирования Borland Delphi 7.
1. Организация таблицы идентификаторов
1.1 Исходные данные
На входе имеется набор идентификаторов, которые организуются в таблицу идентификаторов по одному из двух методов:
1. Простое рехэширование.
2. Метод цепочек.
Должна быть предусмотрена возможность осуществления многократного поиска идентификатора в этой таблице. Список идентификаторов задан в виде текстового файла. Длина идентификатора ограничена 32 символами.
Требуется, чтобы программа подсчитывала число коллизий и среднее количество сравнений, выполняемых при поиске идентификатора.
1.2 Назначение таблиц идентификаторов
Проверка правильности семантики и генерация кода требуют знания характеристик идентификаторов, используемых в программе на исходном языке. Эти характеристики выясняются из описаний и из того, как идентификаторы используются в программе и накапливаются в таблице символов, или таблице идентификаторов. Любая таблица идентификаторов состоит из набора полей, количество которых равно числу идентификаторов программы. Каждое поле содержит в себе полную информацию о данном элементе таблицы. Под идентификаторами подразумеваются константы, переменные, имена процедур и функций, формальные и фактические параметры.
В данной работе сравниваются два метода организации таблицы идентификаторов: метод простого рехэширования и метод цепочек.
Данные методы основаны на хеш-адресации, то есть на использовании значения, возвращаемого хеш-функцией, в качестве адреса ячейки из некоторого массива данных. Хеш-функция вычисляется путем выполнения над цепочкой символов некоторых простых арифметических и логических операций. Самой простой хеш-функцией для символа является ASCII-код символа.
В данной курсовой работе принята хэш-функция сумма ASCII-кодов первых двух символов цепочки.
При хэш-адресаци возможна ситуация, когда двум или более идентификаторам соответствует одно и то же значение хэш-функции. Такая ситуация называется коллизией. Сравниваемые в данной работе методы организации таблицы идентификаторов простого рехэширования и метод цепочек отличаются по способу разрешения коллизий. Ниже каждый метод рассмотрен подробнее.
1.3Метод простого рехэширования
Согласно данному методу, если для элемента А адрес п() = h(A), указывает на уже занятую ячейку, то есть в случае возникновения коллизии, необходимо вычислить значение функции n1 = h1(A) и проверить занятость ячейки по адресу n1. Если и она занята, то вы-числяется значение h2(A). И так до тех пор, пока либо не будет найдена свободная ячейка, либо очередное значение hi(A) не совпадет с h(A). В последнем случае считается, что таблица идентификаторов заполнена и места в ней больше нет выдается сообщение об ошибке размещения идентификатора в таблице.
Согласно методу простого рехэширования, hi(A) = (h(A)+i) mod Nm, где Nm максимальное значение хэш-функции.
В данной курсовой работе принята хэш-функция сумма ASCII-кодов первых двух символов цепочки, максимальное значение хэш-функции равно 512.
Поскольку при заполнении таблицы идентификаторов основными операциями являются добавление элемента в таблицу и поиск элемента в ней, на рис. 1 и рис. 2 представлены блок-схемы этих операций для рассматриваемого метода.
Рис. 1. Блок-схема добавления элемента в таблицу идентификаторов по методу простого рехэширования
Рис. 2. Блок-схема алгоритма поиска элемента в таблице идентификаторов, организованной по методу простого рехэширования
1.4 Метод цепочек
Согласно данному методу, хэш-функция вычисляет адрес, по которому происходит обращение сначала к хеш-таблице, а затем через нее по найденному адресу -- к таблице идентификаторов. В таблицу идентификаторов для каждого элемента добавляется поле, в котором может содержаться ссылка на любой элемент таблицы. В случае возникновения коллизии алгоритм размещает элементы в ячейках таблицы, связывая их друг с другом последовательно через поле ссылки.
Поскольку при заполнении таблицы идентификаторов основными операциями являются добавление элемента в таблицу и поиск элемента в ней, на рис. 3 и рис. 4 представлены блок-схемы этих операций для рассматриваемого метода.
Рис. 3. Блок-схема добавления элемента в таблицу идентификаторов по методу цепочек
Рис. 4. Блок-схема алгоритма поиска элемента в таблицу идентифиикаторов, организованной по методу цепочек
1.5 Результаты
Для сравнения метода простого рехэширования и метода цепочек выбран текстовый файл, содержащий 100 строк.
В результате работы программы получены следующие данные, которые представлены в табл. 1.
Таблица 1
Метод простого рехэширования |
Метод цепочек |
||
Коллизий |
74 |
59 |
|
Сравнений |
19 |
3 |
|
Среднее число сравнений |
0,19 |
0,03 |
На основе полученных результатов можно сделать следующие выводы.
Недостатки метода простого рехэширования:
элементы могут попадать в ячейки с адресами, которые потом будут совпадать со значениями хеш-функции, что приводит к возникновению дополнительных коллизий;
среднее время на размещение элемента и на поиск элемента в таблице зависит от заполненности таблицы идентификаторов и качества используемой хеш-функции;
требование неполного заполнения таблицы ведет к неэффективному использованию объема доступной памяти.
Достоинством метода простого рехэширования является то, что он позволяет добиться неплохих результатов для эффективного поиска элемента в таблице (лучших, чем метод бинарного дерева).
Достоинства метода цепочек:
нет необходимости заполнять пустыми значениями таблицу идентификаторов (это можно сделать только для хеш-таблицы), то есть память используется более экономно;
элементы не могут попадать в ячейки с адресами, которые потом будут совпадать со значениями хеш-функции, то есть дополнительные коллизии не будут возникать;
среднее время на размещение элемента и на поиск элемента в таблице зависит только от среднего числа коллизий, возникающих при вычислении хеш-функции.
Недостатком метода цепочек является необходимость организации работы с динамическими массивами данных.
Метод цепочек является более эффективным методом организации таблицы идентификаторов. Именно он и будет в дальнейшем использован для хранения информации об идентификаторах в курсовой работе.
2. Проектирование лексического анализатора
2.1 Исходные данные
Для выполнения данной части курсовой работы требуется написать программу, которая выполняет лексический анализ входного текста в соответствии с заданием и порождает таблицу лексем с указанием их типов и значений. Текст на входном языке задан в виде текстового файла. Программа должна выдавать сообщения о наличие во входном тексте ошибок, которые могут быть обнаружены на этапе лексического анализа. Программа должна допускать наличие комментариев неограниченной длины во входном файле.
В соответствии с заданием должны распознаваться:
ключевые слова : «prog», «end.», «begin», «end», «if», «then», «else», «for», «to», «downto», «do», «and», «or», «not»;
идентификаторы: любые последовательности латинских символов и цифр; идентификатор должен начинаться с символа;
константы: двоичное представление числа;
знаки операций: «=», «<», «>», «-», «+», «*», «/»;
оператор присваивания: «:=»;
разделитель: «;»;
комментарии, заключенные в «{», «}».
2.2 Принципы работы лексического анализатора
Поскольку в данной курсовой работе входной язык является регулярным и может быть задан с помощью регулярной грамматики, распознавателем для него будет служить конечный автомат.
Конечный автомат задается пятеркой:
M=(Q,,,q0,F), где:
Q - конечное множество состояний автомата;
- конечное множество допустимых входных символов;
- множество функций перехода автомата;
q0Q - начальное состояние автомата;
FQ - множество конечных состояний автомата.
Работа автомата выполняется по тактам. На каждом очередном такте i автомат, находясь в некотором состоянии qiQ, считывает очередной символ vV из входной цепочки символов и изменяет свое состояние на qi+1=(qi,v), после чего указатель в цепочке входных символов передвигается на следующий символ и начинается такт i+1. Так продолжается до тех пор, пока цепочка входных символов не закончится. Конец цепочки символов часто помечают особым символом . Считается также, что перед тактом 1 автомат находится в начальном состоянии q0.
Графически автомат отображается нагруженным однонаправленным графом, в котором вершины представляют состояния, дуги отображают переходы из одного состояния в другое, а символы нагрузки (пометки) дуг соответствуют входному символу. Если функция перехода предусматривает переход из состояния q в q' по нескольким символам, то между ними строится одна дуга, которая помечается всеми символами, по которым происходит переход из q в q'.
2.3 Схема распознавателя
Граф конечного автомата, используемого для распознавания входных цепочек языка, представлен на рис. 1 в приложении Б.
Начальное состояние автомата на рисунке обозначено "Н". В случае ошибочной входной цепочки автомат попадает в состояние ошибки E. При этом работа автомата останавливается.
Кроме того, типичными для автомата являются состояния I (переменная) и G (константа). Остальные состояния автомата определяются допустимыми для компилятора исходного языка лексемами.
Каждый переход в конечное состояние "S" сообщает о конце текущей входной цепочки. В этом случае производится анализ распознанной цепочки и перезапуск автомата для очередной входной цепочки символов. Заметим также, что возможна повторная обработка некоторых символов входной цепочки символов. Это необходимо в тех случаях, когда символ, приведший к переходу автомата в конечное состояние, является началом следующей цепочки символов.
2.4 Результаты
На основе сравнения методов организации таблиц идентификаторов, проведенного в первой части курсовой работы, выбран метод цепочек. На основе таблицы идентификаторов, заполненной по методу цепочек, организована таблица лексем. На рис. 5 и рис. 6 представлены таблица идентификаторов и таблица лексем, построенные при обработке следующего текстового файла:
prog ttt;
Begin
for j:=p7p downto 1001b do begin
if(t<f)and t then {rt rrrr}
c:=c*111111111b
else 5jhg;
End.
Рис. 5. Результат работы лексического анализатора таблица идентификаторов.
Содержимое файла: Неизвестные лексемы
Рис. 6 Результат работы лексического анализатора таблица лексем
3. Проектирование синтаксического анализатора
3.1 Исходные данные
Для программной реализации процесса построения дерева вывода требуется написать программу, которая выполняет синтаксический разбор текста по заданной КС-грамматике с построением дерева разбора. Текст на входном языке задан в виде текстового файла. Программа должна выдавать сообщения о наличие во входном тексте ошибок.
3.2 Построение синтаксического анализатора
Исходная КС-грамматика:
G ({ prog, end., if, then, else, endif, begin, end, for, to, downto, do, and, or, not, =, <, >, (, ),{, }, -, +, *, /, a, c, ;, :=}, {S, L, O, B, C, K, D, H, E, T, M},P, S)
P:
S > prog L end.
L > O | L ; O | L ;
O > if B then O else O endif | if B then O endif | begin L end
| for M to E do O| for M downto E do O| M
M> a:=E
B > B or C | C
C > C and D | D
D >not D | H
H > E < E | E > E | E = E | (B)
E > E - T | E + T | E * T | E / T| T
T > (E) | a | c
Смысл нетерминальных символов грамматики:
S - вся программа,
L - последовательность операторов(может состоять из одного оператора),
O - оператор,
B-, C, D - логическое выражение и его элементы,
H - операции сравнения или логические выражения в скобках,
E,T - арифметические выражения и его элементы,
a - переменная,
с - константа.
КС-языки делятся на классы в соответствии со структурой правил их грамматик. Одним из таких классов является класс грамматик предшествования. Они используются для синтаксического разбора цепочек с помощью алгоритма “сдвиг-свертка”.
Грамматикой операторного предшествования называется приведенная КС-грамматика без -правил, в которой правые части продукций не содержат смежных нетерминальных символов. Для грамматики операторного предшествования строится матрица операторного предшествования, которая содержит только терминальные символы грамматики. Отношения =, < и > называют отношениями предшествования.
Исходная КС-грамматика, представленная выше, является грамматикой операторного предшествования.
Строятся множества крайних левых и крайних правых символов L(U), R(U) относительно всех нетерминальных символов грамматики. Результат построения приведен в табл. 2.
Таблица 2
U |
L(U) |
R(U) |
|
T |
(, a, c |
), a, c |
|
E |
E, T |
T |
|
H |
(, E |
E, ) |
|
D |
not, H |
D, H |
|
C |
C, D |
D |
|
B |
B, C |
C |
|
O |
if, begin, for, M |
endif, end, O, M |
|
M |
a |
E |
|
L |
L, O |
O, ; |
|
S |
prog |
end. |
На основе полученных множеств строятся множества крайних левых и крайних правых терминальных символов Lt(U), Rt(U) относительно всех нетерминальных символов грамматики. Результат построения приведен в табл. 3.
Таблица 3
U |
Lt(U) |
Rt(U) |
|
T |
(, a, c |
), a, c |
|
E |
-, +,*, /, (, a, c |
-, +,*, /, ), a, c |
|
H |
<, >, =, (, -, +,*, /, a, c |
<, >, =, ), -, +,*, /, a, c |
|
D |
not, <, >, =, (, -, +,*, /, a, c |
not, <, >, =, ), -, +,*, /, a, c |
|
C |
and, not, <, >, =, (, -, +,*, /, a, c |
and, not, <, >, =, ), -, +,*, /, a, c |
|
B |
or, and, not, <, >, =, (, -, +,*, /, a, c |
or, and, not, <, >, =, ), -, +,*, /, a, c |
|
O |
if, begin, for, a |
endif, end, do, :=, -, +, ), a, c |
|
M |
a |
:=, -, +, ), a, c |
|
L |
;, if, begin, for, a |
;, endif, end, do, :=, -, +, ), a, c |
|
S |
prog |
end. |
На основе данных множеств и правил исходной КС-грамматики G построим матрицу операторного предшествования, которая представлена в приложении В.
Алгоритм разбора цепочек грамматики операторного предшествования игнорирует нетерминальные символы. Поэтому имеет смысл преобразовать исходную грамматику таким образом, чтобы оставить в ней только один нетерминальный символ.
Остовная грамматика, полученная на основе исходной грамматики:
G' ({ prog, end., if, then, else, endif, begin, end, for, to, downto, do, and, or, not, =, <, >, (, ), -, +,*, /, a, c, ;, :=}, {E}, P', S)
E > program E end.
E > E | E ; E | E ;
E > if E then E else E endif | if E then E endif | begin E end | for E to E do E | for E downto E do E | E
E > a:=E
E > E or E | E
E > E and E | E
E > not E | E
E > E < E | E > E | E = E | (E)
E > E - E | E + E | E * E| E / E | E
E > (E) | a | c
Для различия скобок, определяющих соответственно приоритет арифметических и логических операций, остовная грамматика дополняется нетерминальным символом B, который будет обозначать логические выражения.
Преобразованная остовная грамматика имеет следующий вид:
G' ({ prog, end., if, then, else, endif, begin, end, for, to, downto, do, and, or, not, =, <, >, (, ), -, +,*, /, a, c, ;, :=}, {E}, P', S)
E > program E end.
E > E | E ; E | E ;
E > if B then E else E endif | if B then E endif | begin E end | for E to E do E | for E downto E do E | E
E > a:=E
B > B or B | B
B > B and B | B
B > not B | B
B > E < E | E > E | E = E | (B)
E > E - E | E + E | E * E| E / E | E
E > (E) | a | c
3.3 Результаты
Программа проводит синтаксический анализ последовательного набора лексем, поступающего от лексического анализатора, на основе правил остовной грамматики. Результатом ее работы является дерево синтаксического разбора. В случае ошибки на экране появляется сообщение об ошибке.
На вход подается следующий текстовый файл:
prog
if (p=0110b) then begin y := h; end
endif; {komment }
for k:=0011b to u do k:=k+00101b;
end.
Результат работы синтаксического анализатора представлены на рис. 7.
Рис. 7. Результат построения дерева разбора
На вход подается следующий текстовый файл:
prog
if (p=0110b) then begin y := h; end
endif; {komment }
for k:=0011b to u do k:=k+00101b;
begin
end.
Результат работы синтаксического анализатора при подаче на вход анализатора ошибочных конструкций представлен на рис. 8.
Использованные правила: Дерево разбора
Рис. 8. Результат построения дерева разбора при подаче на вход анализатора ошибочных конструкций
Заключение
В процессе выполнения курсовой работы было разработано приложение, реализующее отдельные фазы компиляции заданного языка. Для разработки приложения использовалась среда программной разработки Borland Delphi 7.
Список использованной литературы
1. Системное программное обеспечение: Учебник для вузов/ А.Ю. Молчанов- СПб.: Питер, 2003.- 396 с.
2. Системное программное обеспечение. Лабораторный практикум/ А.Ю. Молчанов- СПб.: Питер, 2005.- 284 с.
Приложение А
Исходный текст программы
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, ExtCtrls, ComCtrls;
type
TAutoState=(AUTO_H,AUTO_PP,AUTO_PP1,AUTO_PP2,AUTO_PP3,AUTO_BB,AUTO_BB1,AUTO_I,
AUTO_BB2,AUTO_BB3,AUTO_BB4,AUTO_EE,AUTO_EE1,AUTO_EE2,AUTO_G,AUTO_UM,AUTO_RZ,
AUTO_SL,AUTO_VI,AUTO_M,AUTO_B,AUTO_P,AUTO_OO,AUTO_ZZ,AUTO_A,AUTO_A1,AUTO_A2,
AUTO_O,AUTO_O1,AUTO_N,AUTO_N1,AUTO_N2,AUTO_II,AUTO_I1,AUTO_T,AUTO_T1,AUTO_T2,
AUTO_T3,AUTO_E1,AUTO_E2,AUTO_E3,AUTO_FF,AUTO_FF1,AUTO_FF2,AUTO_T10,AUTO_D,
AUTO_D1,AUTO_D2,AUTO_D3,AUTO_D4,AUTO_D5,AUTO_Q,AUTO_Q1,AUTO_TK,AUTO_TZ,AUTO_K,
AUTO_E,AUTO_G1,AUTO_EE3,AUTO_EE4);
TForm1 = class(TForm)
PageControl1: TPageControl; TabSheet2: TTabSheet; Label11: TLabel; Label14: TLabel;Label8: TLabel;Label26: TLabel; Button4: TButton; Memo1: TMemo; Button5: TButton; Panel1: TPanel; Label27: TLabel; Button6: TButton; Edit1: TEdit; GroupBox4: TGroupBox; Label28: TLabel; Label29: TLabel; Label30: TLabel; Label19: TLabel; Label21: TLabel; Label23: TLabel; GroupBox6: TGroupBox; Label34: TLabel; Label35: TLabel; Label36: TLabel; Label20: TLabel; Label22: TLabel; Label24: TLabel; GroupBox7: TGroupBox; Label40: TLabel; Label41: TLabel; StringGrid1: TStringGrid; GroupBox8: TGroupBox; Label42: TLabel; Label43: TLabel; Label44: TLabel; StringGrid2: TStringGrid; StringGrid3: TStringGrid; TabSheet1: TTabSheet; OpenDialog1: TOpenDialog; Label1: TLabel; Label5: TLabel; Label2: TLabel; Memo2: TMemo; StringGrid4: TStringGrid; Memo3: TMemo; Button9: TButton; Button3: TButton; TabSheet3: TTabSheet; StringGrid6: TStringGrid; Label7: TLabel; Button1: TButton; Button2: TButton; Label3: TLabel; Memo4: TMemo; StringGrid5: TStringGrid; TabSheet4: TTabSheet; Button7: TButton; Button8: TButton; Label4: TLabel; Memo5: TMemo; Label6: TLabel; Memo6: TMemo; TreeView1: TTreeView; Memo7: TMemo; Label9: TLabel;Label10: TLabel; Label12: TLabel; Label16: TLabel; Label13: TLabel; Label15: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button9Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button8Click(Sender: TObject);
procedure Edit1Change(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const
PredMatrix:array [1..29,1..29] of char= (
{prog end. ; if then else ef beg end for to down do a c := or and not < > = ( ) - + * / !}
{prog} (' ','=','<','<',' ',' ',' ','<',' ','<',' ',' ',' ','<',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '),
{end.} (' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','>'),
{;} (' ','>','>','<',' ',' ',' ','<','>','<',' ',' ',' ','<',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '),
{if} (' ',' ',' ',' ','=',' ',' ',' ',' ',' ',' ',' ',' ','<','<',' ','<','<','<','<','<','<','<',' ','<','<','<','<',' '),
{then} (' ',' ',' ','<',' ','=','=','<',' ','<',' ',' ',' ','<',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '),
{else} (' ',' ',' ','<',' ',' ','=','<',' ','<',' ',' ',' ','<',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '),
{endif} (' ','>','>',' ',' ','>','>',' ','>','<',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '),
{begin} (' ',' ','<','<',' ',' ',' ','<','=','<',' ',' ',' ','<',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '),
{end} (' ','>','>',' ',' ','>','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '),
{for} (' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','=','=',' ','<',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '),
{to} (' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','=','<','<',' ',' ',' ',' ',' ',' ',' ','<',' ','<','<','<','<',' '),
{downto}(' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','=','<','<',' ',' ',' ',' ',' ',' ',' ','<',' ','<','<','<','<',' '),
{do} (' ','>','>','<',' ','>','>','<','>','<',' ',' ',' ','<',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '),
{a} (' ','>','>',' ','>','>','>',' ','>','>','>','>','>',' ',' ','=','>','>','>','>','>','>',' ','>','>','>','>','>',' '),
{c} (' ','>','>',' ','>','>','>',' ','>','>','>','>','>',' ',' ',' ','>','>',' ','>','>','>',' ','>','>','>','>','>',' '),
{:=} (' ','>','>',' ',' ','>','>',' ','>',' ','>','>',' ','<','<',' ',' ',' ',' ',' ',' ',' ','<','>','<','<','<','<',' '),
{or} (' ',' ',' ',' ','>',' ',' ',' ',' ',' ',' ',' ',' ','<',' ',' ','>','<','<','<','<','<','<','>','<','<','<','<',' '),
{and} (' ',' ',' ',' ','>',' ',' ',' ',' ',' ',' ',' ',' ','<',' ',' ','>','<','<','<','<','<','<','>','<','<','<','<',' '),
{not} (' ',' ',' ',' ','>',' ',' ',' ',' ',' ',' ',' ',' ','<',' ',' ','>','<','<','<','<','<','<','>','<','<','<','<',' '),
{<} (' ',' ',' ',' ','>',' ',' ',' ',' ',' ',' ',' ',' ','<','<',' ','>','<',' ',' ',' ',' ','<','>','<','<','<','<',' '),
{>} (' ',' ',' ',' ','>',' ',' ',' ',' ',' ',' ',' ',' ','<','<',' ','>','<',' ',' ',' ',' ','<','>','<','<','<','<',' '),
{=} (' ',' ',' ',' ','>',' ',' ',' ',' ',' ',' ',' ',' ','<','<',' ','>','<',' ',' ',' ',' ','<','>','<','<','<','<',' '),
{(} (' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','<','<',' ','<','<','<','<','<','<','<','=','<','<','<','<',' '),
{)} (' ','>','>',' ','>','>','>',' ','>','>','>','>','>',' ',' ',' ','>','>',' ','>','>','>',' ','>','>','>','>','>',' '),
{-} (' ','>','>',' ','>','>','>',' ','>','>','>','>','>','<','<',' ','>','>',' ','>','>','>',' ','>','>','>','>','>',' '),
{+} (' ','>','>',' ','>','>','>',' ','>','>','>','>','>','<','<',' ','>','>',' ','>','>','>',' ','>','>','>','>','>',' '),
{*} (' ','>','>',' ','>','>','>',' ','>','>','>','>','>','<','<',' ','>','>',' ','>','>','>',' ','>','>','>','>','>',' '),
{/} (' ','>','>',' ','>','>','>',' ','>','>','>','>','>','<','<',' ','>','>',' ','>','>','>',' ','>','>','>','>','>',' '),
{!} ('<',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '));
grammar:array [1..29] of string=
('progEend.','E','E;E','E;','ifBthenEelseEendif','ifBthenEendif','beginEend','forEtoEdoE','forEdowntoEdoE','E','a:=E',
'BorB','B','BandB','B','notB','B','E<E','E>E','E=E','(B)','E-E','E+E','E*E','E/E','E','(E)','a','c');
term:array [1..29] of string= ('prog','end.',';','if','then','else','endif','begin','end','for','to','downto','do','a','c',':=','or','and','not','<','>','=','(',')','-','+','*','/','!');
notterm:array [1..29] of char=
('E','E','E','E','E','E','E','E','E','E','E','B','B','B','B','B','B','B','B','B','B','E','E','E','E','E','E','E','E');
CanonO:array [1..29,1..7] of string=
(('prog','E','end.','','','',''),
('E','','','','','',''),
('E',';','E','','','',''),
('E',';','','','','',''),
('if','E','then','E','else','E','endif'),
('if','E','then','E','endif','',''),
('begin','E','end','','','',''),
('for','E','to','E','do','E',''),
('for','E','downto','E','do','E',''),
('E','','','','','',''),
('a',':=','E','','','',''),
('E','or','E','','','',''),
('E','','','','','',''),
('E','and','E','','','',''),
('D','','','','','',''),
('not','E','','','','',''),
('E','','','','','',''),
('E','<','E','','','',''),
('E','>','E','','','',''),
('E','=','E','','','',''),
('(','E',')','','','',''),
('E','-','E','','','',''),
('E','+','E','','','',''),
('E','*','E','','','',''),
('E','/','E','','','',''),
('E','','','','','',''),
('(','E',')','','','',''),
('a','','','','','',''),
('c','','','','','',''));
var
Form1: TForm1;
implementation
function IndMatrix(SymS:String):integer;
var i:integer;
begin
indMatrix:=0;
if term[1]=SymS then IndMatrix:=1;
for i:=1 to 29 do
if term[i]=SymS then IndMatrix:=i;
end;
function inArray(myS:String;A:Array of string;N:integer):boolean;
var i:integer;
begin
inArray:=False;
if MyS='prog' then inArray:=true;
for i:=1 to N do
if myS=A[i] then begin inArray:=true end;
end;
function NomRul(myS:String):integer;
var i:integer;
begin
NomRul:=0;
if (myS=grammar[1])then NomRul:=1;
for i:=1 to 29 do
if grammar[i]=myS then NomRul:=i;
end;
function findnt(myS:String):string;
begin
findnt:='';
findnt:=notterm[nomRul(myS)]
end;
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Text:='';
Memo2.Text:='';
Memo3.Text:='';
Memo4.Text:='';
Memo5.Text:='';
Memo6.Text:='';
Form1.StringGrid1.Cells[0,0]:='ХФ';
Form1.StringGrid1.Cells[1,0]:='Идентификатор';
Form1.StringGrid2.Cells[0,0]:='ХФ';
Form1.StringGrid2.Cells[1,0]:='Номер';
Form1.StringGrid3.Cells[0,0]:='Номер';
Form1.StringGrid3.Cells[1,0]:='Идентификатор';
Form1.StringGrid3.Cells[2,0]:='Ссылка';
Form1.StringGrid6.Cells[0,0]:='Номер';
Form1.StringGrid6.Cells[1,0]:='Идентификатор';
Form1.StringGrid6.Cells[2,0]:='Ссылка';
Form1.Label19.Caption:='';
Form1.Label20.Caption:='';
Form1.Label21.Caption:='';
Form1.Label22.Caption:='';
Form1.Label23.Caption:='';
Form1.Label24.Caption:='';
Form1.Label8.Caption:='';
StringGrid4.Cells[0,0]:='№';
StringGrid4.Cells[1,0]:='Лексема';
StringGrid4.Cells[2,0]:='Тип лексемы';
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if Form1.OpenDialog1.Execute
then Form1.Memo1.Lines.LoadFromFile(Form1.OpenDialog1.FileName);
end;
procedure TForm1.Button2Click(Sender: TObject);
label L1,L2,L3;
var i,i1,i2,i3,i4,j1,j2,HF,f,p,ukaz,j,adr,adrr:integer;
str:string;
begin
for i:=1 to 513 do
begin
Form1.StringGrid1.Cells[0,i]:='';
Form1.StringGrid1.Cells[1,i]:='';
end;
i1:=Form1.Memo1.Lines.Count;
//******************************************* рехэширование
for j1:=1 to 513 do Form1.StringGrid1.Cells[0,j1]:=IntToStr(j1);
i2:=1; i3:=0;
if Form1.Memo1.Lines[0]<>'' then
for i:=0 to i1-1 do
begin
f:=0;
str:=Form1.Memo1.Lines[i];
i4:=Length(str);
if i4=1 then HF:=Ord(str[1])+Ord(str[1])
else HF:=Ord(str[1])+Ord(str[2]);
j1:=HF;
L1: if Form1.StringGrid1.Cells[1,HF]='' then Form1.StringGrid1.Cells[1,HF]:=str
else begin
if Form1.StringGrid1.Cells[1,HF]=str then
begin
ShowMessage('Повторение идентификатора '+str);
goto L2;
end
else begin
if f=0 then i3:=i3+1;
f:=1;
i2:=i2+1;
HF:=(j1+i2) mod 512;
goto L1;
end;
end;
i2:=1;
L2: end;
Form1.Label8.Caption:=inttostr(i3);
//******************************************* метод цепочек
p:=0;
for j1:=1 to 513 do Form1.StringGrid2.Cells[0,j1]:=IntToStr(j1);
ukaz:=1;
Form1.StringGrid3.RowCount:=ukaz+1;
if Form1.Memo1.Lines[0]<>'' then
for i:=0 to i1-1 do
begin
str:=Form1.Memo1.Lines[i];
i4:=Length(str);
if i4=1 then HF:=Ord(str[1])+Ord(str[1])
else HF:=Ord(str[1])+Ord(str[2]);
j1:=HF;
if Form1.StringGrid2.Cells[1,HF]=''
then begin
Form1.StringGrid2.Cells[1,HF]:=inttostr(ukaz);
Form1.StringGrid3.Cells[0,ukaz]:=inttostr(ukaz);
Form1.StringGrid3.Cells[1,ukaz]:=str;
Form1.StringGrid3.RowCount:=ukaz+1;
ukaz:=ukaz+1;
end
else begin
p:=p+1;
j:=1;
adr:=strtoint(Form1.StringGrid2.Cells[1,HF]);
L3: if Form1.StringGrid3.Cells[1,adr]<>str then
if Form1.StringGrid3.Cells[2,adr]='' then
begin
Form1.StringGrid3.Cells[0,ukaz]:=inttostr(ukaz);
Form1.StringGrid3.Cells[1,ukaz]:=str;
Form1.StringGrid3.Cells[2,adr]:=inttostr(ukaz);
Form1.StringGrid3.RowCount:=ukaz+1;
ukaz:=ukaz+1;
end
else begin
j:=j+1;
adrr:=strtoint(Form1.StringGrid3.Cells[2,adr]);
adr:=adrr;
goto L3;
end;
end;
end;
Form1.Label15.Caption:=inttostr(p);
end;
procedure TForm1.Button8Click(Sender: TObject);
label L1,L2;
var str:string;
adr,adrr,j,i1,a1,b1,b2,f,HF,HFF:integer;
begin
i1:=Memo1.Lines.Count;
//******************************************* рехэширование
begin
f:=0; b2:=0; b1:=1;
if Edit1.Text<>'' then
begin
str:=Edit1.Text;
if Length(str)=1 then HF:=Ord(str[1])+Ord(str[1])
else HF:=Ord(str[1])+Ord(str[2]);
HFF:=HF;
L1:
if StringGrid1.Cells[1,HF]<>'' then
begin
if StringGrid1.Cells[1,HF]=str then
begin
b2:=b2+1;
f:=1;
end
else begin
b2:=b2+1;
b1:=b1+1;
HF:=(HFF+b1) mod 512;
goto L1;
end;
end
end
else begin
ShowMessage('Введите идентификатор для поиска.');
f:=2;
end;
if f=1 then begin
Label19.Caption:='ЭЛЕМЕНТ НАЙДЕН';
StringGrid1.Cells[0,HF]:='Найден!';
end
else if f<>2 then Label19.Caption:='ЭЛЕМЕНТ НЕ НАЙДЕН';
Label21.Caption:=IntToStr(b2);
Label23.Caption:=FloatToStr(b2/i1);
end;
//******************************************* метод цепочек
begin
a1:=0;
if Edit1.Text<>'' then
begin
str:=Edit1.Text;
if Length(str)=1 then HF:=Ord(str[1])+Ord(str[1])
else HF:=Ord(str[1])+Ord(str[2]);
if StringGrid2.Cells[1,HF]<>'' then
begin
j:=1;
adr:=strtoint(StringGrid2.Cells[1,HF]);
L2: if StringGrid3.Cells[1,adr]<>str then
begin
a1:=a1+1;
if StringGrid3.Cells[2,adr]=''
then Label20.Caption:='ЭЛЕМЕНТ НЕ НАЙДЕН'
else begin
j:=j+1;
adrr:=strtoint(StringGrid3.Cells[2,adr]);
adr:=adrr;
goto L2;
end;
end
else begin
a1:=a1+1;
Label20.Caption:='ЭЛЕМЕНТ НАЙДЕН';
StringGrid3.Cells[0,adr]:='Найден!';
end;
end
else Label20.Caption:='ЭЛЕМЕНТ НЕ НАЙДЕН';
end;
Label22.Caption:=IntToStr(a1);
Label24.Caption:=FloatToStr(a1/i1);
end;
end;
procedure TForm1.Edit1Change(Sender: TObject);
var q,w,i:integer;
begin
q:=StringGrid1.RowCount;
w:=StringGrid3.RowCount;
for i:=1 to q do StringGrid1.Cells[0,i]:=inttostr(i);
for i:=1 to w do StringGrid3.Cells[0,i]:=inttostr(i);
end;
procedure TForm1.Button9Click(Sender: TObject);
begin
if Form1.OpenDialog1.Execute
then begin
Form1.Memo2.Lines.LoadFromFile(Form1.OpenDialog1.FileName);
Form1.Memo4.Lines.LoadFromFile(Form1.OpenDialog1.FileName);
Form1.Memo5.Lines.LoadFromFile(Form1.OpenDialog1.FileName);
end;
end;
procedure TForm1.Button3Click(Sender: TObject);
var ind,i,j,i1,i2,fl,zn,h,w,ukaz,i4,HF,j1,adr,ddd:integer;
adrr,nom,dl,yy,m,j2,fl2,n,k,vetv,u,f:integer;
st,str,stroka:string;
o1,o2,o3,o4,o5,o6,pr:string;
sost:TAutoState;
inputString,SymbStack:TStringList;
NRow,verh:integer;
gamma,MyinS,syms,tek,cep:String;
Mycase:char;
CepofV:array [1..100]of integer;
p,stek,d:TStringList;
MyTreeNode:TTreeNode;
nodeTree: TTreeNode;
label L3,M1,M2, Myend,zap,tree;
begin
Memo3.Text:='';
Memo4.Text:='';
Form1.StringGrid4.RowCount:=1001;
for j:=1 to 1000 do Form1.StringGrid4.Cells[0,j]:='';
for j:=1 to 1000 do Form1.StringGrid4.Cells[1,j]:='';
for j:=1 to 1000 do Form1.StringGrid4.Cells[2,j]:='';
for i:=1 to 513 do
begin
Form1.StringGrid6.Cells[0,i]:='';
Form1.StringGrid6.Cells[1,i]:='';
Form1.StringGrid6.Cells[2,i]:='';
Form1.StringGrid5.Cells[0,i]:='';
Form1.StringGrid5.Cells[1,i]:='';
end;
u:=1;
p:=TStringList.Create;
p.Sorted:=False;
stek:=TStringList.Create;
stek.Sorted:=False;
d:=TStringList.Create;
d.Sorted:=False;
i1:=Memo2.Lines.Count;
ind:=1;w:=0;i:=0;
while(i<>i1)do
begin
str:='';
sost:=AUTO_H;
stroka:=Memo2.Lines[i];
stroka:=stroka+' #';
fl:=0; zn:=0; j:=1;
while(stroka[j]<>'#')do
begin
st:=stroka[j];
case sost of
AUTO_H:
case stroka[j] of
'P','p':begin sost:=AUTO_PP;str:=str+st; end;
'B','b':begin sost:=AUTO_BB;str:=str+st; end;
'E','e':begin sost:=AUTO_EE;str:=str+st; end;
'F','f':begin sost:=AUTO_FF;str:=str+st; end;
'A','a':begin sost:=AUTO_A;str:=str+st; end;
'O','o':begin sost:=AUTO_O;str:=str+st; end;
'N','n':begin sost:=AUTO_N;str:=str+st; end;
'D','d':begin sost:=AUTO_D;str:=str+st; end;
'I','i':begin sost:=AUTO_II;str:=str+st; end;
'T','t':begin sost:=AUTO_T;str:=str+st; end;
'0','1':begin sost:=AUTO_G;str:=str+st; end;
';': begin sost:=AUTO_TZ;str:=str+st; end;
'.': begin sost:=AUTO_TK;str:=str+st; end;
'{': begin sost:=AUTO_K;str:=str+st; end;
'+': begin sost:=AUTO_SL;str:=str+st; end;
'-': begin sost:=AUTO_VI;str:=str+st; end;
':': begin sost:=AUTO_Q;str:=str+st; end;
'=': begin sost:=AUTO_P;str:=str+st; end;
'<': begin sost:=AUTO_B;str:=str+st; end;
'>': begin sost:=AUTO_M;str:=str+st; end;
'(': begin sost:=AUTO_OO;str:=str+st; end;
')': begin sost:=AUTO_ZZ;str:=str+st; end;
'*': begin sost:=AUTO_UM;str:=str+st; end;
'/': begin sost:=AUTO_RZ;str:=str+st; end;
' ': begin sost:=AUTO_H;str:=''; end;
'C','c','G','g','H','h','J'..'M','j'..'m','Q'..'S',
'q'..'s','U'..'Z','u'..'z': begin sost:=AUTO_I;str:=str+st; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_PP:
case stroka[j] of
'R','r':begin sost:=AUTO_PP1;str:=str+st; end;
'A'..'Q','S'..'Z','a'..'q','s'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/':begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_PP1:
case stroka[j] of
'O','o':begin sost:=AUTO_PP2;str:=str+st; end;
'A'..'N','P'..'Z','a'..'n','p'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/':begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_PP2:
case stroka[j] of
'G','g':begin sost:=AUTO_PP3;str:=str+st; end;
'A'..'F','H'..'Z','a'..'f','h'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_PP3:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ': begin sost:=AUTO_H;fl:=1;zn:=1;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_BB:
case stroka[j] of
'E','e':begin sost:=AUTO_BB1;str:=str+st; end;
'A'..'D','a'..'d','F'..'Z','f'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_BB1:
case stroka[j] of
'G','g':begin sost:=AUTO_BB2;str:=str+st; end;
'A'..'F','H'..'Z','a'..'f','h'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_BB2:
case stroka[j] of
'I','i':begin sost:=AUTO_BB3;str:=str+st; end;
'A'..'H','J'..'Z','a'..'h','j'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_BB3:
case stroka[j] of
'N','n':begin sost:=AUTO_BB4;str:=str+st; end;
'A'..'M','O'..'Z','a'..'m','o'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_BB4:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ': begin sost:=AUTO_H;fl:=1;zn:=2;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_EE:
case stroka[j] of
'N','n':begin sost:=AUTO_EE1;str:=str+st; end;
'L','l':begin sost:=AUTO_E1;str:=str+st; end;
'A'..'K','O'..'Z','a'..'k','o'..'z','M','m','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_EE1:
case stroka[j] of
'D','d':begin sost:=AUTO_EE2;str:=str+st; end;
'A'..'C','E'..'Z','a'..'c','e'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_EE2:
case stroka[j] of
'I','i':begin sost:=AUTO_EE3;str:=str+st; end;
'A'..'H','J'..'Z','a'..'h','j'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ',';': begin sost:=AUTO_H;fl:=1;zn:=3;j:=j-1; end;
'.': begin sost:=AUTO_H;fl:=1;zn:=16;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_EE3:
case stroka[j] of
'F','f':begin sost:=AUTO_EE4;str:=str+st; end;
'A'..'E','G'..'Z','a'..'e','g'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_EE4:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ',';': begin sost:=AUTO_H;fl:=1;zn:=13;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_D:
case stroka[j] of
'O','o':begin sost:=AUTO_D1;str:=str+st;end;
'A'..'N','a'..'n','P'..'Z','p'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_D1:
case stroka[j] of
'W','w':begin sost:=AUTO_D2;str:=str+st;end;
'A'..'V','a'..'v','X'..'Z','x'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ': begin sost:=AUTO_H;fl:=1;zn:=9;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_D2:
case stroka[j] of
'N','n':begin sost:=AUTO_D3;str:=str+st;end;
'A'..'M','a'..'m','O'..'Z','o'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_D3:
case stroka[j] of
'T','t':begin sost:=AUTO_D4;str:=str+st;end;
'A'..'S','a'..'s','U'..'Z','u'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_D4:
case stroka[j] of
'A'..'N','P'..'Z','a'..'n','p'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
'O','o':begin sost:=AUTO_D5;str:=str+st;end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_D5:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','(': begin sost:=AUTO_H;fl:=1;zn:=9;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_G:
case stroka[j] of
'0','1':begin
w:=w+1;
if(w<9)then begin sost:=AUTO_G;str:=str+st;end
else begin sost:=AUTO_E;str:=str+st; end;
end;
'B','b':begin sost:=AUTO_G1;str:=str+st;w:=0; end;
else begin sost:=AUTO_E;str:=str+st;w:=0; end;
end;
AUTO_G1:
case stroka[j] of
' ','+','-',';',')','>','<','=','*','/':begin sost:=AUTO_H;fl:=1;zn:=15;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_A:
case stroka[j] of
'N','n':begin sost:=AUTO_A1;str:=str+st; end;
'A'..'M','O'..'Z','a'..'m','o'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_A1:
case stroka[j] of
'D','d':begin sost:=AUTO_A2;str:=str+st; end;
'A'..'C','E'..'Z','a'..'c','e'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_A2:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','(': begin sost:=AUTO_H;fl:=1;zn:=14;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_O:
case stroka[j] of
'R','r':begin sost:=AUTO_O1;str:=str+st; end;
'A'..'Q','S'..'Z','a'..'q','s'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_O1:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','(': begin sost:=AUTO_H;fl:=1;zn:=14;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_N:
case stroka[j] of
'O','o':begin sost:=AUTO_N1;str:=str+st; end;
'A'..'N','P'..'Z','a'..'n','p'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_N1:
case stroka[j] of
'T','t':begin sost:=AUTO_N2;str:=str+st; end;
'A'..'S','U'..'Z','a'..'s','u'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_N2:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','(': begin sost:=AUTO_H;fl:=1;zn:=14;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_II:
case stroka[j] of
'F','f':begin sost:=AUTO_I1;str:=str+st; end;
'A'..'E','G'..'Z','a'..'e','g'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_I1:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','(': begin sost:=AUTO_H;fl:=1;zn:=13;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_T:
case stroka[j] of
'H','h':begin sost:=AUTO_T1;str:=str+st; end;
'O','o':begin sost:=AUTO_T10;str:=str+st; end;
'A'..'G','I'..'N','P'..'Z','a'..'g','i'..'n','p'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_T10:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','(': begin sost:=AUTO_H;fl:=1;zn:=9;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_T1:
case stroka[j] of
'E','e':begin sost:=AUTO_T2;str:=str+st; end;
'A'..'D','F'..'Z','a'..'d','f'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_T2:
case stroka[j] of
'N','n':begin sost:=AUTO_T3;str:=str+st; end;
'A'..'M','O'..'Z','a'..'m','o'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_T3:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ': begin sost:=AUTO_H;fl:=1;zn:=13;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_E1:
case stroka[j] of
'S','s':begin sost:=AUTO_E2;str:=str+st; end;
'A'..'R','T'..'Z','a'..'r','t'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_E2:
case stroka[j] of
'E','e':begin sost:=AUTO_E3;str:=str+st; end;
'A'..'D','F'..'Z','a'..'d','f'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',':',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_E3:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ', '(': begin sost:=AUTO_H;fl:=1;zn:=13;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_FF:
case stroka[j] of
'O','o':begin sost:=AUTO_FF1;str:=str+st; end;
'A'..'N','P'..'Z','a'..'n','p'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',')',':','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_FF1:
case stroka[j] of
'R','r':begin sost:=AUTO_FF2;str:=str+st; end;
'A'..'Q','S'..'Z','a'..'q','s'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','+','-',';',')',':','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_FF2:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9':begin sost:=AUTO_I;str:=str+st; end;
' ','(': begin sost:=AUTO_H;fl:=1;zn:=9;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_TZ:
case stroka[j] of
' ','A'..'Z','a'..'z','0','1': begin sost:=AUTO_H;fl:=1;zn:=4;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_TK:
case stroka[j] of
' ': begin sost:=AUTO_H;fl:=1;zn:=6;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_K:
case stroka[j] of
'}': begin sost:=AUTO_H;j:=j-1;end;
else begin
sost:=AUTO_K;
str:=str+st;
end;
end;
AUTO_SL:
case stroka[j] of
' ','A'..'Z','a'..'z','0','1','(': begin sost:=AUTO_H;fl:=1;zn:=8;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_VI:
case stroka[j] of
' ','A'..'Z','a'..'z','0','1','(': begin sost:=AUTO_H;fl:=1;zn:=8;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_Q:
case stroka[j] of
'=': begin sost:=AUTO_Q1;str:=str+st; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_Q1:
case stroka[j] of
' ','A'..'Z','a'..'z','0','1','(': begin sost:=AUTO_H;fl:=1;zn:=7;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_P:
case stroka[j] of
' ','A'..'Z','a'..'z','0','1','(': begin sost:=AUTO_H;fl:=1;zn:=12;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_B:
case stroka[j] of
' ','A'..'Z','a'..'z','0','1','(': begin sost:=AUTO_H;fl:=1;zn:=12;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_M:
case stroka[j] of
' ','A'..'Z','a'..'z','0','1','(': begin sost:=AUTO_H;fl:=1;zn:=12;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_OO:
case stroka[j] of
' ','A'..'Z','a'..'z','0','1','(': begin sost:=AUTO_H;fl:=1;zn:=10;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_ZZ:
case stroka[j] of
' ','A'..'Z','a'..'z','0','1',')',';','<','>','=','+','-','*','/': begin sost:=AUTO_H;fl:=1;zn:=11;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_UM:
case stroka[j] of
' ','A'..'Z','a'..'z','0','1','(': begin sost:=AUTO_H;fl:=1;zn:=8;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_RZ:
case stroka[j] of
' ','A'..'Z','a'..'z','0','1','(': begin sost:=AUTO_H;fl:=1;zn:=8;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_I:
case stroka[j] of
'A'..'Z','a'..'z','0'..'9': begin sost:=AUTO_I;str:=str+st; end;
' ',':','+','-',';',')','>','<','=','*','/': begin sost:=AUTO_H;fl:=1;zn:=5;j:=j-1; end;
else begin sost:=AUTO_E;str:=str+st; end;
end;
AUTO_E: begin
if(stroka[j-1]='}')then begin sost:=AUTO_H;str:='';j:=j-1;end
else if(stroka[j]=' ')or(stroka[j]='+')or(stroka[j]='-')or(stroka[j]='*')
or(stroka[j]='/')or(stroka[j]='>')or(stroka[j]='<')or(stroka[j]='=')
or(stroka[j]=':')or(stroka[j]=';')or(stroka[j]='(')or(stroka[j]=')')
then
begin
sost:=AUTO_H;
Memo3.Lines.Append(str);
str:='';
j:=j-1;
end
else begin
sost:=AUTO_E;
str:=str+st;
end;
end;
end;
if fl=1 then
begin
StringGrid4.Cells[0,ind]:=IntToStr(ind);
StringGrid4.Cells[1,ind]:=str;
case zn of
1: begin StringGrid4.Cells[2,ind]:='Ключевое слово (начало программы)';end;
2: begin StringGrid4.Cells[2,ind]:='Ключевое слово (начало составного оператора)';end;
3: begin StringGrid4.Cells[2,ind]:='Ключевое слово (конец составного оператора)';end;
4: begin StringGrid4.Cells[2,ind]:='Разделитель';end;
5: begin StringGrid4.Cells[2,ind]:='Идентификатор';end;
6: begin StringGrid4.Cells[2,ind]:='';
StringGrid4.Cells[1,ind]:='';
StringGrid4.Cells[0,ind]:='';
end;
7: begin StringGrid4.Cells[2,ind]:='Оператор присваивания';end;
8: begin StringGrid4.Cells[2,ind]:='Арифметическая операция';end;
9: begin StringGrid4.Cells[2,ind]:='Ключевое слово (оператор цикла)';end;
10: begin StringGrid4.Cells[2,ind]:='Круглая скобка открывающаяся';end;
11: begin StringGrid4.Cells[2,ind]:='Круглая скобка закрывающаяся';end;
Подобные документы
Организация таблицы идентификаторов, ее содержание и назначение. Метод бинарного дерева и цепочек. Проектирование лексического анализатора и схема распознавателя. Построение дерева вывода, синтаксический анализатор. Анализ результатов работы программы.
курсовая работа [1,0 M], добавлен 25.12.2014Проектирование программы-анализатора, состоящей из двух частей: лексического анализатора, разбивающего исходный текст программы на лексемы и заполняющего таблицу имен; синтаксического анализатора, проверяющего соответствие текста заданной грамматике.
курсовая работа [2,0 M], добавлен 14.06.2010Методы грамматического разбора при разработке учебного транслятора. Проектирование лексического анализатора и магазинного автомата. Программная реализация синтаксического анализатора текстового языка высокого уровня. Разработка модуля интерпретации.
курсовая работа [697,2 K], добавлен 06.01.2013Назначение, принципы и методы построения таблиц идентификаторов. Метод простого рехэширования с помощью произведения. Назначение лексического анализатора. Таблица лексем и содержащаяся в ней информация. Построение лексических анализаторов (сканеров).
курсовая работа [703,1 K], добавлен 08.02.2011Структура, классификация и требования к реализации компилятора. Проектирование и реализация анализирующей части компилятора языка С++. Способы реализации лексического анализа. Алгоритм работы синтаксического анализатора. Принципы программной реализации.
курсовая работа [774,2 K], добавлен 26.01.2013Общая характеристика и оценка возможностей языка программирования си-шарп, его сходные и отличительные черты от С++ и Java. Разработка с помощью данного языка программирования лексического и синтаксического анализатора. Составление таблиц разбора.
курсовая работа [111,6 K], добавлен 11.06.2010Функции компилятора как системной обрабатывающей программы. Этапы компиляции: анализ и синтез. Разработка лексического анализатора. Алгоритм и программа лексического анализа. Реализация двухфазного компилятора. Описание логической структуры программы.
курсовая работа [310,4 K], добавлен 26.03.2010Написание программы, которая выполняет лексический и синтаксический анализ входного языка программирования, порождает таблицу лексем с указанием их типов и значений, а также строит синтаксическое дерево; текст входного языка вводится с клавиатуры.
курсовая работа [761,5 K], добавлен 23.02.2012Разработка технического задания на проектирование, определение требований к программе. Предварительный выбор метода решения синтаксического анализатора, проектирование программного приложения, конфигурация технических средств программы и её тестирование.
курсовая работа [28,5 K], добавлен 28.06.2011Описание синтаксиса и семантики входного языка. Описание типов лексем, определение их синтаксиса. Построение диаграммы лексического анализатора, а также его таблицы, тестирование. Построение КС-грамматики входного языка. Описание промежуточного языка.
курсовая работа [83,0 K], добавлен 23.01.2014