PageRenderTime 43ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/project/src/tiny.y

https://github.com/luyifan/pascal-compile
Happy | 620 lines | 606 code | 14 blank | 0 comment | 0 complexity | ae599cf725d0d8eaa2920760e227a68d MD5 | raw file
  1. %{
  2. #define YYPARSER
  3. #include "global.h"
  4. #include "util.h"
  5. #include "scan.h"
  6. #include "parse.h"
  7. #define YYSTYPE TreeNode *
  8. static char * savedName;
  9. static char * savedName1;
  10. static int savedLineNo;
  11. static TreeNode* savedTree;
  12. static int savedNum;
  13. static int level=0;
  14. static int yylex(){
  15. return getToken();
  16. }
  17. int yyerror(char* message);
  18. %}
  19. %token TOKEN_PROGRAM TOKEN_FUNCTION TOKEN_PROCEDURE TOKEN_CONST TOKEN_TYPE TOKEN_VAR
  20. %token TOKEN_IF TOKEN_THEN TOKEN_ELSE TOKEN_REPEAT TOKEN_UNTIL TOKEN_WHILE TOKEN_DO TOKEN_CASE TOKEN_TO TOKEN_DOWNTO TOKEN_FOR
  21. %token TOKEN_EQUAL TOKEN_UNEQUAL TOKEN_GE TOKEN_GT TOKEN_LE TOKEN_LT TOKEN_ASSIGN TOKEN_PLUS TOKEN_MINUS TOKEN_MUL TOKEN_DIV TOKEN_OR TOKEN_AND TOKEN_NOT TOKEN_MOD TOKEN_READ TOKEN_WRITE TOKEN_WRITELN
  22. %token TOKEN_LB TOKEN_RB TOKEN_SEMI TOKEN_DOT TOKEN_DOTDOT TOKEN_LP TOKEN_RP TOKEN_COMMA TOKEN_COLON
  23. %token TOKEN_INTEGER_TYPE TOKEN_BOOLEAN_TYPE TOKEN_CHAR_TYPE TOKEN_REAL_TYPE
  24. %token TOKEN_TRUE TOKEN_FALSE TOKEN_MAXINT
  25. %token TOKEN_ARRAY TOKEN_OF TOKEN_RECORD TOKEN_BEGIN TOKEN_END TOKEN_GOTO
  26. %token TOKEN_ID TOKEN_INT TOKEN_REAL TOKEN_CHAR TOKEN_STRING
  27. %token ERROR
  28. %%
  29. program : TOKEN_PROGRAM TOKEN_ID
  30. { savedName1 = copyString(tokenString); }
  31. TOKEN_SEMI routine TOKEN_DOT
  32. { $$ = $5;
  33. $$->attr.name=savedName1;
  34. savedTree = $$;
  35. };
  36. routine : routine_head routine_body
  37. {
  38. $$ = $1;
  39. $$->sibling=$2;
  40. };
  41. routine_head : const_part type_part var_part routine_part
  42. {
  43. $$ = newDeclNode(DECL_ROUTINEHEAD);
  44. $$ ->child[0]=$1;
  45. $$ ->child[1]=$2;
  46. $$ ->child[2]=$3;
  47. $$ ->child[3]=$4;
  48. };
  49. routine_part :
  50. { $$= NULL;}
  51. | routine_part function_decl
  52. { YYSTYPE t=$1;
  53. if(t!=NULL){
  54. while(t->sibling!=NULL)
  55. t=t->sibling;
  56. t->sibling=$2;
  57. $$=$1;
  58. }
  59. else
  60. $$=$2;
  61. }
  62. | routine_part procedure_decl
  63. { YYSTYPE t=$1;
  64. if(t!=NULL){
  65. while(t->sibling!=NULL)
  66. t=t->sibling;
  67. t->sibling=$2;
  68. $$=$1;
  69. }
  70. else
  71. $$=$2;
  72. }
  73. | function_decl {$$=$1;}
  74. | procedure_decl {$$=$1;}
  75. ;
  76. function_decl : function_head TOKEN_SEMI routine TOKEN_SEMI
  77. {
  78. $$=newDeclNode(DECL_FUNCTION);
  79. $$->attr.name=copyString( $1->attr.name);
  80. printf("functional:%s",$1->attr.name);
  81. $$->child[0]=$1->child[1];
  82. $$->child[1]=$1->child[0];
  83. $$ ->child[2]=$3;
  84. free($1);
  85. }
  86. ;
  87. function_head : TOKEN_FUNCTION TOKEN_ID
  88. { savedName=copyString(tokenString);}
  89. parameters TOKEN_COLON simple_type_decl
  90. {
  91. $$=newDeclNode(DECL_FUNCTIONHEAD);
  92. $$->attr.name=savedName;
  93. $$->child[0]=$4;
  94. $$->child[1]=$6;
  95. }
  96. ;
  97. parameters :
  98. {$$=NULL;}
  99. | TOKEN_LP para_decl_list TOKEN_RP
  100. {$$=$2;}
  101. ;
  102. para_decl_list : para_decl_list TOKEN_SEMI para_type_list
  103. { YYSTYPE t=$1;
  104. if(t!=NULL){
  105. while(t->sibling!=NULL)
  106. t=t->sibling;
  107. t->sibling=$3;
  108. $$=$1;
  109. }
  110. else
  111. $$=$3;
  112. }
  113. | para_type_list
  114. { $$=$1; }
  115. ;
  116. para_type_list : TOKEN_VAR name_list TOKEN_COLON simple_type_decl
  117. {
  118. $$=newDeclNode(DECL_VAR_PARA);
  119. $$->child[0]=$2;
  120. $$->child[1]=$4;
  121. }
  122. | name_list TOKEN_COLON simple_type_decl
  123. {
  124. $$=newDeclNode(DECL_VAL_PARA);
  125. $$->child[0]=$1;
  126. $$->child[1]=$3;
  127. }
  128. ;
  129. procedure_decl : procedure_head TOKEN_SEMI routine TOKEN_SEMI
  130. {
  131. $$=newDeclNode(DECL_PROCEDURE);
  132. $$->attr.name=copyString( $1->attr.name);
  133. $$->child[0]=NULL;
  134. $$->child[1]=$1->child[0];
  135. $$ ->child[2]=$3;
  136. free($1);
  137. }
  138. ;
  139. procedure_head : TOKEN_PROCEDURE TOKEN_ID
  140. { savedName=copyString(tokenString);}
  141. parameters
  142. { $$=newDeclNode(DECL_PROCEDUREHEAD);
  143. $$->attr.name=savedName;
  144. $$->child[0]=$4;
  145. }
  146. ;
  147. var_part :
  148. { $$ = NULL;}
  149. | TOKEN_VAR var_decl_list
  150. { $$=$2;}
  151. ;
  152. var_decl_list : var_decl_list var_decl
  153. { YYSTYPE t = $1;
  154. if(t!=NULL){
  155. while(t->sibling!=NULL)
  156. t=t->sibling;
  157. t->sibling=$2;
  158. $$=$1;
  159. }
  160. else
  161. $$=$2;
  162. }
  163. | var_decl {$$=$1;}
  164. ;
  165. var_decl : name_list TOKEN_COLON type_decl TOKEN_SEMI
  166. { $$=newDeclNode(DECL_VAR);
  167. $$->child[0]=$1;
  168. $$->child[1]=$3;
  169. }
  170. ;
  171. const_part :
  172. { $$ = NULL; }
  173. | TOKEN_CONST const_expr_list
  174. { $$=$2; }
  175. ;
  176. const_expr_list : const_expr_list const_expr
  177. {
  178. YYSTYPE t = $1;
  179. if(t!=NULL){
  180. while(t->sibling!=NULL)
  181. t=t->sibling;
  182. t->sibling = $2;
  183. $$=$2;
  184. }
  185. else
  186. $$=$1;
  187. }
  188. | const_expr
  189. { $$=$1; }
  190. ;
  191. const_expr : ID TOKEN_EQUAL const_value TOKEN_SEMI
  192. {
  193. $$ = newDeclNode(DECL_CONST);
  194. $$->attr.name = copyString($1->attr.name);
  195. freeNode($1);
  196. $$->child[0] = $3;
  197. $$->type=$3->type;
  198. }
  199. ;
  200. const_value : TOKEN_INT
  201. {
  202. $$ = newExpNode(EXP_CONST);
  203. $$->type = EXPTYPE_INT;
  204. $$->attr.val = atoi(tokenString);
  205. }
  206. | TOKEN_REAL
  207. {
  208. $$ = newExpNode(EXP_CONST);
  209. $$->type = EXPTYPE_REAL;
  210. $$->attr.real_val = atof(tokenString);
  211. }
  212. | TOKEN_CHAR
  213. {
  214. $$ = newExpNode(EXP_CONST);
  215. $$->type = EXPTYPE_CHAR;
  216. $$->attr.char_val = tokenString[1];
  217. }
  218. | TOKEN_STRING
  219. {
  220. $$ = newExpNode(EXP_CONST);
  221. $$->type=EXPTYPE_STRING;
  222. $$->attr.string_val = (char*)malloc(strlen(tokenString)-1);
  223. memmove($$->attr.string_val,tokenString+1,strlen(tokenString)-2);
  224. $$->attr.string_val[strlen(tokenString)-2]='\0';
  225. }
  226. | TOKEN_TRUE
  227. {
  228. $$=newExpNode(EXP_CONST);
  229. $$->type=EXPTYPE_BOOL;
  230. $$->attr.val=1;
  231. }
  232. | TOKEN_FALSE
  233. {
  234. $$=newExpNode(EXP_CONST);
  235. $$->type=EXPTYPE_BOOL;
  236. $$->attr.val=0;
  237. }
  238. | TOKEN_MAXINT
  239. {
  240. $$=newExpNode(EXP_CONST);
  241. $$->type=EXPTYPE_INT;
  242. $$->attr.val=2147483647;
  243. }
  244. ;
  245. type_part :
  246. { $$=NULL;}
  247. | TOKEN_TYPE type_decl_list
  248. { $$=$2;}
  249. ;
  250. type_decl_list : type_decl_list type_definition
  251. {
  252. YYSTYPE t=$1;
  253. if(t!=NULL){
  254. while(t->sibling!=NULL)
  255. t=t->sibling;
  256. t->sibling=$2;
  257. $$=$1;
  258. }
  259. else
  260. $$=$2;
  261. }
  262. | type_definition
  263. { $$=$1;}
  264. ;
  265. type_definition : ID TOKEN_EQUAL type_decl TOKEN_SEMI
  266. { $$=newDeclNode(DECL_TYPE);
  267. $$->child[0]=$1;
  268. $$->child[1]=$3;
  269. }
  270. ;
  271. type_decl : simple_type_decl {$$=$1;}
  272. | array_type_decl {$$=$1;}
  273. | record_type_decl {$$=$1;}
  274. ;
  275. record_type_decl : TOKEN_RECORD field_decl_list TOKEN_END
  276. { $$=$2;}
  277. ;
  278. field_decl_list : field_decl_list field_decl
  279. {
  280. YYSTYPE t=$1;
  281. if(t!=NULL){
  282. while(t->sibling!=NULL)
  283. t=t->sibling;
  284. t->sibling=$2;
  285. $$=$1;
  286. }
  287. else
  288. $$=$2;
  289. }
  290. | field_decl {$$=$1;}
  291. ;
  292. field_decl : name_list TOKEN_COLON type_decl TOKEN_SEMI
  293. {
  294. $$=newTypeNode(TYPE_RECORD);
  295. $$->child[0]=$1;
  296. $$->child[1]=$3;
  297. }
  298. ;
  299. array_type_decl : TOKEN_ARRAY TOKEN_LB simple_type_decl TOKEN_RB TOKEN_OF type_decl
  300. {
  301. $$=newTypeNode(TYPE_ARRAY);
  302. $$->child[0]=$3;
  303. $$->child[1]=$6;
  304. $$->type=EXPTYPE_ARRAY;
  305. printf("%d\n",$6->type);
  306. }
  307. ;
  308. simple_type_decl : ID
  309. {
  310. $$=newTypeNode(TYPE_SIMPLE_ID);
  311. printf("RUNNNNNNNNNN %s\n",$1->attr.name);
  312. $$->attr.name = copyString($1->attr.name);
  313. free($1);
  314. }
  315. | TOKEN_LP name_list TOKEN_RP
  316. { $$=newTypeNode(TYPE_SIMPLE_ENUM);
  317. $$->child[0]=$2;
  318. $$->type=EXPTYPE_ENUM;
  319. }
  320. | const_value TOKEN_DOTDOT const_value
  321. { $$=newTypeNode(TYPE_SIMPLE_LIMIT);
  322. $$->child[0]=$1;
  323. $$->child[1]=$3;
  324. $$->type=EXPTYPE_LIMIT;
  325. }
  326. | TOKEN_MINUS const_value TOKEN_DOTDOT const_value
  327. {
  328. $$=newTypeNode(TYPE_SIMPLE_LIMIT);
  329. $$->child[0]=$2;
  330. $$->child[0]->attr.val *= -1;
  331. $$->child[1]=$4;
  332. $$->type=EXPTYPE_LIMIT;
  333. }
  334. | TOKEN_MINUS const_value TOKEN_DOTDOT TOKEN_MINUS const_value
  335. { $$=newTypeNode(TYPE_SIMPLE_LIMIT);
  336. $$->child[0]=$2;
  337. $$->child[0]->attr.val *=-1;
  338. $$->child[1]=$5;
  339. $$->child[1]->attr.val *=-1;
  340. $$->type=EXPTYPE_LIMIT;
  341. }
  342. | ID TOKEN_DOTDOT ID
  343. {
  344. $$=newTypeNode(TYPE_SIMPLE_LIMIT);
  345. $$->child[0]=$1;
  346. $$->child[1]=$3;
  347. $$->type=EXPTYPE_LIMIT;
  348. }
  349. | TOKEN_INTEGER_TYPE
  350. { $$=newTypeNode(TYPE_SIMPLE_SYS);
  351. $$->type=EXPTYPE_INT;
  352. }
  353. | TOKEN_BOOLEAN_TYPE
  354. { $$=newTypeNode(TYPE_SIMPLE_SYS);
  355. $$->type=EXPTYPE_BOOL;
  356. }
  357. | TOKEN_REAL_TYPE
  358. { $$=newTypeNode(TYPE_SIMPLE_SYS);
  359. $$->type=EXPTYPE_REAL;
  360. }
  361. | TOKEN_CHAR_TYPE
  362. { $$=newTypeNode(TYPE_SIMPLE_SYS);
  363. $$->type=EXPTYPE_CHAR;
  364. }
  365. ;
  366. name_list : name_list TOKEN_COMMA ID
  367. {
  368. YYSTYPE t=$1;
  369. if(t!=NULL){
  370. while(t->sibling!=NULL)
  371. t=t->sibling;
  372. t->sibling=$3;
  373. $$=$1;
  374. }
  375. else
  376. $$=$1;
  377. }
  378. | ID { $$=$1; }
  379. ;
  380. ID : TOKEN_ID
  381. { $$=newExpNode(EXP_ID);
  382. $$->attr.name=copyString(tokenString);
  383. } ;
  384. routine_body : compound_stmt {$$=$1;} ;
  385. compound_stmt : TOKEN_BEGIN stmt_list TOKEN_END {$$=$2;} ;
  386. stmt_list :
  387. {$$=NULL;}
  388. | stmt_list stmt TOKEN_SEMI
  389. {
  390. YYSTYPE t=$1;
  391. if(t!=NULL){
  392. while(t->sibling!=NULL)
  393. t=t->sibling;
  394. t->sibling=$2;
  395. $$=$1;
  396. }
  397. else
  398. $$=$2;
  399. }
  400. ;
  401. stmt : TOKEN_INT
  402. { savedNum= atoi(tokenString);}
  403. TOKEN_COLON no_label_stmt
  404. {
  405. $$=newStmtNode(STMT_LABEL);
  406. $$->attr.val=savedNum;
  407. $$->child[0]=$4;
  408. }
  409. | no_label_stmt
  410. { $$=$1;}
  411. ;
  412. no_label_stmt : assign_stmt {$$=$1;}
  413. | compound_stmt {$$=$1;}
  414. | goto_stmt {$$=$1;}
  415. | if_stmt {$$=$1;}
  416. | repeat_stmt {$$=$1;}
  417. | while_stmt {$$=$1;}
  418. | case_stmt {$$=$1;}
  419. | for_stmt {$$=$1;}
  420. | proc_stmt {$$=$1;};
  421. assign_stmt : ID TOKEN_ASSIGN expression
  422. { $$=newExpNode(EXP_OP);
  423. $$->attr.op = TOKEN_ASSIGN;
  424. $$->child[0] = $1;
  425. $$->child[1] = $3;
  426. }
  427. | ID TOKEN_LB expression TOKEN_RB TOKEN_ASSIGN expression
  428. { $$=newExpNode(EXP_OP);
  429. $$->attr.op = TOKEN_ASSIGN;
  430. $1->type = EXPTYPE_ARRAY;
  431. $1->child[0] = $3;
  432. $$->child[0] = $1;
  433. $$->child[1] = $6;
  434. }
  435. ;
  436. goto_stmt : TOKEN_GOTO TOKEN_INT
  437. { $$=newStmtNode(STMT_GOTO);
  438. $$->attr.val=atoi(tokenString);
  439. }
  440. ;
  441. if_stmt : TOKEN_IF expression TOKEN_THEN stmt else_clause
  442. { $$=newStmtNode(STMT_IF);
  443. $$->child[0]=$2;
  444. $$->child[1]=$4;
  445. $$->child[2]=$5;
  446. }
  447. ;
  448. else_clause : {$$=NULL;}
  449. | TOKEN_ELSE stmt {$$=$2;}
  450. ;
  451. repeat_stmt : TOKEN_REPEAT stmt_list TOKEN_UNTIL expression
  452. {
  453. $$=newStmtNode(STMT_REPEAT);
  454. $$->child[0]=$2;
  455. $$->child[1]=$4;
  456. }
  457. |
  458. while_stmt : TOKEN_WHILE expression TOKEN_DO stmt
  459. { $$=newStmtNode(STMT_WHILE);
  460. $$->child[0]=$2;
  461. $$->child[1]=$4;
  462. };
  463. case_stmt : TOKEN_CASE expression TOKEN_OF case_expr_list TOKEN_END
  464. { $$=newStmtNode(STMT_CASE);
  465. $$->child[0]=$2;
  466. $$->child[1]=$4;
  467. };
  468. case_expr_list : case_expr_list case_expr
  469. { YYSTYPE t=$1;
  470. if(t!=NULL){
  471. while(t->sibling!=NULL)
  472. t=t->sibling;
  473. t->sibling=$2;
  474. $$=$1;
  475. }
  476. else
  477. $$=$2;
  478. }
  479. | case_expr {$$=$1;};
  480. case_expr : const_value TOKEN_COLON stmt TOKEN_SEMI
  481. {
  482. $$=newExpNode(EXP_CASE);
  483. $$->child[0]=$1;
  484. $$->child[1]=$3;
  485. }
  486. | ID TOKEN_COLON stmt TOKEN_SEMI
  487. {
  488. $$=newExpNode(EXP_CASE);
  489. $$->child[0]=$1;
  490. $$->child[1]=$3;
  491. };
  492. for_stmt : TOKEN_FOR ID TOKEN_ASSIGN expression TOKEN_TO expression TOKEN_DO stmt
  493. {
  494. $$=newStmtNode(STMT_FOR);
  495. $$->child[0]=$2;
  496. $$->child[1]=$4;
  497. $$->child[2]=$6;
  498. $$->child[3]=$8;
  499. $$->attr.op=TOKEN_TO;
  500. }
  501. | TOKEN_FOR ID TOKEN_ASSIGN expression TOKEN_DOWNTO expression TOKEN_DO stmt
  502. {
  503. $$=newStmtNode(STMT_FOR);
  504. $$->child[0]=$2;
  505. $$->child[1]=$4;
  506. $$->child[2]=$6;
  507. $$->child[3]=$8;
  508. $$->attr.op=TOKEN_DOWNTO;
  509. };
  510. proc_stmt : ID
  511. {
  512. $$=newExpNode(EXP_FUNC);
  513. $$->attr.name=copyString($1->attr.name);
  514. $$->child[0]=$1;
  515. $$->child[1]=NULL;
  516. }
  517. | ID TOKEN_LP args_list TOKEN_RP
  518. { $$=newExpNode(EXP_FUNC);
  519. $$->attr.name=copyString($1->attr.name);
  520. $$->child[0]=$1;
  521. $$->child[1]=$3;
  522. }
  523. | TOKEN_READ TOKEN_LP factor TOKEN_RP
  524. {
  525. $$=newStmtNode(STMT_PROC_SYS);
  526. $$->attr.op=TOKEN_READ;
  527. $$->child[0]=$3;
  528. }
  529. | TOKEN_WRITE TOKEN_LP args_list TOKEN_RP
  530. { $$=newStmtNode(STMT_PROC_SYS);
  531. $$->attr.op=TOKEN_WRITE;
  532. $$->child[1]=$3;
  533. }
  534. | TOKEN_WRITELN
  535. { $$=newStmtNode(STMT_PROC_SYS);
  536. $$->attr.op=TOKEN_WRITELN;
  537. }
  538. | TOKEN_WRITELN TOKEN_LP args_list TOKEN_RP
  539. { $$=newStmtNode(STMT_PROC_SYS);
  540. $$->attr.op=TOKEN_WRITELN;
  541. $$->child[1]=$3;
  542. };
  543. args_list : args_list TOKEN_COMMA expression
  544. { YYSTYPE t=$1;
  545. if(t!=NULL){
  546. while(t->sibling!=NULL)
  547. t=t->sibling;
  548. t->sibling=$3;
  549. $$=$1;
  550. }
  551. else
  552. $$=$3;
  553. }
  554. | expression {$$=$1;};
  555. expression : expression TOKEN_GE expr { $$=newOpExpNode($1,$3,TOKEN_GE); }
  556. | expression TOKEN_GT expr { $$=newOpExpNode($1,$3,TOKEN_GT); }
  557. | expression TOKEN_LE expr { $$=newOpExpNode($1,$3,TOKEN_LE); }
  558. | expression TOKEN_LT expr { $$=newOpExpNode($1,$3,TOKEN_LT); }
  559. | expression TOKEN_EQUAL expr { $$=newOpExpNode($1,$3,TOKEN_EQUAL); }
  560. | expression TOKEN_UNEQUAL expr { $$=newOpExpNode($1,$3,TOKEN_UNEQUAL); }
  561. | expr { $$=$1;} ;
  562. expr : expr TOKEN_PLUS term { $$=newOpExpNode($1,$3,TOKEN_PLUS); }
  563. | expr TOKEN_MINUS term { $$=newOpExpNode($1,$3,TOKEN_MINUS); }
  564. | expr TOKEN_OR term { $$=newOpExpNode($1,$3,TOKEN_OR); }
  565. | term { $$=$1;} ;
  566. term : term TOKEN_MUL factor { $$=newOpExpNode($1,$3,TOKEN_MUL); }
  567. | term TOKEN_DIV factor { $$=newOpExpNode($1,$3,TOKEN_DIV); }
  568. | term TOKEN_MOD factor { $$=newOpExpNode($1,$3,TOKEN_MOD); }
  569. | term TOKEN_AND factor { $$=newOpExpNode($1,$3,TOKEN_AND); }
  570. | factor {$$=$1;} ;
  571. factor : ID
  572. {$$=$1;}
  573. | ID TOKEN_LP args_list TOKEN_RP
  574. { $$=newExpNode(EXP_FUNC);
  575. $$->attr.name=copyString($1->attr.name);
  576. $$->child[1]=$3;
  577. }
  578. | const_value {$$=$1;}
  579. | TOKEN_LP expression TOKEN_RP {$$=$2;}
  580. | TOKEN_NOT factor
  581. { $$=newOpExpNode($2,NULL,TOKEN_NOT);
  582. }
  583. | TOKEN_MINUS factor
  584. { $$=newOpExpNode($2,NULL,TOKEN_MINUS);
  585. }
  586. | ID TOKEN_LB expression TOKEN_RB
  587. { $$=$1;
  588. $$->child[0]=$3;
  589. $$->type=EXPTYPE_ARRAY;
  590. }
  591. | ID TOKEN_DOT ID
  592. { $$=$1;
  593. $$->child[0]=$3;
  594. $$->type=EXPTYPE_RECORD;
  595. }
  596. ;
  597. %%
  598. int yyerror(char* message){
  599. fprintf(listing, "Syntax error at line %d: %s\n",lineno,message);
  600. // printToken(yychar, tokenString);
  601. return 0;
  602. }
  603. TreeNode * parse(){
  604. yyparse();
  605. return savedTree;
  606. }