Browse Source

implement symbol table and start asm

Arnaud Vergnet 8 months ago
parent
commit
96ab1bf771
9 changed files with 384 additions and 33 deletions
  1. 6
    3
      Makefile
  2. 5
    1
      al.lex
  3. 19
    22
      as.y
  4. 30
    0
      asm_instructions.c
  5. 59
    0
      asm_instructions.h
  6. 119
    2
      symbol_table.c
  7. 85
    5
      symbol_table.h
  8. 59
    0
      symbol_table.test.c
  9. 2
    0
      test.c

+ 6
- 3
Makefile View File

@@ -2,10 +2,13 @@ LEX = flex
2 2
 YACC = bison -d -v
3 3
 CC = gcc
4 4
 
5
-all: compilateur
5
+all: compilateur test
6 6
 
7
-compilateur: as.tab.c lex.yy.c symbol_table.c
8
-	$(CC) -o compilateur as.tab.c lex.yy.c symbol_table.c
7
+test: symbol_table.test.c symbol_table.c symbol_table.h
8
+	$(CC) -o test symbol_table.test.c symbol_table.c
9
+
10
+compilateur: as.tab.c lex.yy.c symbol_table.c symbol_table.h asm_instructions.c asm_instructions.h
11
+	$(CC) -o compilateur as.tab.c lex.yy.c symbol_table.c asm_instructions.c
9 12
 
10 13
 as.tab.c: as.y
11 14
 	$(YACC) as.y

+ 5
- 1
al.lex View File

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

+ 19
- 22
as.y View File

@@ -1,9 +1,16 @@
1 1
 %{
2 2
 #include "stdio.h"
3 3
 #include "stdlib.h"
4
+#include "symbol_table.h"
5
+
6
+enum Type current_type = TYPE_INT;
7
+
8
+SymbolTable symbol_table;
9
+
4 10
 %}
5 11
 
6 12
 %union {
13
+    char* symbol_name;
7 14
 	int nombre;
8 15
 }
9 16
 
@@ -37,7 +44,7 @@
37 44
 %token tELSIF
38 45
 %token tWHILE
39 46
 %token tPRINTF
40
-%token tID
47
+%token<symbol_name> tID
41 48
 
42 49
 %left tADD
43 50
 %left tSUB
@@ -64,20 +71,22 @@ Instructions : Instruction Instructions |  { printf("Instructions\n"); } ;
64 71
 
65 72
 Instruction : Aff | Printf { printf("Instruction\n"); } ;
66 73
 
67
-Aff : tID tEQ E tPV { printf("Aff\n"); } ;
74
+Aff : tID tEQ E tPV { mark_symbol_initialized(&symbol_table, $1); } ;
68 75
 
69
-E : tNB | tID | E tADD E | E tMUL E | E tSUB E | E tDIV E | tPO E tPF | tSUB E { printf("E\n"); } ;
76
+E : tNB { printf("%d\n", $1); } | tID | E tADD E | E tMUL E | E tSUB E | E tDIV E | tPO E tPF | tSUB E ;
70 77
 
71 78
 Declarations : | Declaration Declarations { printf("Declarations\n"); } ;
72 79
 
73 80
 Declaration : DeclarationInt | DeclarationConst { printf("Declaration\n"); } ;
74 81
 
75
-DeclarationInt : tINT DeclarationBody tPV { printf("DeclarationInt\n"); } ;
82
+DeclarationInt : tINT { current_type = TYPE_INT; } DeclarationBody tPV ;
76 83
 
77
-DeclarationConst : tCONST DeclarationBody tPV { printf("DeclarationConst\n"); } ;
84
+DeclarationConst : tCONST { current_type = TYPE_CONST; }  DeclarationBody tPV ;
78 85
 
79
-DeclarationBody : tID tVIRG DeclarationBody | tID { printf("DeclarationBody\n"); } ;
86
+DeclarationBody : VariableIdentifier tVIRG DeclarationBody | VariableIdentifier ;
80 87
 
88
+VariableIdentifier: tID { add_symbol(&symbol_table, current_type, $1); }
89
+    
81 90
 // While : tWHILE tPO Cond tPF Body { printf("While\n"); } ;
82 91
 // 
83 92
 // 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ê
151 160
 
152 161
 */
153 162
 
