This commit is contained in:
Arnaud Vergnet 2021-04-06 18:17:10 +02:00
parent ec138f82b3
commit a1c0f7a19f
7 changed files with 130 additions and 36 deletions

51
al.lex
View file

@ -2,6 +2,7 @@
#include "asm_instructions.h"
#include "symbol_table.h"
#include "as.tab.h"
#include "yacc_util.h"
%}
D [0-9]
@ -36,13 +37,49 @@ D [0-9]
"," { return tVIRG; }
"{" { return tAO; }
"}" { return tAF; }
"!" { return tNOT; }
"==" { return tEQ2; }
"!=" { return tNOTEQ; }
"<" { return tINF; }
"<=" { return tINFEQ; }
">" { return tSUP; }
">=" { return tSUPEQ; }
"==" {
struct Condition* c = malloc(sizeof(struct Condition));
c->instruction = EQU;
c->not = 0;
yylval.condition = c;
return tEQ2;
}
"!=" {
struct Condition* c = malloc(sizeof(struct Condition));
c->instruction = EQU;
c->not = 1;
yylval.condition = c;
return tNOTEQ;
}
"<" {
struct Condition* c = malloc(sizeof(struct Condition));
c->instruction = INF;
c->not = 0;
yylval.condition = c;
return tINF;
}
"<=" {
struct Condition* c = malloc(sizeof(struct Condition));
c->instruction = SUP;
c->not = 1;
yylval.condition = c;
return tINFEQ;
}
">" {
struct Condition* c = malloc(sizeof(struct Condition));
c->instruction = SUP;
c->not = 0;
yylval.condition = c;
return tSUP;
}
">=" {
struct Condition* c = malloc(sizeof(struct Condition));
c->instruction = INF;
c->not = 1;
yylval.condition = c;
return tSUPEQ;
}
"!" { return tNOT; }
"&&" { return tAND; }
"||" { return tOR; }
[ \t\n]+ { }

53
as.y
View file

@ -16,7 +16,9 @@ InstructionTable instruction_table;
char* symbol_name;
SymbolItem* symbol;
int nombre;
int address;
Instruction instruction;
struct Condition* condition;
}
%token<nombre> tNB
@ -31,13 +33,13 @@ InstructionTable instruction_table;
%token tAO
%token tAF
%token tEQ
%token tEQ2
%token tNOTEQ
%token<condition> tEQ2
%token<condition> tNOTEQ
%token<condition> tINF
%token<condition> tINFEQ
%token<condition> tSUP
%token<condition> tSUPEQ
%token tNOT
%token tINF
%token tINFEQ
%token tSUP
%token tSUPEQ
%token tAND
%token tOR
@ -56,6 +58,8 @@ InstructionTable instruction_table;
%left tMUL
%left tDIV
%type<symbol> E
%type<symbol> Cond
%type<address> IfSimple
%%
@ -74,7 +78,7 @@ Body : tAO Instructions tAF { printf("Body\n"); } ;
Instructions : Instruction Instructions | { printf("Instructions\n"); } ;
Instruction : Aff | Printf { printf("Instruction\n"); } ;
Instruction : Aff | Printf | If { printf("Instruction\n"); } ;
Aff : tID tEQ E tPV { write_affectation(&symbol_table, &instruction_table, $1, $3); } ;
@ -97,30 +101,29 @@ DeclarationConst : tCONST { current_type = TYPE_CONST; } DeclarationBody tPV ;
DeclarationBody : VariableIdentifier tVIRG DeclarationBody | VariableIdentifier ;
VariableIdentifier: tID { add_symbol(&symbol_table, current_type, $1); }
VariableIdentifier: tID { add_symbol(&symbol_table, current_type, $1); } ;
// While : tWHILE tPO Cond tPF Body { printf("While\n"); } ;
//
// If : IfSimple | IfElse { printf("If\n"); } ;
//
// IfSimple : tIF tPO Cond tPF Body { printf("IfSimple\n"); } ;
//
If : IfSimple { update_jmf(&instruction_table, $1); } ;
IfSimple : tIF tPO Cond tPF { $<address>$ = write_jmf(&instruction_table, $3); } Body { $$ = $<address>5; };
// IfElse : IfSimple tELSE Body { printf("IfElse\n"); } ;
//
// Cond : tNOT Cond | Cond tAND Cond | Cond tOR Cond | E tEQ2 E | E tINF E | E tINFEQ E | E tSUP E | E tSUPEQ E | E tNOTEQ E | tNOT tPO Cond tPF { printf("Cond\n"); } ;
Cond : tNOT Cond { $$ = write_not_condition(&symbol_table, &instruction_table, $2); }
| Cond tAND Cond { $$ = write_op(&symbol_table, &instruction_table, MUL, $1, $3); }
| Cond tOR Cond { $$ = write_op(&symbol_table, &instruction_table, ADD, $1, $3); }
| E tEQ2 E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
| E tINF E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
| E tINFEQ E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
| E tSUP E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
| E tSUPEQ E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
| E tNOTEQ E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
| tNOT tPO Cond tPF { $$ = write_not_condition(&symbol_table, &instruction_table, $3); } ;
Printf : tPRINTF tPO E tPF tPV { write_print(&instruction_table, $3); } ;
// If : tIF tPO Cond tPF Body ;
//
// Cond : Cond tAND Cond | Cond tOR Cond | E tEQ2 E | E tINF E | tNOT Cond ;
// Invocation : tID tPO Args tPF ;
// Args : .... cf params
// Return : tRET E tPV ;
%%
#include <string.h>

