Début génération assembleur

这个提交包含在:
Faure Paul 2021-03-22 12:45:54 +01:00
父节点 3f2aa96c19
当前提交 eeba39940b
共有 17 个文件被更改,包括 5507 次插入0 次删除

二进制文件未显示。

查看文件

@ -0,0 +1,52 @@
les fonctions (avec parametres)
le if
le while
les declarations
les affectations
les operations arith.
le retour de fonction
l'invocation de fonctions
C : Fonctions ;
Fonctions : Fonction Fonctions | Fonction ;
Fonction : tInt tID tPO Params tPF Body ;
Params : | Param SuiteParams ;
Param : tInt tID ;
SuiteParams : tVirgule Param SuiteParams | ;
// Ps : P Ps | ;
// P : tInt tID tVirgule
// Ps =>* tInt tID tVirgule tInt tID tVirgule
// Ps => P Ps => P P Ps ...
Body : tAO Instructions tAF ;
Instructions : Instruction Instructions | ;
Instruction : Aff | If | While | Return | Decl | Invocation tPV ;
Aff : tID tEQ E tPV ;
E : tNB | tID | E tADD E | E tMUL E | E tMINUS E | E tDIV E | Invocation | tPO E tPF | tMINUS E ;
// E : tID tADD tID | ...
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 ;

15
Fichiers_Tests/progC 普通文件
查看文件

@ -0,0 +1,15 @@
int main(int x, int i){
const int a = 4;
const int a, b, c = 2 + a - 5 * (7 / 8) + 5;
printf(coucou);
int y = 7e8;
int res_2 = x + y;
if ( (a == 2) && b || c > (7*8)) {
}
else if (a) {
int x = 90;
} else {
int a = b;
}
printf(i);
}

二进制
Lex_Yacc/a.out 可执行文件

二进制文件未显示。

43
Lex_Yacc/al.lex 普通文件
查看文件

@ -0,0 +1,43 @@
%{
#include "as.tab.h"
int yywrap(void){return 1;}
%}
%%
"main" { return tMAIN ;}
"{" { return tOBRACKET;}
"}" { return tCBRACKET; }
"(" { return tOBRACE; }
")" { return tCBRACE; }
"const" { return tCONST; }
"int" { return tINT; }
"printf" { return tPRINTF; } //Degeu mais à degager
"if" { return tIF; }
"while" { return tWHILE; }
"<" { return tLT; }
">" { return tGT; }
"==" { return tEQCOND; }
"&&" { return tAND; }
"||" { return tOR; }
"else" { return tELSE;}
[0-9]+ { yylval.nombre = atoi(yytext); return tNB; }
[0-9]+e[0-9]+ { yylval.nombre = -1; return tNBEXP; } //Renvoyer le token tNB et pas tNBEXP
"+" { return tADD; }
"-" { return tSUB; }
"*" { return tMUL; }
"/" { return tDIV; }
"=" { return tEQ; }
";" { return tPV; }
" " {} //Ne pas les retourner à Yacc
" " {} //Ne pas les retourner à Yacc
"," { return tCOMA; }
"\n" {} //Ne pas les retourner à Yacc
[a-zA-Z][a-zA-Z0-9_]* { strcpy(yylval.id, yytext); return tID; }
. { return tERROR; }
%%

1290
Lex_Yacc/as.output 普通文件

文件差异内容过多而无法显示 加载差异

1714
Lex_Yacc/as.tab.c 普通文件

文件差异内容过多而无法显示 加载差异

102
Lex_Yacc/as.tab.h 普通文件
查看文件

@ -0,0 +1,102 @@
/* A Bison parser, made by GNU Bison 3.0.4. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_YY_AS_TAB_H_INCLUDED
# define YY_YY_AS_TAB_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 1
#endif
#if YYDEBUG
extern int yydebug;
#endif
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
tMAIN = 258,
tOBRACKET = 259,
tCBRACKET = 260,
tOBRACE = 261,
tCBRACE = 262,
tINT = 263,
tCONST = 264,
tPV = 265,
tCOMA = 266,
tMUL = 267,
tDIV = 268,
tADD = 269,
tSUB = 270,
tEQ = 271,
tNB = 272,
tNBEXP = 273,
tID = 274,
tPRINTF = 275,
tERROR = 276,
tIF = 277,
tWHILE = 278,
tELSE = 279,
tLT = 280,
tGT = 281,
tEQCOND = 282,
tAND = 283,
tOR = 284,
tNOT = 285
};
#endif
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
#line 1 "as.y" /* yacc.c:1909 */
int nombre;
char id[30];
#line 90 "as.tab.h" /* yacc.c:1909 */
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;
int yyparse (void);
#endif /* !YY_YY_AS_TAB_H_INCLUDED */

