syntax.ypp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. %code top {
  5. #include <algorithm>
  6. #include <cstdarg>
  7. #include <cstdio>
  8. #include <cstdlib>
  9. #include <iostream>
  10. #include <list>
  11. #include "executable_semantics/syntax_helpers.h"
  12. }
  13. %code requires {
  14. #include "executable_semantics/ast/declaration.h"
  15. #include "executable_semantics/ast/expression_or_field_list.h"
  16. #include "executable_semantics/ast/function_definition.h"
  17. }
  18. %code {
  19. extern int yylineno;
  20. extern int yylex();
  21. void yyerror(char* error) {
  22. Carbon::PrintSyntaxError(error, yylineno);
  23. }
  24. // void yyerror(char* error, ...);
  25. }
  26. %union {
  27. char* str;
  28. int num;
  29. Carbon::Expression* expression;
  30. std::list<std::pair<std::string, Carbon::Expression*>>* field_types;
  31. Carbon::Statement* statement;
  32. Carbon::Statement* statement_list;
  33. Carbon::FunctionDefinition* function_definition;
  34. Carbon::Declaration* declaration;
  35. std::list<Carbon::Declaration*>* declaration_list;
  36. Carbon::Member* member;
  37. std::list<Carbon::Member*>* member_list;
  38. Carbon::ExpOrFieldList* field_list;
  39. std::pair<std::string, Carbon::Expression*>* alternative;
  40. std::list<std::pair<std::string, Carbon::Expression*>>* alternative_list;
  41. std::pair<Carbon::Expression*, Carbon::Statement*>* clause;
  42. std::list<std::pair<Carbon::Expression*, Carbon::Statement*>>* clause_list;
  43. Carbon::Expression* fun_type;
  44. };
  45. %token <num> integer_literal
  46. %token <str> identifier
  47. %type <str> designator
  48. %type <declaration> declaration
  49. %type <function_definition> function_declaration
  50. %type <function_definition> function_definition
  51. %type <declaration_list> declaration_list
  52. %type <statement> statement
  53. %type <statement> optional_else
  54. %type <statement_list> statement_list
  55. %type <expression> expression
  56. %type <expression> pattern
  57. %type <expression> return_type
  58. %type <expression> tuple
  59. %type <member> member
  60. %type <member_list> member_list
  61. %type <field_list> field
  62. %type <field_list> field_list
  63. %type <alternative> alternative
  64. %type <alternative_list> alternative_list
  65. %type <clause> clause
  66. %type <clause_list> clause_list
  67. %token AND
  68. %token OR
  69. %token NOT
  70. %token INT
  71. %token BOOL
  72. %token TYPE
  73. %token FN
  74. %token FNTY
  75. %token ARROW
  76. %token VAR
  77. %token EQUAL
  78. %token IF
  79. %token ELSE
  80. %token WHILE
  81. %token BREAK
  82. %token CONTINUE
  83. %token RETURN
  84. %token TRUE
  85. %token FALSE
  86. %token STRUCT
  87. %token CHOICE
  88. %token MATCH
  89. %token CASE
  90. %token DBLARROW
  91. %token DEFAULT
  92. %token AUTO
  93. %nonassoc '{' '}'
  94. %nonassoc ':' ',' DBLARROW
  95. %left OR AND
  96. %nonassoc EQUAL NOT
  97. %left '+' '-'
  98. %left '.' ARROW
  99. %nonassoc '(' ')' '[' ']'
  100. %start input
  101. %locations
  102. %%
  103. input: declaration_list
  104. { Carbon::ExecProgram($1); }
  105. ;
  106. pattern:
  107. expression
  108. { $$ = $1; }
  109. ;
  110. expression:
  111. identifier
  112. { $$ = Carbon::MakeVar(yylineno, $1); }
  113. | expression designator
  114. { $$ = Carbon::MakeGetField(yylineno, $1, $2); }
  115. | expression '[' expression ']'
  116. { $$ = Carbon::MakeIndex(yylineno, $1, $3); }
  117. | expression ':' identifier
  118. { $$ = Carbon::MakeVarPat(yylineno, $3, $1); }
  119. | integer_literal
  120. { $$ = Carbon::MakeInt(yylineno, $1); }
  121. | TRUE
  122. { $$ = Carbon::MakeBool(yylineno, true); }
  123. | FALSE
  124. { $$ = Carbon::MakeBool(yylineno, false); }
  125. | INT
  126. { $$ = Carbon::MakeIntType(yylineno); }
  127. | BOOL
  128. { $$ = Carbon::MakeBoolType(yylineno); }
  129. | TYPE
  130. { $$ = Carbon::MakeTypeType(yylineno); }
  131. | AUTO
  132. { $$ = Carbon::MakeAutoType(yylineno); }
  133. | tuple { $$ = $1; }
  134. | expression EQUAL expression
  135. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Eq, $1, $3); }
  136. | expression '+' expression
  137. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Add, $1, $3); }
  138. | expression '-' expression
  139. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Sub, $1, $3); }
  140. | expression AND expression
  141. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::And, $1, $3); }
  142. | expression OR expression
  143. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Or, $1, $3); }
  144. | NOT expression
  145. { $$ = Carbon::MakeUnOp(yylineno, Carbon::Operator::Not, $2); }
  146. | '-' expression
  147. { $$ = Carbon::MakeUnOp(yylineno, Carbon::Operator::Neg, $2); }
  148. | expression tuple
  149. {
  150. if ($2->tag == Carbon::ExpressionKind::Tuple) {
  151. $$ = Carbon::MakeCall(yylineno, $1, $2);
  152. } else {
  153. auto vec =
  154. new std::vector<std::pair<std::string, Carbon::Expression*>>();
  155. vec->push_back(std::make_pair("", $2));
  156. $$ = Carbon::MakeCall(yylineno, $1, Carbon::MakeTuple(yylineno, vec));
  157. }
  158. }
  159. | FNTY tuple return_type
  160. { $$ = Carbon::MakeFunType(yylineno, $2, $3); }
  161. ;
  162. designator: '.' identifier { $$ = $2; }
  163. ;
  164. tuple: '(' field_list ')'
  165. {
  166. switch ($2->tag) {
  167. case Carbon::ExpOrFieldListKind::Exp:
  168. $$ = $2->u.exp;
  169. break;
  170. case Carbon::ExpOrFieldListKind::FieldList:
  171. auto vec = new std::vector<std::pair<std::string,Carbon::Expression*>>(
  172. $2->u.fields->begin(), $2->u.fields->end());
  173. $$ = Carbon::MakeTuple(yylineno, vec);
  174. break;
  175. }
  176. }
  177. ;
  178. field:
  179. pattern
  180. { $$ = Carbon::MakeExp($1); }
  181. | designator '=' pattern
  182. {
  183. auto fields =
  184. new std::list<std::pair<std::string, Carbon::Expression*>>();
  185. fields->push_back(std::make_pair($1, $3));
  186. $$ = Carbon::MakeFieldList(fields);
  187. }
  188. ;
  189. field_list:
  190. // Empty
  191. {
  192. $$ = Carbon::MakeFieldList(
  193. new std::list<std::pair<std::string, Carbon::Expression*>>());
  194. }
  195. | field
  196. { $$ = $1; }
  197. | field ',' field_list
  198. { $$ = Carbon::MakeConsField($1, $3); }
  199. ;
  200. clause:
  201. CASE pattern DBLARROW statement
  202. { $$ = new std::pair<Carbon::Expression*, Carbon::Statement*>($2, $4); }
  203. | DEFAULT DBLARROW statement
  204. {
  205. auto vp = Carbon::MakeVarPat(yylineno, "_",
  206. Carbon::MakeAutoType(yylineno));
  207. $$ = new std::pair<Carbon::Expression*, Carbon::Statement*>(vp, $3);
  208. }
  209. ;
  210. clause_list:
  211. // Empty
  212. {
  213. $$ = new std::list<std::pair<Carbon::Expression*, Carbon::Statement*>>();
  214. }
  215. | clause clause_list
  216. { $$ = $2; $$->push_front(*$1); }
  217. ;
  218. statement:
  219. expression '=' expression ';'
  220. { $$ = Carbon::MakeAssign(yylineno, $1, $3); }
  221. | VAR pattern '=' expression ';'
  222. { $$ = Carbon::MakeVarDef(yylineno, $2, $4); }
  223. | expression ';'
  224. { $$ = Carbon::MakeExpStmt(yylineno, $1); }
  225. | IF '(' expression ')' statement optional_else
  226. { $$ = Carbon::MakeIf(yylineno, $3, $5, $6); }
  227. | WHILE '(' expression ')' statement
  228. { $$ = Carbon::MakeWhile(yylineno, $3, $5); }
  229. | BREAK ';'
  230. { $$ = Carbon::MakeBreak(yylineno); }
  231. | CONTINUE ';'
  232. { $$ = Carbon::MakeContinue(yylineno); }
  233. | RETURN expression ';'
  234. { $$ = Carbon::MakeReturn(yylineno, $2); }
  235. | '{' statement_list '}'
  236. { $$ = Carbon::MakeBlock(yylineno, $2); }
  237. | MATCH '(' expression ')' '{' clause_list '}'
  238. { $$ = Carbon::MakeMatch(yylineno, $3, $6); }
  239. ;
  240. optional_else:
  241. // Empty
  242. { $$ = 0; }
  243. | ELSE statement { $$ = $2; }
  244. ;
  245. statement_list:
  246. // Empty
  247. { $$ = 0; }
  248. | statement statement_list
  249. { $$ = Carbon::MakeSeq(yylineno, $1, $2); }
  250. ;
  251. return_type:
  252. // Empty
  253. {
  254. $$ = Carbon::MakeTuple(
  255. yylineno,
  256. new std::vector<std::pair<std::string, Carbon::Expression*>>());
  257. }
  258. | ARROW expression
  259. { $$ = $2; }
  260. ;
  261. function_definition:
  262. FN identifier tuple return_type '{' statement_list '}'
  263. { $$ = MakeFunDef(yylineno, $2, $4, $3, $6); }
  264. | FN identifier tuple DBLARROW expression ';'
  265. {
  266. $$ = Carbon::MakeFunDef(yylineno, $2, Carbon::MakeAutoType(yylineno), $3,
  267. Carbon::MakeReturn(yylineno, $5));
  268. }
  269. ;
  270. function_declaration:
  271. FN identifier tuple return_type ';'
  272. { $$ = MakeFunDef(yylineno, $2, $4, $3, 0); }
  273. ;
  274. member:
  275. VAR expression ':' identifier ';'
  276. { $$ = MakeField(yylineno, $4, $2); }
  277. ;
  278. member_list:
  279. // Empty
  280. { $$ = new std::list<Carbon::Member*>(); }
  281. | member member_list
  282. { $$ = $2; $$->push_front($1); }
  283. ;
  284. alternative:
  285. identifier tuple ';'
  286. { $$ = new std::pair<std::string, Carbon::Expression*>($1, $2); }
  287. ;
  288. alternative_list:
  289. // Empty
  290. { $$ = new std::list<std::pair<std::string, Carbon::Expression*>>(); }
  291. | alternative alternative_list
  292. { $$ = $2; $$->push_front(*$1); }
  293. ;
  294. declaration:
  295. function_definition
  296. { $$ = Carbon::MakeFunDecl($1); }
  297. | function_declaration
  298. { $$ = Carbon::MakeFunDecl($1); }
  299. | STRUCT identifier '{' member_list '}'
  300. { $$ = Carbon::MakeStructDecl(yylineno, $2, $4); }
  301. | CHOICE identifier '{' alternative_list '}'
  302. { $$ = Carbon::MakeChoiceDecl(yylineno, $2, $4); }
  303. ;
  304. declaration_list:
  305. // Empty
  306. { $$ = new std::list<Carbon::Declaration*>(); }
  307. | declaration declaration_list
  308. {
  309. $$ = $2;
  310. $$->push_front($1);
  311. }
  312. ;
  313. %%