%{ #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 tNB %token tADD %token tSUB %token tMUL %token tDIV %token tPO %token tPF %token tPV %token tVIRG %token tAO %token tAF %token tEQ %token tEQ2 %token tNOTEQ %token tINF %token tINFEQ %token tSUP %token tSUPEQ %token tNOT %token tAND %token tOR %token tINT %token tCONST %token tMAIN %token tIF %token tELSE %token tELSIF %token tWHILE %token tPRINTF %token tID %left tADD %left tSUB %left tMUL %left tDIV %type E %type Cond %type
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 { $
$ = write_jmf(&instruction_table, $3); } Body { $$ = $
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 #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); }