1
0
Ответвление 0

implement symbol table and start asm

Этот коммит содержится в:
Arnaud Vergnet 2021-03-22 12:51:56 +01:00
родитель d250a8f837
коммит 96ab1bf771
9 изменённых файлов: 384 добавлений и 33 удалений

Просмотреть файл

@ -2,10 +2,13 @@ LEX = flex
YACC = bison -d -v
CC = gcc
all: compilateur
all: compilateur test
compilateur: as.tab.c lex.yy.c symbol_table.c
$(CC) -o compilateur as.tab.c lex.yy.c symbol_table.c
test: symbol_table.test.c symbol_table.c symbol_table.h
$(CC) -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
as.tab.c: as.y
$(YACC) as.y

6
al.lex
Просмотреть файл

@ -41,7 +41,11 @@ D [0-9]
"elsif" { return tELSIF; }
"while" { return tWHILE; }
"printf" { return tPRINTF; }
[a-zA-Z][a-zA-Z0-9_]* { return tID; }
[a-zA-Z][a-zA-Z0-9_]* {
yylval.symbol_name = malloc(sizeof(yytext));
strcpy(yylval.symbol_name, yytext);
return tID;
}
%%

41
as.y
Просмотреть файл

@ -1,9 +1,16 @@
%{
#include "stdio.h"
#include "stdlib.h"
#include "symbol_table.h"
enum Type current_type = TYPE_INT;
SymbolTable symbol_table;
%}
%union {
char* symbol_name;
int nombre;
}
@ -37,7 +44,7 @@
%token tELSIF
%token tWHILE
%token tPRINTF
%token tID
%token<symbol_name> tID
%left tADD
%left tSUB
@ -64,20 +71,22 @@ Instructions : Instruction Instructions | { printf("Instructions\n"); } ;
Instruction : Aff | Printf { printf("Instruction\n"); } ;
Aff : tID tEQ E tPV { printf("Aff\n"); } ;
Aff : tID tEQ E tPV { mark_symbol_initialized(&symbol_table, $1); } ;
E : tNB | tID | E tADD E | E tMUL E | E tSUB E | E tDIV E | tPO E tPF | tSUB E { printf("E\n"); } ;
E : tNB { printf("%d\n", $1); } | tID | E tADD E | E tMUL E | E tSUB E | E tDIV E | tPO E tPF | tSUB E ;
Declarations : | Declaration Declarations { printf("Declarations\n"); } ;
Declaration : DeclarationInt | DeclarationConst { printf("Declaration\n"); } ;
DeclarationInt : tINT DeclarationBody tPV { printf("DeclarationInt\n"); } ;
DeclarationInt : tINT { current_type = TYPE_INT; } DeclarationBody tPV ;
DeclarationConst : tCONST DeclarationBody tPV { printf("DeclarationConst\n"); } ;
DeclarationConst : tCONST { current_type = TYPE_CONST; } DeclarationBody tPV ;
DeclarationBody : tID tVIRG DeclarationBody | tID { printf("DeclarationBody\n"); } ;
DeclarationBody : VariableIdentifier tVIRG DeclarationBody | VariableIdentifier ;
VariableIdentifier: tID { add_symbol(&symbol_table, current_type, $1); }
// While : tWHILE tPO Cond tPF Body { printf("While\n"); } ;
//
// If : IfSimple | IfElse { printf("If\n"); } ;
@ -151,22 +160,8 @@ On suppose que E est tout le temps une vt, donc on génère tout le temps le mê
*/
int id_counter = 0;
typedef struct node {
char label[LABEL_SIZE];
int left_child;
int right_child;
int id;
} node;
int create_node(char* l, int n1, int n2) {
node n;
strcpy(l, n.label);
n.left_child = n1;
n.right_child = n2;
n.id = id_counter;
id_counter++;
void init() {
init_table(&symbol_table);
}
void yyerror(char const* err) {
@ -175,5 +170,7 @@ void yyerror(char const* err) {
}
void main(void) {
init();
yyparse();
print_table(&symbol_table);
}

30
asm_instructions.c Обычный файл
Просмотреть файл

@ -0,0 +1,30 @@
#include "asm_instructions.h"
void init_instruction_table(InstructionTable *table) {
table->index = 0;
}
int add_instruction(InstructionTable *table, Instruction instruction, int arg1, int arg2, int arg3) {
if (table->index >= INSTRUCTION_TABLE_SIZE) {
return -1;
}
InstructionItem newItem;
newItem.instruction = instruction;
newItem.arg1 = arg1;
newItem.arg2 = arg2;
newItem.arg3 = arg3;
table->table[table->index] = newItem;
table->index++;
return 0;
}
void write_instruction_table(InstructionTable *table, FILE *file) {
for (int i = 0; i < table->index; i++) {
write_instruction(&table->table[i], file);
}
}
void write_instruction(InstructionItem *item, FILE *file) {
fprintf(file, "%s %d %d %d", instructions_labels[item->instruction], item->arg1, item->arg2, item->arg3);
}

59
asm_instructions.h Обычный файл
Просмотреть файл

@ -0,0 +1,59 @@
#ifndef COMPILATOR_2000_ASM_INSTRUCTIONS_H
#define COMPILATOR_2000_ASM_INSTRUCTIONS_H
#include <stdio.h>
#define INSTRUCTION_TABLE_SIZE 100
typedef enum Instruction {
ADD,
MUL,
SUO,
DIV,
COP,
AFC,
JMP,
JMF,
INF,
SUP,
EQU,
PRI
} Instruction;
char* instructions_labels[12] = {
"ADD",
"MUL",
"SUO",
"DIV",
"COP",
"AFC",
"JMP",
"JMF",
"INF",
"SUP",
"EQU",
"PRI"
};
typedef struct InstructionItem {
Instruction instruction;
int arg1;
int arg2;
int arg3;
} InstructionItem;
typedef struct InstructionTable {
InstructionItem table[INSTRUCTION_TABLE_SIZE];
int index;
} InstructionTable;
void init_instruction_table(InstructionTable *table);
int add_instruction(InstructionTable *table, Instruction instruction, int arg1, int arg2, int arg3);
void write_instruction_table(InstructionTable *table, FILE *file);
void write_instruction(InstructionItem *item, FILE *file);
#endif //COMPILATOR_2000_ASM_INSTRUCTIONS_H

Просмотреть файл

@ -1,5 +1,122 @@
#include "symbol_table.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void add_symbol(SymbolTable table, enum Type type, char *name) {
void init_table(SymbolTable *table) {
table->index = 0;
table->temp_index = SYMBOL_TABLE_SIZE - 1;
}
}
int has_symbol(SymbolTable* table, char *name) {
for (int i = 0; i < table->index; i++) {
if (strcmp(table->table[i].name, name) == 0) {
return 1;
}
}
for (int i = SYMBOL_TABLE_SIZE -1; i > table->temp_index; i--) {
if (strcmp(table->table[i].name, name) == 0) {
return 1;
}
}
return 0;
}
int add_symbol(SymbolTable *table, enum Type type, char *name) {
if (table->index > table->temp_index) {
return -2;
}
if (has_symbol(table, name)) {
return -1;
}
SymbolItem newItem;
newItem.type = type;
newItem.name = name;
newItem.address = table->index;
newItem.init = 0;
table->table[table->index] = newItem;
table->index++;
return 0;
}
int add_temp_symbol(SymbolTable* table, enum Type type, char *name) {
if (table->temp_index < table->index) {
return -2;
}
if (has_symbol(table, name)) {
return -1;
}
if (name[0] != '_') {
return -3;
}
SymbolItem newItem;
newItem.type = type;
newItem.name = name;
newItem.address = table->temp_index;
newItem.init = 0;
table->table[table->temp_index] = newItem;
table->temp_index--;
return 0;
}
int mark_symbol_initialized(SymbolTable *table, char *name) {
struct SymbolItem *item = get_symbol_item(table, name);
if (item != NULL) {
if (item->init == 1) {
return -2;
}
item->init = 1;
return 0;
}
return -1;
}
char* type_to_string(enum Type type) {
if (type == TYPE_CONST) {
return "const";
} else {
return " int ";
}
}
void print_table(SymbolTable *table) {
printf("Variables:\n");
printf("%10s | %5s | %3s | %1s\n", "name", "type", "@", "I");
for (int i = 0; i < table->index; i++) {
print_item(&table->table[i]);
}
printf("Temporary variables:\n");
for (int i = SYMBOL_TABLE_SIZE - 1; i > table->temp_index; i--) {
print_item(&table->table[i]);
}
}
void print_item(struct SymbolItem *item) {
if (item == NULL) {
printf("NULL");
}
else {
printf("%10s | %5s | %3d | %1d\n",
item->name,
type_to_string(item->type),
item->address,
item->init);
}
}
SymbolItem *get_symbol_item(SymbolTable *table, char *name) {
for (int i = 0; i < table->index; i++) {
if (strcmp(table->table[i].name, name) == 0) {
return &table->table[i];
}
}
for (int i = SYMBOL_TABLE_SIZE -1; i > table->temp_index; i--) {
if (strcmp(table->table[i].name, name) == 0) {
return &table->table[i];
}
}
return NULL;
}

Просмотреть файл

@ -8,18 +8,98 @@ enum Type {
TYPE_INT
};
struct SymbolItem {
typedef struct SymbolItem {
enum Type type;
char* name;
char *name;
int address;
int init;
};
} SymbolItem;
/**
* Stores temp variables at the end of the table
*/
typedef struct SymbolTable {
struct SymbolIte table[SYMBOL_TABLE_SIZE];
struct SymbolItem table[SYMBOL_TABLE_SIZE];
int index;
int temp_index;
} SymbolTable;
void add_symbol(SymbolTable table, enum Type type, char* name);
/**
* Initializes the table's index to 0
*
* @param table
*/
void init_table(SymbolTable *table);
/**
* Checks if the given symbol is in the table
*
* @param table
* @param name
* @return
*/
int has_symbol(SymbolTable* table, char *name);
/**
* Adds the given symbol to the table.
*
* @param table
* @param type
* @param name
* @return 0 on success, -1 if the symbol already exists, -2 if the table is full
*/
int add_symbol(SymbolTable* table, enum Type type, char *name);
/**
* Adds the given symbol to temporary variables space
* Temporary variables must start with _
*
* @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 _
*/
int add_temp_symbol(SymbolTable* table, enum Type type, char *name);
/**
* Marks the given symbol as initialized
*
* @param table
* @param name
* @return 0 on success, -1 if the symbol was not found, -2 if the symbol was already initialized
*/
int mark_symbol_initialized(SymbolTable* table, char *name);
/**
* Prints the whole table to the console
*
* @param table
*/
void print_table(SymbolTable* table);
/**
* Prints the given item to the console
*
* @param item
*/
void print_item(struct SymbolItem *item);
/**
* Converts a Type to a string
*
* @param type
* @return
*/
char* type_to_string(enum Type type);
/**
* Gets the table line for the given symbol name
*
* @param table
* @param name
* @return the item if found, NULL otherwise
*/
SymbolItem *get_symbol_item(SymbolTable* table, char *name);
#endif /* !SYMBOL_TABLE_H_INCLUDED */

59
symbol_table.test.c Обычный файл
Просмотреть файл

@ -0,0 +1,59 @@
#include "symbol_table.h"
#include <stdio.h>
#include <assert.h>
int main() {
int err;
SymbolTable table;
SymbolItem *item;
init_table(&table);
err = add_symbol(&table, TYPE_CONST, "y");
printf("Adding y symbol\n");
assert(err == 0);
err = add_symbol(&table, TYPE_INT, "x");
printf("Adding x symbol\n");
assert(err == 0);
err = add_symbol(&table, TYPE_CONST, "y");
printf("Adding y symbol\n");
assert(err == -1);
item = get_symbol_item(&table, "y");
printf("Getting item y: \n");
print_item(item);
err = mark_symbol_initialized(&table, "y");
printf("Mark y initialized\n");
assert(err == 0);
print_item(item);
err = mark_symbol_initialized(&table, "y");
printf("Mark y initialized\n");
assert(err == -2);
print_item(item);
err = mark_symbol_initialized(&table, "b");
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);
item = get_symbol_item(&table, "_temp1");
printf("_temp1:\n");
print_item(item);
item = get_symbol_item(&table, "_temp5");
printf("_temp5:\n");
print_item(item);
printf("\n=================\n");
printf("Full table: \n");
print_table(&table);
}

2
test.c
Просмотреть файл

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