Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pch.h"
- #include <iostream>
- #include <fstream>
- #include <vector>
- using namespace std;
- string keyWord[4] = { "if", "then", "else", "end" };
- enum State
- {
- S,
- Id, //идентификатор
- Co, //число
- K_w, //ключевое слово
- L, // <
- R, // >
- Eq, // =
- As, // <= >= ==
- Add, // + -
- Unk, // неопознанный элемент
- };
- enum SyntaxState
- {
- OUT,
- IFS,
- OPERAND,
- LOGIC_OPERATOR,
- THENS,
- OPERATOR,
- ELSES,
- ENDS,
- ERROR
- };
- enum LexType { IF, THEN, ELSE, END, Contrast, Eqate, Addition, Constant, Ident, UnknownToken };
- struct SyntaxResult
- {
- SyntaxResult(bool isSuccesful)
- {
- this->isSuccessful = isSuccesful;
- }
- char *errorMessage;
- bool isSuccessful;
- };
- struct Lex
- {
- LexType type;
- char* str;
- };
- const State LexMatrix[10][8] =
- {
- // a-Z 0-9 < > = +/-
- K_w, Co, L, R, Eq, Co, S, Unk, //старт
- Id, Id, Unk, Unk, Unk, Unk, S, Unk, //идентификатор
- Unk, Co, Unk, Unk, Unk, Unk, S, Unk, //число
- K_w, Id, Unk, Unk, Unk, Unk, S, Unk, //ключевое слово
- Unk, Unk, Unk, As, As, Unk, S, Unk, // <
- Unk, Unk, Unk, Unk, As, Unk, S, Unk, // >
- Unk, Unk, Unk, Unk, As, Unk, S, Unk, // =
- Unk, Unk, Unk, Unk, Unk, Unk, S, Unk, // <= >= ==
- Unk, Unk, Unk, Unk, Unk, Unk, S, Unk, // + -
- Unk, Unk, Unk, Unk, Unk, Unk, S, Unk, // неопознанный элемент
- };
- const SyntaxState SyntaxMatrix[9][10] =
- {
- //IF THEN ELSE END Contrast Eqate Addition Constant Ident UnknownToken
- IFS, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, // OUT
- ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, OPERAND, OPERAND, ERROR, // IF
- ERROR, THENS, ERROR, ERROR, LOGIC_OPERATOR, LOGIC_OPERATOR, ERROR, ERROR, ERROR, ERROR, // OPERAND
- ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, OPERAND, OPERAND, ERROR, // LOGIC_OPERATOR
- ERROR, ERROR, ELSES, ENDS, ERROR, ERROR, ERROR, OPERATOR, OPERATOR, ERROR, // THEN
- ERROR, ERROR, ELSES, ENDS, OPERATOR, OPERATOR, OPERATOR, OPERATOR, OPERATOR, ERROR, // OPERATOR
- ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, OPERATOR, OPERATOR, ERROR, // ELSE
- IFS, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, // END
- IFS, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR // END
- };
- int LexCollumn(char a) // вычисление столбца матрицы переходов
- {
- if ((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z'))
- return 0;
- if (a >= '0' && a <= '9')
- return 1;
- if (a == '<')
- return 2;
- if (a == '>')
- return 3;
- if (a == '=')
- return 4;
- if (a == '+' || a == '-')
- return 5;
- if (a == ' ' || a == '\t' || a == '\n' || a == '\r' || a == '\0')
- return 6;
- return 7;
- }
- bool equals(string& str1, char* str2)
- {
- int lenght2 = strlen(str2);
- if (lenght2 != str1.size())
- return 0;
- for (int i = 0; i < lenght2; ++i)
- if (str1[i] != str2[i])
- return 0;
- return 1;
- }
- Lex classifierLex(char* lex, State state) {
- Lex lexem;
- lexem.str = lex;
- if (state == K_w)
- {
- lexem.type = Ident;
- if (equals(keyWord[0], lex))
- lexem.type = IF;
- if (equals(keyWord[1], lex))
- lexem.type = THEN;
- if (equals(keyWord[2], lex))
- lexem.type = ELSE;
- if (equals(keyWord[3], lex))
- lexem.type = END;
- }
- else if (state == L || state == R || state == As) {
- lexem.type = Contrast;
- }
- else if (state == Eq) {
- lexem.type = Eqate;
- }
- else if (state == Add) {
- lexem.type = Addition;
- }
- else if (state == Id)
- {
- lexem.type = Ident;
- }
- else if (state == Co)
- {
- lexem.type = Constant;
- }
- else if (state == Unk)
- {
- lexem.type = UnknownToken;
- }
- return lexem;
- }
- vector<Lex>* LexAnalysis(char* str) //Функция лексического анализа
- {
- vector<Lex>* v = new vector<Lex>();
- int position = 0; //текущая позиция в строке
- int start = 0; //позиция начала лексемы
- State curr_state = S; //текущее состояние
- Lex lexema; //текущая лексема
- while (str[position] != '\0') {
- if (curr_state == S) //Инициализация лексемы
- start = position;
- State previous = curr_state;
- curr_state = LexMatrix[curr_state][LexCollumn(str[position])]; //Переход по матрице состояний
- if (curr_state == S)
- {
- int length = position - start;
- if (length)
- {
- char* word = new char[length + 1];
- strncpy_s(word, length + 1, str + start, length); //вычленение подстроки и запись в лексему
- Lex currentLex = classifierLex(word, previous);
- v->push_back(currentLex); //запись лексемы в список
- }
- }
- position++;
- }
- return v;
- }
- char* getStateName(SyntaxState state) {
- char* name = new char();
- switch (state)
- {
- case 0:name = (char*)"ничего"; break;
- case 1:name = (char*)"if"; break;
- case 2:name = (char*)"<констранта или идентификатор>"; break;
- case 3:name = (char*)"<логический оператор>"; break;
- case 4:name = (char*)"then"; break;
- case 5:name = (char*)"<оператор>"; break;
- case 6:name = (char*)"else"; break;
- case 7:name = (char*)"end"; break;
- }
- return name;
- }
- void getErrorMessage(SyntaxState prev, Lex current) {
- cout << "Введено: " << current.str;
- cout << " но требовалось: ";
- for (int i = 0; i < 9; ++i)
- {
- SyntaxState state = SyntaxMatrix[prev][i];
- if (state != ERROR)
- {
- cout << getStateName(state) << " ";
- }
- }
- cout << endl;
- }
- SyntaxState getStatetByTpe(LexType t) {
- switch (t)
- {
- case IF: return IFS;
- case THEN: return THENS;
- case ELSE: return ELSES;
- case END: return ENDS;
- case Contrast: return LOGIC_OPERATOR;
- case Eqate: return OPERATOR;
- case Addition: return OPERATOR;
- case Constant: return OPERAND;
- case Ident: return OPERAND;
- case UnknownToken: return ERROR;
- }
- }
- void SyntaxAnalysis(vector<Lex> *lexems) {
- SyntaxState currentState = OUT;
- for (int i = 0; i < lexems->size(); ++i)
- {
- SyntaxState previous = currentState;
- currentState = SyntaxMatrix[currentState][lexems->at(i).type];
- if (currentState == ERROR)
- {
- int g = i;
- getErrorMessage(previous, lexems->at(g));
- while (currentState != IFS && g < lexems->size())
- {
- currentState = SyntaxMatrix[currentState][lexems->at(g).type];
- g++;
- }
- }
- if (currentState == ENDS) {
- cout << "+" << endl;
- }
- }
- }
- char* inputFileText() {
- ifstream fin("input.txt", ios::binary);
- char* text;
- if (!fin)
- return inputFileText();
- else
- {
- fin.seekg(0, ios::end);
- int length = fin.tellg();
- char* text = new char[length + 2];
- fin.seekg(0, ios::beg);
- fin.read(text, length);
- text[length] = ' ';
- text[length + 1] = '\0';
- return text;
- }
- }
- int main()
- {
- setlocale(LC_ALL, "Russian");
- char *text = inputFileText();
- vector<Lex>* lexems = LexAnalysis(text);
- SyntaxAnalysis(lexems);
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement