Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <vector>
- using namespace std;
- string keyWord[4] = { "if", "then", "else", "end" };
- string special[6] = { ">", "<", "<>", "<=", ">=", "=" };
- enum State {
- S,
- Ai,
- Id,
- Sp,
- Op,
- Co,
- Unk
- };
- enum LexType { Keyword, SpecialSymbol, Constant, Ident, UnknownToken };
- struct Lex
- {
- LexType type;
- char* str;
- };
- const State matrix[7][6] =
- {
- // a-Z 0-9 <=> +/-
- Ai, Co, Sp, Op, S, Unk, // S
- Ai, Id, Unk, Unk, S, Unk, // ключевое слово
- Id, Id, Unk, Unk, S, Unk, // идетификатор
- Unk, Unk, Sp, Unk, S, Unk, // специальный символ
- Unk, Unk, Unk, Unk, S, Unk, // оператор
- Unk, Co, Unk, Unk, S, Unk, // константа
- Unk, Unk, Unk, Unk, S, Unk, // E
- };
- int collumn(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 2;
- if (a == '=')
- return 2;
- if (a == '+' || a == '-')
- return 3;
- if (a == ' ' || a == '\t' || a == '\n' || a == '\r' || a == '\0')
- return 4;
- return 5;
- }
- 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 == Ai)
- {
- lexem.type = Ident;
- for (int i = 0; i < 6; ++i)
- if (equals(keyWord[i], lex))
- lexem.type = Keyword;
- }
- else if (state == Sp) {
- lexem.type = UnknownToken;
- for (int i = 0; i < 6; ++i)
- if (equals(special[i], lex))
- lexem.type = SpecialSymbol;
- }
- else if (state == Op)
- {
- lexem.type = SpecialSymbol;
- }
- 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 = matrix[curr_state][collumn(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;
- }
- void print(vector<Lex>* v, LexType p)
- {
- for (int i = 0; i < v->size(); ++i)
- if (p == v->at(i).type)
- cout << v->at(i).str << ' ';
- cout << endl;
- }
- int main()
- {
- setlocale(LC_ALL, "Russian");
- ifstream ifs("input.txt", ios::binary); //поток ввода, binary - без форматирования
- if (!ifs.is_open())
- return 0;
- ifs.seekg(0, ios::end);
- int length = ifs.tellg(); //получаем текущую позицию курсора
- char* str = new char[length + 2]; //выделяем память под входные данные, оставляем два символа для пробела и \0
- ifs.seekg(0, ios::beg); //перемещение указателя на начало
- ifs.read(str, length); //читаем length символов в строку str
- str[length] = ' ';
- str[length + 1] = '\0';
- vector<Lex>* v = LexAnalysis(str);
- delete[] str;
- ifs.close();
- if (!v->size())
- {
- cout << "Файл пуст";
- }
- else
- {
- for (int i = 0; i < v->size(); ++i) {
- cout << v->at(i).str << "\t- ";
- if (v->at(i).type == Ident)
- cout << "Идентификатор";
- else if (v->at(i).type == Constant)
- cout << "Константа";
- else if (v->at(i).type == SpecialSymbol)
- cout << "Специальный символ";
- else if (v->at(i).type == Keyword)
- cout << "Ключевое слово";
- else if (v->at(i).type == UnknownToken)
- cout << "Некорректная лексема";
- cout << endl;
- } // таблица лексем
- cout << "Идентификаторы:" << endl;
- print(v, Ident);
- cout << "Константы:" << endl;
- print(v, Constant);
- for (int i = 0; i < v->size(); ++i)
- delete[] v->at(i).str; //удаляем строки из памяти //очищаем вектор
- }
- delete v; //удаляем указатель на вектор
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement