This commit is contained in:
2025-12-20 16:21:57 +01:00
parent 3118619f77
commit 31754a0fad
2 changed files with 213 additions and 65 deletions

2
.gitignore vendored
View File

@@ -5,3 +5,5 @@ leks
lex.yy.cc
lex.yy.o
triplets.txt
symbols.txt
output.asm

176
def.yy
View File

@@ -1,14 +1,18 @@
%{
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include <string>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include <string>
#include <map>
#include <vector>
#include <cctype>
#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<std::string, SymbolInfo> symbolTable;
int memoryCounter = 0;
std::stack<StackElement> expressionsStack;
FILE *tripletFile;
int tempVarCounter = 0;
std::string generateTempVar() {
return "result" + std::to_string(tempVarCounter++);
std::vector<std::string> 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,7 +184,19 @@ variable_declaration
}
;
expression
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();
@@ -91,6 +205,10 @@ expression
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");
@@ -100,6 +218,10 @@ expression
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");
@@ -109,6 +231,10 @@ expression
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");
@@ -118,6 +244,10 @@ expression
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 {
@@ -129,10 +259,8 @@ expression
}
| ID {
printf("Identyfikator: %s\n", $1);
char buffer[128];
snprintf(buffer, sizeof(buffer), "%s", $1);
StackElement element;
element.value = std::string(buffer);
element.value = std::string($1);
element.type = StackElement::VAR;
expressionsStack.push(element);
}
@@ -143,10 +271,28 @@ expression
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;
}
yyparse();
// 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;
}