compilator-2000/as.y
Arnaud Vergnet a1c0f7a19f add if
2021-04-06 18:17:10 +02:00

195 lines
5.1 KiB
Text

%{
#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;
int address;
Instruction instruction;
struct Condition* condition;
}
%token<nombre> tNB
%token<instruction> tADD
%token<instruction> tSUB
%token<instruction> tMUL
%token<instruction> tDIV
%token tPO
%token tPF
%token tPV
%token tVIRG
%token tAO
%token tAF
%token tEQ
%token<condition> tEQ2
%token<condition> tNOTEQ
%token<condition> tINF
%token<condition> tINFEQ
%token<condition> tSUP
%token<condition> tSUPEQ
%token tNOT
%token tAND
%token tOR
%token tINT
%token tCONST
%token tMAIN
%token tIF
%token tELSE
%token tELSIF
%token tWHILE
%token tPRINTF
%token<symbol_name> tID
%left tADD
%left tSUB
%left tMUL
%left tDIV
%type<symbol> E
%type<symbol> Cond
%type<address> IfSimple
%%
S : Main { printf("S\n"); } ;
Main : tINT tMAIN tPO Params tPF MainBody { printf("Main\n"); } ;
Params : | Param SuiteParams { printf("Params\n"); } ;
Param : tINT tID { printf("Param\n"); } ;
SuiteParams : tVIRG Param SuiteParams { printf("SuiteParam\n"); } ;
MainBody : tAO Declarations Instructions tAF { printf("MainBody\n"); } ;
Body : tAO Instructions tAF { printf("Body\n"); } ;
Instructions : Instruction Instructions | { printf("Instructions\n"); } ;
Instruction : Aff | Printf | If { printf("Instruction\n"); } ;
Aff : tID tEQ E tPV { write_affectation(&symbol_table, &instruction_table, $1, $3); } ;
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 ;
Declaration : DeclarationInt | DeclarationConst ;
DeclarationInt : tINT { current_type = TYPE_INT; } DeclarationBody tPV ;
DeclarationConst : tCONST { current_type = TYPE_CONST; } DeclarationBody tPV ;
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 { update_jmf(&instruction_table, $1); } ;
IfSimple : tIF tPO Cond tPF { $<address>$ = write_jmf(&instruction_table, $3); } Body { $$ = $<address>5; };
// IfElse : IfSimple tELSE Body { printf("IfElse\n"); } ;
Cond : tNOT Cond { $$ = write_not_condition(&symbol_table, &instruction_table, $2); }
| Cond tAND Cond { $$ = write_op(&symbol_table, &instruction_table, MUL, $1, $3); }
| Cond tOR Cond { $$ = write_op(&symbol_table, &instruction_table, ADD, $1, $3); }
| E tEQ2 E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
| E tINF E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
| E tINFEQ E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
| E tSUP E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
| E tSUPEQ E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
| E tNOTEQ E { $$ = write_condition(&symbol_table, &instruction_table, $2, $1, $3); }
| tNOT tPO Cond tPF { $$ = write_not_condition(&symbol_table, &instruction_table, $3); } ;
Printf : tPRINTF tPO E tPF tPV { write_print(&instruction_table, $3); } ;
%%
#include <string.h>
#define LABEL_SIZE 10
// ADD @ + @ -> @
// SUB @ - @ -> @
// AFC nb -> @
// CPY @ -> @
// Exemple
// y = 1 + 2;
// AFC 1 32
// AFC 2 33
// ADD 32 33 32
// CPY 32 @y
/*
table des symboles (tS) :
sous forme de pile
-> où sera la variable lors de l'exec
|
| nom | type | @ | init |
|-------|--------|-----|--------|
| a | | 0 | |
| b | | 1 | |
| c | | 2 | |
| | | | |
| . | | . | | -> entiers sur 1 octet
| . | | . | |
| . | | . | |
| | | | |
| y | | 26 | |
Donc on remplace @y par 26 dans CPY 32 @y
/!\
E + E + E
| | |
-> -> -> vt variable temporaire (autre expression)
-> -> -> variable -> ADD @E1 @E2 vt
-> -> -> nombre
Donc 9 possibilités (3 par E)
On suppose que E est tout le temps une vt, donc on génère tout le temps le même code
*/
void init() {
init_table(&symbol_table);
init_instruction_table(&instruction_table);
}
void yyerror(char const* err) {
printf("%s\n", err);
exit(1);
}
void main(void) {
init();
yyparse();
print_table(&symbol_table);
FILE *f = fopen("instruction_table.txt", "w+");
write_instruction_table(&instruction_table, f);
fclose(f);
}