parser_handle_paren_expression.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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/parser_context.h"
  5. namespace Carbon {
  6. auto ParserHandleParenExpression(ParserContext& context) -> void {
  7. auto state = context.PopState();
  8. // Advance past the open paren.
  9. context.AddLeafNode(ParseNodeKind::ParenExpressionOrTupleLiteralStart,
  10. context.ConsumeChecked(TokenKind::OpenParen));
  11. if (context.PositionIs(TokenKind::CloseParen)) {
  12. state.state = ParserState::ParenExpressionFinishAsTuple;
  13. context.PushState(state);
  14. } else {
  15. state.state = ParserState::ParenExpressionFinishAsNormal;
  16. context.PushState(state);
  17. context.PushState(ParserState::ParenExpressionParameterFinishAsUnknown);
  18. context.PushState(ParserState::Expression);
  19. }
  20. }
  21. // Handles ParenExpressionParameterFinishAs(Unknown|Tuple).
  22. static auto ParserHandleParenExpressionParameterFinish(ParserContext& context,
  23. bool as_tuple) -> void {
  24. auto state = context.PopState();
  25. auto list_token_kind = context.ConsumeListToken(
  26. ParseNodeKind::TupleLiteralComma, TokenKind::CloseParen, state.has_error);
  27. if (list_token_kind == ParserContext::ListTokenKind::Close) {
  28. return;
  29. }
  30. // If this is the first item and a comma was found, switch to tuple handling.
  31. // Note this could be `(expr,)` so we may not reuse the current state, but
  32. // it's still necessary to switch the parent.
  33. if (!as_tuple) {
  34. state.state = ParserState::ParenExpressionParameterFinishAsTuple;
  35. auto finish_state = context.PopState();
  36. CARBON_CHECK(finish_state.state ==
  37. ParserState::ParenExpressionFinishAsNormal)
  38. << "Unexpected parent state, found: " << finish_state.state;
  39. finish_state.state = ParserState::ParenExpressionFinishAsTuple;
  40. context.PushState(finish_state);
  41. }
  42. // On a comma, push another expression handler.
  43. if (list_token_kind == ParserContext::ListTokenKind::Comma) {
  44. context.PushState(state);
  45. context.PushState(ParserState::Expression);
  46. }
  47. }
  48. auto ParserHandleParenExpressionParameterFinishAsUnknown(ParserContext& context)
  49. -> void {
  50. ParserHandleParenExpressionParameterFinish(context, /*as_tuple=*/false);
  51. }
  52. auto ParserHandleParenExpressionParameterFinishAsTuple(ParserContext& context)
  53. -> void {
  54. ParserHandleParenExpressionParameterFinish(context, /*as_tuple=*/true);
  55. }
  56. auto ParserHandleParenExpressionFinishAsNormal(ParserContext& context) -> void {
  57. auto state = context.PopState();
  58. context.AddNode(ParseNodeKind::ParenExpression, context.Consume(),
  59. state.subtree_start, state.has_error);
  60. }
  61. auto ParserHandleParenExpressionFinishAsTuple(ParserContext& context) -> void {
  62. auto state = context.PopState();
  63. context.AddNode(ParseNodeKind::TupleLiteral, context.Consume(),
  64. state.subtree_start, state.has_error);
  65. }
  66. } // namespace Carbon