%{ #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; } %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 tNOT %token tINF %token tINFEQ %token tSUP %token tSUPEQ %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 %% 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 { printf("Instruction\n"); } ; Aff : tID tEQ E tPV { mark_symbol_initialized(&symbol_table, $1); } ; 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 { 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 | IfElse { printf("If\n"); } ; // // IfSimple : tIF tPO Cond tPF Body { printf("IfSimple\n"); } ; // // IfElse : IfSimple tELSE Body { printf("IfElse\n"); } ; // // Cond : tNOT Cond | Cond tAND Cond | Cond tOR Cond | E tEQ2 E | E tINF E | E tINFEQ E | E tSUP E | E tSUPEQ E | E tNOTEQ E | tNOT tPO Cond tPF { printf("Cond\n"); } ; Printf : tPRINTF tPO tID tPF tPV { printf("Printf\n"); } ; // If : tIF tPO Cond tPF Body ; // // Cond : Cond tAND Cond | Cond tOR Cond | E tEQ2 E | E tINF E | tNOT Cond ; // Invocation : tID tPO Args tPF ; // Args : .... cf params // Return : tRET E tPV ; %% #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); } void yyerror(char const* err) { printf("%s\n", err); exit(1); } void main(void) { init(); yyparse(); print_table(&symbol_table); }