parser.ypp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  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. // -----------------------------------------------------------------------------
  5. // Bison Configuration
  6. // -----------------------------------------------------------------------------
  7. %require "3.2"
  8. %language "c++"
  9. // We don't need a separate header for Bison locations.
  10. %define api.location.file none
  11. // Use a type-safe C++ variant for semantic values
  12. %define api.value.type variant
  13. // Have Bison generate the functions ‘make_TEXT’ and ‘make_NUMBER’, but also
  14. // ‘make_YYEOF’, for the end of input.
  15. %define api.token.constructor
  16. // Generate the parser as `::Carbon::Parser`.
  17. %define api.namespace { Carbon }
  18. %define api.parser.class { Parser }
  19. // Make parse error messages more detailed
  20. %define parse.error verbose
  21. // Enable support for parser debugging
  22. %define parse.trace true
  23. // Generate location structs.
  24. %locations
  25. // Parameters to the parser and lexer.
  26. //
  27. // Parameters to the parser are stored therein as protected data members, and
  28. // thus available to its methods.
  29. // "out" parameter passed to the parser, where the AST is written.
  30. %parse-param {std::optional<AST>& parsed_program}
  31. // "inout" parameters passed to both the parser and the lexer.
  32. %param {yyscan_t yyscanner}
  33. %param {ParseAndLexContext& context}
  34. // No shift-reduce conflicts are expected.
  35. %expect 0
  36. // -----------------------------------------------------------------------------
  37. %code top {
  38. #include <algorithm>
  39. #include <cstdarg>
  40. #include <cstdio>
  41. #include <cstdlib>
  42. #include <list>
  43. #include <vector>
  44. #include "common/check.h"
  45. #include "executable_semantics/syntax/parse_and_lex_context.h"
  46. #include "llvm/ADT/StringExtras.h"
  47. } // %code top
  48. %code requires {
  49. #include <optional>
  50. #include "executable_semantics/ast/ast.h"
  51. #include "executable_semantics/ast/declaration.h"
  52. #include "executable_semantics/ast/expression.h"
  53. #include "executable_semantics/ast/function_definition.h"
  54. #include "executable_semantics/ast/paren_contents.h"
  55. #include "executable_semantics/ast/pattern.h"
  56. #include "executable_semantics/common/arena.h"
  57. #include "executable_semantics/common/ptr.h"
  58. #include "executable_semantics/syntax/bison_wrap.h"
  59. namespace Carbon {
  60. class ParseAndLexContext;
  61. } // namespace Carbon
  62. typedef void* yyscan_t;
  63. } // %code requires
  64. %code {
  65. void Carbon::Parser::error(const location_type&, const std::string& message) {
  66. context.PrintDiagnostic(message);
  67. }
  68. } // %code
  69. %token <int> integer_literal
  70. %token <std::string> identifier
  71. %token <std::string> sized_type_literal
  72. %token <std::string> string_literal
  73. %type <std::string> designator
  74. %type <std::pair<LibraryName, bool>> package_directive
  75. %type <LibraryName> import_directive
  76. %type <std::vector<LibraryName>> import_directives
  77. %type <std::string> optional_library_path
  78. %type <bool> api_or_impl
  79. %type <BisonWrap<Ptr<const Declaration>>> declaration
  80. %type <BisonWrap<Ptr<const FunctionDefinition>>> function_declaration
  81. %type <BisonWrap<Ptr<const FunctionDefinition>>> function_definition
  82. %type <std::list<Ptr<const Declaration>>> declaration_list
  83. %type <BisonWrap<Ptr<const Statement>>> statement
  84. %type <BisonWrap<Ptr<const Statement>>> if_statement
  85. %type <std::optional<Ptr<const Statement>>> optional_else
  86. %type <BisonWrap<std::pair<Ptr<const Expression>, bool>>> return_expression
  87. %type <BisonWrap<Ptr<const Statement>>> block
  88. %type <std::optional<Ptr<const Statement>>> statement_list
  89. %type <BisonWrap<Ptr<const Expression>>> expression
  90. %type <BisonWrap<GenericBinding>> generic_binding
  91. %type <std::vector<GenericBinding>> deduced_params
  92. %type <std::vector<GenericBinding>> deduced_param_list
  93. %type <BisonWrap<Ptr<const Pattern>>> pattern
  94. %type <BisonWrap<Ptr<const Pattern>>> non_expression_pattern
  95. %type <BisonWrap<std::pair<Ptr<const Expression>, bool>>> return_type
  96. %type <BisonWrap<Ptr<const Expression>>> paren_expression
  97. %type <BisonWrap<Ptr<const Expression>>> tuple
  98. %type <std::optional<std::string>> binding_lhs
  99. %type <BisonWrap<Ptr<const BindingPattern>>> variable_declaration
  100. %type <BisonWrap<Ptr<Member>>> member
  101. %type <std::list<Ptr<Member>>> member_list
  102. %type <BisonWrap<ParenContents<Expression>::Element>> paren_expression_element
  103. %type <ParenContents<Expression>> paren_expression_base
  104. %type <ParenContents<Expression>> paren_expression_contents
  105. %type <BisonWrap<Ptr<const Pattern>>> paren_pattern
  106. %type <BisonWrap<Ptr<const TuplePattern>>> tuple_pattern
  107. %type <BisonWrap<Ptr<const TuplePattern>>> maybe_empty_tuple_pattern
  108. %type <ParenContents<Pattern>> paren_pattern_base
  109. %type <BisonWrap<ParenContents<Pattern>::Element>> paren_pattern_element
  110. %type <ParenContents<Pattern>> paren_pattern_contents
  111. %type <BisonWrap<std::pair<std::string, Ptr<const Expression>>>> alternative
  112. %type <std::list<std::pair<std::string, Ptr<const Expression>>>> alternative_list
  113. %type <BisonWrap<std::pair<Ptr<const Pattern>, Ptr<const Statement>>>> clause
  114. %type <std::list<std::pair<Ptr<const Pattern>, Ptr<const Statement>>>> clause_list
  115. %token
  116. // Most tokens have their spelling defined in lexer.lpp.
  117. AND
  118. API
  119. ARROW
  120. AUTO
  121. AWAIT
  122. BOOL
  123. BREAK
  124. CASE
  125. CHOICE
  126. CLASS
  127. COLON
  128. COLON_BANG
  129. COMMA
  130. CONTINUATION
  131. CONTINUATION_TYPE
  132. CONTINUE
  133. DEFAULT
  134. DOUBLE_ARROW
  135. ELSE
  136. EQUAL
  137. EQUAL_EQUAL
  138. FALSE
  139. FN
  140. FNTY
  141. IF
  142. IMPL
  143. IMPORT
  144. LEFT_CURLY_BRACE
  145. LEFT_PARENTHESIS
  146. LEFT_SQUARE_BRACKET
  147. LIBRARY
  148. MATCH
  149. MINUS
  150. NOT
  151. OR
  152. PACKAGE
  153. PERIOD
  154. PLUS
  155. RETURN
  156. RIGHT_CURLY_BRACE
  157. RIGHT_PARENTHESIS
  158. RIGHT_SQUARE_BRACKET
  159. RUN
  160. SEMICOLON
  161. SLASH
  162. STRING
  163. TRUE
  164. TYPE
  165. UNDERSCORE
  166. VAR
  167. WHILE
  168. // Used to track EOF.
  169. END_OF_FILE 0
  170. // Only used for precedence.
  171. FNARROW "-> in return type"
  172. // The lexer determines the arity and fixity of each `*` based on whitespace
  173. // and adjacent tokens. UNARY_STAR indicates that the operator is unary but
  174. // could be either prefix or postfix.
  175. UNARY_STAR "unary *"
  176. PREFIX_STAR "prefix *"
  177. POSTFIX_STAR "postfix *"
  178. BINARY_STAR "binary *"
  179. ;
  180. %precedence FNARROW
  181. %precedence LEFT_CURLY_BRACE RIGHT_CURLY_BRACE
  182. %precedence COLON_BANG COLON COMMA DOUBLE_ARROW
  183. %left OR AND
  184. %nonassoc EQUAL_EQUAL
  185. %left PLUS MINUS
  186. %left BINARY_STAR
  187. %precedence NOT UNARY_MINUS PREFIX_STAR
  188. // We need to give the `UNARY_STAR` token a precedence, rather than overriding
  189. // the precedence of the `expression UNARY_STAR` rule below, because bison
  190. // compares the precedence of the final token (for a shift) to the precedence
  191. // of the other rule (for a reduce) when attempting to resolve a shift-reduce
  192. // conflict. See https://stackoverflow.com/a/26188429/1041090. When UNARY_STAR
  193. // is the final token of a rule, it must be a postfix usage, so we give it the
  194. // same precedence as POSTFIX_STAR.
  195. %precedence POSTFIX_STAR UNARY_STAR
  196. %left PERIOD ARROW
  197. %precedence
  198. LEFT_PARENTHESIS
  199. RIGHT_PARENTHESIS
  200. LEFT_SQUARE_BRACKET
  201. RIGHT_SQUARE_BRACKET
  202. ;
  203. %start input
  204. %%
  205. input: package_directive import_directives declaration_list
  206. {
  207. parsed_program = AST({.package = $1.first,
  208. .is_api = $1.second,
  209. .imports = std::move($2),
  210. .declarations = std::move($3)});
  211. }
  212. ;
  213. package_directive:
  214. PACKAGE identifier optional_library_path api_or_impl SEMICOLON
  215. { $$ = {LibraryName({.package = $2, .path = $3}), $4}; }
  216. ;
  217. import_directive:
  218. IMPORT identifier optional_library_path SEMICOLON
  219. { $$ = LibraryName({.package = $2, .path = $3}); }
  220. ;
  221. import_directives:
  222. // Empty
  223. { $$ = std::vector<LibraryName>(); }
  224. | import_directives import_directive
  225. {
  226. $$ = std::move($1);
  227. $$.push_back($2);
  228. }
  229. ;
  230. optional_library_path:
  231. // Empty
  232. { $$ = ""; }
  233. | LIBRARY string_literal
  234. { $$ = $2; }
  235. ;
  236. api_or_impl:
  237. API
  238. { $$ = true; }
  239. | IMPL
  240. { $$ = false; }
  241. ;
  242. expression:
  243. identifier
  244. { $$ = global_arena->New<IdentifierExpression>(context.SourceLoc(), $1); }
  245. | expression designator
  246. {
  247. $$ =
  248. global_arena->New<FieldAccessExpression>(context.SourceLoc(), $1, $2);
  249. }
  250. | expression LEFT_SQUARE_BRACKET expression RIGHT_SQUARE_BRACKET
  251. { $$ = global_arena->New<IndexExpression>(context.SourceLoc(), $1, $3); }
  252. | integer_literal
  253. { $$ = global_arena->New<IntLiteral>(context.SourceLoc(), $1); }
  254. | string_literal
  255. { $$ = global_arena->New<StringLiteral>(context.SourceLoc(), $1); }
  256. | TRUE
  257. { $$ = global_arena->New<BoolLiteral>(context.SourceLoc(), true); }
  258. | FALSE
  259. { $$ = global_arena->New<BoolLiteral>(context.SourceLoc(), false); }
  260. | sized_type_literal
  261. {
  262. int val;
  263. CHECK(llvm::to_integer(llvm::StringRef($1).substr(1), val));
  264. CHECK($1[0] == 'i' && val == 32)
  265. << "Only i32 is supported for now: " << $1;
  266. $$ = global_arena->New<IntTypeLiteral>(context.SourceLoc());
  267. }
  268. | STRING
  269. { $$ = global_arena->New<StringTypeLiteral>(context.SourceLoc()); }
  270. | BOOL
  271. { $$ = global_arena->New<BoolTypeLiteral>(context.SourceLoc()); }
  272. | TYPE
  273. { $$ = global_arena->New<TypeTypeLiteral>(context.SourceLoc()); }
  274. | CONTINUATION_TYPE
  275. { $$ = global_arena->New<ContinuationTypeLiteral>(context.SourceLoc()); }
  276. | paren_expression { $$ = $1; }
  277. | expression EQUAL_EQUAL expression
  278. {
  279. $$ = global_arena->New<PrimitiveOperatorExpression>(
  280. context.SourceLoc(), Operator::Eq,
  281. std::vector<Ptr<const Expression>>({$1, $3}));
  282. }
  283. | expression PLUS expression
  284. {
  285. $$ = global_arena->New<PrimitiveOperatorExpression>(
  286. context.SourceLoc(), Operator::Add,
  287. std::vector<Ptr<const Expression>>({$1, $3}));
  288. }
  289. | expression MINUS expression
  290. {
  291. $$ = global_arena->New<PrimitiveOperatorExpression>(
  292. context.SourceLoc(), Operator::Sub,
  293. std::vector<Ptr<const Expression>>({$1, $3}));
  294. }
  295. | expression BINARY_STAR expression
  296. {
  297. $$ = global_arena->New<PrimitiveOperatorExpression>(
  298. context.SourceLoc(), Operator::Mul,
  299. std::vector<Ptr<const Expression>>({$1, $3}));
  300. }
  301. | expression AND expression
  302. {
  303. $$ = global_arena->New<PrimitiveOperatorExpression>(
  304. context.SourceLoc(), Operator::And,
  305. std::vector<Ptr<const Expression>>({$1, $3}));
  306. }
  307. | expression OR expression
  308. {
  309. $$ = global_arena->New<PrimitiveOperatorExpression>(
  310. context.SourceLoc(), Operator::Or,
  311. std::vector<Ptr<const Expression>>({$1, $3}));
  312. }
  313. | NOT expression
  314. {
  315. $$ = global_arena->New<PrimitiveOperatorExpression>(
  316. context.SourceLoc(), Operator::Not,
  317. std::vector<Ptr<const Expression>>({$2}));
  318. }
  319. | MINUS expression %prec UNARY_MINUS
  320. {
  321. $$ = global_arena->New<PrimitiveOperatorExpression>(
  322. context.SourceLoc(), Operator::Neg,
  323. std::vector<Ptr<const Expression>>({$2}));
  324. }
  325. | PREFIX_STAR expression
  326. {
  327. $$ = global_arena->New<PrimitiveOperatorExpression>(
  328. context.SourceLoc(), Operator::Deref,
  329. std::vector<Ptr<const Expression>>({$2}));
  330. }
  331. | UNARY_STAR expression %prec PREFIX_STAR
  332. {
  333. $$ = global_arena->New<PrimitiveOperatorExpression>(
  334. context.SourceLoc(), Operator::Deref,
  335. std::vector<Ptr<const Expression>>({$2}));
  336. }
  337. | expression tuple
  338. { $$ = global_arena->New<CallExpression>(context.SourceLoc(), $1, $2); }
  339. | expression POSTFIX_STAR
  340. {
  341. $$ = global_arena->New<PrimitiveOperatorExpression>(
  342. context.SourceLoc(), Operator::Ptr,
  343. std::vector<Ptr<const Expression>>({$1}));
  344. }
  345. | expression UNARY_STAR
  346. {
  347. $$ = global_arena->New<PrimitiveOperatorExpression>(
  348. context.SourceLoc(), Operator::Ptr,
  349. std::vector<Ptr<const Expression>>({$1}));
  350. }
  351. | FNTY tuple return_type
  352. {
  353. auto [return_exp, is_omitted_exp] = $3.Release();
  354. $$ = global_arena->New<FunctionTypeLiteral>(context.SourceLoc(), $2,
  355. return_exp, is_omitted_exp);
  356. }
  357. ;
  358. designator: PERIOD identifier { $$ = $2; }
  359. ;
  360. paren_expression: paren_expression_base
  361. { $$ = ExpressionFromParenContents(context.SourceLoc(), $1); }
  362. ;
  363. tuple: paren_expression_base
  364. { $$ = TupleExpressionFromParenContents(context.SourceLoc(), $1); }
  365. ;
  366. paren_expression_element:
  367. expression
  368. { $$ = {.name = std::nullopt, .term = $1}; }
  369. | designator EQUAL expression
  370. { $$ = {.name = $1, .term = $3}; }
  371. ;
  372. paren_expression_base:
  373. LEFT_PARENTHESIS RIGHT_PARENTHESIS
  374. { $$ = {.elements = {}, .has_trailing_comma = false}; }
  375. | LEFT_PARENTHESIS paren_expression_contents RIGHT_PARENTHESIS
  376. { $$ = $2; }
  377. | LEFT_PARENTHESIS paren_expression_contents COMMA RIGHT_PARENTHESIS
  378. {
  379. $$ = $2;
  380. $$.has_trailing_comma = true;
  381. }
  382. ;
  383. paren_expression_contents:
  384. paren_expression_element
  385. { $$ = {.elements = {$1}, .has_trailing_comma = false}; }
  386. | paren_expression_contents COMMA paren_expression_element
  387. {
  388. $$ = $1;
  389. $$.elements.push_back($3);
  390. }
  391. ;
  392. // In many cases, using `pattern` recursively will result in ambiguities.
  393. // When that happens, it's necessary to factor out two separate productions,
  394. // one for when the sub-pattern is an expression, and one for when it is not.
  395. // To facilitate this, non-terminals besides `pattern` whose names contain
  396. // `pattern` are structured to be disjoint from `expression`, unless otherwise
  397. // specified.
  398. pattern:
  399. non_expression_pattern
  400. { $$ = $1; }
  401. | expression
  402. { $$ = global_arena->New<ExpressionPattern>($1); }
  403. ;
  404. non_expression_pattern:
  405. AUTO
  406. { $$ = global_arena->New<AutoPattern>(context.SourceLoc()); }
  407. | binding_lhs COLON pattern
  408. { $$ = global_arena->New<BindingPattern>(context.SourceLoc(), $1, $3); }
  409. | paren_pattern
  410. { $$ = $1; }
  411. | expression tuple_pattern
  412. { $$ = global_arena->New<AlternativePattern>(context.SourceLoc(), $1, $2); }
  413. ;
  414. binding_lhs:
  415. identifier { $$ = $1; }
  416. | UNDERSCORE { $$ = std::nullopt; }
  417. ;
  418. paren_pattern: paren_pattern_base
  419. { $$ = PatternFromParenContents(context.SourceLoc(), $1); }
  420. ;
  421. paren_pattern_base:
  422. LEFT_PARENTHESIS paren_pattern_contents RIGHT_PARENTHESIS
  423. { $$ = $2; }
  424. | LEFT_PARENTHESIS paren_pattern_contents COMMA RIGHT_PARENTHESIS
  425. {
  426. $$ = $2;
  427. $$.has_trailing_comma = true;
  428. }
  429. ;
  430. // paren_pattern is analogous to paren_expression, but in order to avoid
  431. // ambiguities, it must be disjoint from paren_expression, meaning it must
  432. // contain at least one non_expression_pattern. The structure of this rule
  433. // is very different from the corresponding expression rule because is has to
  434. // enforce that requirement.
  435. paren_pattern_contents:
  436. paren_pattern_element
  437. { $$ = {.elements = {$1}, .has_trailing_comma = false}; }
  438. | paren_expression_contents COMMA paren_pattern_element
  439. {
  440. $$ = ParenExpressionToParenPattern($1);
  441. $$.elements.push_back($3);
  442. }
  443. | paren_pattern_contents COMMA paren_expression_element
  444. {
  445. $$ = $1;
  446. auto el = $3.Release();
  447. $$.elements.push_back(
  448. {.name = el.name,
  449. .term = global_arena->New<ExpressionPattern>(el.term)});
  450. }
  451. | paren_pattern_contents COMMA paren_pattern_element
  452. {
  453. $$ = $1;
  454. $$.elements.push_back($3);
  455. }
  456. ;
  457. paren_pattern_element:
  458. non_expression_pattern
  459. { $$ = {.name = std::nullopt, .term = $1}; }
  460. | designator EQUAL non_expression_pattern
  461. { $$ = {.name = $1, .term = $3}; }
  462. ;
  463. tuple_pattern: paren_pattern_base
  464. { $$ = TuplePatternFromParenContents(context.SourceLoc(), $1); }
  465. ;
  466. // Unlike most `pattern` nonterminals, this one overlaps with `expression`,
  467. // so it should be used only when prior context (such as an introducer)
  468. // rules out the possibility of an `expression` at this point.
  469. maybe_empty_tuple_pattern:
  470. LEFT_PARENTHESIS RIGHT_PARENTHESIS
  471. {
  472. $$ = global_arena->New<TuplePattern>(context.SourceLoc(),
  473. std::vector<TuplePattern::Field>());
  474. }
  475. | tuple_pattern
  476. { $$ = $1; }
  477. ;
  478. clause:
  479. CASE pattern DOUBLE_ARROW statement
  480. { $$ = std::pair<Ptr<const Pattern>, Ptr<const Statement>>($2, $4); }
  481. | DEFAULT DOUBLE_ARROW statement
  482. {
  483. auto vp = global_arena -> New<BindingPattern>(
  484. context.SourceLoc(), std::nullopt,
  485. global_arena->New<AutoPattern>(context.SourceLoc()));
  486. $$ = std::pair<Ptr<const Pattern>, Ptr<const Statement>>(vp, $3);
  487. }
  488. ;
  489. clause_list:
  490. // Empty
  491. { $$ = std::list<std::pair<Ptr<const Pattern>, Ptr<const Statement>>>(); }
  492. | clause clause_list
  493. {
  494. $$ = $2;
  495. $$.push_front($1);
  496. }
  497. ;
  498. statement:
  499. expression EQUAL expression SEMICOLON
  500. { $$ = global_arena->New<Assign>(context.SourceLoc(), $1, $3); }
  501. | VAR pattern EQUAL expression SEMICOLON
  502. { $$ = global_arena->New<VariableDefinition>(context.SourceLoc(), $2, $4); }
  503. | expression SEMICOLON
  504. { $$ = global_arena->New<ExpressionStatement>(context.SourceLoc(), $1); }
  505. | if_statement
  506. { $$ = $1; }
  507. | WHILE LEFT_PARENTHESIS expression RIGHT_PARENTHESIS block
  508. { $$ = global_arena->New<While>(context.SourceLoc(), $3, $5); }
  509. | BREAK SEMICOLON
  510. { $$ = global_arena->New<Break>(context.SourceLoc()); }
  511. | CONTINUE SEMICOLON
  512. { $$ = global_arena->New<Continue>(context.SourceLoc()); }
  513. | RETURN return_expression SEMICOLON
  514. {
  515. auto [return_exp, is_omitted_exp] = $2.Release();
  516. $$ = global_arena->New<Return>(context.SourceLoc(), return_exp,
  517. is_omitted_exp);
  518. }
  519. | block
  520. { $$ = $1; }
  521. | MATCH LEFT_PARENTHESIS expression RIGHT_PARENTHESIS LEFT_CURLY_BRACE
  522. clause_list RIGHT_CURLY_BRACE
  523. { $$ = global_arena->New<Match>(context.SourceLoc(), $3, $6); }
  524. | CONTINUATION identifier statement
  525. { $$ = global_arena->New<Continuation>(context.SourceLoc(), $2, $3); }
  526. | RUN expression SEMICOLON
  527. { $$ = global_arena->New<Run>(context.SourceLoc(), $2); }
  528. | AWAIT SEMICOLON
  529. { $$ = global_arena->New<Await>(context.SourceLoc()); }
  530. ;
  531. if_statement:
  532. IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS block optional_else
  533. { $$ = global_arena->New<If>(context.SourceLoc(), $3, $5, $6); }
  534. ;
  535. optional_else:
  536. // Empty
  537. { $$ = std::nullopt; }
  538. | ELSE if_statement
  539. { $$ = $2; }
  540. | ELSE block
  541. { $$ = $2; }
  542. ;
  543. return_expression:
  544. // Empty
  545. { $$ = {global_arena->New<TupleLiteral>(context.SourceLoc()), true}; }
  546. | expression
  547. { $$ = {$1, false}; }
  548. ;
  549. statement_list:
  550. // Empty
  551. { $$ = std::nullopt; }
  552. | statement statement_list
  553. { $$ = global_arena->New<Sequence>(context.SourceLoc(), $1, $2); }
  554. ;
  555. block:
  556. LEFT_CURLY_BRACE statement_list RIGHT_CURLY_BRACE
  557. { $$ = global_arena->New<Block>(context.SourceLoc(), $2); }
  558. ;
  559. return_type:
  560. // Empty
  561. { $$ = {global_arena->New<TupleLiteral>(context.SourceLoc()), true}; }
  562. | ARROW expression %prec FNARROW
  563. { $$ = {$2, false}; }
  564. ;
  565. generic_binding:
  566. identifier COLON_BANG expression
  567. { $$ = GenericBinding({.name = std::move($1), .type = $3}); }
  568. ;
  569. deduced_param_list:
  570. // Empty
  571. { $$ = std::vector<GenericBinding>(); }
  572. | generic_binding
  573. {
  574. $$ = std::vector<GenericBinding>();
  575. $$.push_back($1);
  576. }
  577. | generic_binding COMMA deduced_param_list
  578. {
  579. $$ = $3;
  580. $$.push_back($1);
  581. }
  582. ;
  583. deduced_params:
  584. // Empty
  585. { $$ = std::vector<GenericBinding>(); }
  586. | LEFT_SQUARE_BRACKET deduced_param_list RIGHT_SQUARE_BRACKET
  587. { $$ = $2; }
  588. ;
  589. function_definition:
  590. FN identifier deduced_params maybe_empty_tuple_pattern return_type block
  591. {
  592. auto [return_exp, is_omitted_exp] = $5.Release();
  593. $$ = global_arena->New<FunctionDefinition>(
  594. context.SourceLoc(), $2, $3, $4,
  595. global_arena->New<ExpressionPattern>(return_exp), is_omitted_exp, $6);
  596. }
  597. | FN identifier deduced_params maybe_empty_tuple_pattern DOUBLE_ARROW expression
  598. SEMICOLON
  599. {
  600. // The return type is not considered "omitted" because it's automatic from
  601. // the expression.
  602. $$ = global_arena->New<FunctionDefinition>(
  603. context.SourceLoc(), $2, $3, $4,
  604. global_arena->New<AutoPattern>(context.SourceLoc()), true,
  605. global_arena->New<Return>(context.SourceLoc(), $6, true));
  606. }
  607. ;
  608. function_declaration:
  609. FN identifier deduced_params maybe_empty_tuple_pattern return_type SEMICOLON
  610. {
  611. auto [return_exp, is_omitted_exp] = $5.Release();
  612. $$ = global_arena->New<FunctionDefinition>(
  613. context.SourceLoc(), $2, $3, $4,
  614. global_arena->New<ExpressionPattern>(return_exp), is_omitted_exp,
  615. std::nullopt);
  616. }
  617. ;
  618. variable_declaration: identifier COLON pattern
  619. { $$ = global_arena->New<BindingPattern>(context.SourceLoc(), $1, $3); }
  620. ;
  621. member: VAR variable_declaration SEMICOLON
  622. { $$ = global_arena->New<FieldMember>(context.SourceLoc(), $2); }
  623. ;
  624. member_list:
  625. // Empty
  626. { $$ = std::list<Ptr<Member>>(); }
  627. | member member_list
  628. {
  629. $$ = $2;
  630. $$.push_front($1);
  631. }
  632. ;
  633. alternative:
  634. identifier tuple
  635. { $$ = std::pair<std::string, Ptr<const Expression>>($1, $2); }
  636. | identifier
  637. {
  638. $$ = std::pair<std::string, Ptr<const Expression>>(
  639. $1, global_arena->New<TupleLiteral>(context.SourceLoc()));
  640. }
  641. ;
  642. alternative_list:
  643. // Empty
  644. { $$ = std::list<std::pair<std::string, Ptr<const Expression>>>(); }
  645. | alternative
  646. {
  647. $$ = std::list<std::pair<std::string, Ptr<const Expression>>>();
  648. $$.push_front($1);
  649. }
  650. | alternative COMMA alternative_list
  651. {
  652. $$ = std::move($3);
  653. $$.push_front($1);
  654. }
  655. ;
  656. declaration:
  657. function_definition
  658. { $$ = global_arena->New<FunctionDeclaration>($1); }
  659. | function_declaration
  660. { $$ = global_arena->New<FunctionDeclaration>($1); }
  661. | CLASS identifier LEFT_CURLY_BRACE member_list RIGHT_CURLY_BRACE
  662. { $$ = global_arena->New<ClassDeclaration>(context.SourceLoc(), $2, $4); }
  663. | CHOICE identifier LEFT_CURLY_BRACE alternative_list RIGHT_CURLY_BRACE
  664. { $$ = global_arena->New<ChoiceDeclaration>(context.SourceLoc(), $2, $4); }
  665. | VAR variable_declaration EQUAL expression SEMICOLON
  666. {
  667. $$ = global_arena->New<VariableDeclaration>(context.SourceLoc(), $2, $4);
  668. }
  669. ;
  670. declaration_list:
  671. // Empty
  672. { $$ = std::list<Ptr<const Declaration>>(); }
  673. | declaration declaration_list
  674. {
  675. $$ = $2;
  676. $$.push_front(Ptr<const Declaration>($1));
  677. }
  678. ;
  679. %%