Advertisement
Benjo_M

bison

Dec 11th, 2019
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.85 KB | None | 0 0
  1. %{
  2. #include <iostream>
  3. #include <map>
  4. #include <string>
  5. #include <vector>
  6. using namespace std;
  7. extern FILE *yyin;
  8. extern int yylex ();
  9. int yyerror(char *s) { printf("%s\n", s); }
  10.  
  11. map<string, int> variables; //map string et int adresse en memoire avec un compteur memoire entier 0,1,2,3,4
  12. map<string,int>::iterator itvar;
  13. //memoire vector double qu'on utilisera ensuite dans le run (une adresse memoire en gros)
  14. vector<double> memory;
  15. vector<string> fMemory;
  16. int incmemory = 0;
  17. int incFmemory = 0;
  18.  
  19. vector<pair<int,double>> instructions;
  20. int ic = 0; // compteur instruction
  21. inline ins(int c, double d) { instructions.push_back(make_pair(c,d)); ic++;};
  22.  
  23. // structure pour stocker les adresses pour les sauts condistionnels et autres...
  24. typedef struct adr {
  25. int ic_goto;
  26. int ic_false;
  27. } t_adresse;
  28.  
  29. %}
  30.  
  31. %union
  32. {
  33. double valeur;
  34. char nom[50];
  35. t_adresse adresse;
  36. }
  37.  
  38. %token <valeur> NUMBER
  39. %token <nom> VARIABLE
  40. %token <nom> TEXT
  41. %type <valeur> expression
  42. %token <adresse> SI
  43. %token ALORS
  44. %token SINON
  45. %token FINSI
  46. %token REPEAT
  47.  
  48. %token <adresse> TANTQUE
  49. %token FAIRE
  50. %token FINTANTQUE
  51.  
  52. %token <adresse> POURDE
  53.  
  54. %token JUSQUA
  55. %token FINPOUR
  56.  
  57. %token JMP
  58. %token JNZ
  59. %token OUT
  60.  
  61. %token PRINT
  62. %left ASK
  63.  
  64. %token DOUBLE_EGAL
  65. %token SUP_EGAL
  66. %token SUP_STRICT
  67. %token INF_EGAL
  68. %token INF_STRICT
  69.  
  70.  
  71. %left '+' '-' /* associativité à gauche */
  72. %left '*' '/' /* associativité à gauche */
  73. %token '=' '&'
  74.  
  75. %%
  76. bloc : bloc instruction '\n'
  77. | /* Epsilon */
  78. ;
  79. instruction : expression { ins (OUT,0); /* imprimer le résultat de l'expression */ }
  80. | VARIABLE '=' expression { if ( variables.find($1) == variables.end() ) {
  81. variables[$1] = incmemory;
  82. memory.push_back(0) ;
  83. incmemory++;
  84. }
  85. ins('=', variables[$1]);}
  86. | SI expression '\n' { $1.ic_goto = ic;
  87. ins (JNZ,0); }
  88. ALORS '\n' bloc { $1.ic_false = ic;
  89. ins (JMP,0);
  90. instructions[$1.ic_goto].second = ic;
  91. }
  92. SINON '\n' bloc { instructions[$1.ic_false].second = ic; }
  93. FINSI { }
  94. | TANTQUE expression '\n' { $1.ic_goto = ic;
  95. ins (JNZ,0);
  96. }
  97. FAIRE '\n' bloc { $1.ic_false = ic;
  98. ins (JMP,$1.ic_goto-3);
  99. instructions[$1.ic_goto].second = ic;
  100. }
  101. FINTANTQUE {
  102.  
  103. }
  104. | POURDE VARIABLE JUSQUA expression '\n' {
  105. $1.ic_goto = ic;
  106. ins(VARIABLE,variables[$2]);
  107. ins(NUMBER,$4);
  108. ins(INF_STRICT, 0);
  109. $1.ic_false = ic;
  110. ins(JNZ, 0);
  111. }
  112.  
  113.  
  114. FAIRE '\n' bloc {
  115. ins(VARIABLE,variables[$2] );
  116. ins(NUMBER, 1);
  117. ins('+', 0);
  118. ins('=',variables[$2]);
  119.  
  120. instructions[$1.ic_false].second = ic+1;
  121. ins(JMP,$1.ic_goto);
  122.  
  123. }
  124. FINPOUR { }
  125. | REPEAT '(' expression ')' expression {
  126.  
  127. }
  128. | ASK '(' VARIABLE ')' { if ( variables.find($3) == variables.end() ) {
  129. variables[$3] = incmemory;
  130. memory.push_back(0) ;
  131. incmemory++;
  132. }
  133. ins(ASK,variables[$3]);
  134. }
  135. | /* Ligne vide*/
  136. ;
  137. expression: expression '+' expression { ins('+', 0);}
  138. | expression '-' expression { ins('-', 0);}
  139. | expression '*' expression { ins('*', 0);}
  140. | expression '/' expression { ins('/', 0);}
  141.  
  142. | expression DOUBLE_EGAL expression { ins(DOUBLE_EGAL, 0);}
  143. | expression SUP_EGAL expression { ins(SUP_EGAL,0);}
  144. | expression SUP_STRICT expression { ins(SUP_STRICT,0);}
  145. | expression INF_EGAL expression { ins(INF_EGAL,0);}
  146. | expression INF_STRICT expression { ins(INF_STRICT,0);}
  147. | '(' expression ')' { }
  148. | PRINT '(' expression ')' {ins(PRINT,$3);}
  149. | NUMBER { ins(NUMBER, $1);}
  150. | VARIABLE { if ( variables.find($1) == variables.end() ) {
  151. variables[$1] = incmemory;
  152. memory.push_back(0) ;
  153. incmemory++;
  154. }
  155. ins(VARIABLE, variables[$1]);
  156. }
  157. | TEXT {
  158. }
  159. ;
  160. %%
  161.  
  162.  
  163. // Pour imprimer le code généré de manière plus lisible
  164. string nom(int instruction){
  165. switch (instruction){
  166. case '+' : return "ADD";
  167. case '*' : return "MUL";
  168. case '-' : return "MIN";
  169. case '/' : return "DIV";
  170. case '=' : return "EQU";
  171. case DOUBLE_EGAL : return "EG?";
  172. case SUP_EGAL : return "SE?";
  173. case SUP_STRICT : return "SS?";
  174. case INF_EGAL : return "IE?";
  175. case INF_STRICT : return "IS?";
  176. case NUMBER : return "NUM";
  177. case VARIABLE : return "VAR";
  178. case TEXT : return "TXT";
  179. case OUT : return "OUT";
  180. case JNZ : return "JNZ"; // Jump if not zero
  181. case JMP : return "JMP"; // Unconditional Jump
  182. case ASK : return "ASK";
  183. case PRINT : return "PRT";
  184. default : return to_string (instruction);
  185. }
  186. }
  187.  
  188. void print_program(){
  189. cout << "==== CODE GENERE ====" << endl;
  190. int i = 0;
  191. for (auto ins : instructions )
  192. cout << i++ << '\t' << nom(ins.first) << "\t" << ins.second << endl;
  193. cout << "=====================" << endl;
  194. }
  195.  
  196. double depiler(vector<double> &pile) {
  197. double t = pile[pile.size()-1];
  198. //cout << "Dépiler " << t << endl;
  199. pile.pop_back();
  200. return t;
  201. }
  202.  
  203. void run_program(){
  204. vector<double> pile;
  205. double x,y;
  206. int memoryMark;
  207. string varName;
  208.  
  209. cout << "===== EXECUTION =====" << endl;
  210. ic = 0;
  211. while ( ic < instructions.size() ){
  212. auto ins = instructions[ic];
  213. //cout << ic << '\t' << nom(ins.first) << "\t" << ins.second << endl;
  214.  
  215. switch(ins.first){
  216. case '+':
  217. x = depiler(pile);
  218. y = depiler(pile);
  219. pile.push_back(y+x);
  220. ic++;
  221. break;
  222.  
  223. case '*':
  224. x = depiler(pile);
  225. y = depiler(pile);
  226. pile.push_back(y*x);
  227. ic++;
  228. break;
  229.  
  230. case '-':
  231. x = depiler(pile);
  232. y = depiler(pile);
  233. pile.push_back(y-x);
  234. ic++;
  235. break;
  236.  
  237. case '/':
  238. x=depiler(pile);
  239. y=depiler(pile);
  240. pile.push_back(y/x);
  241. ic++;
  242. break;
  243.  
  244. case '=':
  245. x = depiler(pile);
  246. memory[ins.second] = x;
  247. pile.push_back(memory[(int)ins.second]);
  248. ic++;
  249. break;
  250.  
  251. case DOUBLE_EGAL:
  252. x=depiler(pile);
  253. y=depiler(pile);
  254. if(y == x){pile.push_back(1);}
  255. else{pile.push_back(0);}
  256. ic++;
  257. break;
  258.  
  259. case SUP_EGAL:
  260. x=depiler(pile);
  261. y=depiler(pile);
  262. if(y >= x){pile.push_back(1);}
  263. else{pile.push_back(0);}
  264. ic++;
  265. break;
  266.  
  267. case SUP_STRICT:
  268. x=depiler(pile);
  269. y=depiler(pile);
  270. if(y > x){pile.push_back(1);}
  271. else{pile.push_back(0);}
  272. ic++;
  273. break;
  274.  
  275. case INF_EGAL:
  276. x=depiler(pile);
  277. y=depiler(pile);
  278. if(y <= x){pile.push_back(1);}
  279. else{pile.push_back(0);}
  280. ic++;
  281. break;
  282.  
  283. case INF_STRICT:
  284. x=depiler(pile);
  285. y=depiler(pile);
  286. if(y < x){pile.push_back(1);}
  287. else{pile.push_back(0);}
  288. ic++;
  289. break;
  290.  
  291. case NUMBER :
  292. x = ins.second;
  293. pile.push_back(x);
  294. ic++;
  295. break;
  296.  
  297. case VARIABLE :
  298. memoryMark = (int)ins.second;
  299. //cout << "pos = " << memoryMark << endl;
  300. x = memory[memoryMark];
  301. pile.push_back(x);
  302. ic++;
  303. break;
  304.  
  305. case PRINT:
  306. cout << ins.second << endl;
  307. ic++;
  308. break;
  309.  
  310. case JMP :
  311. ic = ins.second;
  312. break;
  313.  
  314. case JNZ :
  315. x = depiler(pile);
  316. ic = ( x ? ic + 1 : ins.second);
  317. break;
  318.  
  319. case ASK :
  320. for (auto it = variables.begin(); it != variables.end(); ++it)
  321. { if (it->second == ins.second){ varName = it->first; }; }
  322. cout << varName << " : ";
  323. cin >> memory[ins.second];
  324. ic++;
  325. break;
  326.  
  327. case OUT :
  328. cout << "Résultat : " << depiler(pile) << endl;
  329. ic++;
  330. break;
  331. }
  332. }
  333. cout << "=====================" << endl;
  334. }
  335.  
  336. int main(int argc, char **argv) {
  337.  
  338. if ( argc > 1 )
  339. yyin = fopen( argv[1], "r" );
  340. else
  341. yyin = stdin;
  342. yyparse();
  343.  
  344. print_program();
  345.  
  346. run_program();
  347.  
  348. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement