|
|
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
к курсовому проекту
по курсу «Системное програмное обеспечение»
Тема: “Лексический анализатор конструкций языка PASCAL”
РЕФЕРАТ
Пояснительная записка к курсовому проекту: с., 1 табл.
В данном курсовом проекте был разработан лексический анализатор конструкций языка Pascal, позволяющий проверять правильность написания конструкций. Главным инструментальным средством разработки является среда визуального программирования Delphi 4.
ЛЕКСИЧЕСКИЙ АНАЛИЗ, ПРОЕКТ, ОБЪЕКТ, МОДУЛЬ, ОПЕРАЦИОННАЯ СИСТЕМА.
У даному курсовому проекті був розроблен лексичний аналізатор конс-трукцій язика Pascal, який дозволяє перевіряти правильність написання конс-трукцій. Головним інструментальним засобом розробки є середа візуального програмування Delphi 4.
ЛЕКСИЧНИЙ АНАЛІЗ, ПРОЕКТ, ОБ'ЄКТ, МОДУЛЬ, ОПЕРАЦІЙНА СИСТЕМА.
СОДЕРЖАНИЕ
ВВЕДЕНИЕ
1 ПОСТАНОВКА ЗАДАЧИ
2 АНАЛИЗ ПРЕДМЕТНОЙ ОБЛАСТИ
2.1 Алфавит символов
2.2 Преобразование к лексическим единицам
2.3 Лексический анализатор
2.4 Ограничения по структуре языка
3 ОПИСАНИЕ ПРОГРАММЫ
3.1 Проектирование архитектуры.
3.2 Модули системы.
3.3 Общие сведения
3.4 Запуск и работа
3.5 Входные данные.
ПЕРЕЧЕНЬ ССЫЛОК
ПРИЛОЖЕНИЕ
ВВЕДЕНИЕ
В настоящее время существует много языков программирования и программисты могут выбирать, что им по вкусу, из огромного количества програмных оболочек для написания программы для личного пользования или своего программного продукта для огромной корпорации, но не многие задумывались над тем, что делает эта оболочка.
Мы подразумеваем под словом «откомпилировал» нечто преобразующее обычный текст программы в исполняемый файл, но это не просто как кажется. В момент компиляции происходит проверка правильности написания конструкций, правильность использования переменных, правильность вызова процедуры или функции, составление тавлиц лексем, оптимизация и перобразование в исполняемый код.
Целью данного курсового проекта является разработка лексического анализатора конструкций языка Pascal, выполняющего такие функции: редактирование исходного текста, преоразование текта программы в лексемы, составление таблиц лексем и разбор конструкции описания переменных.
1 ПОСТАНОВКА ЗАДАЧИ
В настоящее время существует много профессиональных компиляторов различных языков, и они выполняют очень большой объём работ по проверке ошибок и преобразованию, поэтому целью данной курсовой работы не является разработка какого-нибудь компилятора, а показать занания по лексическому анализу.
Первым шагом любого компилятора является – лексический анализ (лексический анализатор). Так как данное мне задание звучит как разаработка лексического анализатора, значит мне предстояло разработать программу начальной обработки и подготовки программы к остальным стадиям компиляции. Входными данными компилятора является файл с текстом программы на языке Pascal (в нашем случае), значит нужно преобразовать текст программы на паскале в лексеммы и подготовить таблицы лексем, для работы синтаксического анализатора. Так как следующим этапом служит именно синтаксический анализ, который и производит проверку синтаксических ошибок (то есть проверку на правильность конструкций и арифметических вырвжений).
2 АНАЛИЗ ПРЕДМЕТНОЙ ОБЛАСТИ
2.1 Алфавит символов
Первая фаза любого компилятора является лексический анализ. Входом компилятора, а следовательно, и лексического анализатора, служит цепочка символов некоторого алфавита. А значит составляем алфавит символов из которых строятся конструкции заданного мне языка:
‘A'…'Z' , ‘0'…'9' , ‘_' , пробел , ';‘ , ‘+' , '-‘ , '*' , '/' , '=' , '<' , '>', '.' , ':' , '(' , ')' , «'» .
В последствии эти символы (в определенной последовательности) будут распознаваться как конструкции языка и преобразовываться в лексемы.
2.2 Преобразование к лексическим единицам
В программе некоторые комбинации символов часто рассматриваются как единые объекты. Среди типичных примеров можно указать следующие:
• Цепочка, сотоящая из оного или более пробелов считается одним пробелом.
• Ключевые слова, например: begin, end, goto, do, integer и т.д., считаются одним символом.
• Цепочка, представляющая числовую или символьную константу считается одним символом.
• Идентификаторы, используемые как имена переменных, функций или процедур, также считаются одним символом.
2.3 Лексический анализатор
Работа лексического анализатора состоит в том, чтобы сгрупировать определенные терминальные символы в единые синтаксические объекты, называемые лексемами. Какие объекты считать лексемыми, зависит от определений языка программирования.
Лексема – это цепочка терминальных символов, с которой мы связываем лексическую структуру, состоящию из пары вида ( тип лексемы, некоторые данные ). Первой компонентой пары является синтаксическая категория, такая, как « константа » или «идентификатор», а вторая – указатель: в ней указывается адрес ячейки, хранящей информацию о конкретной лексеме.
Лексемы распознаются по такой схеме:
• (‘A'…'Z','_')+(‘A'…'Z','0'…'9','_')+…+ (‘A'…'Z','0'…'9','_') – это процедуры и функции, переменные, зарезервированые слова и операторы;
• ('0'…'9')… ('0'…'9') – это константы целого типа;
• («'»)+(все символы, кроме знака «'»)+(«'») – это константы типа String;
• '+' , '-' , '<' , '>' , '=' , '/' , '*' , ',' , '.' , ':' , ';' – это операции.
Таким образом, лексический анализатор – это транслятор, входом которого служит цепочка символов, а выходом – последовательность лексем. Этот выход образует вход в синтаксический анализатор.
2.4 Ограничения по структуре языка:
1. Написание конструкций языка производится в любом регистре и различие регистра игнорируется.
2. Поддерживается такая структура программы отклонения от данного пункта вызовет ошибку):
Program {имя программы};
[uses {имя модуля}[,{ имя модуля }…];]
var
{имя переменной1}[,{имя переменной2}…]:{тип переменной};
.
.
{имя переменной1}[,{имя переменной2}…]:{тип переменной};
begin
{зарезервированные слова и конструкции}
.
.
.
{зарезервированные слова и конструкции}
end.
3. Преобразование в лексемы производиться с конструкции begin и до end.
3 ОПИСАНИЕ ПРОГРАММЫ
При проектировании этого программного продукта были определены и проанализированы основные функции, характеристики и требования к разрабатываемой программе. Вследствие анализа были выделены основные объекты – составляющие системы – и поставлен ряд задач об их взаимодействии. Использование объектно- ориентированного программирования позволило решить эти задачи.
3.1 Проектирование архитектуры.
Проектирование архитектуры производилось в среде программирования Borland Delphi 4. Особенностью этой среды является то, что она поддерживает концепцию объектно-ориентированного программирования.
Программа может запускаться из проводника, причем никаких дополнительных параметров в командной строке не требуется.
3.2 Модули системы.
Программный код редактора хранится в 3 модулях, объединенных единым файлом проекта и файлом, содержащим графические ресурсы проекта. В таблице 1 содержится информация о модулях.
Таблица 1- Программные модули
№ п/п Имя файла модуля Тип модуля Описание модулей
1 Main.pas Модуль Содержит основную программу
2 Childwin.pas Модуль Содержит дочернее окно ввода
3 FormInfo.pas Модуль Содержит диалоговое окно вывода информации о лексемах
4 FormTitle.pas Модуль Содержит окно заставки
5 KursIII.dpr Файл проекта Файл проекта, объединяющий вышеперечисленные модули в единый проект.
6 KursIII.res Файл ресурсов Хранит графические ресурсы, применяемые в данной программе.
В дополнении к каждому вышеприведенному файлу класса модулей прилагается файл формы, хранящий в двоичном виде отображение соответствующей формы модуля.
Основные положения текста программы представлены в приложении А.
3.3 Общие сведения
Данная программа разработана для работы под операционной системой класс Microsoft Windows 98 при наличии необходимого программного и аппаратного комплекса, указанного ниже:
1) аппаратные требования: минимальные –iPentium133 или совместимый процессор, 8 мегабайт оперативной памяти, 2 Мб свободного места на жестком диске VGA видео карта; рекомендуемые –iPentium166 или аналогичный процессор, 16 Мб оперативной памяти SVGA видео карта;
2) требования к программному обеспечению: операционная система Microsoft Windows 95/98.
3.4 Запуск и работа
Программа запускается запуском, например из проводника, файла KursIII.exe и только требует нахождения папки Modules в папке откуда был произведён запуск программы.
Программа состоит из 3 основных модулей.
С Начала запускается форма main.pas из которой и производятся все действия: открытие файла и его редактирование, запись файла, запуск на проверку и просмотр лексем.
Форма childwin.pas вызывается при открытии файла, а также содержит функцию (Lingvo), производящую разбор и проверку ошибок, и которая вызывается из главной формы при выборе из меню «Компиляция \ Компиляция» или нажатием F9. Форма содержит компоненты:
Memo1(TRichEdit) – отображает текущий открытый файл;
Memo2(TRichEdit) – отображает лексемы после проверки;
Memo3(TMemo) – отображает найденые ошибки при проверке.
Форма FormInfo.pas вывается при выборе из меню «Компиляция \ Информация» или нажатия F11, которая отображает значение переменных Vars, Proc, Resr, Oper текущей открытой формы. Форма содержит 5 кнопок и 4 таблицы.
Главная функция Lingvo выполняет преобразование всего текста программы в нижний регистр и производит вызов функции Rasbor, которая в свою очередь производит разбор и проверку правильности написания раздела текста от начала программы до команды begin, это, в основном, разбор описания переменных.
Функция Rasbor производит проверку конструкций program, uses и var. При разборе раздела var происходит определение имен преременных (также происходит проверка на не дублирование имен зарезервированными словами), опреределение их типов изанесение в переменную Vars, организованную как список, этих значений для дальнейшего использования при преобразовании текста в лексемы.
В процедуре Lingvo происходит загрузка из файлов преременных Proc (содержит информацию о подключеных процедурах и функциях), Oper (содержит информацию о зарезервированых операциях) и Resr (содержит информацию о зарезервированых словах). Затем эта процедура с помощью соответствующих проверок производит перевод текста программы в лексемы. Лексемы отображаются в компоненке Memo2 и в последствии можно вызвать форму FormInfo и проверить правильность распознавания лексем.
Так же Lingvo очень широко использует функции SelWord (вырезает слово из текста), SelChislo (вырезает число из текста) и SelOper (вырезает оператор из текста). Все эти функции работают на основе регулярного выражения. Затем происходит проверка на наличие в списках данного слова, если есть преобразуем в лексему, если нет – ошибка: «неизвестный идентификатор», кроме случаев с константами (их зарезервировано всего два типа: integer и string). Т.к. константы записываются в список переменых (Var) из раздела тела программы.
3.5 Входные данные.
Входными данными для программы являются *.pas файлы, содержащие текст программы на языке Pascal.
ВЫВОДЫ
В результате выполнения курсового проекта был разработан редактор и лексический анализатор конструкций языка pascal, который работает под управлением операционной системы Windows 95/98. А также был практически закреплен материал по лексическому анализу.
ПЕРЕЧЕНЬ ССЫЛОК
1. Фараонов В.В. Delphi 4. Учебный курс. – М.: «Нолидж», -1998.-464с., ил
2. Самоучитель Delphi 3: Пер. с англ./Франк Энго. – К.: «ДиаСофт», 1998.- 320с.
3. ДСТУ 3008-95 "Документація. Звіти в сфері науки і техніки. Струк-тура і правила оформлення" – Державний стандарт України.
4. Ахо А. Теория синтаксического анализа, перевода и компиляции. Том 1 – И.:”МИР” Москва 1978, - 612с.
ПРИЛОЖЕНИЕ
Текст функции Lingvo и используемых ей функций
type
TVars=^PVars;
PVars=record
Name :string[20];
Types :String[20];
Constant :Boolean;
Next : TVars;
end;
type
TProc=^PProc;
PProc=record
Name :string[20];
Proc : Boolean;
Params : string;
Func : string[20];
Next : TProc;
end;
type
TRes= ^PRes;
PRes=record
Word :string[20];
Info :string;
Next :TRes;
end;
type
TOper=^POper;
POper=record
Word :string[5];
Info :string;
Next :TOper;
end;
type TAllWord=record
case byte of
0:(Oper : TOper);
1:(Proc : TProc);
2:(Resr : TRes);
3:(Vars : TVars);
end;
type
TMDIChild = class(TForm)
Memo2: TRichEdit;
Memo1: TRichEdit;
Memo3: TMemo;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Memo1Change(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormResize(Sender: TObject);
procedure FormCreate(Sender: TObject);
Procedure ShowError(Error:string;Lines:integer);
Procedure Lingvo;
Procedure LoadAll;
Function Rasbor(var Ends:integer):boolean;
Function SelWord(var start:integer;s:string):string;
Function SelOper(var start:integer;s:string):string;
Function SelChislo(var start:integer;s:string):string;
Procedure Selected(Start,Length:integer;color:TColor);
Procedure UnLoadAll;
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
Change : Boolean;
OperFile : Text;
ResFile : Text;
ProcFile : Text;
Vars : TVars;
Proc : TProc;
Resr : TRes;
Oper : TOper;
end;
implementation
uses Main ;
const NTypes=9;
Types:array[1..NTypes]of string[20]=('BYTE','CHAR','INTEGER',
'LONG','POINTER','REAL','SHORT','STRING','WORD');
CRes =clBlue;
CProc=clAqua;
CVar =clGray;
COper=clGreen;
CStr =clYellow;
Procedure TMDIChild.ShowError(Error:string;Lines:integer);
begin
if lines=0 then Memo3.Lines.Add(Error)
else Memo3.Lines.Add(Error+' Ошибка в сторке '+IntToStr(Lines));
Memo1.Lines.Strings[Lines-1]:=Memo1.Lines.Strings[Lines-1];
end;
Procedure TMDIChild.Selected(Start,Length:integer;color:TColor);
begin
Memo1.SelStart:=Start;
Memo1.SelLength:=Length;
Memo1.SelAttributes.Color:=Color;
end;
Procedure TMDIChild.LoadAll;
var
s : string;
i : integer;
NRes1,NRes2 : TRes;
NOp1,NOp2 : TOper;
NAll1,NAll2 : TAllWord;
begin
// Reserved
Reset(ResFile);
ReadLn(ResFile,s);
New(Resr);
i:=pos(' ',s);
if i=0 then begin
Resr.Word:=s;
Resr.Info:='';
end
else begin
Resr.Word:=copy(s,1,i-1);
Resr.Info:=Copy(s,i+1,Length(s));
end;
Resr.Next:=nil;
NRes1:=Resr;
While not eof(ResFile) do
begin
ReadLn(ResFile,s);
New(NRes2);
i:=pos(' ',s);
if i=0 then begin
NRes2.Word:=s;
NRes2.Info:='';
end
else begin
NRes2.Word:=copy(s,1,i-1);
NRes2.Info:=Copy(s,i+1,Length(s));
end;
NRes2.Next:=Nil;
NRes1.Next:=NRes2;
NRes1:=NRes2;
end;
CloseFile(ResFile);
// Operation
Reset(OperFile);
ReadLn(OperFile,s);
New(Oper);
i:=pos(' ',s);
if i=0 then begin
Oper.Word:=s;
Oper.Info:='';
end
else begin
Oper.Word:=copy(s,1,i-1);
Oper.Info:=Copy(s,i+1,Length(s));
end;
Oper.Next:=nil;
NOp1:=Oper;
While not eof(OperFile) do
begin
ReadLn(OperFile,s);
New(NOp2);
i:=pos(' ',s);
if i=0 then begin
NOp2.Word:=s;
NOp2.Info:='';
end
else begin
NOp2.Word:=copy(s,1,i-1);
NOp2.Info:=Copy(s,i+1,Length(s));
end;
NOp2.Next:=Nil;
NOp1.Next:=NOp2;
NOp1:=NOp2;
end;
CloseFile(OperFile);
// proc
Reset(ProcFile);
ReadLn(ProcFile,s);
New(Proc);
i:=pos(' ',s);
Proc.Name:=copy(s,1,i-1);
delete(s,1,i);
i:=pos(' ',s);
Proc.Params:=copy(s,1,i-1);
delete(s,1,i);
if copy(s,1,4)='func' then begin
Proc.Proc:=False;
Proc.Func:=copy(s,5,length(s));
end
else begin
Proc.Proc:=True;
Proc.Func:='Нет';
end;
Proc.Next:=nil;
NAll1.Proc:=Proc;
While not eof(ProcFile) do
begin
ReadLn(ProcFile,s);
New(NAll2.Proc);
i:=pos(' ',s);
NAll2.Proc.Name:=copy(s,1,i-1);
delete(s,1,i);
i:=pos(' ',s);
NAll2.Proc.Params:=copy(s,1,i-1);
delete(s,1,i);
if copy(s,1,4)='func' then begin
NAll2.Proc.Proc:=False;
NAll2.Proc.Func:=copy(s,5,length(s));
end
else begin
NAll2.Proc.Proc:=True;
NAll2.Proc.Func:='Нет';
end;
NAll2.Proc.Next:=Nil;
NAll1.Proc.Next:=NAll2.Proc;
NAll1.Proc:=NAll1.Proc.Next;
end;
CloseFile(ProcFile);
end;
Procedure TMDIChild.UnLoadAll;
Var
NVar : TVars;
NOp : TOper;
NRes : TRes;
NProc: TProc;
begin
// Vars
while Vars<>nil do
begin
NVar:=Vars;
Vars:=Vars.Next;
dispose(NVar);
end;
// Oper
while Oper<>nil do
begin
NOp:=Oper;
Oper:=Oper.Next;
dispose(NOp);
end;
// Resr
while Resr<>nil do
begin
NRes:=Resr;
Resr:=Resr.Next;
dispose(NRes);
end;
// Proc
while Proc<>nil do
begin
NProc:=Proc;
Proc:=Proc.Next;
dispose(NProc);
end;
//end;
end;
Function TMDIChild.SelWord(var start:integer;s:string):string;
var
st,ss : string;
i :integer;
begin
ss:=LowerCase(s);
st:='';
for i:=start to Length(ss) do
case ss[i] of
'a'..'z','0'..'9','_': st:=st+ss[i];
else break;
end;
Memo1.SelStart:=start-1;
Memo1.SelLength:=i-start;
start:=i;
Result:=st;
end;
Function TMDIChild.SelChislo(var start:integer;s:string):string;
var
st,ss : string;
i :integer;
begin
ss:=LowerCase(s);
st:='';
for i:=start to Length(ss) do
case ss[i] of
'0'..'9': st:=st+ss[i];
else break;
end;
Memo1.SelStart:=start-1;
Memo1.SelLength:=i-start;
start:=i;
Result:=st;
end;
Function TMDIChild.SelOper(var start:integer;s:string):string;
var
st,ss : string;
i :integer;
begin
ss:=LowerCase(s);
st:='';
for i:=start to Length(ss) do
case ss[i] of
'<','>','=','*','+','-','/',',',':',#39
: st:=st+ss[i];
else break;
end;
Memo1.SelStart:=start-1;
Memo1.SelLength:=i-start;
start:=i;
Result:=st;
end;
Function TMDIChild.Rasbor(var Ends:integer):boolean;
var
s,ss:string;
NAll1,NAll2:TAllWord;
i:integer;
yes:boolean;
Function Spaces(s:string;var i:integer):boolean;
begin
Result:=False;
while (s[i]=#32)or(s[i]=#10)or(s[i]=#13) do
begin
if not Result then Result:=true;
inc(i);
end;
end;
begin
Result:=False;
Ends:=1;
s:=LowerCase(Memo1.Text);
Spaces(s,Ends);
if copy(s,Ends,7)='program' then begin
Selected(Ends-1,7,clBlue);
inc(Ends,7);
end
else begin
ShowError('Не та конструкция(Program <Name>;)!!!',0);
exit;
end;
Spaces(s,Ends);
SelWord(Ends,s);
Spaces(s,Ends);
if s[Ends]<>';' then begin
ShowError('Не та конструкция(Program <Name>;)!!!',0);
exit;
end;
inc(Ends);
Spaces(s,Ends);
if copy(s,Ends,4)='uses' then begin
Selected(Ends-1,4,clBlue);
inc(Ends,4);
while s[Ends]<>';' do
begin
Spaces(s,Ends);
if SelWord(Ends,s)='' then begin
ShowError('Не та конструкция(Uses Module1[,Module2..];)!!!',0);
exit;
end;
Spaces(s,Ends);
if (s[Ends]<>',')and(s[Ends]<>';') then begin
ShowError('Не та конструкция(Uses Module1[,Module2..];)!!!',0);
exit;
end;
end;
inc(Ends);
end;
{rasdel var}
Spaces(s,Ends);
if copy(s,Ends,3)='var' then begin
Selected(Ends-1,3,clBlue);
inc(Ends,3);
Repeat
Memo2.Lines.Clear;
while s[Ends]<>';' do
begin
Spaces(s,Ends);
Memo2.Lines.Add(SelWord(Ends,s));
Memo1.SelAttributes.Color:=clGray;
if Memo2.Lines.Strings[Memo2.Lines.Count-1]='' then begin
ShowError('Не та конструкция(Имя1[,Имя2..]:Тип;)!!!',0);
exit;
end;
Spaces(s,Ends);
if (s[Ends]<>',')and(s[Ends]<>':') then begin
ShowError('Не та конструкция(Имя1[,Имя2..]:Тип;)!!!',0);
exit;
end;
if s[Ends]=':' then begin
inc(Ends);
break;
end;
inc(Ends);
end;
Spaces(s,Ends);
Yes:=false;
ss:=SelWord(Ends,s);
Memo1.SelAttributes.Color:=clMaroon;
for i:=1 to NTypes do
if ss=LowerCase(Types[i]) then Yes:=true;
if not Yes then begin
ShowError('Неизвестный тип(Имя1[,Имя2..]:Тип;)!!!',0);
exit;
end;
Spaces(s,Ends);
if S[Ends]<>';' then begin
ShowError('Нет ;!!!',0);
exit;
end;
inc(Ends);
if Vars=nil then begin
New(Vars);
Vars.Name:=Memo2.Lines.Strings[0];
Vars.Types:=ss;
Vars.Constant:=False;
Vars.Next:=nil;
NAll1.Vars:=Vars;
end
else begin
NAll1.Vars:=Vars;
while NAll1.Vars.Next<>nil do
NAll1.Vars:=NAll1.Vars.Next;
New(NAll2.Vars);
NAll2.Vars.Name:=Memo2.Lines.Strings[0];
NAll2.Vars.Types:=ss;
NAll2.Vars.Constant:=False;
NAll2.Vars.Next:=nil;
NAll1.Vars.Next:=NAll2.Vars;
NAll1.Vars:=NAll1.Vars.Next;
end;
for i:=1 to Memo2.Lines.Count-1 do
begin
New(NAll2.Vars);
NAll2.Vars.Name:=Memo2.Lines.Strings[i];
NAll2.Vars.Types:=ss;
NAll2.Vars.Constant:=False;
NAll2.Vars.Next:=nil;
NAll1.Vars.Next:=NAll2.Vars;
NAll1.Vars:=NAll1.Vars.Next;
end;
Spaces(s,Ends);
until copy(s,Ends,5)='begin';
end;
Result:=True;
end;
//
Procedure TMDIChild.Lingvo;
var
i,t : integer;
s,st : string;
Lines : Integer;
Nall : TAllWord;
Function FindOper(s:string):boolean;
var
NAll : TAllWord;
i : integer;
begin
result:=false;
NAll.Oper:=Oper;
i:=1;
while NAll.Oper<>nil do
begin
if NAll.Oper.Word=s then begin
Memo2.Lines.Strings[Memo2.Lines.Count-1]:=
Memo2.Lines.Strings[Memo2.Lines.Count-1]+'Oper['+IntToStr(i)+']';
Memo1.SelAttributes.Color:=COper;
Result:=True;
exit;
end;
inc(I);
NAll.Oper:=NAll.Oper.Next;
end;
end;
Function FindWord(s:string):boolean;
var
NAll : TAllWord;
I : INTEGER;
begin
result:=false;
NAll.Resr:=Resr;
i:=1;
while NAll.Resr<>nil do
begin
if NAll.Resr.Word=s then begin
Memo2.Lines.Strings[Memo2.Lines.Count-1]:=Memo2.Lines.Strings[Memo2.Lines.Count-1]+'Res['+IntToStr(i)+']';
Memo1.SelAttributes.Color:=CRes;
result:=true;
exit;
end;
inc(i);
NAll.Resr:=NAll.Resr.Next;
end;
//
NAll.Proc:=Proc;
i:=1;
while NAll.Proc<>nil do
begin
if NAll.Proc.Name=s then begin
Memo2.Lines.Strings[Memo2.Lines.Count-1]:=Memo2.Lines.Strings[Memo2.Lines.Count-1]+'Proc['+IntToStr(i)+']';
Memo1.SelAttributes.Color:=CProc;
result:=true;
exit;
end;
inc(i);
NAll.Proc:=NAll.Proc.Next;
end;
//
NAll.Vars:=Vars;
i:=1;
while NAll.Vars<>nil do
begin
if NAll.Vars.Name=s then begin
Memo2.Lines.Strings[Memo2.Lines.Count-1]:=Memo2.Lines.Strings[Memo2.Lines.Count-1]+'Var['+IntToStr(i)+']';
Memo1.SelAttributes.Color:=CVar;
result:=true;
exit;
end;
inc(i);
NAll.Vars:=NAll.Vars.Next;
end;
end;
begin
Lines:=1;
Memo3.Lines.Clear;
Memo3.Visible:=True;
UnLoadAll;// уничтожить списки
LoadAll;// загрузить списки
if not Rasbor(i) then exit;
Memo2.Clear;
Memo2.Lines.Add('');
Memo2.Lines.Add('');
st:=LowerCase(Memo1.Text);
repeat
case st[i] of
'a'..'z','_':begin
if not FindWord(SelWord(i,Memo1.Text))
then begin
ShowError('Неопределённый индитификатор!!!',Lines);
Exit;
end;
end;
'0'..'9':begin
s:=SelChislo(i,Memo1.Text);
Nall.Vars:=Vars;
t:=1;
while NAll.Vars.Next<>nil do
begin
NAll.Vars:=NAll.Vars.Next;
inc(t);
end;
Memo2.Lines.Strings[Memo2.Lines.Count-1]:=
Memo2.Lines.Strings[Memo2.Lines.Count-1]+'Var['+IntToStr(t+1)+']';
new(Nall.Vars.Next);
NAll.Vars:=NAll.Vars.Next;
Nall.Vars.Name:=s;
Nall.Vars.Types:='Integer';
Nall.Vars.Constant:=True;
Nall.Vars.Next:=nil;
Memo1.SelAttributes.Color:=clRed;
end;
'(':begin
Memo2.Lines.Strings[Memo2.Lines.Count-1]:=
Memo2.Lines.Strings[Memo2.Lines.Count-1]+'(';
Selected(i-1,1,COper);
inc(i);
end;
')':begin
Memo2.Lines.Strings[Memo2.Lines.Count-1]:=
Memo2.Lines.Strings[Memo2.Lines.Count-1]+')';
Selected(i-1,1,COper);
inc(i);
end;
';':begin
NAll.Oper:=Oper;
t:=1;
while NAll.Oper<>nil do
begin
if Nall.Oper.Word=';' then break;
inc(t);
Nall.Oper:=Nall.Oper.Next;
end;
Memo2.Lines.Strings[Memo2.Lines.Count-1]:=
Memo2.Lines.Strings[Memo2.Lines.Count-1]+'Oper['+IntToStr(t)+']';
Memo2.Lines.Add('');
Selected(i-1,1,COper);
inc(i);
end;
#39:begin
t:=i;
s:=#39;
inc(i);
while st[i]<>#39 do
begin
s:=s+st[i];
inc(i);
end;
s:=s+#39;
selected(t-1,i-t+1,CStr);
Nall.Vars:=Vars;
t:=1;
while NAll.Vars.Next<>nil do
begin
NAll.Vars:=NAll.Vars.Next;
inc(t);
end;
Memo2.Lines.Strings[Memo2.Lines.Count-1]:=
Memo2.Lines.Strings[Memo2.Lines.Count-1]+'Var['+IntToStr(t+1)+']';
new(Nall.Vars.Next);
NAll.Vars:=NAll.Vars.Next;
Nall.Vars.Name:=s;
Nall.Vars.Types:='String';
Nall.Vars.Constant:=True;
Nall.Vars.Next:=nil;
inc(i);
end;
'<','>','=','*','+','-','/',',',':':
begin
s:=SelOper(i,Memo1.Text);
if FindOper(s)
then Memo1.SelAttributes.Color:=COper
else begin
ShowError('Неизвестная конструкция операторов(операций)!!!',Lines);
Exit;
end;
end;
' ',#10 :inc(i);
#13 :begin
inc(Lines);
inc(i);
end
else begin
ShowError('Неизвестный символ!!!',Lines);
break;
end;
end;{case}
until i>=length(Memo1.Text);
if Memo3.Text='' then Memo3.Visible:=false;
Memo1.SelLength:=0;
end;
|
|
|