154
-int id_counter = 0;
155
-
156
-typedef struct node {
157
-    char label[LABEL_SIZE];
158
-    int left_child;
159
-    int right_child;
160
-    int id;
161
-} node;
162
-
163
-int create_node(char* l, int n1, int n2) {
164
-     node n;
165
-     strcpy(l, n.label);
166
-     n.left_child = n1;
167
-     n.right_child = n2;
168
-     n.id = id_counter;
169
-     id_counter++;
163
+void init() {
164
+    init_table(&symbol_table);
170 165
 }
171 166
 
172 167
 void yyerror(char const* err) {
@@ -175,5 +170,7 @@ void yyerror(char const* err) {
175 170
 }
176 171
 
177 172
 void main(void) {
173
+    init();
178 174
 	yyparse();
175
+	print_table(&symbol_table);
179 176
 }

+ 30
- 0
asm_instructions.c View File

@@ -0,0 +1,30 @@
1
+#include "asm_instructions.h"
2
+
3
+void init_instruction_table(InstructionTable *table) {
4
+    table->index = 0;
5
+}
6
+
7
+int add_instruction(InstructionTable *table, Instruction instruction, int arg1, int arg2, int arg3) {
8
+    if (table->index >= INSTRUCTION_TABLE_SIZE) {
9
+        return -1;
10
+    }
11
+    InstructionItem newItem;
12
+    newItem.instruction = instruction;
13
+    newItem.arg1 = arg1;
14
+    newItem.arg2 = arg2;
15
+    newItem.arg3 = arg3;
16
+
17
+    table->table[table->index] = newItem;
18
+    table->index++;
19
+    return 0;
20
+}
21
+
22
+void write_instruction_table(InstructionTable *table, FILE *file) {
23
+    for (int i = 0; i < table->index; i++) {
24
+        write_instruction(&table->table[i], file);
25
+    }
26
+}
27
+
28
+void write_instruction(InstructionItem *item, FILE *file) {
29
+    fprintf(file, "%s %d %d %d", instructions_labels[item->instruction], item->arg1, item->arg2, item->arg3);
30
+}

+ 59
- 0
asm_instructions.h View File

@@ -0,0 +1,59 @@
1
+#ifndef COMPILATOR_2000_ASM_INSTRUCTIONS_H
2
+#define COMPILATOR_2000_ASM_INSTRUCTIONS_H
3
+
4
+#include <stdio.h>
5
+
6
+#define INSTRUCTION_TABLE_SIZE 100
7
+
8
+typedef enum Instruction {
9
+        ADD,
10
+        MUL,
11
+        SUO,
12
+        DIV,
13
+        COP,
14
+        AFC,
15
+        JMP,
16
+        JMF,
17
+        INF,
18
+        SUP,
19
+        EQU,
20
+        PRI
21
+} Instruction;
22
+
23
+char* instructions_labels[12] = {
24
+        "ADD",
25
+        "MUL",
26
+        "SUO",
27
+        "DIV",
28
+        "COP",
29
+        "AFC",
30
+        "JMP",
31
+        "JMF",
32
+        "INF",
33
+        "SUP",
34
+        "EQU",
35
+        "PRI"
36
+};
37
+
38
+
39
+typedef struct InstructionItem {
40
+    Instruction instruction;
41
+    int arg1;
42
+    int arg2;
43
+    int arg3;
44
+} InstructionItem;
45
+
46
+typedef struct InstructionTable {
47
+    InstructionItem table[INSTRUCTION_TABLE_SIZE];
48
+    int index;
49
+} InstructionTable;
50
+
51
+void init_instruction_table(InstructionTable *table);
52
+
53
+int add_instruction(InstructionTable *table, Instruction instruction, int arg1, int arg2, int arg3);
54
+
55
+void write_instruction_table(InstructionTable *table, FILE *file);
56
+
57
+void write_instruction(InstructionItem *item, FILE *file);
58
+
59
+#endif //COMPILATOR_2000_ASM_INSTRUCTIONS_H

+ 119
- 2
symbol_table.c View File

@@ -1,5 +1,122 @@
1 1
 #include "symbol_table.h"
2
+#include <stdlib.h>
3
+#include <stdio.h>
4
+#include <string.h>
2 5
 
3
-void add_symbol(SymbolTable table, enum Type type, char *name) {
6
+void init_table(SymbolTable *table) {
7
+    table->index = 0;
8
+    table->temp_index = SYMBOL_TABLE_SIZE - 1;
9
+}
4 10
 
5
-}
11
+int has_symbol(SymbolTable* table, char *name) {
12
+    for (int i = 0; i < table->index; i++) {
13
+        if (strcmp(table->table[i].name, name) == 0) {
14
+            return 1;
15
+        }
16
+    }
17
+    for (int i = SYMBOL_TABLE_SIZE -1; i > table->temp_index; i--) {
18
+        if (strcmp(table->table[i].name, name) == 0) {
19
+            return 1;
20
+        }
21
+    }
22
+    return 0;
23
+}
24
+
25
+int add_symbol(SymbolTable *table, enum Type type, char *name) {
26
+    if (table->index > table->temp_index) {
27
+        return -2;
28
+    }
29
+    if (has_symbol(table, name)) {
30
+        return -1;
31
+    }
32
+    SymbolItem newItem;
33
+    newItem.type = type;
34
+    newItem.name = name;
35
+    newItem.address = table->index;
36
+    newItem.init = 0;
37
+
38
+    table->table[table->index] = newItem;
39
+    table->index++;
40
+    return 0;
41
+}
42
+
43
+int add_temp_symbol(SymbolTable* table, enum Type type, char *name) {
44
+    if (table->temp_index < table->index) {
45
+        return -2;
46
+    }
47
+    if (has_symbol(table, name)) {
48
+        return -1;
49
+    }
50
+    if (name[0] != '_') {
51
+        return -3;
52
+    }
53
+
54
+    SymbolItem newItem;
55
+    newItem.type = type;
56
+    newItem.name = name;
57
+    newItem.address = table->temp_index;
58
+    newItem.init = 0;
59
+
60
+    table->table[table->temp_index] = newItem;
61
+    table->temp_index--;
62
+    return 0;
63
+}
64
+
65
+int mark_symbol_initialized(SymbolTable *table, char *name) {
66
+    struct SymbolItem *item = get_symbol_item(table, name);
67
+    if (item != NULL) {
68
+        if (item->init == 1) {
69
+            return -2;
70
+        }
71
+        item->init = 1;
72
+        return 0;
73
+    }
74
+    return -1;
75
+}
76
+
77
+char* type_to_string(enum Type type) {
78
+    if (type == TYPE_CONST) {
79
+        return "const";
80
+    } else {
81
+        return " int ";
82
+    }
83
+}
84
+
85
+void print_table(SymbolTable *table) {
86
+    printf("Variables:\n");
87
+    printf("%10s | %5s | %3s | %1s\n", "name", "type", "@", "I");
88
+    for (int i = 0; i < table->index; i++) {
89
+        print_item(&table->table[i]);
90
+    }
91
+    printf("Temporary variables:\n");
92
+    for (int i = SYMBOL_TABLE_SIZE - 1; i > table->temp_index; i--) {
93
+        print_item(&table->table[i]);
94
+    }
95
+}
96
+
97
+void print_item(struct SymbolItem *item) {
98
+    if (item == NULL) {
99
+        printf("NULL");
100
+    }
101
+    else {
102
+        printf("%10s | %5s | %3d | %1d\n",
103
+               item->name,
104
+               type_to_string(item->type),
105
+               item->address,
106
+               item->init);
107
+    }
108
+}
109
+
110
+SymbolItem *get_symbol_item(SymbolTable *table, char *name) {
111
+    for (int i = 0; i < table->index; i++) {
112
+        if (strcmp(table->table[i].name, name) == 0) {
113
+            return &table->table[i];
114
+        }
115
+    }
116
+    for (int i = SYMBOL_TABLE_SIZE -1; i > table->temp_index; i--) {
117
+        if (strcmp(table->table[i].name, name) == 0) {
118
+            return &table->table[i];
119
+        }
120
+    }
121
+    return NULL;
122
+}

+ 85
- 5
symbol_table.h View File

@@ -8,18 +8,98 @@ enum Type {
8 8
     TYPE_INT
9 9
 };
10 10
 
11
-struct SymbolItem {
11
+typedef struct SymbolItem {
12 12
     enum Type type;
13
-    char* name;
13
+    char *name;
14 14
     int address;
15 15
     int init;
16
-};
16
+} SymbolItem;
17 17
 
18
+/**
19
+ * Stores temp variables at the end of the table
20
+ */
18 21
 typedef struct SymbolTable {
19
-    struct SymbolIte table[SYMBOL_TABLE_SIZE];
22
+    struct SymbolItem table[SYMBOL_TABLE_SIZE];
20 23
     int index;
24
+    int temp_index;
21 25
 } SymbolTable;
22 26
 
23
-void add_symbol(SymbolTable table, enum Type type, char* name);
27
+/**
28
+ * Initializes the table's index to 0
29
+ *
30
+ * @param table
31
+ */
32
+void init_table(SymbolTable *table);
33
+
34
+/**
35
+ * Checks if the given symbol is in the table
36
+ *
37
+ * @param table
38
+ * @param name
39
+ * @return
40
+ */
41
+int has_symbol(SymbolTable* table, char *name);
42
+
43
+/**
44
+ * Adds the given symbol to the table.
45
+ *
46
+ * @param table
47
+ * @param type
48
+ * @param name
49
+ * @return 0 on success, -1 if the symbol already exists, -2 if the table is full
50
+ */
51
+int add_symbol(SymbolTable* table, enum Type type, char *name);
52
+
53
+/**
54
+ * Adds the given symbol to temporary variables space
55
+ * Temporary variables must start with _
56
+ *
57
+ * @param table
58
+ * @param type
59
+ * @param name
60
+ * @return 0 on success, -1 if the symbol already exists, -2 if the table is full
61
+ *          -3 if the name doesn't start by _
62
+ */
63
+int add_temp_symbol(SymbolTable* table, enum Type type, char *name);
64
+
65
+/**
66
+ * Marks the given symbol as initialized
67
+ *
68
+ * @param table
69
+ * @param name
70
+ * @return 0 on success, -1 if the symbol was not found, -2 if the symbol was already initialized
71
+ */
72
+int mark_symbol_initialized(SymbolTable* table, char *name);
73
+
74
+/**
75
+ * Prints the whole table to the console
76
+ *
77
+ * @param table
78
+ */
79
+void print_table(SymbolTable* table);
80
+
81
+/**
82
+ * Prints the given item to the console
83
+ *
84
+ * @param item
85
+ */
86
+void print_item(struct SymbolItem *item);
87
+
88
+/**
89
+ * Converts a Type to a string
90
+ *
91
+ * @param type
92
+ * @return
93
+ */
94
+char* type_to_string(enum Type type);
95
+
96
+/**
97
+ * Gets the table line for the given symbol name
98
+ *
99
+ * @param table
100
+ * @param name
101
+ * @return the item if found, NULL otherwise
102
+ */
103
+SymbolItem *get_symbol_item(SymbolTable* table, char *name);
24 104
 
25 105
 #endif /* !SYMBOL_TABLE_H_INCLUDED  */

+ 59
- 0
symbol_table.test.c View File

@@ -0,0 +1,59 @@
1
+#include "symbol_table.h"
2
+#include <stdio.h>
3
+#include <assert.h>
4
+
5
+int main() {
6
+    int err;
7
+    SymbolTable table;
8
+    SymbolItem *item;
9
+
10
+    init_table(&table);
11
+    err = add_symbol(&table, TYPE_CONST, "y");
12
+    printf("Adding y symbol\n");
13
+    assert(err == 0);
14
+    err = add_symbol(&table, TYPE_INT, "x");
15
+    printf("Adding x symbol\n");
16
+    assert(err == 0);
17
+    err = add_symbol(&table, TYPE_CONST, "y");
18
+    printf("Adding y symbol\n");
19
+    assert(err == -1);
20
+
21
+    item = get_symbol_item(&table, "y");
22
+    printf("Getting item y: \n");
23
+    print_item(item);
24
+    err = mark_symbol_initialized(&table, "y");
25
+    printf("Mark y initialized\n");
26
+    assert(err == 0);
27
+    print_item(item);
28
+    err = mark_symbol_initialized(&table, "y");
29
+    printf("Mark y initialized\n");
30
+    assert(err == -2);
31
+    print_item(item);
32
+    err = mark_symbol_initialized(&table, "b");
33
+    printf("Mark b initialized\n");
34
+    assert(err == -1);
35
+
36
+    err = add_temp_symbol(&table, TYPE_INT, "_temp1");
37
+    printf("Add _temp1 temporary variable\n");
38
+    assert(err == 0);
39
+    err = add_temp_symbol(&table, TYPE_INT, "_temp2");
40
+    printf("Add _temp2 temporary variable\n");
41
+    assert(err == 0);
42
+    err = add_temp_symbol(&table, TYPE_INT, "_temp1");
43
+    printf("Add _temp1 temporary variable\n");
44
+    assert(err == -1);
45
+    err = add_temp_symbol(&table, TYPE_INT, "temp1");
46
+    printf("Add temp1 temporary variable\n");
47
+    assert(err == -3);
48
+
49
+    item = get_symbol_item(&table, "_temp1");
50
+    printf("_temp1:\n");
51
+    print_item(item);
52
+    item = get_symbol_item(&table, "_temp5");
53
+    printf("_temp5:\n");
54
+    print_item(item);
55
+
56
+    printf("\n=================\n");
57
+    printf("Full table: \n");
58
+    print_table(&table);
59
+}

+ 2
- 0
test.c View File

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

Loading…
Cancel
Save