159
Lex_Yacc/as.y 普通文件
查看文件

@ -0,0 +1,159 @@
%union {
int nombre;
char id[30];
}
%{
#include "../Symboles/table_symboles.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int addr = 0;
%}
%token tMAIN
%token tOBRACKET tCBRACKET
%token tOBRACE tCBRACE
%token tINT
%token tCONST
%token tPV tCOMA#include <string.h>
%token tMUL tDIV tADD tSUB tEQ
%token<nombre> tNB tNBEXP
%token<id> tID
%token tPRINTF
%token tERROR
%token tIF tWHILE tELSE
%token tLT tGT tEQCOND
%token tAND tOR
%left tAND tOR
%left tNOT
%left tLT tGT
%left tEQCOND
%left tADD tSUB
%left tMUL tDIV
//%type<nombre> E
/******************************************** FAIRE LA GENERATION DU CODE ASSEMBLEUR DANS UN TABLEAU AVEC UN FPRINTF *******************/
%%
Main : tINT tMAIN tOBRACE Params tCBRACE Body { print(pile); printf("addr = %d\n",addr);} ;
Params : { printf("Sans Params\n"); } ;
Params : Param SuiteParams ;
Param : tINT tID { printf("Prametre : %s\n", $2); };
SuiteParams : tCOMA Param SuiteParams ;
SuiteParams : ;
Body : tOBRACKET Instructions tCBRACKET { struct symbole_t symbole = {"Salut", 0x77b58af, INT, 1}; push(symbole, pile); } ;
Instructions : Instruction Instructions ;
Instructions : ;
Instruction : Aff ;
Instruction : Decl ;
Instruction : Invocation tPV ;
Instruction : If;
Instruction : While;
If : tIF tOBRACE Cond tCBRACE Body Else { printf("If reconnu\n"); };
Else : tELSE If { printf("Else if reconnu\n"); };
Else : tELSE Body { printf("Else reconnu\n"); };
Else : ;
While : tWHILE tOBRACE Cond tCBRACE Body { printf("While reconnu\n"); };
Cond : E SuiteCond ;
SuiteCond : ;
SuiteCond : tAND E SuiteCond;
SuiteCond : tOR E SuiteCond;
Aff : tID tEQ E tPV { printf("%s prend une valeur\n", $1);} ; //besoin de get_address
E : tNB { printf("Nombre\n");
struct symbole_t symbole = ("", addr, INT, 1};
push(symbole, pile);
$$=addr;
addr++;
printf("AFC %d %d",addr,$1); } ;
E : tNBEXP { printf("Nombre exp\n"); struct symbole_t symbole = {"", addr, INT, 1}; push(symbole, pile); $$=addr; addr++; printf("AFC %d %d",addr,$1); };
E : tID { printf("Id\n"); /*Faire un get_address sur la pile*/};
E : E tMUL E { printf("Mul\n"); struct symbole_t symbole = {"", addr, INT, 1}; push(symbole, pile); $$=addr; addr++; printf("MUL %d %d %d",addr, $1,$2);};
E : E tDIV E { printf("Div\n"); struct symbole_t symbole = {"", addr, INT, 1}; push(symbole, pile); $$=addr; addr++; printf("DIV %d %d %d",addr, $1,$2);};
E : E tSUB E { printf("Sub\n"); struct symbole_t symbole = {"", addr, INT, 1}; push(symbole, pile); $$=addr; addr++; printf("SOU %d %d %d",addr, $1,$2);};
E : E tADD E { printf("Add\n"); struct symbole_t symbole = {"", addr, INT, 1}; push(symbole, pile); $$=addr; addr++; printf("ADD %d %d %d",addr, $1,$2);}};
E : Invocation { printf("Invoc\n"); struct symbole_t symbole = {"", addr, INT, 1}; push(symbole, pile); $$=addr; addr++; printf("AFC %d %d",addr, $1);};
E : tOBRACE E tCBRACE { printf("Parentheses\n"); $$=$2};
E : tSUB E { printf("Moins\n"); printf("SUB %d 0 %d",addr,$2);};
E : E tEQCOND E { printf("==\n"); struct symbole_t symbole = {"", addr, INT, 1}; push(symbole, pile); $$=addr; addr++; printf("EQU %d %d %d",addr, $1,$3);};
E : E tGT E { printf(">\n"); struct symbole_t symbole = {"", addr, INT, 1}; push(symbole, pile); $$=addr; addr++; printf("SUP %d %d %d",addr, $1,$3);};
E : E tLT E { printf("<\n"); struct symbole_t symbole = {"", addr, INT, 1}; push(symbole, pile); $$=addr; addr++; printf("SUP %d %d %d",addr, $1,$3);};
E : tNOT E { printf("!\n"); };
//Créer un champ isConst dans la table des symboles
Decl : tCONST tINT tID SuiteDeclConst { int init = ($3 != -1);
if (init){
int val = *$2;
printf("AFC %ld %d",addr,val);
}
struct symbole_t symbole = {$2, addr, INT, init};
push(symbole, pile);
addr++;} ;
SuiteDeclConst : tCOMA tID SuiteDecl { $$=$3; int init = ($3 != -1);
if (init){
int val = *$2;
printf("AFC %ld %d",addr,val);
}
struct symbole_t symbole = {$2, addr, INT, init}; push(symbole, pile); addr++;};
SuiteDeclConst : tEQ E tPV { $$=$2; };
SuiteDeclConst : tPV { $$=$2; };
Decl : tINT tID SuiteDecl { int init = ($3 != -1);
if (init){
int val = *$2;
printf("AFC %ld %d",addr,val);
}
struct symbole_t symbole = {$2, addr, INT, init};
push(symbole, pile);
addr++;} ;
SuiteDecl : tCOMA tID SuiteDecl
{ $$=$3;
int init = ($3 != -1);
if (init){
int val = *$2;
printf("AFC %ld %d",addr,val);
}
struct symbole_t symbole = {$2, addr, INT, init};
push(symbole, pile);
addr++;};
SuiteDecl : tEQ E tPV { $$=$2;};
SuiteDecl : tPV { $$=$2; };
Invocation : tPRINTF tOBRACE tID tCBRACE { printf("Appel de printf sur %s\n", $3); } ;
/*S : E tPV
{ printf("RES: %d\n", $1); }
S
| { printf("END\n"); }
;
E : E tADD E { $$ = $1 + $3; }
| E tSUB E { $$ = $1 - $3; }
| tOB E tCB { $$ = $2; }
| tNB { $$ = $1; }
;*/
%%
void main(void) {
init();
yyparse();
}

