Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ConsoleApplication1.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <vector>
- #include <set>
- #include <map>
- #include <stack>
- void prog();
- void expression();
- using namespace std;
- fstream fin("test.txt", ios::in);
- struct Token {
- string token;
- int type;
- Token(string tk, int tp) {
- token = tk;
- type = tp;
- }
- };
- struct tcur {
- string type;
- string current;
- };
- struct list {
- map<string, vector<pair <string, string>>> tid;
- list *up = NULL;
- list *down = NULL;
- };
- list *tids = NULL;
- stack <string> op;
- stack <string> sign;
- bool notif = false;
- bool ifb = false;
- bool whileb = false;
- set<char> operation_chrs = { '+', '*', '-', '/', '=', '<', '>', '!', ':' };
- set<string> operations = { "++", "--", "+=", "-=", "+", "*", "-", "/",
- "=", "//", "/*", "*/", "==", ">=", "<=", "!=", ":" };
- set<string> res_words = { "true", "false", "int", "bool", "string", "break", "continue", "switch", "if", "else", "for" };
- //POLIZ//
- stack <string> st;
- vector <string> poliz;
- /////////
- Token get_token(fstream& fin) {
- int state = 0;
- char c;
- string token = "";
- bool long_com = false;
- bool short_com = false;
- while (fin.get(c)) {
- if (state != 6 && token == "/*") {
- token = "";
- state = 0;
- long_com = true;
- short_com = false;
- }
- if (state != 6 && long_com && token == "*/") {
- token = "";
- state = 0;
- long_com = false;
- continue;
- }
- if (state != 6 && !long_com && token == "//") {
- token = "";
- state = 0;
- short_com = true;
- continue;
- }
- if (state != 6 && short_com && c == '\n') {
- token = "";
- state = 0;
- short_com = false;
- continue;
- }
- if (!long_com && !short_com && c == '"') {
- if (state != 6) {
- if (!short_com && !long_com && token.size()) {
- long long pos = fin.tellg();
- fin.seekg(pos - 1);
- int _state = state;
- state = 6;
- return Token(token, _state);
- }
- token = "";
- token += c;
- state = 6;
- continue;
- }
- else {
- token += c;
- int _state = state;
- state = 0;
- return Token(token, _state);
- }
- }
- if (state == 6) {
- token += c;
- continue;
- }
- if (c == ' ' || c == '\n' || c == '\t') {
- if (!short_com && !long_com && token.size()) {
- long long pos = fin.tellg();
- fin.seekg(pos - 1);
- int _state = state;
- state = 0;
- return Token(token, _state);
- }
- token = "";
- state = 0;
- continue;
- }
- if (c == ',' || c == ';') {
- if (!short_com && !long_com && token.size()) {
- long long pos = fin.tellg();
- fin.seekg(pos - 1);
- int _state = state;
- state = 5;
- return Token(token, _state);
- }
- token = "";
- token += c;
- state = 5;
- continue;
- }
- if (c == '}' || c == '{' || c == '(' || c == ')') {
- if (!short_com && !long_com && token.size()) {
- long long pos = fin.tellg();
- fin.seekg(pos - 1);
- int _state = state;
- state = 3;
- return Token(token, _state);
- }
- token = "";
- token += c;
- state = 3;
- continue;
- }
- if (state == 7)
- continue;
- if (operation_chrs.count(c)) {
- if (state != 4) {
- if (!short_com && !long_com && token.size()) {
- long long pos = fin.tellg();
- fin.seekg(pos - 1);
- int _state = state;
- state = 4;
- return Token(token, _state);
- }
- token = "";
- token += c;
- state = 4;
- continue;
- }
- else {
- if (operations.count(token + c))
- token += c;
- else {
- int _state = state;
- state = 4;
- long long pos = fin.tellg();
- fin.seekg(pos - 1);
- return Token(token, _state);
- }
- continue;
- }
- }
- if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '_') {
- if (state != 1) {
- if (!short_com && !long_com && token.size()) {
- long long pos = fin.tellg();
- fin.seekg(pos - 1);
- int _state = state;
- state = 1;
- return Token(token, _state);
- }
- token = "";
- token += c;
- state = 1;
- continue;
- }
- else {
- token += c;
- continue;
- }
- }
- if ('0' <= c && c <= '9') {
- if (state == 1 || state == 2) {
- token += c;
- continue;
- }
- else {
- if (!short_com && !long_com && token.size()) {
- long long pos = fin.tellg();
- fin.seekg(pos - 1);
- int _state = state;
- state = 2;
- return Token(token, _state);
- }
- token = "";
- token += c;
- state = 2;
- continue;
- }
- }
- if (c == '.') {
- if (state == 2) {
- token += c;
- }
- else {
- if (!short_com && !long_com && token.size()) {
- long long pos = fin.tellg();
- fin.seekg(pos - 1);
- int _state = state;
- state = 0;
- return Token(token, _state);
- }
- state = 0;
- return Token(".", 5);
- }
- }
- }
- if (!short_com && !long_com && token.size())
- return Token(token, state);
- else
- return Token("", -1);
- }
- // states
- // 1 - names
- // 2 - numbers
- // 3 - brackets
- // 4 - operaton
- // 5 - punkt
- // 6 - string
- Token lex("", -1);
- string prevt = "";
- void get_lexem() {
- prevt = lex.token;
- lex = get_token(fin);
- cout << '[' << lex.token << ']' << " - " << lex.type << endl;
- /*if (lex.token == ";")
- {
- while (!op.empty())
- {
- op.pop();
- }
- }*/
- }
- // Функции семантического анализатора
- void listout() // выводить все переменные из тидов
- {
- list *copy;
- copy = tids;
- bool check = false;
- int lvl = 1;
- while (copy != NULL)
- {
- map<string, vector <pair <string, string>>> ch;
- ch = copy->tid;
- for (auto h : ch)
- {
- cout << h.first << " ";
- //<< " " << h.second.first << " " << h.second.current << " " << lvl << endl;
- for (int i = 0; i < h.second.size(); i++)
- {
- cout << h.second[i].first << " " << h.second[i].second << endl;
- }
- }
- copy = copy->up;
- lvl++;
- }
- }
- void create_tid() // создает новый тид
- {
- if (!tids) tids = new list;
- else
- {
- tids->down = new list;
- tids->down->up = tids;
- tids = tids->down;
- }
- }
- void go_up() // удаляет тид и перносит указатель
- {
- if (tids->up == NULL)
- {
- delete tids;
- tids = NULL;
- return;
- }
- else
- {
- tids = tids->up;
- list *tmp = tids->down;
- tids->down = NULL;
- delete tmp;
- }
- }
- void push_id(string name, string type, string cur)
- {
- list *copy = tids;
- if (res_words.count(name) == 0)
- {
- list *copy;
- copy = tids;
- bool check = false;
- map<string, vector <pair <string, string>>> ch;
- ch = copy->tid;
- if (ch.count(name) != 0)
- {
- check = true;
- }
- if (check) throw "The name is already exist";
- else
- {
- tids->tid.emplace(name, make_pair(type, cur)); /// не чисто
- }
- }
- }
- bool exist(string name) // проверяет существование имени в тидах
- {
- list *copy;
- copy = tids;
- bool check = false;
- while (copy != NULL)
- {
- map<string, vector <pair <string, string>>> ch;
- ch = copy->tid;
- if (ch.count(name) != 0)
- {
- check = true;
- }
- copy = copy->up;
- }
- return check;
- }
- void check_id(string name)
- {
- if (res_words.count(name) == 0)
- {
- //cout << name << endl;
- list *copy;
- copy = tids;
- bool check = false;
- while (copy != NULL)
- {
- map<string, vector <pair <string, string>>> ch;
- ch = copy->tid;
- /*for (auto h : ch)
- {
- cout << h.first << " " << h.second << " ";
- }
- cout << endl;*/
- if (ch.count(name) != 0)
- {
- check = true;
- }
- copy = copy->up;
- }
- if (!check) throw("Out of range or the name do not exist");
- }
- else throw "You cannot use reserved words to name";
- }
- void pushop(string type)
- {
- //cout << "TYPE OF PUSHING ELEMENT " << type << endl;
- op.push(type);
- }
- void checkop()
- {
- //cout << "ENTERED " << op.size() << " " << sign.size() << " " << sign.top() << endl;
- stack<string> check = op;
- cout << endl;
- string n1, n2, n3;
- if (op.size() >= 2 && sign.size() >= 1)
- {
- n1 = op.top();
- op.pop();
- n2 = op.top();
- op.pop();
- n3 = sign.top();
- sign.pop();
- if (n1 == "int" && n2 == "int")
- {
- if (n3 != "+" && n3 != "-" && n3 != "/" && n3 != "*" && n3 != ">" && n3 != ">=" && n3 != "<" && n3 != "<=" && n3 != "==" && n3 != "!=")
- throw "Bad action with int";
- if(n3 == "+" || n3 == "-" || n3 == "*" || n3 == "/") op.push("int");
- else op.push("bool");
- }
- else if (n1 == "string" && n2 == "string")
- {
- if (n3 != "+" && n3 != "==" && n3 != "!=" && n3 != ">" && n3 != ">=" && n3 != "<" && n3 != "<=")
- throw "Bad action with string";
- op.push("string");
- }
- else if (n1 == "bool" && n2 == "bool")
- {
- if (n3 != "==" && n3 != "!=" && n3 != "or" && n3 != "and")
- throw "Bad action with bool";
- op.push("bool");
- }
- else throw("Conflict of types");
- }
- }
- void check_id_2(string name, string type)
- {
- list *copy = tids;
- bool check = true;
- while (copy->up != NULL)
- {
- map<string, vector <pair <string, string>>> ch;
- ch = copy->tid;
- if (ch.count(name) != 0)
- {
- op.push(type);
- check = false;
- }
- copy = copy->up;
- }
- if (check) throw "Name do not exist";
- }
- void checkbool()
- {
- if (op.top() != "bool")
- {
- throw "Error of type in brackets";
- }
- }
- string find(string name) //find name in tids. returns type of name
- {
- list *copy = tids;
- string type = "";
- while (copy != NULL)
- {
- map<string, vector <pair <string, string>>> ch;
- ch = copy->tid;
- if (ch.count(name) != 0)
- {
- type = ch[name][0].first;
- }
- copy = copy->up;
- }
- return type;
- }
- // Функции грамматики
- void constant() {
- if (lex.type == 2) {// numbers
- pushop("int");
- get_lexem();
- return;
- }
- if (lex.type == 6) { // string
- pushop("string");
- get_lexem();
- return;
- }
- if (lex.token == "true" || lex.token == "false") { // bool
- pushop("bool");
- if (notif) notif = false;
- //cout << endl << op.top() << endl;
- get_lexem();
- return;
- }
- throw "constant was expected /1";
- }
- bool label() {
- if (lex.token == "state") {
- get_lexem();
- constant();
- if (lex.token != ":")
- throw "':' was expected";
- get_lexem();
- return true;
- }
- return false;
- }
- bool swtch() {
- if (lex.token == "switch") {
- get_lexem();
- if (lex.type != 1)
- throw "name was expected";
- get_lexem();
- if (lex.token != ":")
- throw "':' was expected";
- get_lexem();
- return true;
- }
- return false;
- }
- bool brk() {
- if (lex.token == "break") {
- get_lexem();
- if (lex.token != ";")
- throw "';' was expected";
- get_lexem();
- return true;
- }
- return false;
- }
- bool cnt() {
- if (lex.token == "continue") {
- get_lexem();
- if (lex.token != ";")
- throw "';' was expected";
- get_lexem();
- return true;
- }
- return false;
- }
- void operand() {
- if (lex.type == 1) {
- cout << "operand: " << lex.token << endl;
- string name = lex.token;
- if (res_words.count(name) == 0)
- {
- if (!exist(name))
- {
- throw "Name do not exist";
- }
- string type = find(name); // тут тип переменной
- pushop(type); // кинули в стэк тип переменной
- }
- else if (notif || ifb || whileb)
- {
- constant();
- return;
- }
- get_lexem();
- return;
- }
- constant();
- }
- void exp0() {
- if (lex.token == "(") {
- get_lexem();
- expression();
- if (lex.token != ")")
- throw "')' was expected";
- get_lexem();
- }
- else {
- operand();
- }
- }
- void exp1() {
- exp0();
- if (lex.token == "*" || lex.token == "/" || lex.token == "%") {
- sign.push(lex.token);
- get_lexem();
- exp0();
- checkop();//func
- }
- }
- void exp2() {
- exp1();
- if (lex.token == "+" || lex.token == "-") {
- sign.push(lex.token);
- get_lexem();
- exp2();
- checkop();
- }
- }
- void exp3() {
- exp2();
- if (lex.token == "<" || lex.token == ">" || lex.token == "<=" || lex.token == ">=") {
- sign.push(lex.token);
- get_lexem();
- exp3();
- checkop();
- }
- }
- void exp4() {
- exp3();
- if (lex.token == "==" || lex.token == "!=") {
- sign.push(lex.token);
- get_lexem();
- exp4();
- checkop();
- }
- }
- void exp5() {
- exp4();
- if (lex.token == "and") {
- sign.push(lex.token);
- get_lexem();
- exp5();
- checkop();
- }
- }
- void expression() {
- exp5();
- if (lex.token == "or") {
- sign.push(lex.token);
- get_lexem();
- expression();
- checkop();
- }
- }
- bool assign() {
- if (lex.type == 1) {
- if (!exist(lex.token))
- throw "Out of range";
- get_lexem();
- if (lex.token == "=") {
- get_lexem();
- expression();
- }
- else if (lex.token == "++" || lex.token == "--")
- get_lexem();
- else
- throw "'++' or '--' or '=' was expected";
- if (lex.token != ";")
- throw "';' was expected";
- get_lexem();
- return true;
- }
- else {
- return false;
- }
- }
- int hash = 0;
- bool definition() {
- if (lex.token == "int" || lex.token == "string" || lex.token == "bool") {
- string type = lex.token;
- get_lexem();
- if (lex.type != 1)
- throw "name was expected";
- string name = lex.token;
- cout << "operand: " << name << endl;
- //cout << endl << type << " " << name << endl;
- push_id(name, type, "");
- cout << endl << "NAMES IN TIDS: " << endl;
- listout();
- cout << "END" << endl << endl;
- get_lexem();
- if (lex.token != "=")
- throw "'=' was expected";
- get_lexem();
- if (lex.token == "true" || lex.token == "false")
- {
- notif = true;
- }
- expression();
- if (lex.token != ";")
- throw "';' was expected";
- if (type != op.top())
- throw "Conflict of types";
- while (!op.empty()) op.pop();
- get_lexem();
- cout << "___________" << endl;
- return true;
- }
- else {
- return false;
- }
- }
- void els() {
- if (lex.token == "else") {
- get_lexem();
- if (lex.token != "{")
- throw "'{' was expected";
- get_lexem();
- prog();
- if (lex.token != "}")
- throw "'}' was expected";
- get_lexem();
- }
- }
- bool condition() {
- if (lex.token == "if") {
- ifb = true;
- get_lexem();
- if (lex.token != "(")
- throw "'(' was expected";
- get_lexem();
- expression();
- ifb = false;
- if (op.top() != "bool")
- {
- throw "Error of type in if's brackets /3";
- }
- while (!op.empty()) op.pop();
- if (lex.token != ")")
- throw "')' was expected";
- get_lexem();
- if (lex.token != "{")
- throw "'{' was expected";
- get_lexem();
- prog();
- if (lex.token != "}")
- throw "'}' was expected";
- get_lexem();
- els();
- return true;
- }
- else {
- return false;
- }
- }
- bool loop() {
- if (lex.token == "while") {
- whileb = true;
- get_lexem();
- if (lex.token != "(")
- throw "'(' was expected";
- get_lexem();
- expression();
- if (op.top() != "bool")
- {
- throw "Error of type in while's brackets /4";
- }
- whileb = false;
- while (!op.empty()) op.pop();
- if (lex.token != ")")
- throw "')' was expected";
- get_lexem();
- if (lex.token != "{")
- throw "'{' was expected";
- get_lexem();
- prog();
- if (lex.token != "}")
- throw "'}' was expected";
- get_lexem();
- return true;
- }
- else {
- return false;
- }
- }
- void prog() {
- create_tid();
- while (true) {
- if (definition())
- continue;
- if (loop())
- continue;
- if (condition())
- continue;
- if (label())
- continue;
- if (brk())
- continue;
- if (cnt())
- continue;
- if (swtch())
- continue;
- if (assign())
- continue;
- break;
- }
- go_up();
- }
- // =================
- int main() {
- // А так мы его запускаем
- get_lexem();
- try {
- prog();
- fin.close();
- cout << "SUCCESS" << endl;
- }
- catch (char const* error) {
- fin.close();
- cout << "ERROR: " << error << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement