#include #include #include #include #include #include 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; }; void lexicalanalysator(); char caseupper(char c); bool hexletter(char c); bool parser(); void calc(Command *ptr); void syntaxerror(int nr); bool c1(string token); bool c2(string token); bool h6(string token); bool D(string token); vector rows; vector tokens; vector branchJumpBack; Command *commandTree = new Command("-1", "-1"); Command *commandTreePtr = commandTree; const double pi = 3.1415926535897; string outputColor = "#0000FF"; V2 position = V2(0, 0); vector outputVector; int main() { /*Command *tempCommand = new Command("-1", "-1"); for (int a = 0; a < 5; a++) { tempCommand = new Command(to_string(a), to_string(a)); current->next = tempCommand; current = current->next; }*/ lexicalanalysator(); if (!parser()) return 0; /*for (int a = 0; a < commands.size(); a++) { cout << commands.at(a).s1 << " " << commands.at(a).s2 << endl; }*/ 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 citations; vector 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; }