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

English translation

You have asked to visit this site in English. For now, only the interface is translated, but not all the content yet.

If you want to help me in translations, your contribution is welcome. All you need to do is register on the site, and send me a message asking me to add you to the group of translators, which will give you the opportunity to translate the pages you want. A link at the bottom of each translated page indicates that you are the translator, and has a link to your profile.

Thank you in advance.

Document created the 05/10/2009, last modified the 28/10/2018
Source of the printed document:https://www.gaudry.be/en/sniplet-rf-lsd010/project/source/lsd10.y.html

The infobrol is a personal site whose content is my sole responsibility. The text is available under CreativeCommons license (BY-NC-SA). More info on the terms of use and the author.