implement arithmetic operations asm generation
This commit is contained in:
parent
96ab1bf771
commit
74e97fe963
11 changed files with 152 additions and 69 deletions
6
Makefile
6
Makefile
|
@ -5,10 +5,10 @@ CC = gcc
|
||||||
all: compilateur test
|
all: compilateur test
|
||||||
|
|
||||||
test: symbol_table.test.c symbol_table.c symbol_table.h
|
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
|
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
|
$(CC) -o compilateur as.tab.c lex.yy.c symbol_table.c asm_instructions.c yacc_util.c
|
||||||
|
|
||||||
as.tab.c: as.y
|
as.tab.c: as.y
|
||||||
$(YACC) as.y
|
$(YACC) as.y
|
||||||
|
|
22
al.lex
22
al.lex
|
@ -1,4 +1,6 @@
|
||||||
%{
|
%{
|
||||||
|
#include "asm_instructions.h"
|
||||||
|
#include "symbol_table.h"
|
||||||
#include "as.tab.h"
|
#include "as.tab.h"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -11,10 +13,22 @@ D [0-9]
|
||||||
return tNB;
|
return tNB;
|
||||||
}
|
}
|
||||||
|
|
||||||
"+" { return tADD; }
|
"+" {
|
||||||
"-" { return tSUB; }
|
yylval.instruction = ADD;
|
||||||
"*" { return tMUL; }
|
return tADD;
|
||||||
"/" { return tDIV; }
|
}
|
||||||
|
"-" {
|
||||||
|
yylval.instruction = SOU;
|
||||||
|
return tSUB;
|
||||||
|
}
|
||||||
|
"*" {
|
||||||
|
yylval.instruction = MUL;
|
||||||
|
return tMUL;
|
||||||
|
}
|
||||||
|
"/" {
|
||||||
|
yylval.instruction = DIV;
|
||||||
|
return tDIV;
|
||||||
|
}
|
||||||
"=" { return tEQ; }
|
"=" { return tEQ; }
|
||||||
"(" { return tPO; }
|
"(" { return tPO; }
|
||||||
")" { return tPF; }
|
")" { return tPF; }
|
||||||
|
|
34
as.y
34
as.y
|
@ -2,23 +2,28 @@
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "symbol_table.h"
|
#include "symbol_table.h"
|
||||||
|
#include "asm_instructions.h"
|
||||||
|
#include "yacc_util.h"
|
||||||
|
|
||||||
enum Type current_type = TYPE_INT;
|
enum Type current_type = TYPE_INT;
|
||||||
|
|
||||||
SymbolTable symbol_table;
|
SymbolTable symbol_table;
|
||||||
|
InstructionTable instruction_table;
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
char* symbol_name;
|
char* symbol_name;
|
||||||
|
SymbolItem* symbol;
|
||||||
int nombre;
|
int nombre;
|
||||||
|
Instruction instruction;
|
||||||
}
|
}
|
||||||
|
|
||||||
%token<nombre> tNB
|
%token<nombre> tNB
|
||||||
%token tADD
|
%token<instruction> tADD
|
||||||
%token tSUB
|
%token<instruction> tSUB
|
||||||
%token tMUL
|
%token<instruction> tMUL
|
||||||
%token tDIV
|
%token<instruction> tDIV
|
||||||
%token tPO
|
%token tPO
|
||||||
%token tPF
|
%token tPF
|
||||||
%token tPV
|
%token tPV
|
||||||
|
@ -50,7 +55,7 @@ SymbolTable symbol_table;
|
||||||
%left tSUB
|
%left tSUB
|
||||||
%left tMUL
|
%left tMUL
|
||||||
%left tDIV
|
%left tDIV
|
||||||
// %type<nombre> E
|
%type<symbol> E
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
@ -71,13 +76,20 @@ Instructions : Instruction Instructions | { printf("Instructions\n"); } ;
|
||||||
|
|
||||||
Instruction : Aff | Printf { printf("Instruction\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 ;
|
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() {
|
void init() {
|
||||||
init_table(&symbol_table);
|
init_table(&symbol_table);
|
||||||
|
init_instruction_table(&instruction_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
void yyerror(char const* err) {
|
void yyerror(char const* err) {
|
||||||
|
@ -173,4 +186,7 @@ void main(void) {
|
||||||
init();
|
init();
|
||||||
yyparse();
|
yyparse();
|
||||||
print_table(&symbol_table);
|
print_table(&symbol_table);
|
||||||
|
FILE *f = fopen("instruction_table.txt", "w+");
|
||||||
|
write_instruction_table(&instruction_table, f);
|
||||||
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,20 @@
|
||||||
#include "asm_instructions.h"
|
#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) {
|
void init_instruction_table(InstructionTable *table) {
|
||||||
table->index = 0;
|
table->index = 0;
|
||||||
}
|
}
|
||||||
|
@ -26,5 +41,5 @@ void write_instruction_table(InstructionTable *table, FILE *file) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_instruction(InstructionItem *item, 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);
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
typedef enum Instruction {
|
typedef enum Instruction {
|
||||||
ADD,
|
ADD,
|
||||||
MUL,
|
MUL,
|
||||||
SUO,
|
SOU,
|
||||||
DIV,
|
DIV,
|
||||||
COP,
|
COP,
|
||||||
AFC,
|
AFC,
|
||||||
|
@ -20,20 +20,7 @@ typedef enum Instruction {
|
||||||
PRI
|
PRI
|
||||||
} Instruction;
|
} Instruction;
|
||||||
|
|
||||||
char* instructions_labels[12] = {
|
char* instructions_labels[12];
|
||||||
"ADD",
|
|
||||||
"MUL",
|
|
||||||
"SUO",
|
|
||||||
"DIV",
|
|
||||||
"COP",
|
|
||||||
"AFC",
|
|
||||||
"JMP",
|
|
||||||
"JMF",
|
|
||||||
"INF",
|
|
||||||
"SUP",
|
|
||||||
"EQU",
|
|
||||||
"PRI"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct InstructionItem {
|
typedef struct InstructionItem {
|
||||||
|
|
|
@ -8,6 +8,13 @@ void init_table(SymbolTable *table) {
|
||||||
table->temp_index = SYMBOL_TABLE_SIZE - 1;
|
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) {
|
int has_symbol(SymbolTable* table, char *name) {
|
||||||
for (int i = 0; i < table->index; i++) {
|
for (int i = 0; i < table->index; i++) {
|
||||||
if (strcmp(table->table[i].name, name) == 0) {
|
if (strcmp(table->table[i].name, name) == 0) {
|
||||||
|
@ -30,6 +37,7 @@ int add_symbol(SymbolTable *table, enum Type type, char *name) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SymbolItem newItem;
|
SymbolItem newItem;
|
||||||
|
init_symbol_item(&newItem, strlen(name));
|
||||||
newItem.type = type;
|
newItem.type = type;
|
||||||
newItem.name = name;
|
newItem.name = name;
|
||||||
newItem.address = table->index;
|
newItem.address = table->index;
|
||||||
|
@ -40,26 +48,20 @@ int add_symbol(SymbolTable *table, enum Type type, char *name) {
|
||||||
return 0;
|
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) {
|
if (table->temp_index < table->index) {
|
||||||
return -2;
|
return NULL;
|
||||||
}
|
|
||||||
if (has_symbol(table, name)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (name[0] != '_') {
|
|
||||||
return -3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolItem newItem;
|
SymbolItem *newItem = &table->table[table->temp_index];
|
||||||
newItem.type = type;
|
init_symbol_item(newItem, 10);
|
||||||
newItem.name = name;
|
newItem->type = type;
|
||||||
newItem.address = table->temp_index;
|
sprintf(newItem->name, "_temp%d", table->temp_index);
|
||||||
newItem.init = 0;
|
newItem->address = table->temp_index;
|
||||||
|
newItem->init = 0;
|
||||||
|
|
||||||
table->table[table->temp_index] = newItem;
|
|
||||||
table->temp_index--;
|
table->temp_index--;
|
||||||
return 0;
|
return newItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mark_symbol_initialized(SymbolTable *table, char *name) {
|
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++) {
|
for (int i = 0; i < table->index; i++) {
|
||||||
if (strcmp(table->table[i].name, name) == 0) {
|
if (strcmp(table->table[i].name, name) == 0) {
|
||||||
return &table->table[i];
|
return &table->table[i];
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef SYMBOL_TABLE_H_INCLUDED
|
#ifndef SYMBOL_TABLE_H_INCLUDED
|
||||||
#define SYMBOL_TABLE_H_INCLUDED
|
#define SYMBOL_TABLE_H_INCLUDED
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#define SYMBOL_TABLE_SIZE 100
|
#define SYMBOL_TABLE_SIZE 100
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
|
@ -31,6 +33,13 @@ typedef struct SymbolTable {
|
||||||
*/
|
*/
|
||||||
void init_table(SymbolTable *table);
|
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
|
* 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 table
|
||||||
* @param type
|
* @param type
|
||||||
* @param name
|
* @param name
|
||||||
* @return 0 on success, -1 if the symbol already exists, -2 if the table is full
|
* @return 0 on success, -1 if the table is full
|
||||||
* -3 if the name doesn't start by _
|
|
||||||
*/
|
*/
|
||||||
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
|
* Marks the given symbol as initialized
|
||||||
|
@ -100,6 +108,6 @@ char* type_to_string(enum Type type);
|
||||||
* @param name
|
* @param name
|
||||||
* @return the item if found, NULL otherwise
|
* @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 */
|
#endif /* !SYMBOL_TABLE_H_INCLUDED */
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "symbol_table.h"
|
#include "symbol_table.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int err;
|
int err;
|
||||||
|
@ -33,23 +34,17 @@ int main() {
|
||||||
printf("Mark b initialized\n");
|
printf("Mark b initialized\n");
|
||||||
assert(err == -1);
|
assert(err == -1);
|
||||||
|
|
||||||
err = add_temp_symbol(&table, TYPE_INT, "_temp1");
|
const SymbolItem* var1 = add_temp_symbol(&table, TYPE_INT);
|
||||||
printf("Add _temp1 temporary variable\n");
|
printf("Add _temp99 temporary variable\n");
|
||||||
assert(err == 0);
|
assert(strcmp(var1->name, "_temp99") == 0);
|
||||||
err = add_temp_symbol(&table, TYPE_INT, "_temp2");
|
const SymbolItem* var2 = add_temp_symbol(&table, TYPE_INT);
|
||||||
printf("Add _temp2 temporary variable\n");
|
printf("Add _temp98 temporary variable\n");
|
||||||
assert(err == 0);
|
assert(strcmp(var2->name, "_temp98") == 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);
|
|
||||||
|
|
||||||
item = get_symbol_item(&table, "_temp1");
|
item = get_symbol_item(&table, "_temp98");
|
||||||
printf("_temp1:\n");
|
printf("_temp98:\n");
|
||||||
print_item(item);
|
print_item(item);
|
||||||
item = get_symbol_item(&table, "_temp5");
|
item = get_symbol_item(&table, "_temp0");
|
||||||
printf("_temp5:\n");
|
printf("_temp5:\n");
|
||||||
print_item(item);
|
print_item(item);
|
||||||
|
|
||||||
|
|
4
test.c
4
test.c
|
@ -2,6 +2,6 @@ int main(){
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
const PL5_op, b, c;
|
const PL5_op, b, c;
|
||||||
printf(x);
|
printf(x);
|
||||||
x = 3 + 2;
|
x = 2;
|
||||||
y = 3;
|
y = 3 + 3 + x;
|
||||||
}
|
}
|
||||||
|
|
30
yacc_util.c
Normal file
30
yacc_util.c
Normal 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
16
yacc_util.h
Normal 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
|
Loading…
Reference in a new issue