parser.ypp 18 KB

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