dawrehxyz icon

TreeS2Commented

dawrehxyz | PRO | 11/18/16 12:44:25 PM UTC | 0 ⭐ | 287 👁️ | Never ⏰ | []
C++ |

10.62 KB

|

None

|

0 👍

/

0 👎

/*
    Av :
        Dawood Rehman 960109-4114
        Ramtin Javanmardi 950922-5075
*/
 
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <regex>
#include <algorithm>
 
using namespace std;
 
struct Token
{
    Token(int n, string c)
    {
        s = c;
        nr = n;
    }
    string s;
    int nr;
};
 
struct Command
{
    Command(string p1, string p2)
    {
        s1 = p1;
        s2 = p2;
        next = NULL;
        branch = NULL;
    }
    string s1;
    string s2;
    Command *next;
    Command *branch;
};
 
struct V2
{
    V2(double px, double py)
    {
        x = px;
        y = py;
    }
    double x;
    double y;
    int rotate = 0;
};
 
// lexicalanalysator is used for tokenizing
void lexicalanalysator();
// caseupper is used for turning all letters to uppercase
char caseupper(char c);
// hexletter checks wheter a given character is a hexadecimal number
bool hexletter(char c);
// parser is used for parsing and checking the grammar
bool parser();
// calc is used for calculating the line segments and printing them out
void calc(Command *ptr);
// syntaxerror prints syntaxerror on the given row
void syntaxerror(int nr);
// c1, c2, h6 and D are used for checking whether a token is valid or not.
// For en example, c1 checks if a token is "UP" or "DOWN".
bool c1(string token);
bool c2(string token);
bool h6(string token);
bool D(string token);
 
vector<string> rows;
vector<Token> tokens;
vector<Command*> branchJumpBack;
Command *commandTree = new Command("-1", "-1");
Command *commandTreePtr = commandTree;
 
const double pi = 3.1415926535897;
string outputColor = "#0000FF";
V2 position = V2(0, 0);
vector<string> outputVector;
 
int main()
{
    lexicalanalysator();
    if (!parser()) return 0;
    calc(commandTreePtr);
}
 
void calc(Command *ptr)
{
    static bool stateUP = true;
 
    if (ptr == NULL)
        return;
    else if (ptr->s1 == "-1")
        return;
 
    Command TI = *ptr;
    double d = atoi(TI.s2.c_str());
    if (TI.s1 == "DOWN") stateUP = false;
    else if (TI.s1 == "UP") stateUP = true;
    else if (TI.s1 == "COLOR") outputColor = TI.s2;
    else if (TI.s1 == "LEFT") position.rotate += d;
    else if (TI.s1 == "RIGHT") position.rotate -= d;
    else if (TI.s1 == "FORW")
    {
        string otemp = "";
        otemp += outputColor + " " + to_string(position.x) + " " + to_string(position.y);
        position.x += d*cos(pi*position.rotate / 180.0);
        position.y += d*sin(pi*position.rotate / 180.0);
        otemp += " " + to_string(position.x) + " " + to_string(position.y);
        if (!stateUP) cout << otemp << endl;
    }
    else if (TI.s1 == "BACK")
    {
        string otemp = "";
        otemp += outputColor + " " + to_string(position.x) + " " + to_string(position.y);
        position.x -= d*cos(pi*position.rotate / 180.0);
        position.y -= d*sin(pi*position.rotate / 180.0);
        otemp += " " + to_string(position.x) + " " + to_string(position.y);
        if (!stateUP) cout << otemp << endl;
    }
 
    if (ptr->s1 == "REP")
    {
        for (int a = 0; a < atoi((ptr->s2).c_str()); a++)
        {
            calc(ptr->branch);
        }
    }
 
    calc(ptr->next);
}
 
