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
|
||||
|
||||
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
22
al.lex
|
@ -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
34
as.y
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
4
test.c
|
@ -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
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