Year 2 compilers coureswork

C.y 8.0KB

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