A Hugo incarnation of the blog.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

parser.y 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. %code requires {
  2. #include <string>
  3. #include <vector>
  4. #include "ast.hpp"
  5. #include "definition.hpp"
  6. #include "parser.hpp"
  7. #include "parsed_type.hpp"
  8. class parse_driver;
  9. using yyscan_t = void*;
  10. }
  11. %param { yyscan_t scanner }
  12. %param { parse_driver& drv }
  13. %code {
  14. #include "parse_driver.hpp"
  15. }
  16. %token BACKSLASH
  17. %token PLUS
  18. %token TIMES
  19. %token MINUS
  20. %token DIVIDE
  21. %token <int> INT
  22. %token DEFN
  23. %token DATA
  24. %token CASE
  25. %token OF
  26. %token LET
  27. %token IN
  28. %token OCURLY
  29. %token CCURLY
  30. %token OPAREN
  31. %token CPAREN
  32. %token COMMA
  33. %token ARROW
  34. %token EQUAL
  35. %token <std::string> LID
  36. %token <std::string> UID
  37. %language "c++"
  38. %define api.value.type variant
  39. %define api.token.constructor
  40. %locations
  41. %type <std::vector<std::string>> lowercaseParams
  42. %type <std::vector<branch_ptr>> branches
  43. %type <std::vector<constructor_ptr>> constructors
  44. %type <std::vector<parsed_type_ptr>> typeList
  45. %type <definition_group> definitions
  46. %type <parsed_type_ptr> type nonArrowType typeListElement
  47. %type <ast_ptr> aAdd aMul case let lambda app appBase
  48. %type <definition_data_ptr> data
  49. %type <definition_defn_ptr> defn
  50. %type <branch_ptr> branch
  51. %type <pattern_ptr> pattern
  52. %type <constructor_ptr> constructor
  53. %start program
  54. %%
  55. program
  56. : definitions { $1.vis = visibility::global; std::swap(drv.get_global_defs(), $1); }
  57. ;
  58. definitions
  59. : definitions defn { $$ = std::move($1); auto name = $2->name; $$.defs_defn[name] = std::move($2); }
  60. | definitions data { $$ = std::move($1); auto name = $2->name; $$.defs_data[name] = std::move($2); }
  61. | %empty { $$ = definition_group(); }
  62. ;
  63. defn
  64. : DEFN LID lowercaseParams EQUAL OCURLY aAdd CCURLY
  65. { $$ = definition_defn_ptr(
  66. new definition_defn(std::move($2), std::move($3), std::move($6), @$)); }
  67. ;
  68. lowercaseParams
  69. : %empty { $$ = std::vector<std::string>(); }
  70. | lowercaseParams LID { $$ = std::move($1); $$.push_back(std::move($2)); }
  71. ;
  72. aAdd
  73. : aAdd PLUS aMul { $$ = ast_ptr(new ast_binop(PLUS, std::move($1), std::move($3), @$)); }
  74. | aAdd MINUS aMul { $$ = ast_ptr(new ast_binop(MINUS, std::move($1), std::move($3), @$)); }
  75. | aMul { $$ = std::move($1); }
  76. ;
  77. aMul
  78. : aMul TIMES app { $$ = ast_ptr(new ast_binop(TIMES, std::move($1), std::move($3), @$)); }
  79. | aMul DIVIDE app { $$ = ast_ptr(new ast_binop(DIVIDE, std::move($1), std::move($3), @$)); }
  80. | app { $$ = std::move($1); }
  81. ;
  82. app
  83. : app appBase { $$ = ast_ptr(new ast_app(std::move($1), std::move($2), @$)); }
  84. | appBase { $$ = std::move($1); }
  85. ;
  86. appBase
  87. : INT { $$ = ast_ptr(new ast_int($1, @$)); }
  88. | LID { $$ = ast_ptr(new ast_lid(std::move($1), @$)); }
  89. | UID { $$ = ast_ptr(new ast_uid(std::move($1), @$)); }
  90. | OPAREN aAdd CPAREN { $$ = std::move($2); }
  91. | case { $$ = std::move($1); }
  92. | let { $$ = std::move($1); }
  93. | lambda { $$ = std::move($1); }
  94. ;
  95. let
  96. : LET OCURLY definitions CCURLY IN OCURLY aAdd CCURLY
  97. { $$ = ast_ptr(new ast_let(std::move($3), std::move($7), @$)); }
  98. ;
  99. lambda
  100. : BACKSLASH lowercaseParams ARROW OCURLY aAdd CCURLY
  101. { $$ = ast_ptr(new ast_lambda(std::move($2), std::move($5), @$)); }
  102. ;
  103. case
  104. : CASE aAdd OF OCURLY branches CCURLY
  105. { $$ = ast_ptr(new ast_case(std::move($2), std::move($5), @$)); }
  106. ;
  107. branches
  108. : branches branch { $$ = std::move($1); $$.push_back(std::move($2)); }
  109. | branch { $$ = std::vector<branch_ptr>(); $$.push_back(std::move($1));}
  110. ;
  111. branch
  112. : pattern ARROW OCURLY aAdd CCURLY
  113. { $$ = branch_ptr(new branch(std::move($1), std::move($4))); }
  114. ;
  115. pattern
  116. : LID { $$ = pattern_ptr(new pattern_var(std::move($1), @$)); }
  117. | UID lowercaseParams
  118. { $$ = pattern_ptr(new pattern_constr(std::move($1), std::move($2), @$)); }
  119. ;
  120. data
  121. : DATA UID lowercaseParams EQUAL OCURLY constructors CCURLY
  122. { $$ = definition_data_ptr(new definition_data(std::move($2), std::move($3), std::move($6), @$)); }
  123. ;
  124. constructors
  125. : constructors COMMA constructor { $$ = std::move($1); $$.push_back(std::move($3)); }
  126. | constructor
  127. { $$ = std::vector<constructor_ptr>(); $$.push_back(std::move($1)); }
  128. ;
  129. constructor
  130. : UID typeList
  131. { $$ = constructor_ptr(new constructor(std::move($1), std::move($2))); }
  132. ;
  133. type
  134. : nonArrowType ARROW type { $$ = parsed_type_ptr(new parsed_type_arr(std::move($1), std::move($3))); }
  135. | nonArrowType { $$ = std::move($1); }
  136. ;
  137. nonArrowType
  138. : UID typeList { $$ = parsed_type_ptr(new parsed_type_app(std::move($1), std::move($2))); }
  139. | LID { $$ = parsed_type_ptr(new parsed_type_var(std::move($1))); }
  140. | OPAREN type CPAREN { $$ = std::move($2); }
  141. ;
  142. typeListElement
  143. : OPAREN type CPAREN { $$ = std::move($2); }
  144. | UID { $$ = parsed_type_ptr(new parsed_type_app(std::move($1), {})); }
  145. | LID { $$ = parsed_type_ptr(new parsed_type_var(std::move($1))); }
  146. ;
  147. typeList
  148. : %empty { $$ = std::vector<parsed_type_ptr>(); }
  149. | typeList typeListElement { $$ = std::move($1); $$.push_back(std::move($2)); }
  150. ;