Year 2 compilers coureswork

C.y 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. %{
  2. #pragma GCC diagnostic ignored "-Wall"
  3. #pragma GCC diagnostic ignored "-Wconversion"
  4. #pragma GCC diagnostic ignored "-Wpedantic"
  5. #pragma GCC diagnostic ignored "-Wextra"
  6. #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
  7. #include "nodes.h"
  8. #define YYSTYPE NODE*
  9. #define YYDEBUG 1
  10. extern TOKEN *int_token, *void_token, *function_token, *lasttok;
  11. NODE *ans;
  12. %}
  13. %token IDENTIFIER CONSTANT STRING_LITERAL
  14. %token LE_OP GE_OP EQ_OP NE_OP
  15. %token EXTERN AUTO
  16. %token INT VOID FUNCTION
  17. %token APPLY LEAF
  18. %token IF ELSE WHILE CONTINUE BREAK RETURN
  19. %start goal
  20. %%
  21. goal : translation_unit { ans = $$ = $1;}
  22. ;
  23. primary_expression
  24. : IDENTIFIER { $$ = make_leaf(lasttok); }
  25. | CONSTANT { $$ = make_leaf(lasttok); }
  26. | STRING_LITERAL { $$ = make_leaf(lasttok); }
  27. | '(' expression ')' { $$ = $2; }
  28. ;
  29. postfix_expression
  30. : primary_expression { $$ = $1; }
  31. | postfix_expression '(' ')' { $$ = make_node(APPLY, $1, NULL); }
  32. | postfix_expression '(' argument_expression_list ')' {
  33. $$ = make_node(APPLY, $1, $3); }
  34. ;
  35. argument_expression_list
  36. : assignment_expression { $$ = $1; }
  37. | argument_expression_list ',' assignment_expression {
  38. $$ = make_node(',', $1, $3); }
  39. ;
  40. unary_expression
  41. : postfix_expression { $$ = $1; }
  42. | unary_operator unary_expression { $$ = make_node((int)$1, $2, NULL); }
  43. ;
  44. unary_operator
  45. : '&' { $$ = $1; }
  46. | '*' { $$ = $1; }
  47. | '+' { $$ = $1; }
  48. | '-' { $$ = $1; }
  49. | '!' { $$ = $1; }
  50. ;
  51. multiplicative_expression
  52. : unary_expression { $$ = $1; }
  53. | multiplicative_expression '*' unary_expression {
  54. $$ = make_node('*', $1, $3); }
  55. | multiplicative_expression '/' unary_expression {
  56. $$ = make_node('/', $1, $3); }
  57. | multiplicative_expression '%' unary_expression {
  58. $$ = make_node('%', $1, $3); }
  59. ;
  60. additive_expression
  61. : multiplicative_expression { $$ = $1; }
  62. | additive_expression '+' multiplicative_expression {
  63. $$ = make_node('+', $1, $3); }
  64. | additive_expression '-' multiplicative_expression {
  65. $$ = make_node('-', $1, $3); }
  66. ;
  67. relational_expression
  68. : additive_expression { $$ = $1; }
  69. | relational_expression '<' additive_expression {
  70. $$ = make_node('<', $1, $3); }
  71. | relational_expression '>' additive_expression {
  72. $$ = make_node('>', $1, $3); }
  73. | relational_expression LE_OP additive_expression {
  74. $$ = make_node(LE_OP, $1, $3); }
  75. | relational_expression GE_OP additive_expression {
  76. $$ = make_node(GE_OP, $1, $3); }
  77. ;
  78. equality_expression
  79. : relational_expression { $$ = $1; }
  80. | equality_expression EQ_OP relational_expression {
  81. $$ = make_node(EQ_OP, $1, $3); }
  82. | equality_expression NE_OP relational_expression {
  83. $$ = make_node(NE_OP, $1, $3); }
  84. ;
  85. assignment_expression
  86. : equality_expression { $$ = $1; }
  87. | unary_expression '=' assignment_expression {
  88. $$ = make_node('=', $1, $3); }
  89. ;
  90. expression
  91. : assignment_expression { $$ = $1; }
  92. | expression ',' assignment_expression { $$ = make_node(',', $1, $3); }
  93. ;
  94. declaration
  95. : declaration_specifiers ';' { $$ = $1; }
  96. | function_definition { $$ = $1; }
  97. | declaration_specifiers init_declarator_list ';' {
  98. $$ = make_node('~', $1, $2); }
  99. ;
  100. declaration_specifiers
  101. : storage_class_specifier { $$ = $1; }
  102. | storage_class_specifier declaration_specifiers {
  103. $$ = make_node('~', $1, $2); }
  104. | type_specifier { $$ = $1; }
  105. | type_specifier declaration_specifiers { $$ = make_node('~', $1, $2); }
  106. ;
  107. init_declarator_list
  108. : init_declarator { $$ = $1; }
  109. | init_declarator_list ',' init_declarator { $$ = make_node(',', $1, $3); }
  110. ;
  111. init_declarator
  112. : declarator { $$ = $1; }
  113. | declarator '=' assignment_expression { $$ = make_node('=', $1, $3); }
  114. ;
  115. storage_class_specifier
  116. : EXTERN { $$ = $1; }
  117. | AUTO { $$ = $1; }
  118. ;
  119. type_specifier
  120. : VOID { $$ = make_leaf(void_token); }
  121. | INT { $$ = make_leaf(int_token); }
  122. | FUNCTION { $$ = make_leaf(function_token); }
  123. ;
  124. declarator
  125. : pointer direct_declarator { $$ = make_node('~', $1, $2); }
  126. | direct_declarator { $$ = $1; }
  127. ;
  128. direct_declarator
  129. : IDENTIFIER { $$ = make_leaf(lasttok); }
  130. | '(' declarator ')' { $$ = $2; }
  131. | direct_declarator '(' parameter_list ')' { $$ = make_node('F', $1, $3); }
  132. | direct_declarator '(' identifier_list ')'{ $$ = make_node('F', $1, $3); }
  133. | direct_declarator '(' ')' { $$ = make_node('F', $1, NULL); }
  134. ;
  135. pointer
  136. : '*' { $$ = (NODE*)1; }
  137. | '*' pointer { $$ = (NODE*)((int)$2+1); }
  138. ;
  139. parameter_list
  140. : parameter_declaration { $$ = $1; }
  141. | parameter_list ',' parameter_declaration { $$ = make_node(',', $1, $3); }
  142. ;
  143. parameter_declaration
  144. : declaration_specifiers declarator { $$ = make_node('~', $1, $2); }
  145. | declaration_specifiers abstract_declarator { $$ = make_node('~', $1, $2); }
  146. | declaration_specifiers { $$ = $1; }
  147. ;
  148. identifier_list
  149. : IDENTIFIER { $$ = make_leaf(lasttok); }
  150. | identifier_list ',' IDENTIFIER {
  151. $$ = make_node(',', $1,
  152. make_leaf(lasttok)); }
  153. ;
  154. abstract_declarator
  155. : pointer { $$ = $1; }
  156. | direct_abstract_declarator { $$ = $1; }
  157. | pointer direct_abstract_declarator { $$ = make_node('G', $1, $2); }
  158. ;
  159. direct_abstract_declarator
  160. : '(' abstract_declarator ')' { $$ = $2; }
  161. | '(' ')' { $$ = NULL; }
  162. | '(' parameter_list ')' { $$ = $2; }
  163. | direct_abstract_declarator '(' ')' { $$ = make_node(APPLY, $1, NULL); }
  164. | direct_abstract_declarator '(' parameter_list ')' { $$ = make_node(APPLY, $1, $3); }
  165. ;
  166. statement
  167. : compound_statement { $$ = $1; }
  168. | expression_statement { $$ = $1; }
  169. | selection_statement { $$ = $1; }
  170. | iteration_statement { $$ = $1; }
  171. | jump_statement { $$ = $1; }
  172. ;
  173. compound_statement
  174. : '{' '}' { $$ = NULL; }
  175. | '{' statement_list '}' { $$ = $2; }
  176. | '{' declaration_list '}' { $$ = $2; }
  177. | '{' declaration_list statement_list '}' { $$ = make_node(';', $2, $3); }
  178. ;
  179. declaration_list
  180. : declaration { $$ = $1; }
  181. | declaration_list declaration { $$ = make_node(';', $1, $2); }
  182. ;
  183. statement_list
  184. : statement { $$ = $1; }
  185. | statement_list statement { $$ = make_node(';', $1, $2); }
  186. ;
  187. expression_statement
  188. : ';' { $$ = NULL; }
  189. | expression ';' { $$ = $1; }
  190. ;
  191. selection_statement
  192. : IF '(' expression ')' statement { $$ = make_node(IF, $3, $5); }
  193. | IF '(' expression ')' statement ELSE statement
  194. { $$ = make_node(IF, $3,
  195. make_node(ELSE, $5, $7)); }
  196. ;
  197. iteration_statement
  198. : WHILE '(' expression ')' statement { $$ = make_node(WHILE, $3, $5); }
  199. ;
  200. jump_statement
  201. : CONTINUE ';' { $$ = make_node(CONTINUE, NULL, NULL); }
  202. | BREAK ';' { $$ = make_node(BREAK, NULL, NULL); }
  203. | RETURN ';' { $$ = make_node(RETURN, NULL, NULL); }
  204. | RETURN expression ';' { $$ = make_node(RETURN, $2, NULL); }
  205. ;
  206. translation_unit
  207. : external_declaration { $$ = $1; }
  208. | translation_unit external_declaration { $$ = make_node('~', $1, $2);}
  209. ;
  210. external_declaration
  211. : function_definition { $$ = $1; }
  212. | declaration { $$ = $1; }
  213. ;
  214. function_definition
  215. : declaration_specifiers declarator declaration_list compound_statement {
  216. $$ = make_node('D', make_node('d', $1, make_node('e', $2, $3)), $4); }
  217. | declaration_specifiers declarator compound_statement {
  218. $$ = make_node('D', make_node('d', $1, $2), $3); }
  219. | declarator declaration_list compound_statement {
  220. $$ = make_node('D', make_node('d', $1, $2), $3); }
  221. | declarator compound_statement { $$ = make_node('D', $1, $2); }
  222. ;
  223. %%
  224. #include <stdio.h>
  225. extern char yytext[];
  226. extern int column;
  227. int yyerror(char *s)
  228. {
  229. fflush(stdout);
  230. printf("\n%*s\n%*s\n", column, "^", column, s);
  231. }