Материалы к лекциям (1119465), страница 3
Текст из файла (страница 3)
| z | A | B | ... | Z0 | 1 | 2 | ... | 9Действия, выполняемые при генерации внутреннего представления программы:1.put2.placeзанесение элемента в массив ПОЛИЗ, варианты:нет параметров: резервирование места в массиве ПОЛИЗодин параметр: запись элемента в конец массива ПОЛИЗдва параметра: запись элемента в указанное место массива– определение номера свободного элемента в массиве ПОЛИЗ–Некоторые правила грамматики модельного языка с действиями по генерации ПОЛИЗ:F→SS→→S→I <check_id (); Put (I)> | N <Push (type = int); Put (N)> |L <Push (type = bool); Put (L)> | not F <check_not ()> | (E)I <check_id (); Put (&I)> := E <eq_type (); Put (“:=”)>if E <eq_type (bool); Place (lab1); Put (); Put (“!F”)>thenS <Place (lab2); Put (); Put (“!”); Put (Place, lab1)>elseS<Put (Place, lab2)>while <Place (lab1)> E <eq_type (bool); Place (lab2); Put (); Put (“!F”)>do S <Put (lab1); Put (“!”); Put (Place, lab2)>#include <iostream.h>#include <string.h>#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <typeinfo>using namespace std;//===================================================================//////////////////////Отладочные режимы////////////////////////////===================================================================static unsigned int Dump =#define DUMP_ANY (unsigned#define DUMP_BUF (unsigned#define DUMP_REC (unsigned#define DUMP_LEX (unsigned#define DUMP_PLZ (unsigned#define DUMP_PTA (unsigned#define DUMP_PTC (unsigned#define DUMP_PTI (unsigned#define DUMP_PTL (unsigned#define DUMP_SIM (unsigned0;int) - 1int)int)int)int)int)int)int)int)int)1248163264128256//===================================================================/////////////////////Список лексем языка///////////////////////////===================================================================enum type_of_lex {LEX_VAR,LEX_BOOL,LEX_BEGIN, LEX_END,LEX_IF,LEX_THEN,LEX_DO,LEX_READ,LEX_AND,LEX_NOT,LEX_LE,LEX_EQ,LEX_DIV,LEX_PLUS,LEX_COMMA, LEX_COLON,LEX_ID,LEX_NUM,PLZ_GO,LEX_NULL,LEX_PROGRAM,LEX_INT,LEX_FALSE,LEX_TRUE,LEX_ASSIGN,LEX_ELSE,LEX_WHILE,LEX_WRITE,LEX_OR,LEX_LT,LEX_NE,LEX_GE,LEX_GT,LEX_MINUS, LEX_MULT,LEX_LPAREN, LEX_RPAREN,LEX_SEMICOLON,LEX_FIN,PLZ_FGO};//===================================================================////////////////Таблицы внешних представлений//////////////////////===================================================================static char *KeyWords [] = { "","true","if","write",static type_of_lex LKeyWords [] = { LEX_NULL,LEX_TRUE,LEX_IF,LEX_WRITE,static char *Delimiters [] = { "","<","+",static type_of_lex LDelimiters []= { LEX_NULL,LEX_LT,LEX_PLUS,"program","false","then","not",LEX_PROGRAM,LEX_FALSE,LEX_THEN,LEX_NOT,"@","<=","-",LEX_FIN,LEX_LE,LEX_MINUS,"begin","var","int","else","do","or","and",LEX_BEGIN, LEX_END,"while"," go_to",LEX_VAR,"read"," go_if_not",0};LEX_INT,LEX_BOOL,LEX_ELSE,LEX_OR,",","=","*",LEX_COMMA,LEX_EQ,LEX_MULT,LEX_WHILE,PLZ_GO,":=",">=","(",LEX_ASSIGN,LEX_GE,LEX_LPAREN,LEX_READ,PLZ_FGO,LEX_NULL};";",">",")",0};LEX_SEMICOLON,LEX_GT,LEX_RPAREN, LEX_NULL};//===================================================================/////////////////// Интерфейсы используемых классов ///////////////////===================================================================//===================================================================/////////////////////////Класс buf//// (для сборки лексем) ////////===================================================================class buf {char * b; int size; int top;public: buf (int max_size = 260);~ buf();voidclear();voidadd(const char c);char * get_string() const;intint_buf() const;friend ostream & operator << (ostream &s, const buf & b);};"end",LEX_DO,LEX_AND,":","!=","/",LEX_COLON,LEX_NE,LEX_DIV,"bool",class Token;class ProgramObject;template <class Object> class ObjectTable;ostream & operator << (ostream & s, const Token * t);template <class Object> ostream & operator << (ostream & s, const ObjectTable<Object> & l);ostream & operator << (ostream & s, const ProgramObject * t);//===================================================================///////////////////////Класс таблиц лексем/////////////////////////===================================================================class TokenTable { Token ** p; char ** c; int size;public: TokenTable (int max_size, char * data [], type_of_lex t []);~ TokenTable ();Token *operator ()(int k);char *operator [](int k);intget_size() const;intget_index(const Token * l) const;intget_index(const type_of_lex l) const;Token * get_token(const buf & b) const;voidput_obj (ProgramObject *t, int i);friend ostream & operator << (ostream & s, const TokenTable & t);};//===================================================================/////////////////////////Класс лексем//////////////////////////////===================================================================class Tokenpublic:{ type_of_lex type;ProgramObject * value;Token (const type_of_lex t, ProgramObject * v = 0);type_of_lex get_type() const;voidset_type(const type_of_lex t);voidset_value (ProgramObject * v);ProgramObject * get_value() const;friend ostream & operator << (ostream & s, const Token * t);};//===================================================================/////////////////Класс таблиц объектов программы///////////////////===================================================================template <class Object> class ObjectTable { int size; public: Object ** p; int free;public: ObjectTable(int max_size);~ ObjectTable();Object *operator[] (int k);Object *put_obj (Object *t= 0);Object *put_obj (Object *t, int i);intget_place() const;intget_index(Token * l) const;intget_index(type_of_lex t) const;intget_index(int v) const;Object * get_object(const buf & b) const;friend ostream & operator << (ostream &s, const ObjectTable & t);};//===================================================================////////////////Базовый класс объектов программы///////////////////===================================================================class ProgramObject { protected: type_of_lex type; int value;public: type_of_lex get_type() const;voidset_type(type_of_lex t);intget_value() const;voidset_value(int v);virtual voidexec(int & i) const = 0;virtual boolis_object(const buf & b) const = 0;virtual ostream &print(ostream & s) const = 0;};//===================================================================////////////// Производные классы объектов программы/////////////////===================================================================class Ident:public ProgramObject { char * name; bool declare; bool assign;public: Ident(const buf & b);boolget_assign() const;voidset_assign();boolget_declare() const;voidset_declare();char * get_name() const;boolis_object(const buf & b) const;ostream & print(ostream & s) const;void exec(int &) const;};//===================================================================class Number:public ProgramObject {public: Number(const buf & b);boolis_object(const buf & b) const;ostream & print(ostream & s) const;void exec(int & i) const;};//===================================================================class Label:public ProgramObject {public: Label(int n);boolis_object(const buf & b) const;ostream & print(ostream & s) const;void exec(int & i) const;};//===================================================================class Address: public ProgramObject {public: Addressboolis_objectostream & printvoid exec};(int(const buf &(ostream &(int &n);b) const;s) const;i) const;//===================================================================class Operation:public ProgramObject { char * sign;protected: Operation (char * str, type_of_lex t);public: boolis_object(const buf & b) const;ostream & print(ostream & s) const;};classTrueObject: public Operation { public:TrueObject (char * str,classFalseObject: public Operation { public:FalseObject (char * str,classNotObject: public Operation { public:NotObject (char * str,classOrObject: public Operation { public:OrObject (char * str,classAndObject: public Operation { public:AndObject (char * str,classEqObject: public Operation { public:EqObject (char * str,classLtObject: public Operation { public:LtObject (char * str,classGtObject: public Operation { public:GtObject (char * str,classLeObject: public Operation { public:LeObject (char * str,classGeObject: public Operation { public:GeObject (char * str,classNeObject: public Operation { public:NeObject (char * str,classPlusObject: public Operation { public:PlusObject (char * str,classMinusObject: public Operation { public:MinusObject (char * str,classMultObject: public Operation { public:MultObject (char * str,classDivObject: public Operation { public:DivObject (char * str,class AssignObject: public Operation { public: AssignObject (char * str,classGoToObject: public Operation { public:GoToObject (char * str,class GoIfNotObject: public Operation { public: GoIfNotObject (char * str,classWriteObject: public Operation { public:WriteObject (char * str,classReadObject: public Operation { public:ReadObject (char * str,virtual void exec (int & i) const = 0;type_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lextype_of_lext);t);t);t);t);t);t);t);t);t);t);t);t);t);t);t);t);t);t);t);voidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidexecexecexecexecexecexecexecexecexecexecexecexecexecexecexecexecexecexecexecexec(int(int(int(int(int(int(int(int(int(int(int(int(int(int(int(int(int(int(int(int//===================================================================/////////////////////////Класс Scanner/////////////////////////////===================================================================class Scanner { enum State { H, Comment, NOperator, Operator, LOperator, Identifier, Literal, Error };State FA_State;FILE * fp; char c;buf b;void GetS(); // Процедура ввода очередного символа программы//////////////////// Основные процедуры сканера /////////////////////public:IdentToken};Scanner~Scanner* CreateIdentObject* get_lex(char *);();(const buf & b);();// Конструктор класса// Деструктор классаNumber * CreateNumberObject (const buf & b);// Процедура ввода очередной лексемы&)&)&)&)&)&)&)&)&)&)&)&)&)&)&)&)& i)& i)&)&)const;const;const;const;const;const;const;const;const;const;const;const;const;const;const;const;const;const;const;const;};};};};};};};};};};};};};};};};};};};};//===================================================================/////////////////////////Класс Parser//////////////////////////////===================================================================class Parser { Token * curr_lex;void GetLScanner scan; type_of_lex c_type;(); // Процедура ввода очередной лексемы и установки внутренних переменных/////////////////// Процедуры рекурсивного спуска ///////////////////void P (); void D1 (); void D (); void B (); void S (); void E (); void E1 (); void T (); void F ();////////////////// Процедуры семантического контроля ////////////////voidvoidvoidvoiddeclcheck_opeq_typecheck_id(type_of_lex type)()()()const;const;const;const;void check_not() const;void eq_type(type_of_lex type) const;void check_id_in_read() const;/////////////////// Вспомогательные процедуры ///////////////////////Address * CreateAddressObject (Token * l);Label* CreateLabelObject(int label);//////////// Основные процедуры синтаксического анализа /////////////public: Parser~Parservoid Analyze};(char *program);();();// Конструктор класса// Деструктор класса// Основная процедура анализа//===================================================================///////////////////////Класс Simulator/////////////////////////////===================================================================class Simulator { ProgramObject * curr_obj;public:void Simulate (); // Основная процедура интерпретатора~ Simulator (); // Деструктор класса};//===================================================================//////////////////////// Шаблоны стеков ///////////////////////////////===================================================================template <class T, int max_size> class Stack { T s [max_size]; int top;public: Stack(){reset ();}void reset(){top = 0;}void push (T i){ if (!is_full ()) { s [top ++] = i; }else throw "Стек переполнен";}Tpop(){ if (!is_empty ()) { return s [--top];}else throw "Стек исчерпан";}bool is_empty () const { return top <= 0;}bool is_full () const { return top >= max_size;}};//===================================================================////////////////////////Стеки////////////////////////////////===================================================================Stack<Token *, 100> Names;Stack <type_of_lex, 100> Types;Stack<int, 100> Values;//===================================================================////////////////Таблицы внутренних представлений///////////////////===================================================================TokenTable TW (sizeof(KeyWords) / sizeof(KeyWords [0]), KeyWords,LKeyWords);TokenTable TD (sizeof (Delimiters) / sizeof (Delimiters [0]), Delimiters, LDelimiters);ObjectTable<Ident>TI(100);ObjectTable<Address>TA (sizeof (TI) / sizeof (TI [0]));ObjectTable<Number>TC(100);ObjectTable<Label>TL(100);ObjectTable<Operation>TO(20); // Таблица для 20 операционных объектовObjectTable<ProgramObject> PLZ(1000);intind_GO,ind_FGO;//===================================================================/////////////////// Реализация используемых классов ///////////////////////////// Отладочные операторы выдачи лексем и объектов ////////////===================================================================ostream & operator << (ostream & s, const Token * t){ ProgramObject * p; int i;s << "(Tип = ";s.width (2); s << t -> type << ")";if ((p = t -> get_value ()) != 0) { s << " "; p -> print (s); }else { for (i = 0; i < sizeof (KeyWords) / sizeof(KeyWords [0]); i ++)if ( LKeyWords [i] == t -> type) { s << " Слово " <<KeyWords [i] << endl; return s; }for (i = 0; i < sizeof(Delimiters) / sizeof (Delimiters [0]); i ++)if (LDelimiters [i] == t -> type) { s << " Знак " << Delimiters [i] << endl; return s; }s << endl;}return s;}template <class Object> ostream & operator << (ostream & s, const ObjectTable<Object> & l){ for (int i = 0; i < l.free; i ++) { cout.width (4); cout << i << ": " << l.p [i];}return s;}ostream & operator << (ostream & s, const ProgramObject * t) { t -> print (s); return s; }//===================================================================///////////////////////////Класс buf///////////////////////////////===================================================================buf::buf (int max_size){ b = new char [size = max_size]; top = 0; clear(); }buf::~ buf(){ delete b;}voidbuf::clear(){if (Dump & DUMP_BUF && top) { cout << "Буфер: " << b << endl; }memset (b, '\0', size); top = 0; }voidbuf::add( const char c) { b [top ++] = c;}intbuf::int_buf() const { return atoi (b);}char * buf::get_string () const { return b;}ostream &operator << (ostream &s, const buf & b) { s << "Буфер = " << b.b << endl; return s;}//===================================================================///////////////////////Класс таблиц лексем/////////////////////////===================================================================TokenTable::~ TokenTable() { delete [] p; }Token* TokenTable::operator ()(int k) { return p [k]; }char * TokenTable::operator [](int k) { return c [k]; }voidTokenTable::put_obj (ProgramObject * t, int i) { p [i] -> set_value (t); }TokenTable:: TokenTable (int max_size, char * data [], type_of_lex t []){ p = new Token * [(size = max_size) + 1]; c = data;for (int i = 0; i < size; i ++){ p [i] = 0; if (!data [i]) break;p [i] = new Token (t [i]);}}int TokenTable::get_size () const { return size; }int TokenTable::get_index (const type_of_lex l) const{ Token ** q = p; Token * t; int i = 0;while (* q){ t = * q ++;if (t -> get_type () == l) break;i ++;}return i;}int TokenTable::get_index (const Token * l) const{ Token ** q = p; int i = 0;while (* q != l) { q ++; i ++; }return i;}Token * TokenTable::get_token (const buf & b) const{ Token ** q = p; char ** s = c; Token * t;while (* q){ t = * q ++;if (! strcmp (b.get_string (), * s ++)) return t;}return 0;}ostream & operator << (ostream & s, const TokenTable & l){ for (int i = 0; i < l.size; i ++) cout << l.p [i];return s;}//===================================================================///////////////////////////Класс лексем////////////////////////////===================================================================Token::Token (const type_of_lextype_of_lexToken::get_typevoidToken::set_type(type_of_lexProgramObject * Token::get_valuevoidToken::set_value(ProgramObject *t, ProgramObject * v) {value = v; type = t; }() const{ returntype;}t){type = t; }() const{ return value;}v){value = v;}//===================================================================/////////////////Класс таблиц объектов программы///////////////////===================================================================template <class Object>ObjectTable<Object>::ObjectTable<Object> (int max_size){ p = new Object * [(size = max_size) + 1]; free = 0; }template <class Object> Object * ObjectTable<Object>::put_obj (Object * t, int i){ p [i]= t; return t; }template <class Object> Object * ObjectTable<Object>::put_obj (Object * t){ p [free ++] = t; return t; }template <class Object> intObjectTable<Object>::get_place() const { return free; }template <class Object> Object * ObjectTable<Object>::operator [](int k){ return p[k]; }template <class Object>ObjectTable<Object>:: ~ ObjectTable<Object>(){ delete[] p; }template <class Object> int{ Object ** q = p;for (int i = 0; i < free;};template <class Object> int{ Object ** q = p;for (int i = 0; i < free;};template <class Object> int{ Object ** q = p;for (int i = 0; i < free;};ObjectTable<Object>::get_index (Token * l) consti ++) { if (* q ++ == l -> get_value ())return i; } return - 1;ObjectTable<Object>::get_index (int v) consti ++) { if ((* q ++) -> get_value () == v)return i; } return - 1;ObjectTable<Object>::get_index (type_of_lex t) consti ++) { if ((*(* q ++)).get_type () == t)return i; } return - 1;template <class Object> Object * ObjectTable<Object>::get_object (const buf & b) const{ Object ** q = p; Object * t;for (int i = 0; i < free; i ++) { t = * q ++; if (t -> is_object (b)) return t; } return}0;//===================================================================////////////////Базовый класс объектов программы///////////////////===================================================================type_of_lexvoidintvoidProgramObject::get_typeProgramObject::set_type (type_of_lexProgramObject::get_valueProgramObject::set_value(int() const { return type;t){ type =t;() const { return value;v){ value =v;}}}}//===================================================================/////// Конструкторы производных классов объектов программы//////////===================================================================Ident::Ident(const buf & b) { char * str = b.get_string (); name = new char [strlen (str) + 1];declare = assign = false; strcpy (name, str); }Number::Number(const buf & b){ value = b.int_buf (); }Label::Label(int n) { value = n;}Address::Address(int n) { value = n;}Operation::Operation (char * str, type_of_lex t) { type = t; sign = new char [strlen (str)+1]; strcpy (sign, str); }TrueObject::TrueObject (char * str, type_of_lex t): Operation (str, t) {}FalseObject:: FalseObject (char * str, type_of_lex t): Operation (str, t) {}NotObject::NotObject (char * str, type_of_lex t): Operation (str, t) {}OrObject::OrObject (char * str, type_of_lex t): Operation (str, t) {}AndObject::AndObject (char * str, type_of_lex t): Operation (str, t) {}EqObject::EqObject (char * str, type_of_lex t): Operation (str, t) {}LtObject::LtObject (char * str, type_of_lex t): Operation (str, t) {}GtObject::GtObject (char * str, type_of_lex t): Operation (str, t) {}LeObject::LeObject (char * str, type_of_lex t): Operation (str, t) {}GeObject::GeObject (char * str, type_of_lex t): Operation (str, t) {}NeObject::NeObject (char * str, type_of_lex t): Operation (str, t) {}PlusObject::PlusObject (char * str, type_of_lex t): Operation (str, t) {}MinusObject:: MinusObject (char * str, type_of_lex t): Operation (str, t) {}MultObject::MultObject (char * str, type_of_lex t): Operation (str, t) {}DivObject::DivObject (char * str, type_of_lex t): Operation (str, t) {}AssignObject:: AssignObject (char * str, type_of_lex t): Operation (str, t) {}GoToObject::GoToObject (char * str, type_of_lex t): Operation (str, t) {}GoIfNotObject::GoIfNotObject (char * str, type_of_lex t): Operation (str, t) {}WriteObject:: WriteObject (char * str, type_of_lex t): Operation (str, t) {}ReadObject::ReadObject (char * str, type_of_lex t): Operation (str, t) {}//===================================================================//////// Реализация производных классов объектов программы///////////===================================================================boolvoidboolvoidchar *boolostream &Ident::get_assign() const { return assign;Ident::set_assign(){ assign = true;Ident::get_declare() const { return declare;Ident::set_declare(){ declare = true;Ident::get_name() const { return name;Ident::is_object (const buf & b) const{ return ! strcmp (b.get_string (), name);Ident::print(ostream & s) const{ s << "Имя"<< name << endl; return s;}}}}}}}//===================================================================boolostream &Number::is_object (const buf & b) const{ return b.int_buf () == value;}Number::print(ostream & s) const{ s << "Число = "; s.width (9); s << value << endl; return s;}//===================================================================boolostream &Label::is_object (const buf & b) const { return true;}Label::print(ostream & s) const{ s << "Метка = "; s.width (4); s << value << endl; return s;}//===================================================================boolostream &Address::is_object (const buf & b) const { return true;}Address::print(ostream & s) const{ s << "Адрес = ";s.width (4); s << value << " " << TI [value]; return s; }//===================================================================boolOperation::is_object (const buf & b) const{ return ! strcmp (b.get_string (), sign);}ostream & Operation::print(ostream & s) const{ s << "Объект";s /*.width (4); s << type << " " */ << sign << endl; return s; }//=======================================/////// Класс Scanner ///////===============================================Scanner:: Scanner (char * program) { fp = fopen (program, "r");GetS (); FA_State = H; }Scanner::~Scanner (){fclose (fp); }void Scanner::GetS () { c = fgetc (fp); }Ident * Scanner::CreateIdentObject (const buf &{ Ident * I = TI.get_object(b); return I ==Number* Scanner::CreateNumberObject (const buf &{ Number * N = TC.get_object(b); return N ==Token * Scanner::get_lex (){for (;;) { switch (FA_State) {case H:if (isspace (c))else if (isalpha (c))else if (isdigit (c))else if (c =='@')else if (c =='{')b)0 ? TI.put_obj (new Ident (b)) : I; }b)0 ? TC.put_obj (new Number (b)) : N; }Token * res;GetS ();b.clear (); b.add (c); GetS (); FA_State = Identifier;}b.clear (); b.add (c); GetS (); FA_State = Literal;}b.clear (); b.add (c);FA_State = Error;GetS (); FA_State = Comment;}return TD.get_token (b);}else if (c ==':'||c =='<'||c =='>') { b.clear (); b.add (c); GetS (); FA_State = LOperator;}else if (c =='!'){b.clear (); b.add (c); GetS (); FA_State = NOperator;}else{b.clear (); b.add (c);FA_State = Operator;}break;case Identifier: if (isalnum (c) ) {b.add (c); GetS ();}else { FA_State = H; if ((res = TW.get_token (b)) != 0)return res;elsereturn new Token (LEX_ID, CreateIdentObject (b)); }break;case Literal:if (isdigit (c)) {b.add (c); GetS ();}else { FA_State = H;return new Token (LEX_NUM, CreateNumberObject (b)); }break;case Comment:if (c == '}') {GetS (); FA_State = H;}else if (c == '@') {FA_State = Error;throw c; }else if (c == '{')throw c;elseGetS ();break;case LOperator:FA_State = H; if (c == '=') {b.add (c); GetS ();}return TD.get_token (b);case NOperator:FA_State = H; if (c == '=') {b.add (c); GetS (); return TD.get_token (b);}elsethrow '!';case Operator:FA_State = H; if ((res = TD.get_token (b)) != 0) {GetS (); return res;}elsethrow c;case Error:throw c;} //end switch} // end for}{{{{//===================================================================/////////////////////////Класс Parser//////////////////////////////===================================================================/////////////////// Вспомогательные процедуры ///////////////////////Address * Parser::CreateAddressObject (Token * l){ intIdent_index = TI.get_index (l);intAdr_index = TA.get_index (Ident_index);returnAdr_index >= 0 ? TA [ Adr_index] : TA.put_obj (new Address (Ident_index));}Label* Parser::CreateLabelObject(int label){ intLabel_index = TL.get_index (label);return Label_index >= 0 ? TL [Label_index] : TL.put_obj (newLabel (label));}//////////// Основные процедуры синтаксического анализа /////////////Parser:: Parser (char * program): scan (program) {}Parser::~Parser(){}void Parser::GetL (){ curr_lex = scan.get_lex ();if (Dump & DUMP_LEX) cout << curr_lex;c_type = curr_lex -> get_type ();}void Parser::Analyze (){}void Parser::P (){ if (Dump & DUMP_REC) cout << "P (): entry\n";if (c_type != LEX_PROGRAM)throw curr_lex;if (c_type != LEX_SEMICOLON)throw curr_lex;if (c_type != LEX_FIN)throw curr_lex;if (Dump & DUMP_REC) cout << "P (): exit\n";}void Parser::D1(){ if (Dump & DUMP_REC) cout << "D1 (): entry\n";if (c_type != LEX_VAR)throw curr_lex;do {} while (c_type == LEX_COMMA);if (Dump & DUMP_REC) cout << "D1 (): exit\n";}GetL (); P();GetL (); D1 ();GetL (); B ();GetL (); D();void Parser::D () {if (Dump & DUMP_REC) cout << "D (): entry\n";Names.reset ();if (c_type != LEX_ID)throw curr_lex;Names.push (curr_lex);while (c_type == LEX_COMMA) {if (c_type != LEX_ID)Names.push (curr_lex);}if (c_type != LEX_COLON)throw curr_lex;if (c_type == LEX_INT || c_type == LEX_BOOL) {elsethrow curr_lex;if (Dump & DUMP_REC) cout << "D (): exit\n";decl (c_type);GetL ();GetL ();throw curr_lex;GetL ();GetL ();GetL (); }}voidififdoParser::B () {(Dump & DUMP_REC) cout << "B (): entry\n";(c_type != LEX_BEGIN)throw curr_lex;{} while (c_type == LEX_SEMICOLON);if (c_type != LEX_END)throw curr_lex;if (Dump & DUMP_REC) cout << "B (): exit\n";GetL (); S();GetL ();}void Parser::E () {if (Dump & DUMP_REC) cout << "E(): entry\n";E1 ();if (c_type == LEX_EQ || c_type == LEX_LT || c_type == LEX_GT ||c_type == LEX_LE || c_type == LEX_NE || c_type == LEX_GE){Types.push (c_type);if (Dump & DUMP_REC) cout << "E (): exit\n";GetL (); E1 (); check_op ();}}void Parser::E1 () {if (Dump & DUMP_REC) cout << "E1 (): entry\n";Twhile (c_type == LEX_OR || c_type == LEX_MINUS || c_type == LEX_PLUS){Types.push (c_type);if (Dump & DUMP_REC) cout << "E1 (): exit\n";}GetL (); T();(); check_op ();}void Parser::T () {if (Dump & DUMP_REC) cout << "T(): entry\n";Fwhile (c_type == LEX_MULT || c_type == LEX_DIV || c_type == LEX_AND){Types.push (c_type);if (Dump & DUMP_REC) cout << "T (): exit\n";GetL (); F}void Parser::F () { ProgramObject * Oper = curr_lex -> get_value ();if (Dump & DUMP_REC) cout << "F (): entry\n";if (c_type == LEX_ID){check_id ();PLZ.put_obj (Oper);delete curr_lex;GetL ();else if (c_type == LEX_NUM){ Types.push (LEX_INT);PLZ.put_obj (Oper);delete curr_lex;GetL ();else if (c_type == LEX_TRUE) { Types.push (LEX_BOOL);PLZ.put_obj (Oper);GetL ();else if (c_type == LEX_FALSE) { Types.push (LEX_BOOL);PLZ.put_obj (Oper);GetL ();else if (c_type == LEX_NOT){ GetL (); F (); check_not (); PLZ.put_obj (Oper);else if (c_type == LEX_LPAREN){ GetL (); E (); if (c_type == LEX_RPAREN)GetL ();elsethrow curr_lex;else throw curr_lex;if (Dump & DUMP_REC) cout << "F (): exit\n";}void Parser::S () { int lab1, lab2; ProgramObject * Oper;if (Dump & DUMP_REC) cout << "S (): entry\n";if (c_type == LEX_ID){ check_id ();PLZ.put_obj (CreateAddressObject (curr_lex));delete curr_lex;GetL ();Oper = curr_lex -> get_value();if (c_type == LEX_ASSIGN){ GetL (); E (); eq_type ();PLZ.put_obj (Oper);}else throw curr_lex;} // assign-endelse if (c_type == LEX_WHILE){ GetL (); lab1 = PLZ.get_place ();E (); eq_type (LEX_BOOL); lab2 = PLZ.get_place (); PLZ.put_obj ();PLZ.put_obj (TO [ind_FGO]);if (c_type == LEX_DO){ GetL (); S (); PLZ.put_obj (CreateLabelObject (lab1));PLZ.put_obj (TO [ind_GO]);PLZ.put_obj (CreateLabelObject (PLZ.get_place ()), lab2);}else throw curr_lex;} // end while}}}}}}();(); check_op ();}else if (c_type == LEX_IF){ GetL (); E (); eq_type (LEX_BOOL); lab1 = PLZ.get_place (); PLZ.put_obj ();PLZ.put_obj (TO [ind_FGO]);if (c_type == LEX_THEN){ GetL (); S ();lab2 = PLZ.get_place (); PLZ.put_obj ();PLZ.put_obj (TO [ind_GO]);PLZ.put_obj (CreateLabelObject (PLZ.get_place ()), lab1);if (c_type == LEX_ELSE){ GetL (); S (); PLZ.put_obj (CreateLabelObject (PLZ.get_place ()), lab2);}else throw curr_lex;}else throw curr_lex;} // end ifelse if (c_type == LEX_READ){ Oper = curr_lex -> get_value ();GetL (); if (c_type == LEX_LPAREN){ GetL ();if (c_type == LEX_ID){ check_id_in_read ();PLZ.put_obj (CreateAddressObject (curr_lex));delete curr_lex;GetL ();}else throw curr_lex;if (c_type == LEX_RPAREN){ GetL(); PLZ.put_obj (Oper); }else throw curr_lex;}else throw curr_lex;} // end readelse if (c_type == LEX_WRITE){ Oper = curr_lex -> get_value ();GetL (); if (c_type == LEX_LPAREN){ GetL (); E ();Types.pop ();if (c_type == LEX_RPAREN){ GetL(); PLZ.put_obj (Oper); }else throw curr_lex;}else throw curr_lex;} // end writeelse B ();if (Dump & DUMP_REC) cout << "S (): exit\n";}void Parser::eq_type{ if (Types.pop () != Types.pop ())}() constthrow "Несоответствие типов в присваивании :=";void Parser::eq_type (type_of_lex token) const{ if (Types.pop () != token)throw "Требуется логическое выражение";}void Parser::decl (type_of_lex type) const{ while (! Names.is_empty ()){ Token * Ident_lex = Names.pop ();Ident * t = dynamic_cast<Ident*> (Ident_lex -> get_value ()); delete Ident_lex;if (t -> get_declare ())throw "Повторное описание";else { t -> set_declare (); t -> set_type (type); }}}void Parser::check_op () const// t- тип операнда, требуемый для данной операции// r- тип формируемого операцией результата// (начальные значения t и r соответствуют операциям отношения)// t1 и t2 - реальные типы операндов{ type_of_lex t = LEX_INT, r = LEX_BOOL;type_of_lex t2 = Types.pop ();type_of_lex op = Types.pop ();type_of_lex t1 = Types.pop ();if (op == LEX_PLUS || op == LEX_MINUS || op == LEX_MULT || op == LEX_DIV) r = LEX_INT;if (op == LEX_OR|| op == LEX_AND)t = LEX_BOOL;if (t1 == t2 && t1 == t)Types.push (r);else throw "Неверные типы в двуместной операции";PLZ.put_obj (TO [TO.get_index (op)]);}void Parser::check_not() const{ if (Types.pop () != LEX_BOOL)else Types.push (LEX_BOOL);}void Parser::check_id() const{ Ident * t = dynamic_cast<Ident*> (curr_lex -> get_value ());if (t -> get_declare ())Types.push (t -> get_type ());}void Parser::check_id_in_read () const{ Ident * t = dynamic_cast<Ident*> (curr_lex -> get_value ());if (! t -> get_declare ())}throw "Неверный тип в операции отрицания";else throw "Отсутствует описание";throw "Не описан идентификатор";//===================================================================///////////// Операционные функции программных объектов ///////////////===================================================================voidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidvoidIdent::exec (int &) const{ if (get_assign ()) Values.push (get_value ());else throw "PLZ: неопределенное значение у имени";}Number::exec (int &) const { Values.push (get_value ());}Address::exec (int &) const { Values.push (get_value ());}Label::exec (int &) const { Values.push (get_value ());}TrueObject::exec (int &) const { Values.push (1);}FalseObject::exec (int &) const { Values.push (0);}NotObject::exec (int &) const { Values.push (1 - Values.pop ());}OrObject::exec (int &) const { Values.push (Values.pop () || Values.pop ());}AndObject::exec (int &) const { Values.push (Values.pop () && Values.pop ());}EqObject::exec (int &) const { Values.push (Values.pop () == Values.pop ());}LtObject::exec (int &) const { Values.push (Values.pop () >= Values.pop ());}GtObject::exec (int &) const { Values.push (Values.pop () <= Values.pop ());}LeObject::exec (int &) const { Values.push (Values.pop () > Values.pop ());}GeObject::exec (int &) const { Values.push (Values.pop () < Values.pop ());}NeObject::exec (int &) const { Values.push (Values.pop () != Values.pop ());}PlusObject::exec (int &) const { Values.push (Values.pop () + Values.pop ());}MinusObject::exec (int &) const { int k = Values.pop (); Values.push (Values.pop () - k); }MultObject::exec (int &) const { Values.push (Values.pop () * Values.pop ());}DivObject::exec (int &) const{ int k = Values.pop ();if (k) Values.push (Values.pop () / k);else throw "PLZ: деление на нуль";}AssignObject::exec (int &) const{ int k = Values.pop (); Ident * t = TI [Values.pop ()];t -> set_value (k);t -> set_assign ();}GoToObject::exec (int & i) const { i = Values.pop () - 1;}GoIfNotObject::exec (int & i) const{ int k = Values.pop (); if(!Values.pop ()) i = k - 1; }WriteObject::exec (int &) const{ cout << "Writing=>" << Values.pop () << endl;}voidReadObject::exec (int &) const{ int k = 0; Ident * t = TI [Values.pop ()];if (t -> get_type () == LEX_INT){ cout << "Введите значение для "<< t -> get_name () << " =>" << flush; scanf ("%d", & k);}else { char m [80];for (int l = 0; l < 3; l ++){ cout << "Введите логическое значение как true или false для "<< t -> get_name () << " =>" << flush; scanf ("%s", m);if (! strcmp (m, "true")) { k = 1; break; }else if (! strcmp (m, "false")) { k = 0; break; }cout << "Ошибка при вводе: true/false" << endl;}}t -> set_value (k); t -> set_assign ();}//===================================================================///////////////////////Класс Simulator//////////////////////////////===================================================================void Simulator::Simulate (){ int size;Values.reset ();size = PLZ.get_place ();for (int index = 0; index < size; index ++){ curr_obj = PLZ [index];if (Dump & DUMP_SIM) { cout.width (4); cout << index << ": " << curr_obj; }if (curr_obj) curr_obj -> exec (index);}}Simulator::~ Simulator () {}//===================================================================////////////////////////Функция main///////////////////////////////===================================================================int main (int argc, char ** argv){ bool res = false;//Установка отладочных режимов работы интерпретатораDump = /*/*/*/*/*/*/*/*/*//* /+* /+*/ +*/ +*/ +*/ +*/ +*/ +*/ ++DUMP_BUFDUMP_RECDUMP_LEXDUMP_PLZDUMP_PTADUMP_PTCDUMP_PTIDUMP_PTLDUMP_SIM0;/*/*/*/*/*/*/*/*/**/*/*/*/*/*/*/*/*/Создание операционных объектов и построение индексов для объектов, обрабатываемых индивидуальноToken * T; char * ExtRep; type_of_lex type; int size = TW.get_size () - 1;for (int i = 0; i < size; i ++){ T = TW (i); ExtRep = TW [i]; type = T -> get_type ();switch (type){ case LEX_TRUE: TW.put_obj (TO.put_obj (newTrueObject (ExtRep,type)),case LEX_FALSE: TW.put_obj (TO.put_obj (newFalseObject (ExtRep,type)),case LEX_NOT:TW.put_obj (TO.put_obj (newNotObject (ExtRep,type)),case LEX_OR:TW.put_obj (TO.put_obj (newOrObject (ExtRep,type)),case LEX_AND:TW.put_obj (TO.put_obj (newAndObject (ExtRep,type)),case PLZ_GO:TW.put_obj (TO.put_obj (newGoToObject (ExtRep,type)),case PLZ_FGO:TW.put_obj (TO.put_obj (new GoIfNotObject (ExtRep,type)),case LEX_WRITE: TW.put_obj (TO.put_obj (newWriteObject (ExtRep,type)),case LEX_READ: TW.put_obj (TO.put_obj (newReadObject (ExtRep,type)),}}ind_GO = TO.get_index (PLZ_GO);ind_FGO = TO.get_index (PLZ_FGO);i);i);i);i);i);i);i);i);i);break;break;break;break;break;break;break;break;break;size = TD.get_size () - 1;for (i = 0; i < size; i ++){ T = TD (i); ExtRep = TD [i];switch (type){ case LEX_EQ:TD.put_objcase LEX_LT:TD.put_objcase LEX_GT:TD.put_objcase LEX_LE:TD.put_objcase LEX_GE:TD.put_objcase LEX_NE:TD.put_objcase LEX_PLUS: TD.put_objcase LEX_MINUS: TD.put_objcase LEX_MULT: TD.put_objcase LEX_DIV:TD.put_objcase LEX_ASSIGN:TD.put_obj}}//type = T -> get_type ();(TO.put_obj(TO.put_obj(TO.put_obj(TO.put_obj(TO.put_obj(TO.put_obj(TO.put_obj(TO.put_obj(TO.put_obj(TO.put_obj(TO.put_obj(new(new(new(new(new(new(new(new(new(new(new(ExtRep,type)),(ExtRep,type)),(ExtRep,type)),(ExtRep,type)),(ExtRep,type)),(ExtRep,type)),(ExtRep,type)),(ExtRep,type)),(ExtRep,type)),(ExtRep,type)),(ExtRep,type)),i);i);i);i);i);i);i);i);i);i);i);break;break;break;break;break;break;break;break;break;break;break;Проведение синтаксического анализа указанной программыif (Dump & DUMP_LEX){cout << "Программа в виде последовательности лексем:::"try { Parser * M = new Parser ("program.txt");catchcatchcatchcatchcatch(char c){cout(ProgramObject * l) {cout(Token * t){cout(const char * source){cout(...){coutif (Dump & DUMP_LEX)//ifififififEqObjectLtObjectGtObjectLeObjectGeObjectNeObjectPlusObjectMinusObjectMultObjectDivObjectAssignObject<<<<<<<<<<M -> Analyze ();<< endl << endl;delete M;res}= true;}"Неверный символ при лексическом анализе: "<< c << endl; return 1;}"Неверный программный объект при синтаксическом анализе: " << l << endl; return 1;}"Неверная лексема при синтаксическом анализе: "<< t << endl; return 1;}source<< endl; return 1;}"Непонятная ситуация при анализе входного текста."<< endl; return 1;}{cout << "res = " << (res ? "true " : "false")<< endl;}Отладочная выдача созданных при синтаксическом анализе таблиц(Dump(Dump(Dump(Dump(Dump&&&&&DUMP_PTI)DUMP_PTA)DUMP_PTC)DUMP_PTL)DUMP_PLZ){cout{cout{cout{cout{cout<<<<<<<<<<"Таблица имен:::::::::::::::::::::::::::::::::""Таблица адресов::::::::::::::::::::::::::::::""Таблица констант:::::::::::::::::::::::::::::""Таблица меток::::::::::::::::::::::::::::::::""Программа в инверсной польской записи::::::::"<<<<<<<<<<endlendlendlendlendl<< TI;}<< TA;}<< TC;}<< TL;}<<PLZ;}// Создание объекта для проведения интерпретации и интерпретация внутреннего представленияif (Dump & DUMP_SIM){cout << "Начало работы::::::::::::::::::::::::::::::::"try { Simulator * S = new Simulator ();S -> Simulate ();//}Уничтожение ненужных объектов, собранных в таблицыsize =size =size =size =size =deleteTA.get_placeTC.get_placeTI.get_placeTL.get_placeTO.get_placeS;();();();();();forforforforfor(i(i(i(i(i=====0;0;0;0;0;iiiii<<<<<size;size;size;size;size;iiiii++)++)++)++)++)deletedeletedeletedeletedeleteTATCTITLTO[i];[i];[i];[i];[i];}catch (const char * source){cout << sourcecatch (...){cout << "Непонятная ситуация в интерпретаторе."if (Dump & DUMP_ANY)return 0;}<< endl;{cout << "Конец работы:::::::::::::::::::::::::::::::::"<< endl; return 1;}<< endl; return 1;}<< endl;}.