#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;
}
string s1;
string s2;
};
struct V2
{
V2(float px, float py)
{
x = px;
y = py;
}
float x;
float y;
float rotate = 0;
};
void lexicalanalysator();
char caseupper(char c);
bool hexletter(char c);
bool parser();
void calc();
void syntaxerror(int nr);
bool c1(string token);
bool c2(string token);
bool h6(string token);
bool D(string token);
vector<string> rows;
vector<Token> tokens;
vector<Command> commands;
const double pi = 3.1415926535897;
string outputColor = "#0000FF";
V2 position = V2(0, 0);
vector<string> outputVector;
int main()
{
lexicalanalysator();
if (!parser()) return 0;
/*for (int a = 0; a < commands.size(); a++)
{
cout << commands.at(a).s1 << " " << commands.at(a).s2 << endl;
}*/
calc();
}
void calc()
{
bool stateUP = true;
for (int a = 0; a < commands.size(); a++)
{
Command TI = commands.at(a);
float 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);
position.y += d*sin(pi*position.rotate / 180);
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);
position.y -= d*sin(pi*position.rotate / 180);
otemp += " " + to_string(position.x) + " " + to_string(position.y);
if(!stateUP) cout << otemp << endl;
}
}
}
bool parser()
{
vector<string> citations;
vector<bool> repactivated;
vector<int> repnumbers;
vector<int> oldCommandSize;
string expected = "none";
int repmult = 1;
bool singlerep = false;
for (int a = 0; a < tokens.size(); a++)
{
Token token = tokens.at(a);
if (expected == "none")
{
if (c1(token.s))
{
expected = ".";
commands.push_back(Command(token.s, "-1"));
}
else if (c2(token.s))
{
expected = "c2nr";
commands.push_back(Command(token.s, "-1"));
}
else if (token.s == "COLOR")
{
expected = "colorhex";
commands.push_back(Command(token.s, "-1"));
}
else if (token.s == "REP")
{
expected = "repnr";
}
else if (token.s == "\"" && repactivated.size() && repactivated.back())
{
singlerep = false;
expected = "none";
if (citations.back() == "\"")
{
int commandsSize = commands.size();
for (int b = 0; b < repnumbers.back() - 1; b++)
{
for (int c = oldCommandSize.back(); c < commandsSize; c++)
{
commands.push_back(commands.at(c));
}
}
if (oldCommandSize.back() == commandsSize)
{
syntaxerror(token.nr);
return false;
}
oldCommandSize.pop_back();
citations.pop_back();
repnumbers.pop_back();
repactivated.pop_back();
}
else
{
citations.back() = "\"";
}
}
else
{
syntaxerror(token.nr);
return false;
}
}
else
{
if (expected == ".")
{
expected = "none";
if (singlerep)
{
Command tempCommand = commands.at(commands.size() - 1);
for (int b = 0; b < repnumbers.back() - 1; b++)
{
commands.push_back(tempCommand);
}
singlerep = false;
oldCommandSize.pop_back();
citations.pop_back();
repnumbers.pop_back();
repactivated.pop_back();
}
}
else if (expected == "c2nr")
{
expected = ".";
if (D(token.s))
{
commands.back().s2 = token.s;
}
else
{
syntaxerror(token.nr);
return false;
}
}
else if (expected == "colorhex")
{
expected = ".";
if (h6(token.s))
{
commands.back().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;
}
repactivated.push_back(true);
repnumbers.push_back(repmult);
citations.push_back("");
oldCommandSize.push_back(commands.size());
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