implement symbol table and start asm
This commit is contained in:
rodzic
d250a8f837
commit
96ab1bf771
9 zmienionych plików z 384 dodań i 33 usunięć
9
Makefile
9
Makefile
|
@ -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
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
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
Normal file
30
asm_instructions.c
Normal file
|
@ -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
Normal file
59
asm_instructions.h
Normal file
|
@ -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
|
121
symbol_table.c
121
symbol_table.c
|
@ -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
Normal file
59
symbol_table.test.c
Normal file
|
@ -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
test.c
|
@ -2,4 +2,6 @@ int main(){
|
|||
int x, y, z;
|
||||
const PL5_op, b, c;
|
||||
printf(x);
|
||||
x = 3 + 2;
|
||||
y = 3;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in a new issue