parser.ypp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  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. //
  17. // Parameters to the parser and lexer
  18. //
  19. // Parameters to the parser are stored therein as protected data members, and
  20. // thus available to its methods.
  21. // "out" parameter passed to the parser, where the AST is written.
  22. %parse-param {std::optional<Carbon::AST>& parsedProgram}
  23. // "inout" parameter passed to both the parser and the lexer.
  24. %param {Carbon::ParseAndLexContext& context}
  25. // -----------------------------------------------------------------------------
  26. %code top {
  27. #include <algorithm>
  28. #include <cstdarg>
  29. #include <cstdio>
  30. #include <cstdlib>
  31. #include <iostream>
  32. #include <list>
  33. #include "executable_semantics/syntax/syntax_helpers.h"
  34. #include "executable_semantics/syntax/parse_and_lex_context.h"
  35. }
  36. %code requires {
  37. #include <optional>
  38. #include "executable_semantics/ast/abstract_syntax_tree.h"
  39. #include "executable_semantics/ast/declaration.h"
  40. #include "executable_semantics/ast/field_list.h"
  41. #include "executable_semantics/ast/function_definition.h"
  42. namespace Carbon {
  43. class ParseAndLexContext;
  44. }
  45. }
  46. %code {
  47. extern int yylineno;
  48. void yy::parser::error(
  49. const location_type&, const std::string& message)
  50. {
  51. context.PrintDiagnostic(message, yylineno);
  52. }
  53. }
  54. %token <int> integer_literal
  55. %token <char*> identifier
  56. %type <char*> designator
  57. %type <Carbon::Declaration*> declaration
  58. %type <Carbon::FunctionDefinition*> function_declaration
  59. %type <Carbon::FunctionDefinition*> function_definition
  60. %type <std::list<Carbon::Declaration>*> declaration_list
  61. %type <Carbon::Statement*> statement
  62. %type <Carbon::Statement*> optional_else
  63. %type <Carbon::Statement*> statement_list
  64. %type <Carbon::Expression*> expression
  65. %type <Carbon::Expression*> pattern
  66. %type <Carbon::Expression*> return_type
  67. %type <Carbon::Expression*> paren_expression
  68. %type <Carbon::Expression*> tuple
  69. %type <Carbon::Member*> member
  70. %type <std::list<Carbon::Member*>*> member_list
  71. %type <Carbon::FieldList*> field
  72. %type <Carbon::FieldList*> field_list
  73. %type <std::pair<std::string, Carbon::Expression*>*> alternative
  74. %type <std::list<std::pair<std::string, Carbon::Expression*>>*> alternative_list
  75. %type <std::pair<Carbon::Expression*, Carbon::Statement*>*> clause
  76. %type <std::list<std::pair<Carbon::Expression*, Carbon::Statement*>>*> clause_list
  77. %token END_OF_FILE 0
  78. %token AND
  79. %token OR
  80. %token NOT
  81. %token INT
  82. %token BOOL
  83. %token TYPE
  84. %token FN
  85. %token FNTY
  86. %token ARROW
  87. %token VAR
  88. %token EQUAL_EQUAL
  89. %token IF
  90. %token ELSE
  91. %token WHILE
  92. %token BREAK
  93. %token CONTINUE
  94. %token RETURN
  95. %token TRUE
  96. %token FALSE
  97. %token STRUCT
  98. %token CHOICE
  99. %token MATCH
  100. %token CASE
  101. %token DBLARROW
  102. %token DEFAULT
  103. %token AUTO
  104. %token
  105. EQUAL "="
  106. MINUS "-"
  107. PLUS "+"
  108. STAR "*"
  109. SLASH "/"
  110. LEFT_PARENTHESIS "("
  111. RIGHT_PARENTHESIS ")"
  112. LEFT_CURLY_BRACE "{"
  113. RIGHT_CURLY_BRACE "}"
  114. LEFT_SQUARE_BRACKET "["
  115. RIGHT_SQUARE_BRACKET "]"
  116. PERIOD "."
  117. COMMA ","
  118. SEMICOLON ";"
  119. COLON ":"
  120. ;
  121. %nonassoc "{" "}"
  122. %nonassoc ":" "," DBLARROW
  123. %left OR AND
  124. %nonassoc EQUAL_EQUAL NOT
  125. %left "+" "-"
  126. %left "." ARROW
  127. %nonassoc "(" ")" "[" "]"
  128. %start input
  129. %locations
  130. %%
  131. input: declaration_list
  132. { parsedProgram = $1; }
  133. ;
  134. pattern:
  135. expression
  136. { $$ = $1; }
  137. ;
  138. expression:
  139. identifier
  140. { $$ = Carbon::MakeVar(yylineno, $1); }
  141. | expression designator
  142. { $$ = Carbon::MakeGetField(yylineno, $1, $2); }
  143. | expression "[" expression "]"
  144. { $$ = Carbon::MakeIndex(yylineno, $1, $3); }
  145. | expression ":" identifier
  146. { $$ = Carbon::MakeVarPat(yylineno, $3, $1); }
  147. | integer_literal
  148. { $$ = Carbon::MakeInt(yylineno, $1); }
  149. | TRUE
  150. { $$ = Carbon::MakeBool(yylineno, true); }
  151. | FALSE
  152. { $$ = Carbon::MakeBool(yylineno, false); }
  153. | INT
  154. { $$ = Carbon::MakeIntType(yylineno); }
  155. | BOOL
  156. { $$ = Carbon::MakeBoolType(yylineno); }
  157. | TYPE
  158. { $$ = Carbon::MakeTypeType(yylineno); }
  159. | AUTO
  160. { $$ = Carbon::MakeAutoType(yylineno); }
  161. | paren_expression { $$ = $1; }
  162. | expression EQUAL_EQUAL expression
  163. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Eq, $1, $3); }
  164. | expression "+" expression
  165. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Add, $1, $3); }
  166. | expression "-" expression
  167. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Sub, $1, $3); }
  168. | expression AND expression
  169. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::And, $1, $3); }
  170. | expression OR expression
  171. { $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Or, $1, $3); }
  172. | NOT expression
  173. { $$ = Carbon::MakeUnOp(yylineno, Carbon::Operator::Not, $2); }
  174. | "-" expression
  175. { $$ = Carbon::MakeUnOp(yylineno, Carbon::Operator::Neg, $2); }
  176. | expression tuple
  177. { $$ = Carbon::MakeCall(yylineno, $1, $2); }
  178. | FNTY tuple return_type
  179. { $$ = Carbon::MakeFunType(yylineno, $2, $3); }
  180. ;
  181. designator: "." identifier { $$ = $2; }
  182. ;
  183. paren_expression: "(" field_list ")"
  184. {
  185. if ($2->fields->size() == 1 &&
  186. $2->fields->front().first == "" &&
  187. !$2->has_explicit_comma) {
  188. $$ = $2->fields->front().second;
  189. } else {
  190. auto vec = new std::vector<std::pair<std::string,Carbon::Expression*>>(
  191. $2->fields->begin(), $2->fields->end());
  192. $$ = Carbon::MakeTuple(yylineno, vec);
  193. }
  194. }
  195. ;
  196. tuple: "(" field_list ")"
  197. {
  198. auto vec = new std::vector<std::pair<std::string,Carbon::Expression*>>(
  199. $2->fields->begin(), $2->fields->end());
  200. $$ = Carbon::MakeTuple(yylineno, vec);
  201. }
  202. field:
  203. pattern
  204. {
  205. auto fields =
  206. new std::list<std::pair<std::string, Carbon::Expression*>>();
  207. fields->push_back(std::make_pair("", $1));
  208. $$ = Carbon::MakeFieldList(fields);
  209. }
  210. | designator "=" pattern
  211. {
  212. auto fields =
  213. new std::list<std::pair<std::string, Carbon::Expression*>>();
  214. fields->push_back(std::make_pair($1, $3));
  215. $$ = Carbon::MakeFieldList(fields);
  216. }
  217. ;
  218. field_list:
  219. // Empty
  220. {
  221. $$ = Carbon::MakeFieldList(
  222. new std::list<std::pair<std::string, Carbon::Expression*>>());
  223. }
  224. | field
  225. { $$ = $1; }
  226. | field "," field_list
  227. { $$ = Carbon::MakeConsField($1, $3); }
  228. ;
  229. clause:
  230. CASE pattern DBLARROW statement
  231. { $$ = new std::pair<Carbon::Expression*, Carbon::Statement*>($2, $4); }
  232. | DEFAULT DBLARROW statement
  233. {
  234. auto vp = Carbon::MakeVarPat(yylineno, "_",
  235. Carbon::MakeAutoType(yylineno));
  236. $$ = new std::pair<Carbon::Expression*, Carbon::Statement*>(vp, $3);
  237. }
  238. ;
  239. clause_list:
  240. // Empty
  241. {
  242. $$ = new std::list<std::pair<Carbon::Expression*, Carbon::Statement*>>();
  243. }
  244. | clause clause_list
  245. { $$ = $2; $$->push_front(*$1); }
  246. ;
  247. statement:
  248. expression "=" expression ";"
  249. { $$ = Carbon::MakeAssign(yylineno, $1, $3); }
  250. | VAR pattern "=" expression ";"
  251. { $$ = Carbon::MakeVarDef(yylineno, $2, $4); }
  252. | expression ";"
  253. { $$ = Carbon::MakeExpStmt(yylineno, $1); }
  254. | IF "(" expression ")" statement optional_else
  255. { $$ = Carbon::MakeIf(yylineno, $3, $5, $6); }
  256. | WHILE "(" expression ")" statement
  257. { $$ = Carbon::MakeWhile(yylineno, $3, $5); }
  258. | BREAK ";"
  259. { $$ = Carbon::MakeBreak(yylineno); }
  260. | CONTINUE ";"
  261. { $$ = Carbon::MakeContinue(yylineno); }
  262. | RETURN expression ";"
  263. { $$ = Carbon::MakeReturn(yylineno, $2); }
  264. | "{" statement_list "}"
  265. { $$ = Carbon::MakeBlock(yylineno, $2); }
  266. | MATCH "(" expression ")" "{" clause_list "}"
  267. { $$ = Carbon::MakeMatch(yylineno, $3, $6); }
  268. ;
  269. optional_else:
  270. // Empty
  271. { $$ = 0; }
  272. | ELSE statement { $$ = $2; }
  273. ;
  274. statement_list:
  275. // Empty
  276. { $$ = 0; }
  277. | statement statement_list
  278. { $$ = Carbon::MakeSeq(yylineno, $1, $2); }
  279. ;
  280. return_type:
  281. // Empty
  282. {
  283. $$ = Carbon::MakeTuple(
  284. yylineno,
  285. new std::vector<std::pair<std::string, Carbon::Expression*>>());
  286. }
  287. | ARROW expression
  288. { $$ = $2; }
  289. ;
  290. function_definition:
  291. FN identifier tuple return_type "{" statement_list "}"
  292. { $$ = MakeFunDef(yylineno, $2, $4, $3, $6); }
  293. | FN identifier tuple DBLARROW expression ";"
  294. {
  295. $$ = Carbon::MakeFunDef(yylineno, $2, Carbon::MakeAutoType(yylineno), $3,
  296. Carbon::MakeReturn(yylineno, $5));
  297. }
  298. ;
  299. function_declaration:
  300. FN identifier tuple return_type ";"
  301. { $$ = MakeFunDef(yylineno, $2, $4, $3, 0); }
  302. ;
  303. member:
  304. VAR expression ":" identifier ";"
  305. { $$ = MakeField(yylineno, $4, $2); }
  306. ;
  307. member_list:
  308. // Empty
  309. { $$ = new std::list<Carbon::Member*>(); }
  310. | member member_list
  311. { $$ = $2; $$->push_front($1); }
  312. ;
  313. alternative:
  314. identifier tuple
  315. { $$ = new std::pair<std::string, Carbon::Expression*>($1, $2); }
  316. | identifier
  317. {
  318. $$ = new std::pair<std::string, Carbon::Expression*>(
  319. $1, Carbon::MakeTuple(
  320. yylineno,
  321. new std::vector<std::pair<std::string, Carbon::Expression*>>()));
  322. }
  323. ;
  324. alternative_list:
  325. // Empty
  326. { $$ = new std::list<std::pair<std::string, Carbon::Expression*>>(); }
  327. | alternative
  328. {
  329. $$ = new std::list<std::pair<std::string, Carbon::Expression*>>();
  330. $$->push_front(*$1);
  331. }
  332. | alternative "," alternative_list
  333. { $$ = $3; $$->push_front(*$1); }
  334. ;
  335. declaration:
  336. function_definition
  337. { $$ = new Carbon::Declaration(Carbon::FunctionDeclaration{$1}); }
  338. | function_declaration
  339. { $$ = new Carbon::Declaration(Carbon::FunctionDeclaration{$1}); }
  340. | STRUCT identifier "{" member_list "}"
  341. {
  342. $$ = new Carbon::Declaration(
  343. Carbon::StructDeclaration{yylineno, $2, $4});
  344. }
  345. | CHOICE identifier "{" alternative_list "}"
  346. {
  347. $$ = new Carbon::Declaration(
  348. Carbon::ChoiceDeclaration{yylineno, $2, std::list(*$4)});
  349. }
  350. ;
  351. declaration_list:
  352. // Empty
  353. { $$ = new std::list<Carbon::Declaration>(); }
  354. | declaration declaration_list
  355. {
  356. $$ = $2;
  357. $$->push_front(*$1);
  358. }
  359. ;
  360. %%