5
Lex_Yacc/comp.sh 可执行文件
查看文件

@ -0,0 +1,5 @@
bison -d -t as.y -v
flex al.lex
gcc *.c ../Symboles/table_symboles.c -ly
cat ../Fichiers_Tests/progC | ./a.out

1929
Lex_Yacc/lex.yy.c 普通文件

文件差异内容过多而无法显示 加载差异

118
Symboles/table_symboles.c 普通文件
查看文件

@ -0,0 +1,118 @@
/* TABLE DES SYMBOLE DU COMPILATEUR (PILE)
-----------------------------------------------------
| symbole | adresse | type | initialisé |
-----------------------------------------------------
| | | | |
| | | | |
| | | | |
| i | 0x777756b8 | int | false |
| size | 0x777756b8 | int | true |
-----------------------------------------------------
Types pour l'implémentation :
- enum type_t : [int]
- struct symbole : {
char nom[30];
uintptr_t adresse;
enum type_t type;
char initialized;
}
Opérations possible :
- init -> pile * -> void
- push -> symbole -> pile * -> void
- pop -> pile * -> symbole
- exist -> pile * -> symbole -> char
- initialized -> pile * -> symbole -> char */
#include "table_symboles.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
struct element_t {
struct symbole_t symbole;
struct element_t * suivant;
};
struct pile_t {
int taille;
struct element_t * first;
};
char * type_to_string(enum type_t type) {
if (type == INT) {
return "int";
} else {
return "unknown";
}
}
void print_symbole(struct symbole_t symbole) {
if (symbole.initialized) {
printf("\t\t{nom:%s, adresse:%p, type:%s, initialized:OUI}\n", symbole.nom, (void *)(symbole.adresse), type_to_string(symbole.type));
} else {
printf("\t\t{nom:%s, adresse:%p, type:%s, initialized:NON}\n", symbole.nom, (void *)(symbole.adresse), type_to_string(symbole.type));
}
}
void init (void) {
pile = malloc(sizeof(struct pile_t));
pile->first = NULL;
pile->taille = 0;
}
void push(struct symbole_t symbole, struct pile_t * pile) {
struct element_t * aux = malloc(sizeof(struct element_t));
aux->symbole = symbole;
aux->suivant = pile->first;
pile->first = aux;
pile->taille++;
}
struct symbole_t pop(struct pile_t * pile) {
struct symbole_t retour = {"", 0, UNKNOWN, 0};
struct element_t * aux;
if (pile->taille > 0) {
aux = pile->first;
pile->first = pile->first->suivant;
retour = aux->symbole;
free(aux);
pile->taille--;
}
return retour;
}
char status(char * nom, struct pile_t * pile) {
char retour = 0;
struct element_t * aux = pile->first;
int i;
for (i=0; i < pile->taille; i++) {
if (!strcmp(nom, aux->symbole.nom)) {
if (aux->symbole.initialized) {
retour = 1;
} else {
retour = 2;
}
break;
} else {
aux = aux->suivant;
}
}
return retour;
}
void print(struct pile_t * pile) {
printf("Affichage de la Table des Symboles\n\tSize : %d\n\tContenu : \n", pile->taille);
struct element_t * aux = pile->first;
int i;
for (i=0; i < pile->taille; i++) {
if (aux->symbole.initialized) {
printf("\t\t{nom:%s, adresse:%p, type:%s, initialized:OUI}\n", aux->symbole.nom, (void *)(aux->symbole.adresse), type_to_string(aux->symbole.type));
} else {
printf("\t\t{nom:%s, adresse:%p, type:%s, initialized:NON}\n", aux->symbole.nom, (void *)(aux->symbole.adresse), type_to_string(aux->symbole.type));
}
aux = aux->suivant;
}
}

