Untitled

mail@pastecode.io avatar
unknown
c_cpp
4 years ago
6.2 kB
3
Indexable
Never
#include <iostream>
#include "fstream"
#include <queue>
#include <algorithm>
using namespace std;


/// 1. de lungime oarecare nedepasind 250 caractere
/// 2. separat pentru identificatori si constante
/// 3. tabel arbore binar de cautare (ordine lexicografica)

struct node
{
    pair <char*,int> key;
    struct node *left, *right;
};

vector<string> keywords;
struct node *ids = NULL;
struct node *consts = NULL;
vector<pair<int, char*>> fip;
bool noMistakes = true;


// A utility function to create a new BST node
struct node *newNode(pair <char*,int> item)
{
    auto *temp =  (struct node *)malloc(sizeof(struct node));
    temp->key = item;
    temp->left = temp->right = nullptr;
    return temp;
}

// Print BST Inorder
void inorder(struct node *root)
{
    if (root != nullptr)
    {
        inorder(root->left);
        printf("%d \n", root->key);
        inorder(root->right);
    }
}

// Print BST line by line
void printLevelOrder(node *root)
{
    if (root == nullptr) return;

    queue<node *> q;

    q.push(root);

    while (!q.empty())
    {
        int nodeCount = q.size();

        while (nodeCount > 0)
        {
            node *node = q.front();
            cout << node->key.first << "," << node->key.second << " ";
            q.pop();
            if (node->left != nullptr)
                q.push(node->left);
            if (node->right != nullptr)
                q.push(node->right);
            nodeCount--;
        }
        cout << endl;
    }
}

// Insert a new node in the BST
struct node* insert(struct node* node, pair <char*,int> key)
{
    // if BST is empty case
    if (node == nullptr) return newNode(key);

    if (strcmp(key.first,node->key.first) < 0)
        node->left  = insert(node->left, key);
    else if (strcmp(key.first,node->key.first) > 0)
        node->right = insert(node->right, key);

    return node;
}

void readKeywords(const char *fileName ) {
    ifstream f(fileName);
    string line;

    while (getline(f, line)) {
        keywords.push_back(line);
    }
    f.close();
}

// Function to check if element is ID or Const or error
int checkIfIdOrConst(string element) {
    int letters = 0, digits = 0, symbols = 0;
    for(char i : element) {
        if(isdigit(i)) {
            digits++;
        } else if(isalpha(i)) {
            letters++;
        }
        else{
            symbols++;
        }
    }
    // Const
    if(digits == element.size()){
        return 1;
    }
    // ID
    else if(letters + digits == element.size() && isalpha(element[0])){
        return 2;
    }
    // Error
    return 3;
}

// Function to traverse the tree in preorder and check if the given node exists in it
struct node* ifNodeExists(struct node* node, pair <char*,int> key) {
    if (node == nullptr)
        return nullptr;

    if (strcmp(node->key.first, key.first) == 0)
        return node;

    /* then recur on left sutree */
    struct node* res1 = ifNodeExists(node->left, key);
    // node found, no need to look further
    if(res1)
        return res1;

    /* node is not found in left,
    so recur on right subtree */
    struct node* res2 = ifNodeExists(node->right, key);

    return res2;
}

// Function to print index of k element in fip vector
int getIndex(char* k)
{
    for (int i = 0;i<keywords.size();i++)
    {
        if(keywords[i] == k){
            return i;
        }
    }
    return -1;
}

void readInputAtoms(const char *fileName) {
    ifstream f(fileName);
    string line;

    int codIds = 0, codConsts = 100;

    while (getline(f, line)) {
        if (find(keywords.begin(), keywords.end(), line) == keywords.end())
        {
            int type = checkIfIdOrConst(line);
            // ID
            if(type == 2) {
               if(line.size() <= 250) {
                   char *chr = strdup(line.c_str());
                   struct node* potentialNode = ifNodeExists(ids, make_pair(chr, -1));
                   if (potentialNode == nullptr) {
                       codIds++;
                       string numStr = std::to_string(codIds);
                       fip.emplace_back(1,strdup(numStr.c_str()));
                       if (ids == nullptr) {
                           ids = insert(ids, make_pair(chr, codIds));
                       } else
                           insert(ids, make_pair(chr, codIds));
                   } else {
                       string numStr = std::to_string(potentialNode->key.second);
                       fip.emplace_back(1,strdup(numStr.c_str()));
                   }
               } else{
                   cout << "Maximum id length is 255 characters" << line;
               }
           // Const
            } else if(type == 1) {
                char* chr = strdup(line.c_str());
                struct node* potentialNode = ifNodeExists(consts, make_pair(chr, -1));
                if(potentialNode == nullptr) {
                    codConsts ++;
                    string numStr = std::to_string(codConsts);
                    fip.emplace_back(2,strdup(numStr.c_str()));
                    if(consts == nullptr){
                        consts = insert(consts,make_pair(chr,codConsts));
                    }
                    else
                        insert(consts,make_pair(chr,codConsts));
                } else {
                    string numStr = std::to_string(potentialNode->key.second);
                    fip.emplace_back(2,strdup(numStr.c_str()));
                }
            } else {
                noMistakes = false;
                cout << "Error at:" << line;
            }
        } else {
            char* chr = strdup(line.c_str());
            string numStr = "-";
            fip.emplace_back(getIndex(chr) + 3,strdup(numStr.c_str()));
        }
    }
    f.close();
}

int main() {

    readKeywords("keywords.txt");
    readInputAtoms("atomInput.in");


    /// PRINTS
    if (noMistakes) {
        cout << "FIP" << endl;

        for (const auto &p : fip) {
            std::cout << p.first << ", " << p.second << std::endl;
        }

        cout << endl << "TS";

        cout << endl << "Ids" << endl;
        printLevelOrder(ids);

        cout << endl << "Constants" << endl;
        printLevelOrder(consts);
    }

    return 0;
}