implement arithmetic operations asm generation

This commit is contained in:
Arnaud Vergnet 2021-04-06 16:19:44 +02:00
parent 96ab1bf771
commit 74e97fe963
11 changed files with 152 additions and 69 deletions

View file

@ -5,10 +5,10 @@ CC = gcc
all: compilateur test
test: symbol_table.test.c symbol_table.c symbol_table.h
$(CC) -o test symbol_table.test.c symbol_table.c
$(CC) -g -o test symbol_table.test.c symbol_table.c
compilateur: as.tab.c lex.yy.c symbol_table.c symbol_table.h asm_instructions.c asm_instructions.h
$(CC) -o compilateur as.tab.c lex.yy.c symbol_table.c asm_instructions.c
compilateur: as.tab.c lex.yy.c symbol_table.c symbol_table.h asm_instructions.c asm_instructions.h yacc_util.c yacc_util.h
$(CC) -o compilateur as.tab.c lex.yy.c symbol_table.c asm_instructions.c yacc_util.c
as.tab.c: as.y
$(YACC) as.y

22
al.lex
View file

@ -1,4 +1,6 @@
%{
#include "asm_instructions.h"
#include "symbol_table.h"
#include "as.tab.h"
%}
@ -11,10 +13,22 @@ D [0-9]
return tNB;
}
"+" { return tADD; }
"-" { return tSUB; }
"*" { return tMUL; }
"/" { return tDIV; }
"+" {
yylval.instruction = ADD;
return tADD;
}
"-" {
yylval.instruction = SOU;
return tSUB;
}
"*" {
yylval.instruction = MUL;
return tMUL;
}
"/" {
yylval.instruction = DIV;
return tDIV;
}
"=" { return tEQ; }
"(" { return tPO; }
")" { return tPF; }

34
as.y
View file

