Lab 5
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,3 +5,5 @@ leks
|
||||
lex.yy.cc
|
||||
lex.yy.o
|
||||
triplets.txt
|
||||
symbols.txt
|
||||
output.asm
|
||||
|
||||
164
def.yy
164
def.yy
@@ -4,11 +4,15 @@
|
||||
#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,6 +184,18 @@ variable_declaration
|
||||
}
|
||||
;
|
||||
|
||||
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");
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user