parser2.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  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. #include "toolchain/parser/parser2.h"
  5. #include <cstdlib>
  6. #include <memory>
  7. #include "common/check.h"
  8. #include "llvm/ADT/Optional.h"
  9. #include "llvm/Support/PrettyStackTrace.h"
  10. #include "toolchain/lexer/token_kind.h"
  11. #include "toolchain/lexer/tokenized_buffer.h"
  12. #include "toolchain/parser/parse_node_kind.h"
  13. #include "toolchain/parser/parse_tree.h"
  14. namespace Carbon {
  15. class Parser2::PrettyStackTraceParseState : public llvm::PrettyStackTraceEntry {
  16. public:
  17. explicit PrettyStackTraceParseState(const Parser2* parser)
  18. : parser_(parser) {}
  19. ~PrettyStackTraceParseState() override = default;
  20. auto print(llvm::raw_ostream& output) const -> void override {
  21. output << "Parser stack:\n";
  22. for (int i = 0; i < static_cast<int>(parser_->state_stack_.size()); ++i) {
  23. const auto& entry = parser_->state_stack_[i];
  24. output << "\t" << i << ".\t" << entry.state;
  25. Print(output, entry.token);
  26. }
  27. output << "\tabort\tposition_";
  28. Print(output, *parser_->position_);
  29. }
  30. private:
  31. auto Print(llvm::raw_ostream& output, TokenizedBuffer::Token token) const
  32. -> void {
  33. auto line = parser_->tokens_.GetLine(token);
  34. output << " @ " << parser_->tokens_.GetLineNumber(line) << ":"
  35. << parser_->tokens_.GetColumnNumber(token) << ":"
  36. << " token " << token << " : "
  37. << parser_->tokens_.GetKind(token).Name() << "\n";
  38. }
  39. const Parser2* parser_;
  40. };
  41. Parser2::Parser2(ParseTree& tree_arg, TokenizedBuffer& tokens_arg,
  42. TokenDiagnosticEmitter& emitter)
  43. : tree_(tree_arg),
  44. tokens_(tokens_arg),
  45. emitter_(emitter),
  46. position_(tokens_.tokens().begin()),
  47. end_(tokens_.tokens().end()) {
  48. CARBON_CHECK(position_ != end_) << "Empty TokenizedBuffer";
  49. --end_;
  50. CARBON_CHECK(tokens_.GetKind(*end_) == TokenKind::EndOfFile())
  51. << "TokenizedBuffer should end with EndOfFile, ended with "
  52. << tokens_.GetKind(*end_).Name();
  53. }
  54. auto Parser2::AddLeafNode(ParseNodeKind kind, TokenizedBuffer::Token token,
  55. bool has_error) -> void {
  56. tree_.node_impls_.push_back(
  57. ParseTree::NodeImpl(kind, has_error, token, /*subtree_size=*/1));
  58. if (has_error) {
  59. tree_.has_errors_ = true;
  60. }
  61. }
  62. auto Parser2::AddNode(ParseNodeKind kind, TokenizedBuffer::Token token,
  63. int subtree_start, bool has_error) -> void {
  64. int subtree_size = tree_.size() - subtree_start + 1;
  65. tree_.node_impls_.push_back(
  66. ParseTree::NodeImpl(kind, has_error, token, subtree_size));
  67. if (has_error) {
  68. tree_.has_errors_ = true;
  69. }
  70. }
  71. auto Parser2::ConsumeAndAddCloseParen(TokenizedBuffer::Token open_paren,
  72. ParseNodeKind close_kind) -> bool {
  73. if (ConsumeAndAddLeafNodeIf(TokenKind::CloseParen(), close_kind)) {
  74. return true;
  75. }
  76. // TODO: Include the location of the matching open_paren in the diagnostic.
  77. CARBON_DIAGNOSTIC(ExpectedCloseParen, Error, "Unexpected tokens before `)`.");
  78. emitter_.Emit(*position_, ExpectedCloseParen);
  79. SkipTo(tokens_.GetMatchedClosingToken(open_paren));
  80. AddLeafNode(close_kind, *position_);
  81. ++position_;
  82. return false;
  83. }
  84. auto Parser2::ConsumeAndAddLeafNodeIf(TokenKind token_kind,
  85. ParseNodeKind node_kind) -> bool {
  86. auto token = ConsumeIf(token_kind);
  87. if (!token) {
  88. return false;
  89. }
  90. AddLeafNode(node_kind, *token);
  91. return true;
  92. }
  93. auto Parser2::ConsumeIf(TokenKind kind)
  94. -> llvm::Optional<TokenizedBuffer::Token> {
  95. if (!PositionIs(kind)) {
  96. return llvm::None;
  97. }
  98. auto token = *position_;
  99. ++position_;
  100. return token;
  101. }
  102. auto Parser2::FindNextOf(std::initializer_list<TokenKind> desired_kinds)
  103. -> llvm::Optional<TokenizedBuffer::Token> {
  104. auto new_position = position_;
  105. while (true) {
  106. TokenizedBuffer::Token token = *new_position;
  107. TokenKind kind = tokens_.GetKind(token);
  108. if (kind.IsOneOf(desired_kinds)) {
  109. return token;
  110. }
  111. // Step to the next token at the current bracketing level.
  112. if (kind.IsClosingSymbol() || kind == TokenKind::EndOfFile()) {
  113. // There are no more tokens at this level.
  114. return llvm::None;
  115. } else if (kind.IsOpeningSymbol()) {
  116. new_position =
  117. TokenizedBuffer::TokenIterator(tokens_.GetMatchedClosingToken(token));
  118. // Advance past the closing token.
  119. ++new_position;
  120. } else {
  121. ++new_position;
  122. }
  123. }
  124. }
  125. auto Parser2::Parse() -> void {
  126. // Traces state_stack_. This runs even in opt because it's low overhead.
  127. PrettyStackTraceParseState pretty_stack(this);
  128. PushState(ParserState::Declaration());
  129. while (!state_stack_.empty()) {
  130. switch (state_stack_.back().state) {
  131. #define CARBON_PARSER_STATE(Name) \
  132. case ParserState::Name(): \
  133. Handle##Name##State(); \
  134. break;
  135. #include "toolchain/parser/parser_state.def"
  136. }
  137. }
  138. AddLeafNode(ParseNodeKind::FileEnd(), *position_);
  139. }
  140. auto Parser2::SkipMatchingGroup() -> bool {
  141. if (!PositionKind().IsOpeningSymbol()) {
  142. return false;
  143. }
  144. SkipTo(tokens_.GetMatchedClosingToken(*position_));
  145. ++position_;
  146. return true;
  147. }
  148. auto Parser2::SkipPastLikelyEnd(TokenizedBuffer::Token skip_root)
  149. -> llvm::Optional<TokenizedBuffer::Token> {
  150. if (position_ == end_) {
  151. return llvm::None;
  152. }
  153. TokenizedBuffer::Line root_line = tokens_.GetLine(skip_root);
  154. int root_line_indent = tokens_.GetIndentColumnNumber(root_line);
  155. // We will keep scanning through tokens on the same line as the root or
  156. // lines with greater indentation than root's line.
  157. auto is_same_line_or_indent_greater_than_root =
  158. [&](TokenizedBuffer::Token t) {
  159. TokenizedBuffer::Line l = tokens_.GetLine(t);
  160. if (l == root_line) {
  161. return true;
  162. }
  163. return tokens_.GetIndentColumnNumber(l) > root_line_indent;
  164. };
  165. do {
  166. if (PositionIs(TokenKind::CloseCurlyBrace())) {
  167. // Immediately bail out if we hit an unmatched close curly, this will
  168. // pop us up a level of the syntax grouping.
  169. return llvm::None;
  170. }
  171. // We assume that a semicolon is always intended to be the end of the
  172. // current construct.
  173. if (auto semi = ConsumeIf(TokenKind::Semi())) {
  174. return semi;
  175. }
  176. // Skip over any matching group of tokens_.
  177. if (SkipMatchingGroup()) {
  178. continue;
  179. }
  180. // Otherwise just step forward one token.
  181. ++position_;
  182. } while (position_ != end_ &&
  183. is_same_line_or_indent_greater_than_root(*position_));
  184. return llvm::None;
  185. }
  186. auto Parser2::SkipTo(TokenizedBuffer::Token t) -> void {
  187. CARBON_CHECK(t >= *position_) << "Tried to skip backwards from " << position_
  188. << " to " << TokenizedBuffer::TokenIterator(t);
  189. position_ = TokenizedBuffer::TokenIterator(t);
  190. CARBON_CHECK(position_ != end_) << "Skipped past EOF.";
  191. }
  192. auto Parser2::HandleCodeBlock() -> void {
  193. PushState(ParserState::CodeBlockFinish());
  194. if (ConsumeAndAddLeafNodeIf(TokenKind::OpenCurlyBrace(),
  195. ParseNodeKind::CodeBlockStart())) {
  196. PushState(ParserState::StatementScope());
  197. } else {
  198. AddLeafNode(ParseNodeKind::CodeBlockStart(), *position_,
  199. /*has_error=*/true);
  200. // Recover by parsing a single statement.
  201. CARBON_DIAGNOSTIC(ExpectedCodeBlock, Error, "Expected braced code block.");
  202. emitter_.Emit(*position_, ExpectedCodeBlock);
  203. HandleStatement(PositionKind());
  204. }
  205. }
  206. auto Parser2::HandleCodeBlockFinishState() -> void {
  207. auto state = PopState();
  208. // If the block started with an open curly, this is a close curly.
  209. if (tokens_.GetKind(state.token) == TokenKind::OpenCurlyBrace()) {
  210. AddNode(ParseNodeKind::CodeBlock(), *position_, state.subtree_start,
  211. state.has_error);
  212. ++position_;
  213. } else {
  214. AddNode(ParseNodeKind::CodeBlock(), state.token, state.subtree_start,
  215. /*has_error=*/true);
  216. }
  217. }
  218. auto Parser2::HandleDeclarationState() -> void {
  219. // This maintains the current state unless we're at the end of the file.
  220. switch (PositionKind()) {
  221. case TokenKind::EndOfFile(): {
  222. PopAndDiscardState();
  223. break;
  224. }
  225. case TokenKind::Fn(): {
  226. PushState(ParserState::FunctionIntroducer());
  227. AddLeafNode(ParseNodeKind::FunctionIntroducer(), *position_);
  228. ++position_;
  229. break;
  230. }
  231. case TokenKind::Semi(): {
  232. AddLeafNode(ParseNodeKind::EmptyDeclaration(), *position_);
  233. ++position_;
  234. break;
  235. }
  236. default: {
  237. CARBON_DIAGNOSTIC(UnrecognizedDeclaration, Error,
  238. "Unrecognized declaration introducer.");
  239. emitter_.Emit(*position_, UnrecognizedDeclaration);
  240. tree_.has_errors_ = true;
  241. if (auto semi = SkipPastLikelyEnd(*position_)) {
  242. AddLeafNode(ParseNodeKind::EmptyDeclaration(), *semi,
  243. /*has_error=*/true);
  244. }
  245. break;
  246. }
  247. }
  248. }
  249. auto Parser2::HandleExpressionFormPrimary() -> void {
  250. // TODO: Handle OpenParen and OpenCurlyBrace.
  251. switch (PositionKind()) {
  252. case TokenKind::Identifier():
  253. AddLeafNode(ParseNodeKind::NameReference(), *position_);
  254. break;
  255. case TokenKind::IntegerLiteral():
  256. case TokenKind::RealLiteral():
  257. case TokenKind::StringLiteral():
  258. case TokenKind::IntegerTypeLiteral():
  259. case TokenKind::UnsignedIntegerTypeLiteral():
  260. case TokenKind::FloatingPointTypeLiteral():
  261. AddLeafNode(ParseNodeKind::Literal(), *position_);
  262. break;
  263. default:
  264. CARBON_DIAGNOSTIC(ExpectedExpression, Error, "Expected expression.");
  265. emitter_.Emit(*position_, ExpectedExpression);
  266. ReturnErrorOnState();
  267. return;
  268. }
  269. ++position_;
  270. }
  271. auto Parser2::HandleExpressionState() -> void {
  272. // TODO: This is temporary, we should need this state. If not, maybe add an
  273. // overload that uses pop_back instead of pop_back_val.
  274. auto state = PopState();
  275. (void)state;
  276. HandleExpressionFormPrimary();
  277. }
  278. auto Parser2::HandleExpressionForTypeState() -> void {
  279. // TODO: This is temporary, we should need this state. If not, maybe add an
  280. // overload that uses pop_back instead of pop_back_val.
  281. auto state = PopState();
  282. (void)state;
  283. HandleExpressionFormPrimary();
  284. }
  285. auto Parser2::HandleExpressionStatementFinishState() -> void {
  286. auto state = PopState();
  287. if (auto semi = ConsumeIf(TokenKind::Semi())) {
  288. AddNode(ParseNodeKind::ExpressionStatement(), *semi, state.subtree_start,
  289. state.has_error);
  290. return;
  291. }
  292. if (!state.has_error) {
  293. CARBON_DIAGNOSTIC(ExpectedSemiAfterExpression, Error,
  294. "Expected `;` after expression.");
  295. emitter_.Emit(*position_, ExpectedSemiAfterExpression);
  296. }
  297. if (auto semi_token = SkipPastLikelyEnd(state.token)) {
  298. AddNode(ParseNodeKind::ExpressionStatement(), *semi_token,
  299. state.subtree_start,
  300. /*has_error=*/true);
  301. return;
  302. }
  303. // Found junk not even followed by a `;`, no node to add.
  304. ReturnErrorOnState();
  305. }
  306. auto Parser2::HandleFunctionError(StateStackEntry state,
  307. bool skip_past_likely_end) -> void {
  308. auto token = state.token;
  309. if (skip_past_likely_end) {
  310. if (auto semi = SkipPastLikelyEnd(token)) {
  311. token = *semi;
  312. }
  313. }
  314. AddNode(ParseNodeKind::FunctionDeclaration(), token, state.subtree_start,
  315. /*has_error=*/true);
  316. }
  317. auto Parser2::HandleFunctionIntroducerState() -> void {
  318. auto state = PopState();
  319. if (!ConsumeAndAddLeafNodeIf(TokenKind::Identifier(),
  320. ParseNodeKind::DeclaredName())) {
  321. CARBON_DIAGNOSTIC(ExpectedFunctionName, Error,
  322. "Expected function name after `fn` keyword.");
  323. emitter_.Emit(*position_, ExpectedFunctionName);
  324. // TODO: We could change the lexer to allow us to synthesize certain
  325. // kinds of tokens and try to "recover" here, but unclear that this is
  326. // really useful.
  327. HandleFunctionError(state, true);
  328. return;
  329. }
  330. if (!PositionIs(TokenKind::OpenParen())) {
  331. CARBON_DIAGNOSTIC(ExpectedFunctionParams, Error,
  332. "Expected `(` after function name.");
  333. emitter_.Emit(*position_, ExpectedFunctionParams);
  334. HandleFunctionError(state, true);
  335. return;
  336. }
  337. // Parse the parameter list as its own subtree; once that pops, resume
  338. // function parsing.
  339. state.state = ParserState::FunctionAfterParameterList();
  340. PushState(state);
  341. // TODO: When swapping () start/end, this should AddLeafNode the open before
  342. // continuing.
  343. PushState(ParserState::FunctionParameterListFinish());
  344. // Advance past the open paren.
  345. ++position_;
  346. if (PositionKind() != TokenKind::CloseParen()) {
  347. PushState(ParserState::PatternForFunctionParameter());
  348. }
  349. }
  350. auto Parser2::HandleFunctionParameterListFinishState() -> void {
  351. auto state = PopState();
  352. CARBON_CHECK(PositionKind() == TokenKind::CloseParen())
  353. << PositionKind().Name();
  354. AddLeafNode(ParseNodeKind::ParameterListEnd(), *position_);
  355. AddNode(ParseNodeKind::ParameterList(), state.token, state.subtree_start,
  356. state.has_error);
  357. ++position_;
  358. }
  359. auto Parser2::HandleFunctionAfterParameterListState() -> void {
  360. auto state = PopState();
  361. // Regardless of whether there's a return type, we'll finish the signature.
  362. state.state = ParserState::FunctionSignatureFinish();
  363. PushState(state);
  364. // If there is a return type, parse the expression before adding the return
  365. // type nod.e
  366. if (PositionIs(TokenKind::MinusGreater())) {
  367. PushState(ParserState::FunctionReturnTypeFinish());
  368. ++position_;
  369. PushState(ParserState::ExpressionForType());
  370. }
  371. }
  372. auto Parser2::HandleFunctionReturnTypeFinishState() -> void {
  373. auto state = PopState();
  374. AddNode(ParseNodeKind::ReturnType(), state.token, state.subtree_start,
  375. state.has_error);
  376. }
  377. auto Parser2::HandleFunctionSignatureFinishState() -> void {
  378. auto state = PopState();
  379. switch (PositionKind()) {
  380. case TokenKind::Semi(): {
  381. AddNode(ParseNodeKind::FunctionDeclaration(), *position_,
  382. state.subtree_start, state.has_error);
  383. ++position_;
  384. break;
  385. }
  386. case TokenKind::OpenCurlyBrace(): {
  387. AddNode(ParseNodeKind::FunctionDefinitionStart(), *position_,
  388. state.subtree_start, state.has_error);
  389. ++position_;
  390. // Any error is recorded on the FunctionDefinitionStart.
  391. state.has_error = false;
  392. state.state = ParserState::FunctionDefinitionFinish();
  393. PushState(state);
  394. PushState(ParserState::StatementScope());
  395. break;
  396. }
  397. default: {
  398. CARBON_DIAGNOSTIC(
  399. ExpectedFunctionBodyOrSemi, Error,
  400. "Expected function definition or `;` after function declaration.");
  401. emitter_.Emit(*position_, ExpectedFunctionBodyOrSemi);
  402. // Only need to skip if we've not already found a new line.
  403. bool skip_past_likely_end =
  404. tokens_.GetLine(*position_) == tokens_.GetLine(state.token);
  405. HandleFunctionError(state, skip_past_likely_end);
  406. break;
  407. }
  408. }
  409. }
  410. auto Parser2::HandleFunctionDefinitionFinishState() -> void {
  411. auto state = PopState();
  412. AddNode(ParseNodeKind::FunctionDefinition(), *position_, state.subtree_start,
  413. state.has_error);
  414. ++position_;
  415. }
  416. auto Parser2::HandlePatternStart(PatternKind pattern_kind) -> void {
  417. auto state = PopState();
  418. // Ensure the finish state always follows.
  419. switch (pattern_kind) {
  420. case PatternKind::Parameter: {
  421. state.state = ParserState::PatternForFunctionParameterFinish();
  422. break;
  423. }
  424. case PatternKind::Variable: {
  425. CARBON_FATAL() << "TODO";
  426. break;
  427. }
  428. }
  429. // Handle an invalid pattern introducer.
  430. if (!PositionIs(TokenKind::Identifier()) ||
  431. tokens_.GetKind(*(position_ + 1)) != TokenKind::Colon()) {
  432. switch (pattern_kind) {
  433. case PatternKind::Parameter: {
  434. CARBON_DIAGNOSTIC(ExpectedParameterName, Error,
  435. "Expected parameter declaration.");
  436. emitter_.Emit(*position_, ExpectedParameterName);
  437. break;
  438. }
  439. case PatternKind::Variable: {
  440. CARBON_DIAGNOSTIC(ExpectedVariableName, Error,
  441. "Expected pattern in `var` declaration.");
  442. emitter_.Emit(*position_, ExpectedVariableName);
  443. break;
  444. }
  445. }
  446. state.has_error = true;
  447. PushState(state);
  448. return;
  449. }
  450. // Switch the context token to the colon, so that it'll be used for the root
  451. // node.
  452. state.token = *(position_ + 1);
  453. PushState(state);
  454. PushState(ParserState::ExpressionForType());
  455. AddLeafNode(ParseNodeKind::DeclaredName(), *position_);
  456. position_ += 2;
  457. }
  458. auto Parser2::HandleKeywordStatementFinish(TokenKind token_kind,
  459. ParseNodeKind node_kind) -> void {
  460. auto state = PopState();
  461. auto semi =
  462. ConsumeAndAddLeafNodeIf(TokenKind::Semi(), ParseNodeKind::StatementEnd());
  463. if (!semi) {
  464. CARBON_DIAGNOSTIC(ExpectedSemiAfter, Error, "Expected `;` after `{0}`.",
  465. TokenKind);
  466. emitter_.Emit(*position_, ExpectedSemiAfter, token_kind);
  467. if (auto semi_token = SkipPastLikelyEnd(state.token)) {
  468. AddLeafNode(ParseNodeKind::StatementEnd(), *semi_token,
  469. /*has_error=*/true);
  470. }
  471. }
  472. AddNode(node_kind, state.token, state.subtree_start, state.has_error);
  473. }
  474. auto Parser2::HandleKeywordStatementFinishForReturnState() -> void {
  475. HandleKeywordStatementFinish(TokenKind::Return(),
  476. ParseNodeKind::ReturnStatement());
  477. }
  478. auto Parser2::HandleParenConditionState() -> void {
  479. auto state = PopState();
  480. auto open_paren = ConsumeIf(TokenKind::OpenParen());
  481. if (open_paren) {
  482. state.token = *open_paren;
  483. } else {
  484. CARBON_DIAGNOSTIC(ExpectedParenAfter, Error, "Expected `(` after `{0}`.",
  485. TokenKind);
  486. emitter_.Emit(*position_, ExpectedParenAfter, tokens_.GetKind(state.token));
  487. }
  488. // TODO: This should be adding a ConditionStart here instead of ConditionEnd
  489. // later, so this does state modification instead of a simpler push.
  490. state.state = ParserState::ParenConditionFinish();
  491. PushState(state);
  492. PushState(ParserState::Expression());
  493. }
  494. auto Parser2::HandleParenConditionFinishState() -> void {
  495. auto state = PopState();
  496. if (tokens_.GetKind(state.token) != TokenKind::OpenParen()) {
  497. // Don't expect a matching closing paren if there wasn't an opening paren.
  498. // TODO: Should probably push nodes on this state in order to have the
  499. // condition wrapped, but it wasn't before, so not doing it for consistency.
  500. ReturnErrorOnState();
  501. return;
  502. }
  503. bool close_paren =
  504. ConsumeAndAddCloseParen(state.token, ParseNodeKind::ConditionEnd());
  505. return AddNode(ParseNodeKind::Condition(), state.token, state.subtree_start,
  506. /*has_error=*/state.has_error || !close_paren);
  507. }
  508. auto Parser2::HandlePatternForFunctionParameterState() -> void {
  509. HandlePatternStart(PatternKind::Parameter);
  510. }
  511. auto Parser2::HandlePatternForFunctionParameterFinishState() -> void {
  512. auto state = PopState();
  513. // If an error was encountered, propagate it without adding a node.
  514. bool has_error = state.has_error;
  515. if (has_error) {
  516. ReturnErrorOnState();
  517. } else {
  518. // TODO: may need to mark has_error if !type.
  519. AddNode(ParseNodeKind::PatternBinding(), state.token, state.subtree_start,
  520. state.has_error);
  521. }
  522. // Handle tokens following a parameter.
  523. switch (PositionKind()) {
  524. case TokenKind::CloseParen(): {
  525. // Done with the parameter list.
  526. return;
  527. }
  528. case TokenKind::Comma(): {
  529. // Comma handling is after the switch.
  530. break;
  531. }
  532. default: {
  533. // Don't error twice for the same issue.
  534. if (!has_error) {
  535. CARBON_DIAGNOSTIC(UnexpectedTokenAfterListElement, Error,
  536. "Expected `,` or `)`.");
  537. emitter_.Emit(*position_, UnexpectedTokenAfterListElement);
  538. ReturnErrorOnState();
  539. }
  540. // Recover from the invalid token.
  541. auto end_of_element =
  542. FindNextOf({TokenKind::Comma(), TokenKind::CloseParen()});
  543. // The lexer guarantees that parentheses are balanced.
  544. CARBON_CHECK(end_of_element) << "missing matching `)` for `(`";
  545. SkipTo(*end_of_element);
  546. if (PositionKind() == TokenKind::CloseParen()) {
  547. // Done with the parameter list.
  548. return;
  549. }
  550. // Comma handling is after the switch.
  551. break;
  552. }
  553. }
  554. // We are guaranteed to now be at a comma.
  555. AddLeafNode(ParseNodeKind::ParameterListComma(), *position_);
  556. ++position_;
  557. if (PositionKind() != TokenKind::CloseParen()) {
  558. PushState(ParserState::PatternForFunctionParameter());
  559. }
  560. }
  561. auto Parser2::HandleStatementIf() -> void {
  562. PushState(ParserState::StatementIfConditionFinish());
  563. PushState(ParserState::ParenCondition());
  564. ++position_;
  565. }
  566. auto Parser2::HandleStatementIfConditionFinishState() -> void {
  567. auto state = PopState();
  568. state.state = ParserState::StatementIfThenBlockFinish();
  569. PushState(state);
  570. HandleCodeBlock();
  571. }
  572. auto Parser2::HandleStatementIfThenBlockFinishState() -> void {
  573. auto state = PopState();
  574. if (ConsumeAndAddLeafNodeIf(TokenKind::Else(),
  575. ParseNodeKind::IfStatementElse())) {
  576. state.state = ParserState::StatementIfElseBlockFinish();
  577. PushState(state);
  578. // `else if` is permitted as a special case.
  579. if (PositionIs(TokenKind::If())) {
  580. HandleStatementIf();
  581. } else {
  582. HandleCodeBlock();
  583. }
  584. } else {
  585. AddNode(ParseNodeKind::IfStatement(), state.token, state.subtree_start,
  586. state.has_error);
  587. }
  588. }
  589. auto Parser2::HandleStatementIfElseBlockFinishState() -> void {
  590. auto state = PopState();
  591. AddNode(ParseNodeKind::IfStatement(), state.token, state.subtree_start,
  592. state.has_error);
  593. }
  594. auto Parser2::HandleStatement(TokenKind token_kind) -> void {
  595. switch (token_kind) {
  596. case TokenKind::If(): {
  597. HandleStatementIf();
  598. break;
  599. }
  600. case TokenKind::Return(): {
  601. auto return_token = *position_;
  602. if (tokens_.GetKind(*(position_ + 1)) == TokenKind::Semi()) {
  603. int subtree_start = tree_.size();
  604. AddLeafNode(ParseNodeKind::StatementEnd(), *(position_ + 1));
  605. AddNode(ParseNodeKind::ReturnStatement(), return_token, subtree_start,
  606. /*has_error=*/false);
  607. position_ += 2;
  608. } else {
  609. PushState(ParserState::KeywordStatementFinishForReturn());
  610. ++position_;
  611. PushState(ParserState::Expression());
  612. }
  613. break;
  614. }
  615. default: {
  616. PushState(ParserState::ExpressionStatementFinish());
  617. PushState(ParserState::Expression());
  618. break;
  619. }
  620. }
  621. }
  622. auto Parser2::HandleStatementScopeState() -> void {
  623. // This maintains the current state until we're at the end of the scope.
  624. auto token_kind = PositionKind();
  625. if (token_kind == TokenKind::CloseCurlyBrace()) {
  626. auto state = PopState();
  627. if (state.has_error) {
  628. ReturnErrorOnState();
  629. }
  630. } else {
  631. HandleStatement(token_kind);
  632. }
  633. }
  634. } // namespace Carbon