View file

@ -48,4 +48,8 @@ void write_instruction(InstructionItem *item, FILE *file) {
} else {
fprintf(file, "%s %d %d %d\n", instructions_labels[item->instruction], item->arg1, item->arg2, item->arg3);
}
}
int get_current_address(struct InstructionTable *table) {
return table->index;
}

View file

@ -2,6 +2,7 @@
#define COMPILATOR_2000_ASM_INSTRUCTIONS_H
#include <stdio.h>
#include "symbol_table.h"
#define INSTRUCTION_TABLE_SIZE 100
@ -43,4 +44,6 @@ void write_instruction_table(InstructionTable *table, FILE *file);
void write_instruction(InstructionItem *item, FILE *file);
int get_current_address(InstructionTable *table);
#endif //COMPILATOR_2000_ASM_INSTRUCTIONS_H

5
test.c
View file

@ -4,4 +4,9 @@ int main(){
x = 2;
printf(x);
y = 3 + 3 + x;
if (x == 2) {
printf(x);
printf(y);
}
x = 3;
}

View file

@ -15,13 +15,11 @@ const SymbolItem* write_op(SymbolTable* symbol_table, InstructionTable *instruct
const SymbolItem* write_negation(SymbolTable* symbol_table, InstructionTable *instruction_table, SymbolItem *op2) {
// Create temp variable with 0
const SymbolItem* op1 = init_temp_symbol(symbol_table, instruction_table, 0);
const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT);
// Make the 0 - variable operation
add_instruction(instruction_table, SOU, dest->address, op1->address, op2->address);
return dest;
add_instruction(instruction_table, SOU, op1->address, op1->address, op2->address);
return op1;
}
const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable *instruction_table, int constant) {
const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT);
add_instruction(instruction_table, AFC, dest->address, constant, 0);
@ -32,4 +30,36 @@ void write_print(InstructionTable *instruction_table, SymbolItem *src) {
add_instruction(instruction_table, PRI, src->address, 0, 0);
}
int update_jmf(InstructionTable *table, int address) {
if (address > table->index) {
return -1;
}
table->table[address].arg2 = get_current_address(table);
return 0;
}
int write_jmf(InstructionTable *table, SymbolItem* cond) {
int addr = get_current_address(table);
add_instruction(table, JMF, cond->address, 0, 0);
return addr;
}
const SymbolItem* write_not_condition(SymbolTable* symbol_table, InstructionTable *instruction_table, const SymbolItem* cond) {
// Create temp variable with 0
const SymbolItem* op1 = init_temp_symbol(symbol_table, instruction_table, 0);
// Check if the condition is equal to 0 (makes the negation)
add_instruction(instruction_table, EQU, op1->address, op1->address, cond->address);
return op1;
}
const SymbolItem* write_condition(SymbolTable* symbol_table, InstructionTable *instruction_table, Condition* op, SymbolItem* cond1, SymbolItem* cond2) {
const SymbolItem *dest = write_op(symbol_table, instruction_table, op->instruction, cond1, cond2);
if (op->not) {
return write_not_condition(symbol_table, instruction_table, dest);
}
return dest;
}

View file

@ -4,6 +4,10 @@
#ifndef COMPILATOR_2000_YACC_UTIL_H
#define COMPILATOR_2000_YACC_UTIL_H
typedef struct Condition {
Instruction instruction;
int not;
} Condition;
void write_affectation(SymbolTable* symbolTable, InstructionTable *instructionTable, char* symbol_dest, SymbolItem* src);
@ -15,4 +19,12 @@ const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable *
void write_print(InstructionTable *instruction_table, SymbolItem *src);
int update_jmf(InstructionTable *table, int address);
int write_jmf(InstructionTable *table, SymbolItem* cond);
const SymbolItem* write_not_condition(SymbolTable* symbol_table, InstructionTable *table, const SymbolItem* cond);
const SymbolItem* write_condition(SymbolTable* symbol_table, InstructionTable *table, Condition* op, SymbolItem* cond1, SymbolItem* cond2);
#endif //COMPILATOR_2000_YACC_UTIL_H