This commit is contained in:
2026-01-09 21:59:30 +01:00
parent 6b16ce98bc
commit 3a4c292473
5 changed files with 90 additions and 9 deletions

3
.gitignore vendored
View File

@@ -7,3 +7,6 @@ lex.yy.o
triplets.txt triplets.txt
symbols.txt symbols.txt
output.asm output.asm
cutie
cutie.yy.cc
cutie.yy.o

View File

@@ -4,16 +4,16 @@ LEX=flex
YACC=bison YACC=bison
LD=gcc LD=gcc
all: leks all: cutie
leks: def.tab.o lex.yy.o cutie: def.tab.o lex.yy.o
$(CXX) -std=c++11 lex.yy.o def.tab.o -o leks -ll $(CXX) -std=c++11 cutie.yy.o def.tab.o -o cutie -ll
lex.yy.o: lex.yy.cc lex.yy.o: lex.yy.cc
$(CXX) -std=c++11 -c lex.yy.cc $(CXX) -std=c++11 -c cutie.yy.cc
lex.yy.cc: z5.l lex.yy.cc: z5.l
$(LEX) -o lex.yy.cc z5.l $(LEX) -o cutie.yy.cc z5.l
def.tab.o: def.tab.cc def.tab.o: def.tab.cc
$(CXX) -std=c++11 -c def.tab.cc $(CXX) -std=c++11 -c def.tab.cc
@@ -22,4 +22,4 @@ def.tab.cc: def.yy
$(YACC) -d def.yy $(YACC) -d def.yy
clean: clean:
rm *.o cutie def.tab.cc def.tab.hh lex.yy.* triplets.txt rm *.o cutie def.tab.cc def.tab.hh cutie.yy.* triplets.txt

67
def.yy
View File

