ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 18.04.2025

Просмотров: 392

Скачиваний: 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)

{