48
Symboles/table_symboles.h 普通文件
查看文件

@ -0,0 +1,48 @@
/* TABLE DES SYMBOLE DU COMPILATEUR (PILE)
-----------------------------------------------------
| symbole | adresse | type | initialisé |
-----------------------------------------------------
| | | | |
| | | | |
| | | | |
| i | 0x777756b8 | int | false |
| size | 0x777756b8 | int | true |
-----------------------------------------------------
Types pour l'implémentation :
- enum type_t : [int]
- struct symbole : {
char nom[30];
uintptr_t adresse;
enum type_t type;
char initialized;
}
Opérations possible :
- init -> pile * -> void
- push -> symbole -> pile * -> void
- pop -> pile * -> symbole
- status -> nom -> pile -> char */
#include <stdint.h>
enum type_t {UNKNOWN, INT};
struct symbole_t {
char nom[30];
uintptr_t adresse;
enum type_t type;
char initialized;
};
void print_symbole(struct symbole_t symbole);
struct pile_t * pile;
void init(void);
void push(struct symbole_t symbole, struct pile_t * pile);
struct symbole_t pop(struct pile_t * pile);
// renvoi 0 si nom n'existe pas, 2 si nom existe sans etre initialisée, 1 sinon
char status(char * nom, struct pile_t * pile);
void print(struct pile_t * pile);

二进制
Symboles/table_symboles.o 普通文件

二进制文件未显示。

二进制
Symboles/test_table_symbole 可执行文件

二进制文件未显示。

查看文件

@ -0,0 +1,32 @@
#include "table_symboles.h"
#include <stdio.h>
int main() {
printf("Procedure de test de la Table des Symboles\n");
init();
printf("Affichage de la Table des Symboles (vide)\n");
print(pile);
printf("Test de la fonction push :\n");
struct symbole_t symbole = {"Salut", 0x77b58af, INT, 1};
push(symbole, pile);
printf("Affichage de la Table des Symboles (1 élément : Salut)\n");
print(pile);
struct symbole_t symbole2 = {"Coucou", 0x77b54af, UNKNOWN, 0};
push(symbole2, pile);
printf("Affichage de la Table des Symboles (2 élément : Salut, Coucou)\n");
print(pile);
printf("Test de la fonction status :\n\tStatus de Salut (1 expected) : %d\n\tStatus de Coucou (2 expected) : %d\n\tStatus de Truc (0 expected) : %d\n", (int)status("Salut",pile), (int)status("Coucou",pile), (int)status("Truc",pile));
printf("Test de la fonction pop :\n");
printf("Symbole expected Coucou\n\t");
print_symbole(pop(pile));
print(pile);
printf("Symbole expected Salut\n\t");
print_symbole(pop(pile));
print(pile);
printf("Symbole expected Aucun\n\t");
print_symbole(pop(pile));
print(pile);
}

二进制
Symboles/test_table_symbole.o 普通文件

二进制文件未显示。