@@ -31,9 +31,11 @@ std::map<std::string, SymbolInfo> symbolTable;
int memoryCounter = 0; int memoryCounter = 0;
std::stack<StackElement> expressionsStack; std::stack<StackElement> expressionsStack;
std::stack<std::string> labelStack;
FILE *tripletFile; FILE *tripletFile;
int tempVarCounter = 0; int tempVarCounter = 0;
int stringCounter = 0; int stringCounter = 0;
int labelCounter = 0;
std::vector<std::string> asmCode; std::vector<std::string> asmCode;
std::map<std::string, std::string> stringLiterals; std::map<std::string, std::string> stringLiterals;
@@ -57,6 +59,10 @@ void addSymbol(const std::string& name, const std::string& type) {
} }
} }
std::string generateLabel() {
return "LBL" + std::to_string(labelCounter++);
}
// ASM // ASM
std::string generateLoad(const std::string& reg, const std::string& value) { std::string generateLoad(const std::string& reg, const std::string& value) {
@@ -171,6 +177,42 @@ void writeTriplet(const std::string& result, const std::string& arg1,
generateAsm(result, arg1, arg2, op); generateAsm(result, arg1, arg2, op);
} }
void generateIfJumpStatement(const std::string& op) {
if (expressionsStack.size() < 2) {
yyerror("Blad: niewystarczajaca liczba elementów w warunku");
return;
}
StackElement rhs = expressionsStack.top();
expressionsStack.pop();
StackElement lhs = expressionsStack.top();
expressionsStack.pop();
std::string label = generateLabel();
labelStack.push(label);
asmCode.push_back(generateLoad("$t2", lhs.value));
asmCode.push_back(generateLoad("$t3", rhs.value));
std::string jumpInstr;
if (op == "<") jumpInstr = "bge";
else if (op == ">") jumpInstr = "ble";
else if (op == "<=") jumpInstr = "bgt";
else if (op == ">=") jumpInstr = "blt";
else if (op == "==") jumpInstr = "bne";
else if (op == "!=") jumpInstr = "beq";
asmCode.push_back(jumpInstr + " $t2, $t3, " + label);
}
void generateIfEndStatement() {
if (!labelStack.empty()) {
std::string label = labelStack.top();
labelStack.pop();
asmCode.push_back(label + ":");
}
}
%} %}
%union { %union {
@@ -181,10 +223,13 @@ void writeTriplet(const std::string& result, const std::string& arg1,
%token <text> ID %token <text> ID
%token <text> STRING_LIT %token <text> STRING_LIT
%token <ival> INT_LIT %token <ival> INT_LIT
%token IF
%token LET PRINT_INT PRINT_FLOAT PRINT_STRING READ_INT READ_FLOAT %token LET PRINT_INT PRINT_FLOAT PRINT_STRING READ_INT READ_FLOAT
%token INT_TYPE %token INT_TYPE
%token SEMICOLON COLON %token SEMICOLON COLON
%token LE GE EQ NE
%left '<' '>' LE GE EQ NE
%left '+' '-' %left '+' '-'
%left '*' '/' %left '*' '/'
@@ -206,6 +251,7 @@ statement
| assignment { printf("Instrukcja przypisania\n"); } | assignment { printf("Instrukcja przypisania\n"); }
| print_statement { printf("Instrukcja wypisania\n"); } | print_statement { printf("Instrukcja wypisania\n"); }
| read_statement { printf("Instrukcja odczytu\n"); } | read_statement { printf("Instrukcja odczytu\n"); }
| if_expr { printf("Instrukcja warunkowa\n"); }
| expression SEMICOLON { | expression SEMICOLON {
printf("instrukcja\n"); printf("instrukcja\n");
if (!expressionsStack.empty()) { if (!expressionsStack.empty()) {
@@ -214,6 +260,27 @@ statement
} }
; ;
if_expr
: if_begin code_block { generateIfEndStatement(); }
;
if_begin
: IF '(' cond_expr ')' { generateIfJumpStatement($<text>3); }
;
code_block
: '{' statement_list '}'
;
cond_expr
: expression '<' expression { $<text>$ = strdup("<"); }
| expression '>' expression { $<text>$ = strdup(">"); }
| expression LE expression { $<text>$ = strdup("<="); }
| expression GE expression { $<text>$ = strdup(">="); }
| expression EQ expression { $<text>$ = strdup("=="); }
| expression NE expression { $<text>$ = strdup("!="); }
;
variable_declaration variable_declaration
: LET ID COLON INT_TYPE '=' expression SEMICOLON : LET ID COLON INT_TYPE '=' expression SEMICOLON
{ {

View File

@@ -1,5 +1,5 @@
let x: Int = 42; let x: Int = 42;
print_string("Integer: \n"); print_string("całkowita: \n");
print_string("\n"); print_string("\n");
print_integer(x); print_integer(x);
print_string("\n"); print_string("\n");
@@ -11,11 +11,13 @@ print_string("Float: \n");
print_float(f); print_float(f);
print_string("\n"); print_string("\n");
print_string("Podaj integer: \n"); print_string("Podaj liczbe całkowitą: \n");
let y: Int = 0; let y: Int = 0;
read_integer(y); read_integer(y);
print_string("Wynik: \n"); print_string("Wynik: \n");
print_integer(y); print_integer(y);
print_string("\n"); print_string("\n");
print_string("Koniec testu\n"); if (y == 0) {
print_string("y jest równy zeru");
}

9
z5.l
View File

@@ -12,6 +12,7 @@ void yyerror(const char *msg, ...);
%option noyywrap %option noyywrap
%% %%
"let" {fprintf(stdout, "LET\n"); return LET;} "let" {fprintf(stdout, "LET\n"); return LET;}
"if" {fprintf(stdout, "IF\n"); return IF;}
"Int" {fprintf(stdout, "INT_TYPE\n"); return INT_TYPE;} "Int" {fprintf(stdout, "INT_TYPE\n"); return INT_TYPE;}
":" {fprintf(stdout, ":\n"); return COLON;} ":" {fprintf(stdout, ":\n"); return COLON;}
";" {fprintf(stdout, ";\n"); return SEMICOLON;} ";" {fprintf(stdout, ";\n"); return SEMICOLON;}
@@ -20,6 +21,14 @@ void yyerror(const char *msg, ...);
"print_string" {fprintf(stdout, "PRINT_STRING\n"); return PRINT_STRING;} "print_string" {fprintf(stdout, "PRINT_STRING\n"); return PRINT_STRING;}
"read_integer" {fprintf(stdout, "READ_INT\n"); return READ_INT;} "read_integer" {fprintf(stdout, "READ_INT\n"); return READ_INT;}
"read_float" {fprintf(stdout, "READ_FLOAT\n"); return READ_FLOAT;} "read_float" {fprintf(stdout, "READ_FLOAT\n"); return READ_FLOAT;}
"{" {fprintf(stdout, "{\n"); return '{';}
"}" {fprintf(stdout, "}\n"); return '}';}
"<" {fprintf(stdout, "<\n"); return '<';}
">" {fprintf(stdout, ">\n"); return '>';}
"<=" {fprintf(stdout, "<=\n"); return LE;}
">=" {fprintf(stdout, ">=\n"); return GE;}
"==" {fprintf(stdout, "==\n"); return EQ;}
"!=" {fprintf(stdout, "!=\n"); return NE;}
\+ {fprintf(stdout, "+\n"); return '+';} \+ {fprintf(stdout, "+\n"); return '+';}
\* {fprintf(stdout, "*\n"); return '*';} \* {fprintf(stdout, "*\n"); return '*';}
\( {fprintf(stdout, "(\n"); return '(';} \( {fprintf(stdout, "(\n"); return '(';}