lsd10.y

Description du code

Fichier Yacc du langage LSD010 Compilateur LSD010

Code source ou contenu du fichier

  1. %{
  2. /*
  3.  * lsd10.y : lexical parsing file for Bison
  4.  * Part of the compiler project for LSD10 language
  5.  * Gaudry Stéphane
  6.  * More information on http://www.gaudry.be/langages-yacc.html
  7.  */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #if(VERBOSE_LEVEL<=DEB_E)
  11. #include <errno.h>
  12. #endif
  13. #if(VERBOSE_LEVEL<=DEB_EXEC)
  14. #include <time.h>
  15. #endif
  16. #include <sys/types.h>
  17. #include <dirent.h>
  18. #include "common.h"
  19. #ifdef WIN32
  20. #define FILE_SEPARATLEXICAL_OR "\\"
  21. #else
  22. #define FILE_SEPARATLEXICAL_OR "/"
  23. #endif
  24.  
  25. extern int lexLinesCount;
  26. //extern int lexCharsLineCountBeforeToken;
  27. extern int lexTotalCharsCount;
  28. extern char* yytext;
  29. extern int *yylineno;
  30. extern FILE *yyin;
  31. /**
  32.  * Position of a detected error
  33.  */
  34. DebugInfo *debugInfo;
  35.  
  36.  
  37. AstNode *rootNode;
  38.  
  39. // to avoid 'implicit definition'
  40. int yylex(void);
  41. int yyerror(char *str);
  42.  
  43. %}
  44.  
  45. %union{
  46. int nval;
  47. char *text;
  48. struct astNode *node;
  49. }
  50. %error-verbose
  51. %locations
  52. %token LEXICAL_BOOLEAN_TYPE LEXICAL_INTEGER_TYPE LEXICAL_VOID_TYPE LEXICAL_INSTACK_TYPE
  53. %token <nval> NUMBER
  54. %token LEXICAL_TRUE_VAL LEXICAL_FALSE_VAL
  55. %token LEXICAL_AND LEXICAL_OR LEXICAL_ANDLAZY LEXICAL_ORLAZY LEXICAL_NOT LEXICAL_EQUALS LEXICAL_LESS_EQUALS LEXICAL_LESS
  56. %token LEXICAL_AFFECTATION
  57. %token LEXICAL_PLUS LEXICAL_MINUS LEXICAL_MULT LEXICAL_DIV LEXICAL_MOD
  58. %token L_PARENTHESIS LSQUI_BRACKET LSQUA_BRACKET POINT RSQUA_BRACKET R_PARENTHESIS RSQUI_BRACKET
  59. %token LEXICAL_GET_OPS LEXICAL_ISEMPTY_OPS LEXICAL_WRITE_OPS LEXICAL_READ_OPS LEXICAL_PUT_OPS LEXICAL_RETURN_STMT
  60. %token LEXICAL_IF_STMT LEXICAL_ELSE_STMT LEXICAL_WHILE_STMT LEXICAL_FOR_STMT
  61. %token COLON SEMICOLON COMMA
  62. %token LEXICAL_VAR
  63. %token <text>ID
  64.  
  65. %type <node> Prg Function Functions PostFixeFunction
  66. %type <node> ArgDeclaration ParamList ParamList_FunctionCall
  67. %type <node> FuncOrVar VarIds
  68. %type <node> Declarations Declaration
  69. %type <node> Statements Statement
  70. %type <node> iteration_while if_instruction iteration_for
  71. %type <node> LExpr RExpr
  72. %type <nval> FunctionType VarType
  73.  
  74. %left LEXICAL_AND LEXICAL_OR LEXICAL_ANDLAZY LEXICAL_ORLAZY
  75. %right LEXICAL_NOT
  76. %left LEXICAL_EQUALS LEXICAL_LESS_EQUALS LEXICAL_LESS
  77. %left LEXICAL_PLUS LEXICAL_MINUS
  78. %left LEXICAL_MULT LEXICAL_DIV LEXICAL_MOD
  79.  
  80. %start Prg
  81.  
  82. %%
  83. Prg: Functions {
  84. rootNode=$1;//createASTNode(10,createASTNodeInfo("Root", NODE_TYPE_NOTHING, NO_VAL),$1,NULL);
  85. }
  86. ;
  87.  
  88. Functions:
  89. {$$=NULL;}
  90. | Function Functions {
  91. #if(VERBOSE_LEVEL<=DEB_Y)
  92. printMsg(DEB_Y,"Functions node", __FILE__, __LINE__);
  93. #endif
  94. // Avoid building an unneeded node
  95. if($1==NULL && $2!=NULL)
  96. {
  97. $$=$2;
  98. }
  99. else if($2==NULL && $1!=NULL)
  100. {
  101. $$=$1;
  102. }
  103. else
  104. {
  105. $$=createASTNode(&@1,NODE_TYPE_FUNCTIONS, createASTNodeInfo("Functions", NODE_TYPE_NOTHING, NO_VAL), $2, $1);
  106. }
  107. }
  108. ;
  109.  
  110. Function: FunctionType ID L_PARENTHESIS ParamList R_PARENTHESIS PostFixeFunction{
  111. #if(VERBOSE_LEVEL<=DEB_Y)
  112. printMsg(DEB_Y,"Function node", __FILE__, __LINE__);
  113. #endif
  114. $$=createASTNode(&@2,NODE_TYPE_FUNCTION, createASTNodeInfo($2, $1, NO_VAL), $4, $6);
  115. }
  116. ;
  117.  
  118. PostFixeFunction:
  119. LSQUI_BRACKET LSQUI_BRACKET Declarations RSQUI_BRACKET Statements RSQUI_BRACKET {
  120. #if(VERBOSE_LEVEL<=DEB_Y)
  121. printMsg(DEB_Y,"PostFixeFunction node", __FILE__, __LINE__);
  122. #endif
  123.  
  124. // Avoid building an unneeded node
  125. if($3==NULL)
  126. {
  127. $$=$5==NULL?NULL:$5;
  128. }
  129. else if($5==NULL)
  130. {
  131. $$=$3;
  132. }
  133. else
  134. {
  135. $$=createASTNode(&yylloc,NODE_TYPE_CONTAINER, createASTNodeInfo("{{decl}statement}", NODE_TYPE_NOTHING, NO_VAL), $3, $5);
  136. }
  137. }
  138. ;
  139.  
  140. Declarations: {
  141. $$=NULL;
  142. }
  143. | Declaration Declarations {
  144. #if(VERBOSE_LEVEL<=DEB_Y)
  145. printMsg(DEB_Y,"Declarations node", __FILE__, __LINE__);
  146. #endif
  147. // Avoid building an unneeded node
  148. if($2==NULL)
  149. {
  150. $$=$1;
  151. }
  152. else
  153. {
  154. $$=createASTNode(&yylloc,NODE_TYPE_DECLARATIONS, createASTNodeInfo("Declarations node", NODE_TYPE_NOTHING, NO_VAL), $1, $2);
  155. }
  156. }
  157. ;
  158.  
  159. Declaration:
  160. LEXICAL_VOID_TYPE ID L_PARENTHESIS ParamList R_PARENTHESIS PostFixeFunction {
  161. /*void function*/
  162. $$ = createASTNode(&@2,NODE_TYPE_FUNCTION, createASTNodeInfo($2, AST_VOID_VAR_TYPE, NO_VAL), $4, $6);
  163. //setNodeSubType($$, SUBFUNCTION);
  164. }
  165. | VarType ID FuncOrVar {
  166. if($3==NULL || $3->type==NODE_TYPE_VAR_DECL)
  167. {
  168. // multiple variables declarations like "integer i j;"
  169. // we must set the type for each variable
  170. AstNode *tempNode = $3;
  171. while(tempNode!=NULL)
  172. {
  173. //printf("\nVar ids: %s (on %s %d)\n", varNode->info->name, __FILE__, __LINE__);
  174. setComputedType(tempNode,$1);
  175. tempNode=tempNode->left;
  176. }
  177.  
  178. $$=createASTNode(&yylloc,NODE_TYPE_VAR_DECL, createASTNodeInfo($2, $1, NO_VAL), $3, NULL);
  179. setComputedType($$,$1);
  180. }
  181. else
  182. {
  183. // function declaration
  184. $$ = createASTNode(&yylloc,NODE_TYPE_FUNCTION, createASTNodeInfo($2, $1, NO_VAL), $3->right, $3->left);
  185. setComputedType($$,$1);
  186. //setNodeSubType($$, SUBFUNCTION);
  187. free($3);
  188. }
  189. }
  190. ;
  191.  
  192. FuncOrVar:
  193. L_PARENTHESIS ParamList R_PARENTHESIS PostFixeFunction {
  194. $$=createASTNode(&yylloc,NODE_DECL_PVAL, createASTNodeInfo("function", NODE_TYPE_NOTHING, NO_VAL), $2, $4);
  195. }
  196. | VarIds SEMICOLON {
  197. $$=$1;
  198. }
  199. ;
  200.  
  201. VarIds:
  202. {$$=NULL;}
  203. | ID VarIds {
  204. $$=createASTNode(&yylloc,NODE_TYPE_VAR_DECL, createASTNodeInfo($1, NODE_TYPE_NOTHING, NO_VAL), $2, NULL);
  205. }
  206. ;
  207.  
  208. FunctionType:
  209. LEXICAL_BOOLEAN_TYPE {
  210. $$=AST_BOOLEAN_VAR_TYPE;
  211. #if(VERBOSE_LEVEL<=DEB_Y)
  212. printMsg(DEB_Y,"FunctionType node : boolean", __FILE__, __LINE__);
  213. #endif
  214. }
  215. | LEXICAL_INTEGER_TYPE {
  216. $$=AST_INTEGER_VAR_TYPE;
  217. #if(VERBOSE_LEVEL<=DEB_Y)
  218. printMsg(DEB_Y,"FunctionType node : integer", __FILE__, __LINE__);
  219. #endif
  220. }
  221. | LEXICAL_VOID_TYPE {
  222. $$=AST_VOID_VAR_TYPE;
  223. #if(VERBOSE_LEVEL<=DEB_Y)
  224. printMsg(DEB_Y,"FunctionType node : void", __FILE__, __LINE__);
  225. #endif
  226. }
  227. ;
  228.  
  229. ParamList:
  230. ArgDeclaration COMMA ParamList {
  231. $$=createASTNode(&yylloc,NODE_TYPE_PARAM_LIST, createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL), $1, $3);
  232. }
  233. | ArgDeclaration {
  234. $$=createASTNode(&yylloc,NODE_TYPE_PARAM_LIST, createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL), $1, NULL);
  235. }
  236. | {$$=NULL;}
  237. ;
  238.  
  239. ArgDeclaration:
  240. LEXICAL_VAR VarType ID {
  241. #if(VERBOSE_LEVEL<=DEB_Y)
  242. printMsg(DEB_Y,"LEXICAL_VAR VarType ID node", __FILE__, __LINE__);
  243. #endif
  244. $$ = createASTNode(&yylloc,NODE_TYPE_PARAM_DECL, createASTNodeInfo($3, $2, NO_VAL), NULL, NULL);
  245. setNodeSubType($$, LEXICAL_VAR);
  246. }
  247. | VarType ID {
  248. #if(VERBOSE_LEVEL<=DEB_Y)
  249. printMsg(DEB_Y,"VarType ID node", __FILE__, __LINE__);
  250. #endif
  251. $$ = createASTNode(&yylloc,NODE_TYPE_PARAM_DECL, createASTNodeInfo($2, $1, NO_VAL), NULL, NULL);
  252. setNodeSubType($$, ID);
  253. setComputedType($$, $1);
  254. }
  255. ;
  256.  
  257.  
  258. VarType:
  259. LEXICAL_BOOLEAN_TYPE {
  260. $$=AST_BOOLEAN_VAR_TYPE;
  261. #if(VERBOSE_LEVEL<=DEB_Y)
  262. printMsg(DEB_Y,"VarType node : boolean", __FILE__, __LINE__);
  263. #endif
  264. }
  265. | LEXICAL_INTEGER_TYPE {
  266. $$=AST_INTEGER_VAR_TYPE;
  267. #if(VERBOSE_LEVEL<=DEB_Y)
  268. printMsg(DEB_Y,"VarType node : integer", __FILE__, __LINE__);
  269. #endif
  270. }
  271. | LEXICAL_INSTACK_TYPE {
  272. $$=AST_INSTACK_VAR_TYPE;
  273. #if(VERBOSE_LEVEL<=DEB_Y)
  274. printMsg(DEB_Y,"VarType node : instack", __FILE__, __LINE__);
  275. #endif
  276. }
  277. | LEXICAL_INTEGER_TYPE LSQUA_BRACKET NUMBER RSQUA_BRACKET{
  278. $$=AST_INTEGER_ARRAY_VAR_TYPE;
  279. #if(VERBOSE_LEVEL<=DEB_Y)
  280. printMsg(DEB_Y,"VarType node : integer", __FILE__, __LINE__);
  281. #endif
  282. }
  283. | LEXICAL_BOOLEAN_TYPE LSQUA_BRACKET NUMBER RSQUA_BRACKET{
  284. $$=AST_BOOLEAN_ARRAY_VAR_TYPE;
  285. #if(VERBOSE_LEVEL<=DEB_Y)
  286. printMsg(DEB_Y,"VarType node : integer", __FILE__, __LINE__);
  287. #endif
  288. }
  289. ;
  290.  
  291. RExpr:
  292. LEXICAL_NOT RExpr {
  293. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),NULL, $2);
  294. setNodeSubType($$, LEXICAL_NOT);
  295. }
  296. |
  297. RExpr LEXICAL_AND RExpr {
  298. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3);
  299. setNodeSubType($$, LEXICAL_AND);
  300. }
  301. | RExpr LEXICAL_OR RExpr {
  302. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3);
  303. setNodeSubType($$, LEXICAL_OR);
  304. }
  305. | RExpr LEXICAL_ANDLAZY RExpr {
  306. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3);
  307. setNodeSubType($$, LEXICAL_ANDLAZY);
  308. }
  309. | RExpr LEXICAL_ORLAZY RExpr {
  310. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3);
  311. setNodeSubType($$, LEXICAL_ORLAZY);
  312. }
  313. | LEXICAL_TRUE_VAL {
  314. $$=createASTNode(&yylloc,LEXICAL_TRUE_VAL, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),NULL, NULL);
  315. setNodeSubType($$, LEXICAL_TRUE_VAL);
  316. }
  317. | LEXICAL_FALSE_VAL {
  318. $$=createASTNode(&yylloc,LEXICAL_FALSE_VAL, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),NULL, NULL);
  319. setNodeSubType($$, LEXICAL_FALSE_VAL);
  320. }
  321. | LEXICAL_ISEMPTY_OPS L_PARENTHESIS ID R_PARENTHESIS {
  322. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),
  323. NULL,
  324. createASTNode(&yylloc,NODE_TYPE_ID, createASTNodeInfo($3, NODE_TYPE_TODO, NO_VAL),NULL, NULL)
  325. );
  326. setNodeSubType($$, LEXICAL_ISEMPTY_OPS);
  327. }
  328. | LEXICAL_GET_OPS L_PARENTHESIS ID R_PARENTHESIS {
  329. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_INTEGER_VAR_TYPE, NO_VAL),
  330. NULL,
  331. createASTNode(&yylloc,NODE_TYPE_ID, createASTNodeInfo($3, NODE_TYPE_TODO, NO_VAL),NULL, NULL)
  332. );
  333. setNodeSubType($$, LEXICAL_GET_OPS);
  334. }
  335. | RExpr LEXICAL_EQUALS RExpr {
  336. #if(VERBOSE_LEVEL<=DEB_Y)
  337. printMsg(DEB_Y,"=", __FILE__, __LINE__);
  338. #endif
  339. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3);
  340. setNodeSubType($$, LEXICAL_EQUALS);
  341. }
  342. | RExpr LEXICAL_LESS_EQUALS RExpr {
  343. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3);
  344. setNodeSubType($$, LEXICAL_LESS_EQUALS);
  345. #if(VERBOSE_LEVEL<=DEB_Y)
  346. //printf(";\ttest subtype %d",$$->subtype);
  347. printMsg(DEB_Y,"<=", __FILE__, __LINE__);
  348. #endif
  349. }
  350. | RExpr LEXICAL_LESS RExpr {
  351. #if(VERBOSE_LEVEL<=DEB_Y)
  352. printMsg(DEB_Y,"<", __FILE__, __LINE__);
  353. #endif
  354. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3);
  355. setNodeSubType($$, LEXICAL_LESS);
  356. }
  357. | RExpr LEXICAL_PLUS RExpr {
  358. #if(VERBOSE_LEVEL<=DEB_Y)
  359. printMsg(DEB_Y,"+", __FILE__, __LINE__);
  360. #endif
  361. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_INTEGER_VAR_TYPE, NO_VAL),$1, $3);
  362. setNodeSubType($$, LEXICAL_PLUS);
  363. }
  364. | RExpr LEXICAL_MINUS RExpr{
  365. #if(VERBOSE_LEVEL<=DEB_Y)
  366. printMsg(DEB_Y,"-", __FILE__, __LINE__);
  367. #endif
  368. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_INTEGER_VAR_TYPE, NO_VAL),$1, $3);
  369. setNodeSubType($$, LEXICAL_MINUS);
  370. }
  371. | RExpr LEXICAL_MULT RExpr {
  372. #if(VERBOSE_LEVEL<=DEB_Y)
  373. printMsg(DEB_Y,"*", __FILE__, __LINE__);
  374. #endif
  375. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_INTEGER_VAR_TYPE, NO_VAL),$1, $3);
  376. setNodeSubType($$, LEXICAL_MULT);
  377. }
  378. | RExpr LEXICAL_DIV RExpr {
  379. #if(VERBOSE_LEVEL<=DEB_Y)
  380. printMsg(DEB_Y,"LEXICAL_DIV", __FILE__, __LINE__);
  381. #endif
  382. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_INTEGER_VAR_TYPE, NO_VAL),$1, $3);
  383. setNodeSubType($$, LEXICAL_DIV);
  384. }
  385. | RExpr LEXICAL_MOD RExpr {
  386. #if(VERBOSE_LEVEL<=DEB_Y)
  387. printMsg(DEB_Y,"LEXICAL_MOD", __FILE__, __LINE__);
  388. #endif
  389. $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_INTEGER_VAR_TYPE, NO_VAL),$1, $3);
  390. setNodeSubType($$, LEXICAL_MOD);
  391. }
  392. | L_PARENTHESIS RExpr R_PARENTHESIS {
  393. #if(VERBOSE_LEVEL<=DEB_Y)
  394. printMsg(DEB_Y,"(RExpr)", __FILE__, __LINE__);
  395. #endif
  396. $$=$2;//createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, NODE_TYPE_TODO, NO_VAL),NULL, $2);
  397. }
  398. | LExpr {
  399. #if(VERBOSE_LEVEL<=DEB_Y)
  400. printMsg(DEB_Y,"LExpr", __FILE__, __LINE__);
  401. #endif
  402. $$=$1;//createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, NODE_TYPE_TODO, NO_VAL),$1, NULL);
  403. }
  404. | ID L_PARENTHESIS ParamList_FunctionCall R_PARENTHESIS {
  405. #if(VERBOSE_LEVEL<=DEB_Y)
  406. printMsg(DEB_Y,"Function call with parameters", __FILE__, __LINE__);
  407. #endif
  408. $$=createASTNode(&yylloc,NODE_TYPE_FUNCTION_CALL, createASTNodeInfo($1, NODE_TYPE_TODO, NO_VAL),$3, NULL);
  409. }
  410. | ID L_PARENTHESIS R_PARENTHESIS {
  411. #if(VERBOSE_LEVEL<=DEB_Y)
  412. printMsg(DEB_Y,"Function call without parameters", __FILE__, __LINE__);
  413. #endif
  414. $$=createASTNode(&yylloc,NODE_TYPE_FUNCTION_CALL, createASTNodeInfo($1, NODE_TYPE_TODO, NO_VAL),NULL, NULL);
  415. }
  416. | NUMBER {
  417. $$=createASTNode(&yylloc,NUMBER, createASTNodeInfo("CONSTANT, NUMBER", AST_INTEGER_VAR_TYPE, $1),NULL, NULL);
  418. }
  419. | LEXICAL_MINUS NUMBER {
  420. $$=createASTNode(&yylloc,NUMBER, createASTNodeInfo("CONSTANT, NEGATIVE NUMBER", AST_INTEGER_VAR_TYPE, 0-$2),NULL, NULL);
  421. }
  422. // | Statement {
  423. // $$=$1;
  424. // }
  425. ;
  426.  
  427. LExpr:
  428. ID {
  429. #if(VERBOSE_LEVEL<=DEB_Y)
  430. printMsg(DEB_Y,"ID node", __FILE__, __LINE__);
  431. #endif
  432. $$=createASTNode(&yylloc,NODE_TYPE_ID, createASTNodeInfo($1, NODE_TYPE_NOTHING, NO_VAL),NULL, NULL);
  433. }
  434. | ID LSQUA_BRACKET RExpr RSQUA_BRACKET {
  435. $$=createASTNode(&yylloc,NODE_TYPE_ID,createASTNodeInfo($1, NODE_TYPE_NOTHING, NO_VAL),$3,NULL);
  436. setNodeSubType($$, LEXICAL_INSTACK_TYPE);
  437. }
  438. ;
  439.  
  440. ParamList_FunctionCall:
  441. RExpr COMMA ParamList_FunctionCall {
  442. $$=createASTNode(&yylloc,NODE_TYPE_PARAM_LIST, createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL),$1, $3);
  443. }
  444. | RExpr {
  445. $$=$1;
  446. setNodeType($$, NODE_TYPE_PARAM);
  447. }
  448. ;
  449.  
  450. Statements:
  451. Statement Statements{
  452. #if(VERBOSE_LEVEL<=DEB_Y)
  453. printMsg(DEB_Y,"Statements node", __FILE__, __LINE__);
  454. #endif
  455. // Avoid building an unneeded node
  456. if($2==NULL)
  457. {
  458. $$=$1;
  459. }
  460. else
  461. {
  462. $$=createASTNode(&yylloc,NODE_TYPE_FUNCTION_BODY, createASTNodeInfo("Statements node", NODE_TYPE_TODO, NO_VAL),$1, $2);
  463. }
  464. }
  465. | { $$=NULL;}
  466. ;
  467.  
  468. Statement:
  469. SEMICOLON {
  470. #if(VERBOSE_LEVEL<=DEB_Y)
  471. printMsg(DEB_Y,"Statement : ';'", __FILE__, __LINE__);
  472. #endif
  473. $$=NULL;
  474. }
  475. | RExpr SEMICOLON {
  476. #if(VERBOSE_LEVEL<=DEB_Y)
  477. printMsg(DEB_Y,"Statement : 'RExpr;'", __FILE__, __LINE__);
  478. #endif
  479. $$=$1;
  480. }
  481. | LExpr LEXICAL_AFFECTATION RExpr SEMICOLON {
  482. $$=createASTNode(&yylloc,NODE_TYPE_STATEMENT, createASTNodeInfo("Statement : 'LExpr = RExpr;'", NODE_TYPE_CHECK, NO_VAL),$1, $3);
  483. setNodeSubType($$, LEXICAL_AFFECTATION);
  484. }
  485. | if_instruction {
  486. #if(VERBOSE_LEVEL<=DEB_Y)
  487. printMsg(DEB_Y,"Statement : 'if'", __FILE__, __LINE__);
  488. #endif
  489. $$=$1;//createASTNode(&yylloc,NODE_TYPE_STATEMENT, createASTNodeInfo("Statement : 'if'", NODE_TYPE_NOTHING, NO_VAL),$1, NULL);
  490. }
  491. | iteration_while {
  492. #if(VERBOSE_LEVEL<=DEB_Y)
  493. printMsg(DEB_Y,"Statement : 'while'", __FILE__, __LINE__);
  494. #endif
  495. $$=$1;
  496. }
  497. | iteration_for {
  498. #if(VERBOSE_LEVEL<=DEB_Y)
  499. printMsg(DEB_Y,"Statement : 'for'", __FILE__, __LINE__);
  500. #endif
  501. $$=$1;
  502. }
  503. | LEXICAL_WRITE_OPS L_PARENTHESIS RExpr R_PARENTHESIS SEMICOLON {
  504. #if(VERBOSE_LEVEL<=DEB_Y)
  505. printMsg(DEB_Y,"Statement : 'WRITE (RExpr);'", __FILE__, __LINE__);
  506. #endif
  507. $$=createASTNode(&yylloc,LEXICAL_WRITE_OPS, createASTNodeInfo("Statement : 'WRITE (RExpr);'", AST_INTEGER_VAR_TYPE, NO_VAL),NULL, $3);
  508. }
  509. | LEXICAL_READ_OPS L_PARENTHESIS LExpr R_PARENTHESIS SEMICOLON {
  510. #if(VERBOSE_LEVEL<=DEB_Y)
  511. printMsg(DEB_Y,"Statement : 'READ (LExpr);'", __FILE__, __LINE__);
  512. #endif
  513. $$=createASTNode(&yylloc,LEXICAL_READ_OPS, createASTNodeInfo("Statement : 'READ (LExpr);'", AST_INTEGER_VAR_TYPE, NO_VAL),NULL, $3);
  514. }
  515. | LEXICAL_PUT_OPS L_PARENTHESIS ID COMMA RExpr R_PARENTHESIS SEMICOLON {
  516. #if(VERBOSE_LEVEL<=DEB_Y)
  517. printMsg(DEB_Y,"Statement : 'PUT (ID, RExpr);'", __FILE__, __LINE__);
  518. #endif
  519. $$=createASTNode(&yylloc,
  520. LEXICAL_PUT_OPS,
  521. createASTNodeInfo("Statement : 'PUT;'", NODE_TYPE_NOTHING, NO_VAL),
  522. createASTNode(&yylloc,NODE_TYPE_ID, createASTNodeInfo($3, NODE_TYPE_NOTHING, NO_VAL),NULL, NULL),
  523. $5
  524. );
  525. }
  526. | LEXICAL_RETURN_STMT L_PARENTHESIS RExpr R_PARENTHESIS SEMICOLON {
  527. #if(VERBOSE_LEVEL<=DEB_Y)
  528. printMsg(DEB_Y,"Statement : 'LEXICAL_RETURN_STMT(RExpr);'", __FILE__, __LINE__);
  529. #endif
  530. $$=createASTNode(&yylloc,LEXICAL_RETURN_STMT, createASTNodeInfo("Statement : 'LEXICAL_RETURN_STMT(RExpr);'", NODE_TYPE_NOTHING, NO_VAL),NULL, $3);
  531. }
  532. ;
  533.  
  534. iteration_for: LEXICAL_FOR_STMT L_PARENTHESIS Statements COLON RExpr COLON Statements R_PARENTHESIS LSQUI_BRACKET Statements RSQUI_BRACKET {
  535. AstNode *forBoundariesNode = createASTNode(&yylloc,NODE_TYPE_CONTAINER,createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL),$3,$7);
  536. AstNode *forNode = createASTNode(&yylloc,NODE_TYPE_CONTAINER,createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL),forBoundariesNode, $10);
  537. //AstNode *forConditionNode = createASTNode(&yylloc,NODE_TYPE_REXP,createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL),$5,NULL);
  538.  
  539. $$ = createASTNode(&yylloc,NODE_TYPE_STATEMENT,createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL),
  540. $5,
  541. forNode
  542. );
  543. setNodeSubType($$, LEXICAL_FOR_STMT);
  544. }
  545. ;
  546.  
  547. iteration_while: LEXICAL_WHILE_STMT L_PARENTHESIS RExpr R_PARENTHESIS LSQUI_BRACKET Statements RSQUI_BRACKET {
  548. $$=createASTNode(&yylloc,NODE_TYPE_STATEMENT,createASTNodeInfo("while(RExpr){Statement}", NODE_TYPE_NOTHING, NO_VAL),$3, $6);
  549. setNodeSubType($$, LEXICAL_WHILE_STMT);
  550. }
  551. ;
  552.  
  553. if_instruction:
  554. LEXICAL_IF_STMT L_PARENTHESIS RExpr R_PARENTHESIS LSQUI_BRACKET Statements RSQUI_BRACKET LEXICAL_ELSE_STMT LSQUI_BRACKET Statements RSQUI_BRACKET {
  555.  
  556. AstNode *ifNode = $6;
  557. AstNode *elseNode = $10;
  558. $$=createASTNode(&yylloc,
  559. NODE_TYPE_STATEMENT,
  560. createASTNodeInfo("if(RExpr){Statement}else{Statement}", NODE_TYPE_NOTHING, NO_VAL),
  561. $3,
  562. createASTNode(&yylloc,
  563. NODE_TYPE_CONTAINER,
  564. createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL),
  565. ifNode,
  566. elseNode
  567. )
  568. );
  569. setNodeSubType($$, AST_IF_ELSE_STMT);
  570. }
  571. | LEXICAL_IF_STMT L_PARENTHESIS RExpr R_PARENTHESIS LSQUI_BRACKET Statements RSQUI_BRACKET {
  572. $$=createASTNode(&yylloc,NODE_TYPE_STATEMENT,createASTNodeInfo("if(RExpr){Statement}", NODE_TYPE_NOTHING, NO_VAL),$3, $6);
  573. setNodeSubType($$, LEXICAL_IF_STMT);
  574. }
  575. ;
  576.  
  577. %%
  578.  
  579. void finalizeYacc()
  580. {
  581. #if(SYMTABLE_PRINT_REQUESTED==1 || VERBOSE_LEVEL<=DEB_I)
  582. printSymbolsTableFooter();
  583. #endif
  584. #if(VERBOSE_LEVEL<=DEB_EXEC)
  585. printMsg(DEB_EXEC,"Cleaning memory...", __FILE__, __LINE__);
  586. #endif
  587. // finalizeSymbolsTable MUST be called BELEXICAL_FOR_STMTE finalizeAST to avoid double free or corruption
  588. finalizeSymbolsTable();
  589. finalizeAST();
  590.  
  591. // if(psnBeforeToken!=NULL)
  592. // {
  593. // free(psnBeforeToken);
  594. // }
  595. // if(psnAfterToken!=NULL)
  596. // {
  597. // free(psnAfterToken);
  598. // }
  599. yylex_destroy();
  600. #if(VERBOSE_LEVEL<=DEB_EXEC)
  601. printMsg(DEB_EXEC,"...OK Memory cleaned\n;\n;", __FILE__, __LINE__);
  602. #endif
  603. }
  604.  
  605. int testFile(char *path)
  606. {
  607. #if(VERBOSE_LEVEL<=DEB_EXEC)
  608. time_t startTime = time(NULL);
  609. printf(";****************************************************************************************");
  610. printMsg(DEB_EXEC,"Creating Symbols Table",__FILE__, __LINE__);
  611. #endif
  612.  
  613. initializeSymbolsTable();
  614. #if(SYMTABLE_PRINT_REQUESTED==1)
  615. printSymbolsTableHeader();
  616. #endif
  617. #if(SYMTABLE_PRINT_REQUESTED!=1 && VERBOSE_LEVEL<=DEB_EXEC)
  618. printMsg(DEB_W,"Print Symbols table not requested (use DEB_I level minimum to print it)", __FILE__, __LINE__);
  619. #endif
  620.  
  621. if(path==NULL || !(yyin=fopen(path,"r")))
  622. {
  623. #if(VERBOSE_LEVEL<=DEB_EXEC)
  624. printMsg(DEB_EXEC,"Using Test file...false", __FILE__, __LINE__);
  625. printMsg(DEB_E, (char *)strerror(errno), __FILE__, __LINE__);
  626. printMsg(DEB_EXEC,"Calling yyparse()", __FILE__, __LINE__);
  627. #endif
  628. yyparse();
  629. }
  630. else
  631. {
  632. #if(VERBOSE_LEVEL<=DEB_EXEC)
  633. printMsg(DEB_EXEC,"Using Test file...true", __FILE__, __LINE__);
  634. printf("; Parsing %s file...", path);
  635. printMsg(DEB_EXEC,"Calling yyparse()", __FILE__, __LINE__);
  636. #endif
  637. yyparse();/*retourne un booleen?*/
  638. fclose(yyin);
  639. }
  640. #if(VERBOSE_LEVEL<=DEB_EXEC)
  641. printMsg(DEB_EXEC,"End of yyparse execution;", __FILE__, __LINE__);
  642. #endif
  643. #if(AST_PRINT_REQUESTED==1)
  644. printTree();
  645. #endif
  646. #if(AST_PRINT_REQUESTED!=1 && VERBOSE_LEVEL<=DEB_EXEC)
  647. printMsg(DEB_W,"Print tree not requested (use DEB_I level minimum to print it)", __FILE__, __LINE__);
  648. #endif
  649. checkAST();
  650. #if(AST_IMAGE_REQUESTED!=0)
  651. printGraph();
  652. #endif
  653.  
  654. #if(VERBOSE_LEVEL<=DEB_EXEC && PCODE_GENERATION_BYPASS)
  655. printMsg(DEB_EXEC,"P-code generation not requested.", __FILE__, __LINE__);
  656. #endif
  657. #if(!PCODE_GENERATION_BYPASS)
  658. #if(VERBOSE_LEVEL<=DEB_EXEC)
  659. printMsg(DEB_EXEC,"Generating p-code...", __FILE__, __LINE__);
  660. #endif
  661. generatePCode();
  662. #if(VERBOSE_LEVEL<=DEB_EXEC)
  663. printMsg(DEB_EXEC,"...OK P-code generated;", __FILE__, __LINE__);
  664. #endif
  665. #endif
  666. #if(VAR_USAGE_REPORT_REQUESTED)
  667. printSymbolsUsage();
  668. #endif
  669. finalizeYacc();
  670. #if(VERBOSE_LEVEL<=DEB_EXEC)
  671. time_t endTime = time(NULL);
  672.  
  673. char str[1024];//todo: minimize length
  674. sprintf(
  675. str,
  676. "Parsing started at %s;\t%d lines %d chars parsed in %g seconds\n;\tVerbose set on \"%s\" level",
  677. asctime(localtime(&startTime)),
  678. lexLinesCount,
  679. lexTotalCharsCount,
  680. difftime(endTime, startTime),
  681. debugLevelToString(VERBOSE_LEVEL)
  682. );
  683. printMsg(DEB_EXEC,str, __FILE__, __LINE__);
  684. #endif
  685. //fprintf(stderr,"OK\n");
  686. return EXIT_SUCCESS;
  687. }
  688.  
  689. int main()
  690. {
  691. DIR *dir = NULL;
  692. struct dirent *file = NULL;
  693. char *path="tests";
  694.  
  695. #if(VERBOSE_LEVEL<=DEB_EXEC)
  696. printMsg(DEB_EXEC,"\n;\n;\tLSD010 Compiler [SSHD09]\n;\n;", __FILE__, __LINE__);
  697. #endif
  698.  
  699. if((dir = opendir(path)) == NULL)
  700. {
  701. testFile(NULL);
  702. }
  703. else
  704. {
  705. char *filePath;
  706. while((file = readdir(dir)) != NULL)
  707. {
  708. if(strcmp(file->d_name, ".") && strcmp(file->d_name, ".."))
  709. {
  710. filePath = malloc(strlen(path) + strlen(file->d_name) + 2);
  711. sprintf(filePath, "%s%s%s", path, FILE_SEPARATLEXICAL_OR, file->d_name);
  712. //printf("\n; Opening %s file...", filePath);
  713. if(testFile(filePath) != EXIT_SUCCESS)
  714. {
  715. return EXIT_FAILURE;
  716. }
  717. }
  718. }
  719. closedir(dir);
  720. free(filePath);
  721. }
  722. #if(VERBOSE_LEVEL<=DEB_EXEC)
  723. printMsg(DEB_EXEC,"That's All Folks!", __FILE__, __LINE__);
  724. #endif
  725.  
  726.  
  727. fprintf(stderr,"OK\n");
  728. return EXIT_SUCCESS;
  729. }
  730.  
  731. int yyerror(char *str)
  732. {
  733. fprintf(stderr,"KO\n");
  734. if(yytext!=NULL)
  735. {
  736. fprintf(stderr,";\n;\tError : \"%s\" On parsed code, Line %d : UNRECOGNISED '%s'\n\n", str, lexLinesCount, yytext);
  737. }else if(debugInfo!=NULL)
  738. {
  739. fprintf(
  740. stderr,
  741. ";\n;\tError : \"%s\" On %s, Line %d col %d\n\n",
  742. str,
  743. debugInfo->file,
  744. debugInfo->line,
  745. debugInfo->linePsn
  746. );
  747. }
  748. // else if(lexLinesCount>0)
  749. // {
  750. // fprintf(stderr,";\n;\tError : \"%s\" On parsed code, Line %d\n\n", str, lexLinesCount);
  751. // }
  752. else
  753. {
  754. fprintf(stderr,";\n;\tError : \"%s\"\n\n", str);
  755. }
  756. finalizeYacc();
  757. //failure for the parsed code, but success for the compiler (it must stop here)
  758. exit(EXIT_SUCCESS);
  759. }

Autres extraits de codes en Bison

Document créé le 05/10/2009, dernière modification le 28/10/2018
Source du document imprimé : https://www.gaudry.be/sniplet-rf-lsd010/project/source/lsd10.y.html

L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.