Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %{
- #include <iostream>
- #include <map>
- #include <string>
- #include <vector>
- using namespace std;
- extern FILE *yyin;
- extern int yylex ();
- int yyerror(char *s) { printf("%s\n", s); }
- map<string, int> variables; //map string et int adresse en memoire avec un compteur memoire entier 0,1,2,3,4
- map<string,int>::iterator itvar;
- //memoire vector double qu'on utilisera ensuite dans le run (une adresse memoire en gros)
- vector<double> memory;
- vector<string> fMemory;
- int incmemory = 0;
- int incFmemory = 0;
- vector<pair<int,double>> instructions;
- int ic = 0; // compteur instruction
- inline ins(int c, double d) { instructions.push_back(make_pair(c,d)); ic++;};
- // structure pour stocker les adresses pour les sauts condistionnels et autres...
- typedef struct adr {
- int ic_goto;
- int ic_false;
- } t_adresse;
- %}
- %union
- {
- double valeur;
- char nom[50];
- t_adresse adresse;
- }
- %token <valeur> NUMBER
- %token <nom> VARIABLE
- %token <nom> TEXT
- %type <valeur> expression
- %token <adresse> SI
- %token ALORS
- %token SINON
- %token FINSI
- %token REPEAT
- %token <adresse> TANTQUE
- %token FAIRE
- %token FINTANTQUE
- %token <adresse> POURDE
- %token JUSQUA
- %token FINPOUR
- %token JMP
- %token JNZ
- %token OUT
- %token PRINT
- %left ASK
- %token DOUBLE_EGAL
- %token SUP_EGAL
- %token SUP_STRICT
- %token INF_EGAL
- %token INF_STRICT
- %left '+' '-' /* associativité à gauche */
- %left '*' '/' /* associativité à gauche */
- %token '=' '&'
- %%
- bloc : bloc instruction '\n'
- | /* Epsilon */
- ;
- instruction : expression { ins (OUT,0); /* imprimer le résultat de l'expression */ }
- | VARIABLE '=' expression { if ( variables.find($1) == variables.end() ) {
- variables[$1] = incmemory;
- memory.push_back(0) ;
- incmemory++;
- }
- ins('=', variables[$1]);}
- | SI expression '\n' { $1.ic_goto = ic;
- ins (JNZ,0); }
- ALORS '\n' bloc { $1.ic_false = ic;
- ins (JMP,0);
- instructions[$1.ic_goto].second = ic;
- }
- SINON '\n' bloc { instructions[$1.ic_false].second = ic; }
- FINSI { }
- | TANTQUE expression '\n' { $1.ic_goto = ic;
- ins (JNZ,0);
- }
- FAIRE '\n' bloc { $1.ic_false = ic;
- ins (JMP,$1.ic_goto-3);
- instructions[$1.ic_goto].second = ic;
- }
- FINTANTQUE {
- }
- | POURDE VARIABLE JUSQUA expression '\n' {
- $1.ic_goto = ic;
- ins(VARIABLE,variables[$2]);
- ins(NUMBER,$4);
- ins(INF_STRICT, 0);
- $1.ic_false = ic;
- ins(JNZ, 0);
- }
- FAIRE '\n' bloc {
- ins(VARIABLE,variables[$2] );
- ins(NUMBER, 1);
- ins('+', 0);
- ins('=',variables[$2]);
- instructions[$1.ic_false].second = ic+1;
- ins(JMP,$1.ic_goto);
- }
- FINPOUR { }
- | REPEAT '(' expression ')' expression {
- }
- | ASK '(' VARIABLE ')' { if ( variables.find($3) == variables.end() ) {
- variables[$3] = incmemory;
- memory.push_back(0) ;
- incmemory++;
- }
- ins(ASK,variables[$3]);
- }
- | /* Ligne vide*/
- ;
- expression: expression '+' expression { ins('+', 0);}
- | expression '-' expression { ins('-', 0);}
- | expression '*' expression { ins('*', 0);}
- | expression '/' expression { ins('/', 0);}
- | expression DOUBLE_EGAL expression { ins(DOUBLE_EGAL, 0);}
- | expression SUP_EGAL expression { ins(SUP_EGAL,0);}
- | expression SUP_STRICT expression { ins(SUP_STRICT,0);}
- | expression INF_EGAL expression { ins(INF_EGAL,0);}
- | expression INF_STRICT expression { ins(INF_STRICT,0);}
- | '(' expression ')' { }
- | PRINT '(' expression ')' {ins(PRINT,$3);}
- | NUMBER { ins(NUMBER, $1);}
- | VARIABLE { if ( variables.find($1) == variables.end() ) {
- variables[$1] = incmemory;
- memory.push_back(0) ;
- incmemory++;
- }
- ins(VARIABLE, variables[$1]);
- }
- | TEXT {
- }
- ;
- %%
- // Pour imprimer le code généré de manière plus lisible
- string nom(int instruction){
- switch (instruction){
- case '+' : return "ADD";
- case '*' : return "MUL";
- case '-' : return "MIN";
- case '/' : return "DIV";
- case '=' : return "EQU";
- case DOUBLE_EGAL : return "EG?";
- case SUP_EGAL : return "SE?";
- case SUP_STRICT : return "SS?";
- case INF_EGAL : return "IE?";
- case INF_STRICT : return "IS?";
- case NUMBER : return "NUM";
- case VARIABLE : return "VAR";
- case TEXT : return "TXT";
- case OUT : return "OUT";
- case JNZ : return "JNZ"; // Jump if not zero
- case JMP : return "JMP"; // Unconditional Jump
- case ASK : return "ASK";
- case PRINT : return "PRT";
- default : return to_string (instruction);
- }
- }
- void print_program(){
- cout << "==== CODE GENERE ====" << endl;
- int i = 0;
- for (auto ins : instructions )
- cout << i++ << '\t' << nom(ins.first) << "\t" << ins.second << endl;
- cout << "=====================" << endl;
- }
- double depiler(vector<double> &pile) {
- double t = pile[pile.size()-1];
- //cout << "Dépiler " << t << endl;
- pile.pop_back();
- return t;
- }
- void run_program(){
- vector<double> pile;
- double x,y;
- int memoryMark;
- string varName;
- cout << "===== EXECUTION =====" << endl;
- ic = 0;
- while ( ic < instructions.size() ){
- auto ins = instructions[ic];
- //cout << ic << '\t' << nom(ins.first) << "\t" << ins.second << endl;
- switch(ins.first){
- case '+':
- x = depiler(pile);
- y = depiler(pile);
- pile.push_back(y+x);
- ic++;
- break;
- case '*':
- x = depiler(pile);
- y = depiler(pile);
- pile.push_back(y*x);
- ic++;
- break;
- case '-':
- x = depiler(pile);
- y = depiler(pile);
- pile.push_back(y-x);
- ic++;
- break;
- case '/':
- x=depiler(pile);
- y=depiler(pile);
- pile.push_back(y/x);
- ic++;
- break;
- case '=':
- x = depiler(pile);
- memory[ins.second] = x;
- pile.push_back(memory[(int)ins.second]);
- ic++;
- break;
- case DOUBLE_EGAL:
- x=depiler(pile);
- y=depiler(pile);
- if(y == x){pile.push_back(1);}
- else{pile.push_back(0);}
- ic++;
- break;
- case SUP_EGAL:
- x=depiler(pile);
- y=depiler(pile);
- if(y >= x){pile.push_back(1);}
- else{pile.push_back(0);}
- ic++;
- break;
- case SUP_STRICT:
- x=depiler(pile);
- y=depiler(pile);
- if(y > x){pile.push_back(1);}
- else{pile.push_back(0);}
- ic++;
- break;
- case INF_EGAL:
- x=depiler(pile);
- y=depiler(pile);
- if(y <= x){pile.push_back(1);}
- else{pile.push_back(0);}
- ic++;
- break;
- case INF_STRICT:
- x=depiler(pile);
- y=depiler(pile);
- if(y < x){pile.push_back(1);}
- else{pile.push_back(0);}
- ic++;
- break;
- case NUMBER :
- x = ins.second;
- pile.push_back(x);
- ic++;
- break;
- case VARIABLE :
- memoryMark = (int)ins.second;
- //cout << "pos = " << memoryMark << endl;
- x = memory[memoryMark];
- pile.push_back(x);
- ic++;
- break;
- case PRINT:
- cout << ins.second << endl;
- ic++;
- break;
- case JMP :
- ic = ins.second;
- break;
- case JNZ :
- x = depiler(pile);
- ic = ( x ? ic + 1 : ins.second);
- break;
- case ASK :
- for (auto it = variables.begin(); it != variables.end(); ++it)
- { if (it->second == ins.second){ varName = it->first; }; }
- cout << varName << " : ";
- cin >> memory[ins.second];
- ic++;
- break;
- case OUT :
- cout << "Résultat : " << depiler(pile) << endl;
- ic++;
- break;
- }
- }
- cout << "=====================" << endl;
- }
- int main(int argc, char **argv) {
- if ( argc > 1 )
- yyin = fopen( argv[1], "r" );
- else
- yyin = stdin;
- yyparse();
- print_program();
- run_program();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement