syntax.ypp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  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/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::FieldList* 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> paren_expression
  59. %type <expression> tuple
  60. %type <member> member
  61. %type <member_list> member_list
  62. %type <field_list> field
  63. %type <field_list> field_list
  64. %type <alternative> alternative
  65. %type <alternative_list> alternative_list
  66. %type <clause> clause
  67. %type <clause_list> clause_list
  68. %token AND
  69. %token OR
  70. %token NOT
  71. %token INT
  72. %token BOOL
  73. %token TYPE
  74. %token FN
  75. %token FNTY
  76. %token ARROW
  77. %token VAR
  78. %token EQUAL
  79. %token IF
  80. %token ELSE
  81. %token WHILE
  82. %token BREAK
  83. %token CONTINUE
  84. %token RETURN
  85. %token TRUE
  86. %token FALSE
  87. %token STRUCT
  88. %token CHOICE
  89. %token MATCH
  90. %token CASE
  91. %token DBLARROW
  92. %token DEFAULT
  93. %token AUTO
  94. %nonassoc '{' '}'
  95. %nonassoc ':' ',' DBLARROW
  96. %left OR AND
  97. %nonassoc EQUAL NOT
  98. %left '+' '-'
  99. %left '.' ARROW
  100. %nonassoc '(' ')' '[' ']'
  101. %start input
  102. %locations
  103. %%
  104. input: declaration_list
  105. { Carbon::ExecProgram($1); }
  106. ;
  107. pattern:
  108. expression
  109. { $$ = $1; }
  110. ;
  111. expression:
  112. identifier
  113. { $$ = Carbon::MakeVar(yylineno, $1); }
  114. | expression designator
  115. { $$ = Carbon::MakeGetField(yylineno, $1, $2); }
  116. | expression '[' expression ']'
  117. { $$ = Carbon::MakeIndex(yylineno, $1, $3); }
  118. | expression ':' identifier
  119. { $$ = Carbon::MakeVarPat(yylineno, $3, $1); }
  120. | integer_literal
  121. { $$ = Carbon::MakeInt(yylineno, $1); }
  122. | TRUE
  123. { $$ = Carbon::MakeBool(yylineno, true); }
  124. | FALSE
  125. { $$ = Carbon::MakeBool(yylineno, false); }
  126. | INT
  127. { $$ = Carbon::MakeIntType(yylineno); }
  128. | BOOL
  129. { $$ = Carbon::MakeBoolType(yylineno); }
  130. | TYPE
  131. { $$ = Carbon::MakeTypeType(yylineno); }
  132. | AUTO
  133. { $$ = Carbon::MakeAutoType(yylineno); }
  134. | paren_expression { $$ = $1; }
  135. | expression EQUAL expression
  136. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Eq, $1, $3); }
  137. | expression '+' expression
  138. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Add, $1, $3); }
  139. | expression '-' expression
  140. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Sub, $1, $3); }
  141. | expression AND expression
  142. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::And, $1, $3); }
  143. | expression OR expression
  144. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Or, $1, $3); }
  145. | NOT expression
  146. { $$ = Carbon::MakeUnOp(yylineno, Carbon::Operator::Not, $2); }
  147. | '-' expression
  148. { $$ = Carbon::MakeUnOp(yylineno, Carbon::Operator::Neg, $2); }
  149. | expression tuple
  150. { $$ = Carbon::MakeCall(yylineno, $1, $2); }
  151. | FNTY tuple return_type
  152. { $$ = Carbon::MakeFunType(yylineno, $2, $3); }
  153. ;
  154. designator: '.' identifier { $$ = $2; }
  155. ;
  156. paren_expression: '(' field_list ')'
  157. {
  158. if ($2->fields->size() == 1 &&
  159. $2->fields->front().first == "" &&
  160. !$2->has_explicit_comma) {
  161. $$ = $2->fields->front().second;
  162. } else {
  163. auto vec = new std::vector<std::pair<std::string,Carbon::Expression*>>(
  164. $2->fields->begin(), $2->fields->end());
  165. $$ = Carbon::MakeTuple(yylineno, vec);
  166. }
  167. }
  168. ;
  169. tuple: '(' field_list ')'
  170. {
  171. auto vec = new std::vector<std::pair<std::string,Carbon::Expression*>>(
  172. $2->fields->begin(), $2->fields->end());
  173. $$ = Carbon::MakeTuple(yylineno, vec);
  174. }
  175. field:
  176. pattern
  177. {
  178. auto fields =
  179. new std::list<std::pair<std::string, Carbon::Expression*>>();
  180. fields->push_back(std::make_pair("", $1));
  181. $$ = Carbon::MakeFieldList(fields);
  182. }
  183. | designator '=' pattern
  184. {
  185. auto fields =
  186. new std::list<std::pair<std::string, Carbon::Expression*>>();
  187. fields->push_back(std::make_pair($1, $3));
  188. $$ = Carbon::MakeFieldList(fields);
  189. }
  190. ;
  191. field_list:
  192. // Empty
  193. {
  194. $$ = Carbon::MakeFieldList(
  195. new std::list<std::pair<std::string, Carbon::Expression*>>());
  196. }
  197. | field
  198. { $$ = $1; }
  199. | field ',' field_list
  200. { $$ = Carbon::MakeConsField($1, $3); }
  201. ;
  202. clause:
  203. CASE pattern DBLARROW statement
  204. { $$ = new std::pair<Carbon::Expression*, Carbon::Statement*>($2, $4); }
  205. | DEFAULT DBLARROW statement
  206. {
  207. auto vp = Carbon::MakeVarPat(yylineno, "_",
  208. Carbon::MakeAutoType(yylineno));
  209. $$ = new std::pair<Carbon::Expression*, Carbon::Statement*>(vp, $3);
  210. }
  211. ;
  212. clause_list:
  213. // Empty
  214. {
  215. $$ = new std::list<std::pair<Carbon::Expression*, Carbon::Statement*>>();
  216. }
  217. | clause clause_list
  218. { $$ = $2; $$->push_front(*$1); }
  219. ;
  220. statement:
  221. expression '=' expression ';'
  222. { $$ = Carbon::MakeAssign(yylineno, $1, $3); }
  223. | VAR pattern '=' expression ';'
  224. { $$ = Carbon::MakeVarDef(yylineno, $2, $4); }
  225. | expression ';'
  226. { $$ = Carbon::MakeExpStmt(yylineno, $1); }
  227. | IF '(' expression ')' statement optional_else
  228. { $$ = Carbon::MakeIf(yylineno, $3, $5, $6); }
  229. | WHILE '(' expression ')' statement
  230. { $$ = Carbon::MakeWhile(yylineno, $3, $5); }
  231. | BREAK ';'
  232. { $$ = Carbon::MakeBreak(yylineno); }
  233. | CONTINUE ';'
  234. { $$ = Carbon::MakeContinue(yylineno); }
  235. | RETURN expression ';'
  236. { $$ = Carbon::MakeReturn(yylineno, $2); }
  237. | '{' statement_list '}'
  238. { $$ = Carbon::MakeBlock(yylineno, $2); }
  239. | MATCH '(' expression ')' '{' clause_list '}'
  240. { $$ = Carbon::MakeMatch(yylineno, $3, $6); }
  241. ;
  242. optional_else:
  243. // Empty
  244. { $$ = 0; }
  245. | ELSE statement { $$ = $2; }
  246. ;
  247. statement_list:
  248. // Empty
  249. { $$ = 0; }
  250. | statement statement_list
  251. { $$ = Carbon::MakeSeq(yylineno, $1, $2); }
  252. ;
  253. return_type:
  254. // Empty
  255. {
  256. $$ = Carbon::MakeTuple(
  257. yylineno,
  258. new std::vector<std::pair<std::string, Carbon::Expression*>>());
  259. }
  260. | ARROW expression
  261. { $$ = $2; }
  262. ;
  263. function_definition:
  264. FN identifier tuple return_type '{' statement_list '}'
  265. { $$ = MakeFunDef(yylineno, $2, $4, $3, $6); }
  266. | FN identifier tuple DBLARROW expression ';'
  267. {
  268. $$ = Carbon::MakeFunDef(yylineno, $2, Carbon::MakeAutoType(yylineno), $3,
  269. Carbon::MakeReturn(yylineno, $5));
  270. }
  271. ;
  272. function_declaration:
  273. FN identifier tuple return_type ';'
  274. { $$ = MakeFunDef(yylineno, $2, $4, $3, 0); }
  275. ;
  276. member:
  277. VAR expression ':' identifier ';'
  278. { $$ = MakeField(yylineno, $4, $2); }
  279. ;
  280. member_list:
  281. // Empty
  282. { $$ = new std::list<Carbon::Member*>(); }
  283. | member member_list
  284. { $$ = $2; $$->push_front($1); }
  285. ;
  286. alternative:
  287. identifier tuple
  288. { $$ = new std::pair<std::string, Carbon::Expression*>($1, $2); }
  289. | identifier
  290. {
  291. $$ = new std::pair<std::string, Carbon::Expression*>(
  292. $1, Carbon::MakeTuple(
  293. yylineno,
  294. new std::vector<std::pair<std::string, Carbon::Expression*>>()));
  295. }
  296. ;
  297. alternative_list:
  298. // Empty
  299. { $$ = new std::list<std::pair<std::string, Carbon::Expression*>>(); }
  300. | alternative
  301. {
  302. $$ = new std::list<std::pair<std::string, Carbon::Expression*>>();
  303. $$->push_front(*$1);
  304. }
  305. | alternative ',' alternative_list
  306. { $$ = $3; $$->push_front(*$1); }
  307. ;
  308. declaration:
  309. function_definition
  310. { $$ = new Carbon::Declaration(Carbon::FunctionDeclaration{$1}); }
  311. | function_declaration
  312. { $$ = new Carbon::Declaration(Carbon::FunctionDeclaration{$1}); }
  313. | STRUCT identifier '{' member_list '}'
  314. {
  315. $$ = new Carbon::Declaration(
  316. Carbon::StructDeclaration{yylineno, $2, $4});
  317. }
  318. | CHOICE identifier '{' alternative_list '}'
  319. {
  320. $$ = new Carbon::Declaration(
  321. Carbon::ChoiceDeclaration{yylineno, $2, std::list(*$4)});
  322. }
  323. ;
  324. declaration_list:
  325. // Empty
  326. { $$ = new std::list<Carbon::Declaration>(); }
  327. | declaration declaration_list
  328. {
  329. $$ = $2;
  330. $$->push_front(*$1);
  331. }
  332. ;
  333. %%