bool parser()
{
    vector<string> citations;
    vector<bool> repactivated;
    string expected = "none";
    bool singlerep = false;
    bool branch = false;
    bool done = false;
    bool noCommand = false;
    int repmult = 1;
    for (int a = 0; a < tokens.size(); a++)
    {
        if (done)
        {
            done = false;
            if (branch)
            {
                branch = false;
                commandTree->branch = new Command("-1", "-1");
                commandTree = commandTree->branch;
            }
            else
            {
                commandTree->next = new Command("-1", "-1");
                commandTree = commandTree->next;
            }
        }
        Token token = tokens.at(a);
        if (expected == "none")
        {
            if (c1(token.s))
            {
                expected = ".";
                commandTree->s1 = token.s;
            }
            else if (c2(token.s))
            {
                expected = "c2nr";
                commandTree->s1 = token.s;
            }
            else if (token.s == "COLOR")
            {
                expected = "colorhex";
                commandTree->s1 = token.s;
            }
            else if (token.s == "REP")
            {
                expected = "repnr";
                commandTree->s1 = token.s;
            }
            else if (token.s == "\"" && repactivated.size() && repactivated.back())
            {
                expected = "none";
                singlerep = false;
                if (citations.back() == "\"")
                {
                    if (noCommand)
                    {
                        syntaxerror(token.nr);
                        return false;
                    }
                    citations.pop_back();
                    repactivated.pop_back();
                    commandTree = branchJumpBack.back();
                    branchJumpBack.pop_back();
                    done = true;
                }
                else
                {
                    citations.back() = "\"";
                }
            }
            else
            {
                syntaxerror(token.nr);
                return false;
            }
        }
        else
        {
            if (expected == ".")
            {
                done = true;
                noCommand = false;
                expected = "none";
                if (singlerep)
                {
                    singlerep = false;
                    citations.pop_back();
                    repactivated.pop_back();
                    commandTree = branchJumpBack.back();
                    branchJumpBack.pop_back();
                }
            }
            else if (expected == "c2nr")
            {
                expected = ".";
                if (D(token.s))
                {
                    commandTree->s2 = token.s;
                }
                else
                {
                    syntaxerror(token.nr);
                    return false;
                }
            }
            else if (expected == "colorhex")
            {
                expected = ".";
                if (h6(token.s))
                {
                    commandTree->s2 = token.s;
                }
                else
                {
                    syntaxerror(token.nr);
                    return false;
                }
            }
            else if (expected == "repnr")
            {
                expected = "none";
                if (D(token.s))
                {
 
                    repmult *= atoi(token.s.c_str());
                    if (tokens.at(a + 1).s == "REP")
                    {
                        continue;
                    }
 
                    branch = true;
                    done = true;
                    noCommand = true;
 
                    commandTree->s2 = to_string(repmult);
                    branchJumpBack.push_back(commandTree);
 
                    repactivated.push_back(true);
                    citations.push_back("");
 
                    singlerep = true;
                    repmult = 1;
                }
                else
                {
                    syntaxerror(token.nr);
                    return false;
                }
            }
        }
    }
    if (repactivated.size())
    {
        syntaxerror(tokens.at(tokens.size() - 1).nr);
        return false;
    }
    if (expected != "none")
    {
        syntaxerror(tokens.at(tokens.size() - 1).nr);
        return false;
    }
 
    return true;
}
 
bool c1(string token)
{
    if (token == "UP" || token == "DOWN")
        return true;
    return false;
}
 
bool c2(string token)
{
    if (token == "FORW" || token == "BACK" || token == "LEFT" || token == "RIGHT")
        return true;
    return false;
}
 
bool h6(string token)
{
    if (token.length() == 7 && token[0] == '#' && hexletter(token[1]) && hexletter(token[2]) && hexletter(token[3]) && hexletter(token[4]) && hexletter(token[5]) && hexletter(token[6]))
        return true;
    return false;
}
 
bool D(string token)
{
    if (!(token[0] > 48 && token[0] < 58))
        return false;
    for (int a = 0; a < token.length(); a++)
    {
        if (!(token[a] > 47 && token[a] < 58))
            return false;
    }
    return true;
}
 
bool hexletter(char c)
{
    if ((c > 47 && c < 58) || (c > 64 && c < 71))
        return true;
    return false;
}
 
void lexicalanalysator()
{
    string row;
    string word;
 
    ios_base::sync_with_stdio(false);
    while (getline(cin, row)) rows.push_back(row);
 
    for (int a = 0; a < rows.size(); a++)
    {
        bool bc = false;
        row = rows.at(a);
        word = "";
        for (int b = 0; b < row.length(); b++)
        {
            char c = row.at(b);
 
            if (c == '%')
            {
                if (bc)
                {
                    bc = false;
                    tokens.push_back(Token(a + 1, word));
                }
                break;
            }
            else if (c == ' ' || c == '\t')
            {
                if (bc)
                {
                    bc = false;
                    tokens.push_back(Token(a + 1, word));
                }
                word = "";
                continue;
            }
            else if (c == '.')
            {
                if (word != "")
                    tokens.push_back(Token(a + 1, word));
                tokens.push_back(Token(a + 1, "."));
                word = "";
                bc = false;
                continue;
            }
            else if (word == "\"")
            {
                if (bc)
                {
                    bc = false;
                    tokens.push_back(Token(a + 1, word));
                }
                word = "";
            }
 
            bc = true;
            word += caseupper(row.at(b));
 
            if (b == row.length() - 1) tokens.push_back(Token(a + 1, word));
        }
    }
 
    //for (int a = 0; a < tokens.size(); a++)
    //cout << tokens.at(a).nr << " " << tokens.at(a).s << endl;
}
 
char caseupper(char c)
{
    if (c > 96 && c < 123)
        return char(c - 32);
    return c;
}
 
void syntaxerror(int nr)
{
    cout << "syntaxfel på rad " << nr << endl;
}

Comments