Lab 7
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -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
|
||||||
|
|||||||
12
Makefile
12
Makefile
@@ -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
67
def.yy
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
8
in5.txt
8
in5.txt
@@ -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
9
z5.l
@@ -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 '(';}
|
||||||
|
|||||||
Reference in New Issue
Block a user