ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 18.04.2025
Просмотров: 397
Скачиваний: 0
Void __fastcall tForm1::BitBtn1Click(tObject *Sender)
{
try
{
char *txt = Memo1->Lines->GetText();
Ident I;
rez R;
LeksichBlok(I, txt);
Sint(I, R);
Inter(I, R);
ShowMessage("Допустимая цепочка.");
Prints(R);
}
catch(ErrSimb)
{
ShowMessage("Ошибка! Отсутствующий в данной грамматике символ!");
return;
}
catch(ErrOverFlow)
{
ShowMessage("Ошибка! Переполнение массива mas!");
return;
}
catch(ErrIdent)
{
ShowMessage("Ошибка! После цифры не может стоять буква!");
return;
}
catch(ErrSearch)
{
ShowMessage("Ошибка! Не найден искомый символ!");
return;
}
catch(ErrInvChain)
{
ShowMessage("Ошибка! Недопустимая цепочка!");
}
}
LeksBlok.H
#ifndef LeksBlokH
#define LeksBlokH
#include "DataBase.h"
Void Strcpy(char mas[], int n, char *txt, int m);
Void LeksichBlok(Ident &I, char *txt);
#define C_IDENTIF 0 //класс "идентификатор"
#define C_KEY_WORD 1 //класс "ключевое слово"
#define C_INT 2 //класс "константа"
#define C_RAZDEL 3 //класс "разделитель"
#define C_NOV 4 //новый элемент в области данных
#define T_S 10 //терминал S
#define T_SOVOK_OPER 11 //и другие терминалы…
#define T_OPER 12
#define T_OPER_PRISV 13
#define T_E 14
#define T_E_SPIS 15
#define T_T 16
#define T_T_SPIS 17
#define T_F 18
#define T_F_SPIS 19
#define T_P 20
#define T_OPER_IF 21
#define T_ELSE_PART 22
#define T_OPER_CYCLE 23
#define T_LOG_VIR 24
#define T_LOG_SPIS 25
#define S_RAVN 26 //символ "равно"
#define S_T_Z 27 //символ "точка с запятой"
#define S_SK_LEFT 28 //символ "левая скобка"
#define S_SK_RIGHT 29 //символ "правая скобка"
#define KS_THEN 30 //ключевое слово "then"
#define KS_END_WHILE 31 //ключевое слово "end_while"
#define K_PRISV 32 //команда присвоить
#define K_SLOJ 33 //команда сложить
#define K_UMNOJ 34 //команда умножить
#define K_V_STEP 35 //команда возсести в степень
#define K_PEREHOD_0 36 //команда переход, если утв. ложно
#define K_PEREHOD_BEZ_USL 37 //команда безусловный переход
#define K_PEREHOD_SRAVN 38 //команда переход по сравнению
#define K_RAVNO 39 //команда логическое равно
#define K_NE_RAVNO 40 //команда логическое не равно
#define K_METKA 41 //метка
#endif
LeksBlok.Cpp
#pragma hdrstop
#include "LeksBlok.h"
#include "string.h"
//------------------------------------------------------------------------------------------------------------------------------------------------------
void Strcpy(char mas[], int n, char *txt, int m) //скопировать n символов из txt в mas, начиная с m-го
{
for (int i = 0; i < n; ++i)
{
mas[i] = txt[i + m];
}
mas[n] = '\0';
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
Void LeksichBlok(Ident &I, char *txt)
{
elem el;
for(int i = 0, nom = 0; txt[i]>31 || txt[i]==13 || txt[i]==10; i += nom)
{
//Ключевые слова
switch(txt[i])
{
case 101: case 105: case 116: case 119:
el.clas = C_KEY_WORD;
nom = 2;
char IfStr[3];
Strcpy(IfStr, nom, txt, i);
if (strstr(IfStr,"if"))
{
strcpy(el.name, IfStr);
I.Add(el);
continue;
}
nom = 4;
char ThenOrElseStr[5];
Strcpy(ThenOrElseStr, nom, txt, i);
if (strstr(ThenOrElseStr,"then") || strstr(ThenOrElseStr,"else"))
{
strcpy(el.name, ThenOrElseStr);
I.Add(el);
continue;
}
nom = 5;
char WhileStr[6];
Strcpy(WhileStr, nom, txt, i);
if (strstr(WhileStr,"while"))
{
strcpy(el.name, WhileStr);
I.Add(el);
continue;
}
nom = 9;
char End_whileStr[10];
Strcpy(End_whileStr, nom, txt, i);
if (strstr(End_whileStr,"end_while"))
{
strcpy(el.name, End_whileStr);
I.Add(el);
continue;
}
}
//Идентификаторы
if(64 < txt[i] && txt[i] < 91 || 96 < txt[i] && txt[i] < 123)
{
el.clas = C_IDENTIF;
nom = 0;
for (char j = txt[i];
47<j && j<58 || 64<j && j<91 || j==95 || 96<j && j<123;
j = txt[++nom + i]) {}
Strcpy(el.name, nom, txt, i);
I.Add(el);
continue;
}
//Целые числа
if(47 < txt[i] && txt[i] < 58)
{
el.clas = C_INT;
el.value = 0;
nom = 0;
for (char j = txt[i + nom];
47<j && j<58;
j = txt[++nom + i]) {}
Strcpy(el.name, nom, txt, i);
for (int j = 1, k = 1; j <= nom; ++j, k *= 10)
el.value += (txt[i + nom - j] - '0') * k;
if (64<txt[i + nom] && txt[i + nom]<91 ||
96<txt[i + nom] && txt[i + nom]<123)
throw (ErrIdent());
I.Add(el);
continue;
}
//Конец текущей строки, пробел
if (txt[i] == 13 || txt[i] == 10 || txt[i] == 32)
{
nom = 1;
continue;
}
//Разделители
switch(txt[i])
{
case 35: case 40: case 41: case 42:
case 43: case 59: case 61: case 94:
el.clas = C_RAZDEL;
nom = 1;
Strcpy(el.name, nom, txt, i);
I.Add(el);
continue;
default :
throw ErrSimb();
}
}
//концевой маркер
el.clas = C_RAZDEL;
el.name[0] = 182;
el.name[1] = '\0';
I.Add(el);
}
#pragma package(smart_init)
Sintaksis.H
#ifndef SintaksisH
#define SintaksisH
#include "DataBase.h"
Void Sint(Ident &I, rez &r);
#endif
Sintaksis.Cpp
#pragma hdrstop
#include "Sintaksis.h"
#include "Stack_mass.h"
#include "LeksBlok.h"
#include "string.h"
//------------------------------------------------------------------------------------------------------------------------------------------------------
Void Sint(Ident &I, rez &r)
{
Stack<int> St; //стек программы
int ptr; //атрибуты p,q,t
St.push(T_S);
elem el = I.Get(0);
for (int i = 0; St.Size() > 0 && i < I.Size(); el = I.Get(i))
{
switch(St.pop())
{
case T_S: //#1
if (el.clas == C_IDENTIF ||
el.clas == C_KEY_WORD && el.name[0] == 'i' ||
el.clas == C_KEY_WORD && el.name[0] == 'w' ||
el.clas == C_RAZDEL && el.name[0] == -74)
{
St.push(T_SOVOK_OPER);
}
else
throw ErrInvChain();
break;
case T_SOVOK_OPER: //#2
if (el.clas == C_IDENTIF ||
el.clas == C_KEY_WORD && el.name[0] == 'i' ||
el.clas == C_KEY_WORD && el.name[0] == 'w')
{
St.push(T_SOVOK_OPER);
St.push(T_OPER);
break;
}
if (el.clas == C_RAZDEL && el.name[0] == -74 ||
el.clas == C_KEY_WORD && el.name[0] == 'e' && el.name[1] == 'n')
{
break; //#3
}
throw ErrInvChain();
case T_OPER :
if (el.clas == C_IDENTIF) //#4
{
St.push(T_OPER_PRISV);
break;
}
if (el.clas == C_KEY_WORD && el.name[0] == 'i') //#5
{
St.push(T_OPER_IF);
break;
}
if (el.clas == C_KEY_WORD && el.name[0] == 'w') //#6
{
St.push(T_OPER_CYCLE);
break;
}
throw ErrInvChain();
case T_OPER_PRISV:
if (el.clas == C_IDENTIF) //#7
{
St.push(S_T_Z);
St.push(-1);
//проверка на вхождения
for (ptr = 0; ptr < R.Data.Size(); ++ptr)
if (R.Data[ptr].clas == C_IDENTIF && !strcmp(R.Data[ptr].name, el.name))
break;
if (ptr == R.Data.Size())
R.Data.push(el);
St.push(ptr);
St.push(K_PRISV);
St.push(St.Size() - 3);
St.push(T_E);
i += 2;
}
else
throw ErrInvChain();
break;
case T_E:
switch(el.clas)
{