@ -2,23 +2,28 @@
#include "stdio.h"
#include "stdlib.h"
#include "symbol_table.h"
#include "asm_instructions.h"
#include "yacc_util.h"
enum Type current_type = TYPE_INT;
SymbolTable symbol_table;
InstructionTable instruction_table;
%}
%union {
char* symbol_name;
SymbolItem* symbol;
int nombre;
Instruction instruction;
}
%token<nombre> tNB
%token tADD
%token tSUB
%token tMUL
%token tDIV
%token<instruction> tADD
%token<instruction> tSUB
%token<instruction> tMUL
%token<instruction> tDIV
%token tPO
%token tPF
%token tPV
@ -50,7 +55,7 @@ SymbolTable symbol_table;
%left tSUB
%left tMUL
%left tDIV
// %type<nombre> E
%type<symbol> E
%%
@ -71,13 +76,20 @@ Instructions : Instruction Instructions | { printf("Instructions\n"); } ;
Instruction : Aff | Printf { printf("Instruction\n"); } ;
Aff : tID tEQ E tPV { mark_symbol_initialized(&symbol_table, $1); } ;
Aff : tID tEQ E tPV { write_affectation(&symbol_table, &instruction_table, $1, $3); } ;
E : tNB { printf("%d\n", $1); } | tID | E tADD E | E tMUL E | E tSUB E | E tDIV E | tPO E tPF | tSUB E ;
E : tNB { $$ = init_temp_symbol(&symbol_table, &instruction_table, $1); }
| tID { $$ = get_symbol_item(&symbol_table, $1); }
| E tADD E {$$ = write_op(&symbol_table, &instruction_table, $2, $1, $3); }
| E tMUL E { $$ = write_op(&symbol_table, &instruction_table, $2, $1, $3); }
| E tSUB E { $$ = write_op(&symbol_table, &instruction_table, $2, $1, $3); }
| E tDIV E { $$ = write_op(&symbol_table, &instruction_table, $2, $1, $3); }
| tPO E tPF { $$ = $2; }
| tSUB E { $$ = write_negation(&symbol_table, &instruction_table, $2); } ;
Declarations : | Declaration Declarations { printf("Declarations\n"); } ;
Declarations : | Declaration Declarations ;
Declaration : DeclarationInt | DeclarationConst { printf("Declaration\n"); } ;
Declaration : DeclarationInt | DeclarationConst ;
DeclarationInt : tINT { current_type = TYPE_INT; } DeclarationBody tPV ;
@ -162,6 +174,7 @@ On suppose que E est tout le temps une vt, donc on génère tout le temps le mê
void init() {
init_table(&symbol_table);
init_instruction_table(&instruction_table);
}
void yyerror(char const* err) {
@ -173,4 +186,7 @@ void main(void) {
init();
yyparse();
print_table(&symbol_table);
FILE *f = fopen("instruction_table.txt", "w+");
write_instruction_table(&instruction_table, f);
fclose(f);
}

View file

@ -1,5 +1,20 @@
#include "asm_instructions.h"
char* instructions_labels[12] = {
"ADD",
"MUL",
"SOU",
"DIV",
"COP",
"AFC",
"JMP",
"JMF",
"INF",
"SUP",
"EQU",
"PRI"
};
void init_instruction_table(InstructionTable *table) {
table->index = 0;
}
@ -26,5 +41,5 @@ void write_instruction_table(InstructionTable *table, FILE *file) {
}
void write_instruction(InstructionItem *item, FILE *file) {
fprintf(file, "%s %d %d %d", instructions_labels[item->instruction], item->arg1, item->arg2, item->arg3);
fprintf(file, "%s %d %d %d\n", instructions_labels[item->instruction], item->arg1, item->arg2, item->arg3);
}

View file

@ -8,7 +8,7 @@
typedef enum Instruction {
ADD,
MUL,
SUO,
SOU,
DIV,
COP,
AFC,
@ -20,20 +20,7 @@ typedef enum Instruction {
PRI
} Instruction;
char* instructions_labels[12] = {
"ADD",
"MUL",
"SUO",
"DIV",
"COP",
"AFC",
"JMP",
"JMF",
"INF",
"SUP",
"EQU",
"PRI"
};
char* instructions_labels[12];
typedef struct InstructionItem {

View file

@ -8,6 +8,13 @@ void init_table(SymbolTable *table) {
table->temp_index = SYMBOL_TABLE_SIZE - 1;
}
void init_symbol_item(SymbolItem *symbol_item, size_t name_size) {
symbol_item->type = 0;
symbol_item->name = malloc(name_size);
symbol_item->address = 0;
symbol_item->init = 0;
}
int has_symbol(SymbolTable* table, char *name) {
for (int i = 0; i < table->index; i++) {
if (strcmp(table->table[i].name, name) == 0) {
@ -30,6 +37,7 @@ int add_symbol(SymbolTable *table, enum Type type, char *name) {
return -1;
}
SymbolItem newItem;
init_symbol_item(&newItem, strlen(name));
newItem.type = type;
newItem.name = name;
newItem.address = table->index;
@ -40,26 +48,20 @@ int add_symbol(SymbolTable *table, enum Type type, char *name) {
return 0;
}
int add_temp_symbol(SymbolTable* table, enum Type type, char *name) {
const SymbolItem* add_temp_symbol(SymbolTable* table, enum Type type) {
if (table->temp_index < table->index) {
return -2;
}
if (has_symbol(table, name)) {
return -1;
}
if (name[0] != '_') {
return -3;
return NULL;
}
SymbolItem newItem;
newItem.type = type;
newItem.name = name;
newItem.address = table->temp_index;
newItem.init = 0;
SymbolItem *newItem = &table->table[table->temp_index];
init_symbol_item(newItem, 10);
newItem->type = type;
sprintf(newItem->name, "_temp%d", table->temp_index);
newItem->address = table->temp_index;
newItem->init = 0;
table->table[table->temp_index] = newItem;
table->temp_index--;
return 0;
return newItem;
}
int mark_symbol_initialized(SymbolTable *table, char *name) {
@ -107,7 +109,7 @@ void print_item(struct SymbolItem *item) {
}
}
SymbolItem *get_symbol_item(SymbolTable *table, char *name) {
SymbolItem *get_symbol_item(SymbolTable *table, const char *name) {
for (int i = 0; i < table->index; i++) {
if (strcmp(table->table[i].name, name) == 0) {
return &table->table[i];

View file

@ -1,6 +1,8 @@
#ifndef SYMBOL_TABLE_H_INCLUDED
#define SYMBOL_TABLE_H_INCLUDED
#include <stddef.h>
#define SYMBOL_TABLE_SIZE 100
enum Type {
@ -31,6 +33,13 @@ typedef struct SymbolTable {
*/
void init_table(SymbolTable *table);
/**
* Initializes the symbol
*
* @param table
*/
void init_symbol_item(SymbolItem *symbol_item, size_t name_size);
/**
* Checks if the given symbol is in the table
*
@ -57,10 +66,9 @@ int add_symbol(SymbolTable* table, enum Type type, char *name);
* @param table
* @param type
* @param name
* @return 0 on success, -1 if the symbol already exists, -2 if the table is full
* -3 if the name doesn't start by _
* @return 0 on success, -1 if the table is full
*/
int add_temp_symbol(SymbolTable* table, enum Type type, char *name);
const SymbolItem* add_temp_symbol(SymbolTable* table, enum Type type);
/**
* Marks the given symbol as initialized
@ -100,6 +108,6 @@ char* type_to_string(enum Type type);
* @param name
* @return the item if found, NULL otherwise
*/
SymbolItem *get_symbol_item(SymbolTable* table, char *name);
SymbolItem *get_symbol_item(SymbolTable* table, const char *name);
#endif /* !SYMBOL_TABLE_H_INCLUDED */

View file

@ -1,6 +1,7 @@
#include "symbol_table.h"
#include <stdio.h>
#include <assert.h>
#include <string.h>
int main() {
int err;
@ -33,23 +34,17 @@ int main() {
printf("Mark b initialized\n");
assert(err == -1);
err = add_temp_symbol(&table, TYPE_INT, "_temp1");
printf("Add _temp1 temporary variable\n");
assert(err == 0);
err = add_temp_symbol(&table, TYPE_INT, "_temp2");
printf("Add _temp2 temporary variable\n");
assert(err == 0);
err = add_temp_symbol(&table, TYPE_INT, "_temp1");
printf("Add _temp1 temporary variable\n");
assert(err == -1);
err = add_temp_symbol(&table, TYPE_INT, "temp1");
printf("Add temp1 temporary variable\n");
assert(err == -3);
const SymbolItem* var1 = add_temp_symbol(&table, TYPE_INT);
printf("Add _temp99 temporary variable\n");
assert(strcmp(var1->name, "_temp99") == 0);
const SymbolItem* var2 = add_temp_symbol(&table, TYPE_INT);
printf("Add _temp98 temporary variable\n");
assert(strcmp(var2->name, "_temp98") == 0);
item = get_symbol_item(&table, "_temp1");
printf("_temp1:\n");
item = get_symbol_item(&table, "_temp98");
printf("_temp98:\n");
print_item(item);
item = get_symbol_item(&table, "_temp5");
item = get_symbol_item(&table, "_temp0");
printf("_temp5:\n");
print_item(item);

4
test.c
View file

@ -2,6 +2,6 @@ int main(){
int x, y, z;
const PL5_op, b, c;
printf(x);
x = 3 + 2;
y = 3;
x = 2;
y = 3 + 3 + x;
}

30
yacc_util.c Normal file
View file

@ -0,0 +1,30 @@
#include "yacc_util.h"
void write_affectation(SymbolTable* symbol_table, InstructionTable *instruction_table, char* symbol_dest, SymbolItem* src) {
mark_symbol_initialized(symbol_table, symbol_dest);
SymbolItem *dest = get_symbol_item(symbol_table, symbol_dest);
add_instruction(instruction_table, COP, src->address, dest->address, 0);
}
const SymbolItem* write_op(SymbolTable* symbol_table, InstructionTable *instruction_table, Instruction instruction, SymbolItem *op1, SymbolItem *op2) {
const SymbolItem* dest = add_temp_symbol(symbol_table, TYPE_INT);
add_instruction(instruction_table, instruction, dest->address, op1->address, op2->address);
return dest;
}
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;
}
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);
return dest;
}

16
yacc_util.h Normal file
View file

@ -0,0 +1,16 @@
#include "symbol_table.h"
#include "asm_instructions.h"
#ifndef COMPILATOR_2000_YACC_UTIL_H
#define COMPILATOR_2000_YACC_UTIL_H
void write_affectation(SymbolTable* symbolTable, InstructionTable *instructionTable, char* symbol_dest, SymbolItem* src);
const SymbolItem* write_op(SymbolTable* symbol_table, InstructionTable *instruction_table, Instruction instruction, SymbolItem *op1, SymbolItem *op2);
const SymbolItem* write_negation(SymbolTable* symbol_table, InstructionTable *instruction_table, SymbolItem *op2);
const SymbolItem* init_temp_symbol(SymbolTable* symbol_table, InstructionTable *instruction_table, int constant);
#endif //COMPILATOR_2000_YACC_UTIL_H