%{ #include #include #include #include #include #include #include #include #define INFILE_ERROR 1 #define OUTFILE_ERROR 2 extern int yylineno; extern FILE *yyin; extern FILE *yyout; int yylex(); void yyerror(const char *msg, ...); struct StackElement { std::string value; enum { INT, VAR } type; }; struct SymbolInfo { std::string type; int memoryLocation; }; std::map symbolTable; int memoryCounter = 0; std::stack expressionsStack; FILE *tripletFile; int tempVarCounter = 0; std::vector asmCode; bool isNumber(const std::string& s) { if (s.empty()) return false; size_t start = 0; if (s[0] == '-') start = 1; for (size_t i = start; i < s.length(); i++) { if (!isdigit(s[i])) return false; } return true; } void addSymbol(const std::string& name, const std::string& type) { if (symbolTable.find(name) == symbolTable.end()) { SymbolInfo info; info.type = type; info.memoryLocation = memoryCounter++; symbolTable[name] = info; } } // ASM std::string generateLoad(const std::string& reg, const std::string& value) { if (isNumber(value)) { return "li " + reg + ", " + value; } else { return "lw " + reg + ", " + value; } } void generateAsm(const std::string& result, const std::string& arg1, const std::string& arg2, const std::string& op) { if (op == "=" && arg2.empty()) { asmCode.push_back(generateLoad("$t0", arg1)); asmCode.push_back("sw $t0, " + result); } else { asmCode.push_back(generateLoad("$t0", arg1)); asmCode.push_back(generateLoad("$t1", arg2)); std::string asmOp; if (op == "+") asmOp = "add"; else if (op == "-") asmOp = "sub"; else if (op == "*") asmOp = "mul"; else if (op == "/") asmOp = "div"; asmCode.push_back(asmOp + " $t2, $t0, $t1"); asmCode.push_back("sw $t2, " + result); } } void writeDataSection(FILE* out) { fprintf(out, ".data\n"); for (auto& pair : symbolTable) { fprintf(out, "%s: .word 0\n", pair.first.c_str()); } fprintf(out, "\n"); } void writeCodeSection(FILE* out) { fprintf(out, ".text\n"); fprintf(out, ".globl main\n"); fprintf(out, "main:\n"); for (const auto& line : asmCode) { fprintf(out, " %s\n", line.c_str()); } fprintf(out, "\n # Exit program\n"); fprintf(out, " li $v0, 10\n"); fprintf(out, " syscall\n"); } void saveSymbolTable() { FILE* symbolFile = fopen("symbols.txt", "w"); if (symbolFile) { for (auto& pair : symbolTable) { fprintf(symbolFile, "%s: type=%s, location=%d\n", pair.first.c_str(), pair.second.type.c_str(), pair.second.memoryLocation); } fclose(symbolFile); } } // triplets std::string generateTempVar() { std::string result = "result" + std::to_string(tempVarCounter++); addSymbol(result, "Int"); return result; } void writeTriplet(const std::string& result, const std::string& arg1, const std::string& arg2, const std::string& op) { fprintf(tripletFile, "%s= %s %s %s\n", result.c_str(), arg1.c_str(), arg2.c_str(), op.c_str()); generateAsm(result, arg1, arg2, op); } %} %union { char *text; int ival; } %token ID %token INT_LIT %token LET %token INT_TYPE %token SEMICOLON COLON %left '+' '-' %left '*' '/' %start program %% program : statement_list { printf("koniec\n"); } ; statement_list : statement | statement_list statement ; statement : variable_declaration { printf("Deklaracja zmiennej\n"); } | assignment { printf("Instrukcja przypisania\n"); } | expression SEMICOLON { printf("instrukcja\n"); if (!expressionsStack.empty()) { expressionsStack.pop(); } } ; variable_declaration : LET ID COLON INT_TYPE '=' expression SEMICOLON { printf("Deklaracja zmiennej: %s\n", $2); addSymbol(std::string($2), "Int"); if (!expressionsStack.empty()) { StackElement expression = expressionsStack.top(); expressionsStack.pop(); writeTriplet(std::string($2), expression.value, "", "="); } } ; assignment : ID '=' expression SEMICOLON { printf("Przypisanie do zmiennej: %s\n", $1); if (!expressionsStack.empty()) { StackElement expression = expressionsStack.top(); expressionsStack.pop(); writeTriplet(std::string($1), expression.value, "", "="); } } ; expression : expression '+' expression { printf("Wyrazenie z +\n"); StackElement rhs = expressionsStack.top(); expressionsStack.pop(); StackElement lhs = expressionsStack.top(); expressionsStack.pop(); std::string temp = generateTempVar(); writeTriplet(temp, lhs.value, rhs.value, "+"); StackElement element; element.value = temp; element.type = StackElement::VAR; expressionsStack.push(element); } | expression '-' expression { printf("Wyrazenie z -\n"); StackElement rhs = expressionsStack.top(); expressionsStack.pop(); StackElement lhs = expressionsStack.top(); expressionsStack.pop(); std::string temp = generateTempVar(); writeTriplet(temp, lhs.value, rhs.value, "-"); StackElement element; element.value = temp; element.type = StackElement::VAR; expressionsStack.push(element); } | expression '*' expression { printf("Wyrazenie z *\n"); StackElement rhs = expressionsStack.top(); expressionsStack.pop(); StackElement lhs = expressionsStack.top(); expressionsStack.pop(); std::string temp = generateTempVar(); writeTriplet(temp, lhs.value, rhs.value, "*"); StackElement element; element.value = temp; element.type = StackElement::VAR; expressionsStack.push(element); } | expression '/' expression { printf("Wyrazenie z /\n"); StackElement rhs = expressionsStack.top(); expressionsStack.pop(); StackElement lhs = expressionsStack.top(); expressionsStack.pop(); std::string temp = generateTempVar(); writeTriplet(temp, lhs.value, rhs.value, "/"); StackElement element; element.value = temp; element.type = StackElement::VAR; expressionsStack.push(element); } | '(' expression ')' { printf("Wyrazenie w nawiasach\n"); } | INT_LIT { printf("Literal calkowity: %d\n", $1); StackElement element; element.value = std::to_string($1); element.type = StackElement::INT; expressionsStack.push(element); } | ID { printf("Identyfikator: %s\n", $1); StackElement element; element.value = std::string($1); element.type = StackElement::VAR; expressionsStack.push(element); } ; %% int main(int argc, char *argv[]) { tripletFile = fopen("triplets.txt", "w"); if (!tripletFile) { fprintf(stderr, "Blad triplets.txt\n"); return OUTFILE_ERROR; } // Otwórz plik wyjściowy na asembler yyout = fopen("output.asm", "w"); if (!yyout) { fprintf(stderr, "Blad output.asm\n"); fclose(tripletFile); return OUTFILE_ERROR; } yyparse(); fclose(tripletFile); writeDataSection(yyout); writeCodeSection(yyout); fclose(yyout); // Zapisz tablicę symboli do symbols.txt saveSymbolTable(); return 0; }