parser_handle_declaration_name_and_params.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. // Handles DeclarationNameAndParamsAs(Optional|Required).
  7. static auto ParserHandleDeclarationNameAndParams(ParserContext& context,
  8. ParserState after_name)
  9. -> void {
  10. auto state = context.PopState();
  11. // TODO: Should handle designated names.
  12. if (auto identifier = context.ConsumeIf(TokenKind::Identifier)) {
  13. state.state = after_name;
  14. context.PushState(state);
  15. if (context.PositionIs(TokenKind::Period)) {
  16. context.AddLeafNode(ParseNodeKind::Name, *identifier);
  17. state.state = ParserState::PeriodAsDeclaration;
  18. context.PushState(state);
  19. } else {
  20. context.AddLeafNode(ParseNodeKind::Name, *identifier);
  21. }
  22. } else {
  23. CARBON_DIAGNOSTIC(ExpectedDeclarationName, Error,
  24. "`{0}` introducer should be followed by a name.",
  25. TokenKind);
  26. context.emitter().Emit(*context.position(), ExpectedDeclarationName,
  27. context.tokens().GetKind(state.token));
  28. context.ReturnErrorOnState();
  29. context.AddLeafNode(ParseNodeKind::InvalidParse, *context.position());
  30. }
  31. }
  32. auto ParserHandleDeclarationNameAndParamsAsNone(ParserContext& context)
  33. -> void {
  34. ParserHandleDeclarationNameAndParams(
  35. context, ParserState::DeclarationNameAndParamsAfterNameAsNone);
  36. }
  37. auto ParserHandleDeclarationNameAndParamsAsOptional(ParserContext& context)
  38. -> void {
  39. ParserHandleDeclarationNameAndParams(
  40. context, ParserState::DeclarationNameAndParamsAfterNameAsOptional);
  41. }
  42. auto ParserHandleDeclarationNameAndParamsAsRequired(ParserContext& context)
  43. -> void {
  44. ParserHandleDeclarationNameAndParams(
  45. context, ParserState::DeclarationNameAndParamsAfterNameAsRequired);
  46. }
  47. enum class Params {
  48. None,
  49. Optional,
  50. Required,
  51. };
  52. static auto ParserHandleDeclarationNameAndParamsAfterName(
  53. ParserContext& context, Params params) -> void {
  54. auto state = context.PopState();
  55. if (context.PositionIs(TokenKind::Period)) {
  56. // Continue designator processing.
  57. context.PushState(state);
  58. state.state = ParserState::PeriodAsDeclaration;
  59. context.PushState(state);
  60. return;
  61. }
  62. if (params == Params::None) {
  63. return;
  64. }
  65. if (context.PositionIs(TokenKind::OpenSquareBracket)) {
  66. context.PushState(ParserState::DeclarationNameAndParamsAfterDeduced);
  67. context.PushState(ParserState::ParameterListAsDeduced);
  68. } else if (context.PositionIs(TokenKind::OpenParen)) {
  69. context.PushState(ParserState::ParameterListAsRegular);
  70. } else if (params == Params::Required) {
  71. CARBON_DIAGNOSTIC(ParametersRequiredByIntroducer, Error,
  72. "`{0}` requires a `(` for parameters.", TokenKind);
  73. context.emitter().Emit(*context.position(), ParametersRequiredByIntroducer,
  74. context.tokens().GetKind(state.token));
  75. context.ReturnErrorOnState();
  76. }
  77. }
  78. auto ParserHandleDeclarationNameAndParamsAfterNameAsNone(ParserContext& context)
  79. -> void {
  80. ParserHandleDeclarationNameAndParamsAfterName(context, Params::None);
  81. }
  82. auto ParserHandleDeclarationNameAndParamsAfterNameAsOptional(
  83. ParserContext& context) -> void {
  84. ParserHandleDeclarationNameAndParamsAfterName(context, Params::Optional);
  85. }
  86. auto ParserHandleDeclarationNameAndParamsAfterNameAsRequired(
  87. ParserContext& context) -> void {
  88. ParserHandleDeclarationNameAndParamsAfterName(context, Params::Required);
  89. }
  90. auto ParserHandleDeclarationNameAndParamsAfterDeduced(ParserContext& context)
  91. -> void {
  92. context.PopAndDiscardState();
  93. if (context.PositionIs(TokenKind::OpenParen)) {
  94. context.PushState(ParserState::ParameterListAsRegular);
  95. } else {
  96. CARBON_DIAGNOSTIC(
  97. ParametersRequiredByDeduced, Error,
  98. "A `(` for parameters is required after deduced parameters.");
  99. context.emitter().Emit(*context.position(), ParametersRequiredByDeduced);
  100. context.ReturnErrorOnState();
  101. }
  102. }
  103. } // namespace Carbon