From 31754a0fad9d77c4482b8961ae0e7c1f4f6a1ebf Mon Sep 17 00:00:00 2001 From: Oschly Date: Sat, 20 Dec 2025 16:21:57 +0100 Subject: [PATCH] Lab 5 --- .gitignore | 2 + def.yy | 276 ++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 213 insertions(+), 65 deletions(-) diff --git a/.gitignore b/.gitignore index 9a3ccd6..be6548c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ leks lex.yy.cc lex.yy.o triplets.txt +symbols.txt +output.asm diff --git a/def.yy b/def.yy index 21c57d9..b02d6e5 100644 --- a/def.yy +++ b/def.yy @@ -1,14 +1,18 @@ %{ -#include -#include -#include -#include -#include + #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, ...); @@ -18,17 +22,113 @@ struct StackElement { 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::string generateTempVar() { - return "result" + std::to_string(tempVarCounter++); +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 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()); +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); } %} @@ -62,6 +162,7 @@ statement_list statement : variable_declaration { printf("Deklaracja zmiennej\n"); } + | assignment { printf("Instrukcja przypisania\n"); } | expression SEMICOLON { printf("instrukcja\n"); if (!expressionsStack.empty()) { @@ -74,6 +175,7 @@ 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(); @@ -82,71 +184,115 @@ variable_declaration } ; -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, "+"); - } - | 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, "-"); - } - | 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, "*"); - } - | 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, "/"); - } - | '(' 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); - char buffer[128]; - snprintf(buffer, sizeof(buffer), "%s", $1); - StackElement element; - element.value = std::string(buffer); - element.type = StackElement::VAR; - expressionsStack.push(element); - } - ; + 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\n"); + 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; }